Serving WSGI Applications

There are many ways to serve a WSGI application. While you’re developing it,you usually don’t want to have a full-blown webserver like Apache up andrunning, but instead a simple standalone one. Because of that Werkzeug comeswith a builtin development server.

The easiest way is creating a small start-myproject.py file that runs theapplication using the builtin server:

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. from werkzeug.serving import run_simple
  5. from myproject import make_app
  6.  
  7. app = make_app(...)
  8. run_simple('localhost', 8080, app, use_reloader=True)

You can also pass it the extra_files keyword argument with a list ofadditional files (like configuration files) you want to observe.

  • werkzeug.serving.runsimple(_hostname, port, application, use_reloader=False, use_debugger=False, use_evalex=True, extra_files=None, reloader_interval=1, reloader_type='auto', threaded=False, processes=1, request_handler=None, static_files=None, passthrough_errors=False, ssl_context=None)
  • Start a WSGI application. Optional features include a reloader,multithreading and fork support.

This function has a command-line interface too:

  1. python -m werkzeug.serving --help

New in version 0.5: static_files was added to simplify serving of static files as wellas passthrough_errors.

New in version 0.6: support for SSL was added.

New in version 0.8: Added support for automatically loading a SSL context from certificatefile and private key.

New in version 0.9: Added command-line interface.

New in version 0.10: Improved the reloader and added support for changing the backendthrough the reloader_type parameter. See Reloaderfor more information.

Changed in version 0.15: Bind to a Unix socket by passing a path that starts withunix:// as the hostname.

Parameters:

  • hostname – The host to bind to, for example 'localhost'.If the value is a path that starts with unix:// it will bindto a Unix socket instead of a TCP socket..
  • port – The port for the server. eg: 8080
  • application – the WSGI application to execute
  • use_reloader – should the server automatically restart the pythonprocess if modules were changed?
  • use_debugger – should the werkzeug debugging system be used?
  • use_evalex – should the exception evaluation feature be enabled?
  • extra_files – a list of files the reloader should watchadditionally to the modules. For example configurationfiles.
  • reloader_interval – the interval for the reloader in seconds.
  • reloader_type – the type of reloader to use. The default isauto detection. Valid values are 'stat' and'watchdog'. See Reloader for moreinformation.
  • threaded – should the process handle each request in a separatethread?
  • processes – if greater than 1 then handle each request in a new processup to this maximum number of concurrent processes.
  • request_handler – optional parameter that can be used to replacethe default one. You can use this to replace itwith a differentBaseHTTPRequestHandlersubclass.
  • static_files – a list or dict of paths for static files. This worksexactly like SharedDataMiddleware, it’s actuallyjust wrapping the application in that middleware beforeserving.
  • passthrough_errors – set this to True to disable the error catching.This means that the server will die on errors butit can be useful to hook debuggers in (pdb etc.)
  • ssl_context – an SSL context for the connection. Either anssl.SSLContext, a tuple in the form(cert_file, pkey_file), the string 'adhoc' ifthe server should automatically create one, or Noneto disable SSL (which is the default).
  • werkzeug.serving.is_running_from_reloader()
  • Checks if the application is running from within the Werkzeugreloader subprocess.

New in version 0.10.

  • werkzeug.serving.makessl_devcert(_base_path, host=None, cn=None)
  • Creates an SSL key for development. This should be used instead ofthe 'adhoc' key which generates a new cert on each server start.It accepts a path for where it should store the key and cert andeither a host or CN. If a host is given it will use the CN*.host/CN=host.

For more information see run_simple().

New in version 0.9.

Parameters:

  • base_path – the path to the certificate and key. The extension.crt is added for the certificate, .key isadded for the key.
  • host – the name of the host. This can be used as an alternativefor the cn.
  • cn – the CN to use.

Information

The development server is not intended to be used on production systems.It was designed especially for development purposes and performs poorlyunder high load. For deployment setups have a look at theApplication Deployment pages.

Reloader

Changed in version 0.10.

The Werkzeug reloader constantly monitors modules and paths of your webapplication, and restarts the server if any of the observed files change.

Since version 0.10, there are two backends the reloader supports: stat andwatchdog.

  • The default stat backend simply checks the mtime of all files in aregular interval. This is sufficient for most cases, however, it is known todrain a laptop’s battery.
  • The watchdog backend uses filesystem events, and is much faster thanstat. It requires the watchdogmodule to be installed. The recommended way to achieve this is to addWerkzeug[watchdog] to your requirements file.

If watchdog is installed and available it will automatically be usedinstead of the builtin stat reloader.

To switch between the backends you can use the reloader_type parameter of therun_simple() function. 'stat' sets it to the default stat basedpolling and 'watchdog' forces it to the watchdog backend.

Note

Some edge cases, like modules that failed to import correctly, are nothandled by the stat reloader for performance reasons. The watchdog reloadermonitors such files too.

Colored Logging

Werkzeug is able to color the output of request logs when ran from a terminal, just install the termcolor package. Windows users need to install colorama in addition to termcolor for this to work.

Virtual Hosts

Many web applications utilize multiple subdomains. This can be a bit trickyto simulate locally. Fortunately there is the hosts file that can be usedto assign the local computer multiple names.

This allows you to call your local computer yourapplication.local andapi.yourapplication.local (or anything else) in addition to localhost.

You can find the hosts file on the following location:

Windows%SystemRoot%\system32\drivers\etc\hosts
Linux / OS X/etc/hosts

You can open the file with your favorite text editor and add a new name afterlocalhost:

  1. 127.0.0.1 localhost yourapplication.local api.yourapplication.local

Save the changes and after a while you should be able to access thedevelopment server on these host names as well. You can use theURL Routing system to dispatch between different hosts or parserequest.host yourself.

Shutting Down The Server

New in version 0.7.

Starting with Werkzeug 0.7 the development server provides a way to shutdown the server after a request. This currently only works with Python2.6 and later and will only work with the development server. To initiatethe shutdown you have to call a function named'werkzeug.server.shutdown' in the WSGI environment:

  1. def shutdown_server(environ):
  2. if not 'werkzeug.server.shutdown' in environ:
  3. raise RuntimeError('Not running the development server')
  4. environ['werkzeug.server.shutdown']()

Troubleshooting

On operating systems that support ipv6 and have it configured such as modernLinux systems, OS X 10.4 or higher as well as Windows Vista some browsers canbe painfully slow if accessing your local server. The reason for this is thatsometimes “localhost” is configured to be available on both ipv4 and ipv6 socketsand some browsers will try to access ipv6 first and then ipv4.

At the current time the integrated webserver does not support ipv6 and ipv4 atthe same time and for better portability ipv4 is the default.

If you notice that the web browser takes ages to load the page there are two waysaround this issue. If you don’t need ipv6 support you can disable the ipv6 entryin the hosts file by removing this line:

  1. ::1 localhost

Alternatively you can also disable ipv6 support in your browser. For exampleif Firefox shows this behavior you can disable it by going to about:configand disabling the network.dns.disableIPv6 key. This however is notrecommended as of Werkzeug 0.6.1!

Starting with Werkzeug 0.6.1, the server will now switch between ipv4 andipv6 based on your operating system’s configuration. This means if thatyou disabled ipv6 support in your browser but your operating system ispreferring ipv6, you will be unable to connect to your server. In thatsituation, you can either remove the localhost entry for ::1 orexplicitly bind the hostname to an ipv4 address (127.0.0.1)

SSL

New in version 0.6.

The builtin server supports SSL for testing purposes. If an SSL context isprovided it will be used. That means a server can either run in HTTP or HTTPSmode, but not both.

Quickstart

The easiest way to do SSL based development with Werkzeug is by using itto generate an SSL certificate and private key and storing that somewhereand to then put it there. For the certificate you need to provide thename of your server on generation or a CN.

  • Generate an SSL key and store it somewhere:
  1. >>> from werkzeug.serving import make_ssl_devcert
  2. >>> make_ssl_devcert('/path/to/the/key', host='localhost')
  3. ('/path/to/the/key.crt', '/path/to/the/key.key')
  • Now this tuple can be passed as ssl_context to therun_simple() method:
  1. run_simple('localhost', 4000, application,
  2. ssl_context=('/path/to/the/key.crt',
  3. '/path/to/the/key.key'))

You will have to acknowledge the certificate in your browser once then.

Loading Contexts by Hand

In Python 2.7.9 and 3+ you also have the option to use a ssl.SSLContextobject instead of a simple tuple. This way you have better control over the SSLbehavior of Werkzeug’s builtin server:

  1. import ssl
  2. ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
  3. ctx.load_cert_chain('ssl.cert', 'ssl.key')
  4. run_simple('localhost', 4000, application, ssl_context=ctx)

Generating Certificates

A key and certificate can be created in advance using the openssl toolinstead of the make_ssl_devcert(). This requires that you havethe openssl command installed on your system:

  1. $ openssl genrsa 1024 > ssl.key
  2. $ openssl req -new -x509 -nodes -sha1 -days 365 -key ssl.key > ssl.cert

Adhoc Certificates

The easiest way to enable SSL is to start the server in adhoc-mode. Inthat case Werkzeug will generate an SSL certificate for you:

  1. run_simple('localhost', 4000, application,
  2. ssl_context='adhoc')

The downside of this of course is that you will have to acknowledge thecertificate each time the server is reloaded. Adhoc certificates arediscouraged because modern browsers do a bad job at supporting them forsecurity reasons.

This feature requires the pyOpenSSL library to be installed.

Unix Sockets

The dev server can bind to a Unix socket instead of a TCP socket.run_simple() will bind to a Unix socket if the hostnameparameter starts with 'unix://'.

  1. from werkzeug.serving import run_simple
  2. run_simple('unix://example.sock', 0, app)