File: runserver_plus.rst

package info (click to toggle)
python-django-extensions 1.7.4-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 2,016 kB
  • ctags: 1,342
  • sloc: python: 8,873; makefile: 117
file content (230 lines) | stat: -rw-r--r-- 7,831 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
RunServerPlus
=============

:synopsis: RunServerPlus-typical runserver with Werkzeug debugger baked in


Introduction
------------

This item requires that you have the `Werkzeug WSGI utilities` installed.
Included with Werkzeug_ is a kick ass debugger that renders nice
debugging tracebacks and adds an AJAX based debugger (which allows code execution
in the context of the traceback’s frames).  Additionally it provides a nice
access view to the source code.


Getting Started
---------------

To get started we just use the *runserver_plus* command instead of the normal
*runserver* command::

  $ python manage.py runserver_plus

  * Running on http://127.0.0.1:8000/
  * Restarting with reloader...

  Validating models...
  0 errors found

  Django version X.Y.Z, using settings 'screencasts.settings'
  Development server is running at http://127.0.0.1:8000/
  Using the Werkzeug debugger (http://werkzeug.pocoo.org/)
  Quit the server with CONTROL-C.

Note: all normal runserver options apply. In other words, if you need to change
the port number or the host information, you can do so like you would normally.


Usage
-----

Instead of the default Django traceback page, the Werkzeug traceback page
will be shown when an exception occurs.

.. image:: images/2637f826-2c22-11e3-83c6-646acc87808b.png
    :alt: werkzeug-traceback

Along with the typical traceback information we have a couple of options. These
options appear when hovering over a particular traceback line.  Notice that
two buttons appear to the right:

.. image:: images/558ad0ee-2c22-11e3-8ddd-6678d84d77e7.png
    :alt: werkzeug-options

The options are:


View Source
^^^^^^^^^^^

This displays the source underneath the traceback:

.. image:: images/583c8c42-2c22-11e3-9eb9-5c16b8732512.png
    :alt: werkzeug-source

Being able to view the source file is handy because it provides more
context information around the error.  The actual traceback areas are
highlighted so they are easy to spot.

One awkward aspect of the UI is that the page is not scrolled to the bottom.
At first I thought nothing was happening because of this.


Interactive Debugging Console
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Clicking on this button opens up a new pane under the traceback line
you're on. This is the money shot:

.. image:: images/5d12eda6-2c22-11e3-802a-2639ff8813fa.png
    :alt: werkzeug-debugger

An ajax based console appears in the pane and you can start debugging.
Notice in the screenshot above I did a `print environ` to see what was in the
environment parameter coming into the function.

*WARNING*: This should *never* be used in any kind of production environment.
Not even for a quick problem check.  I cannot emphasize this enough. The
interactive debugger allows you to evaluate python code right against the
server.  You've been warned.

.. _`Werkzeug WSGI utilities`: http://werkzeug.pocoo.org/


SSL
^^^

runserver_plus also supports SSL, so that you can easily debug bugs that to pop up
when https is used. To use SSL simply provide a file name for certificates;
a key and certificate file will be automatically generated::

  $ python manage.py runserver_plus --cert cert
  Validating models...
  0 errors found

  Django version X.Y.Z, using settings 'mysite.settings'
  Development server is running at http://127.0.0.1:8000/
  Using the Werkzeug debugger (http://werkzeug.pocoo.org/)
  Quit the server with CONTROL-C.
   * Running on https://127.0.0.1:8000/
   * Restarting with reloader
  Validating models...
  0 errors found

  Django version X.Y.Z, using settings 'mysite.settings'
  Development server is running at http://127.0.0.1:8000/
  Using the Werkzeug debugger (http://werkzeug.pocoo.org/)
  Quit the server with CONTROL-C.

After running this command, your web application can be accessed through
https://127.0.0.1:8000.

You will also find that two files are created in  the current working directory:
a key file and a certificate file. If you run the above command again, these
certificate files will be reused so that you do not have to keep accepting the
self-generated certificates from your browser every time. You can also provide
a specific file for the certificate to be used if you already have one::

  $ python manage.py runserver_plus --cert /tmp/cert

Note that you need the OpenSSL library to use SSL, and Werkzeug 0.9 or later
if you want to reuse existing certificates.

To install OpenSSL::

  $ pip install pyOpenSSL

Configuration
^^^^^^^^^^^^^

The `RUNSERVERPLUS_SERVER_ADDRESS_PORT` setting can be configured to specify
which address and port the development server should bind to.

If you find yourself frequently starting the server with::

  $ python manage.py runserver_plus 0.0.0.0:8000

You can use settings to automatically default your development to an address/port::

    RUNSERVERPLUS_SERVER_ADDRESS_PORT = '0.0.0.0:8000'

To ensure Werkzeug can log to the console, you may need to add the following
to your settings::

  LOGGING = {
      ...
      'handlers': {
          ...
          'console': {
              'level': 'DEBUG',
              'class': 'logging.StreamHandler',
          },
      },
      'loggers': {
          ...
          'werkzeug': {
              'handlers': ['console'],
              'level': 'DEBUG',
              'propagate': True,
          },
      },
  }

IO Calls and CPU Usage
^^^^^^^^^^^^^^^^^^^^^^

As noted in gh625_ `runserver_plus` can be seen to use a lot of CPU and generate many
I/O when idle.

This is due to the way Werkzeug_ has implemented the auto reload capability.
It supports two ways of doing auto reloading either via `stat polling` or `file system events`.

The `stat polling` approach is pretty brute force and continously issues `stat` system calls which
causes the CPU and IO load.

If possible try to install the Watchdog_ package, this should automatically cause Werkzeug_ to use
`file system events` whenever possible.

You can read more about this in `Werkzeug documentation <http://werkzeug.pocoo.org/docs/0.10/serving/#reloader>`_

You can also increase the poll interval when using `stat polling` from the default of 1 second. This
will decrease the CPU load at the expense of file edits taking longer to pick up.

This can be set two ways, in the django settings file:

    RUNSERVERPLUS_POLLER_RELOADER_INTERVAL = 5

or as a commad line argument:

  $ python manage.py runserver_plus --reloader-interval 5


Debugger PIN
------------

.. epigraph::
   The following text about the debugger PIN is taken verbatim from the Werkzeug documentation.

   -- http://werkzeug.pocoo.org/docs/0.11/debug/#debugger-pin

Starting with Werkzeug 0.11 the debugger is additionally protected by a PIN. This is a security helper to
make it less likely for the debugger to be exploited in production as it has happened to people to keep the
debugger active. The PIN based authentication is enabled by default.

When the debugger comes up, on first usage it will prompt for a PIN that is printed to the command line.
The PIN is generated in a stable way that is specific to the project. In some situations it might be not possible
to generate a stable PIN between restarts in which case an explicit PIN can be provided through the environment
variable WERKZEUG_DEBUG_PIN. This can be set to a number and will become the PIN. This variable can also be set
to the value off to disable the PIN check entirely.

If the PIN is entered too many times incorrectly the server needs to be restarted.

This feature is not supposed to entirely secure the debugger. It’s intended to make it harder for an attacker to
exploit the debugger. Never enable the debugger in production.


.. _gh625: https://github.com/django-extensions/django-extensions/issues/625
.. _Werkzeug: http://werkzeug.pocoo.org/
.. _Watchdog: https://pypi.python.org/pypi/watchdog