Python Web Frameworks – Development Server

One of the most frequent tasks of a web developer is running the app while it’s being written. So we’ll begin our examination of Python web frameworks by looking at the development servers provided and how does one run the app.

Django developers are used to invoking

python manage.py runserver

The runserver option runs Django’s development server which is invoked via the run() function in django.core.servers.basehttp. This in turn runs a WSGIServer which is derived from Python’s wsgiref’s simple_server.

Twisted Web has its own server based on its core reactor object. Here’s a simple usage example:

from twisted.web import server, resource
from twisted.internet import reactor

class HelloResource(resource.Resource):
    ...

reactor.listenTCP(8080, server.Site(HelloResource()))
reactor.run()

Pyramid uses Paste’s paste.httpserver which in turn is based on Python’s BaseHTTPServer. Sample usage:

from paste.httpserver import serve
from pyramid.config import Configurator

def hello_world(request):
   ... 

if __name__ == '__main__':
   config = Configurator()
   ...
   app = config.make_wsgi_app()
   serve(app, host='0.0.0.0')

In CherryPy, the normal server is cherrypy.engine which is invoked as:

cherrypy.engine.start()
cherrypy.engine.block()

cherrypy.engine is actually an instance of cherrypy.process.wspbus.Bus. A simpler alternative to the engine calls is to use:

cherrypy.quickstart(app())

Under the covers, CherryPy also defines a global server variable that is an instance of Server which implements the HTTP server, with help from cherrypy._cpwsgi_server.CPWSGIServer.

Werkzeug has a built-in server, used as follows:

from werkzeug.serving import run_simple
from myproject import make_app

app = make_app(...)
run_simple('localhost', 8080, app, use_reloader=True)

run_simple() invokes its own (werkzeug.serving) make_server which creates one of three types of XxxWSGIServer’s, which are derived from Python’s BaseHTTPServer.HTTPServer.

When Web2py is invoked, a GUI dialog is shown. The dialog is implemented in gluon.widget and its web2pyDialog.start method creates a main.HttpServer. gluon.main’s HttpServer class uses the Rocket server whose code is in gluon.rocket.

In web.py, to run an application you instantiate a web.application and invoke its run() method, e.g.:

app = web.application(urls, globals())
app.run()

This eventually runs a BaseHTTPServer.HTTPServer from the Python standard library.

Flask‘s WSGI application class (Flask) has a run() method:

run(host='127.0.0.1', port=5000, debug=None, **options)

This invokes the Werkzeug serving.run_simple function (see above).

WebOb doesn’t offer any server per se, but suggests using Paste’s httpserver.serve or wsgiref.simple_server.

Bottle has a standalone run() function:

run(app=None, server='wsgiref', host='127.0.0.1', port=8080,
    interval=1, reloader=False, quiet=False, plugins=None, **kargs)

This runs one of several web servers supported, by default, wsgiref, which uses the wsgiref.simple_server.

Pesto suggests using the Python wsgiref directly, e.g.:

import pesto
dispatcher = pesto.dispatcher_app()
...
httpd = make_server('', 8080, dispatcher)
httpd.serve_forever()

Diva uses Python’s WSGIServer from the standard library to implement its main() and serve() standalone functions. The former can be used as follows:

from diva.core import Application
from diva.server import main

class MyApp(Application): pass

main(MyApp())

Summary: With the exception of Twisted and CherryPy, all frameworks base their development servers on the standard library’s wsgiref or BaseHTTPServer, Paste or Rocket (which claims to be CherryPy-compatible). Lesson for prospective framework creators: Don’t write your own server. However, you may want to enhance your server with auto-reloading, threading, debugging. etc.

There are two approaches to running the app or server. Django and Web2py don’t want the developer to bother with writing app.run() or similar, the other frameworks expect the programmer to plug the various pieces together.

Best wishes for 2012 to all readers!

16 thoughts on “Python Web Frameworks – Development Server

  1. Pingback: Joe Abbate: Python Web Frameworks –... | Python | Syngu

  2. would like to know more about the strengths/weaknesses of these development resources. For example, one of the things i love about the django dev server is that it “listens” to all the project dependencies and restarts when any file is saved (which has saved me from trying to understand why something I fixed didn’t work and discovering that it’s because the changes weren’t .pyc’d)

    • Most frameworks and/or servers offer some “reload” capability, usually for use during development, at a minimum over the module files and possibly over the template files, but sometimes this can be extended. Werkzeug for example has an extra_files argument to its run_simple function.

  3. [Quixote](http://quixote.ca) provides an easy way to use some simple servers as well.::

    python -m quixote.server.simple_server
    python -m quixote.server.medusa_server
    python -m quixote.server.twisted_server
    python -m quixote.server.fastcgi_server
    python -m quixote.server.scgi_server

    I guess I should add better support for WSGI.

  4. There’s also a Django app which adds a trunserver command to run dev-mode on top of twisted. Very nice for sites with lots of small files, possibly sufficient for very light “production” – you and a couple of friends/alpha testers. I’m not so fond of the default logging, which apes Apache, and clutters the display much more than the regular dev server.

    https://github.com/gregarmer/trunserver

  5. Pingback: Python Web Frameworks – Application Object | Taming Serpents and Pachyderms

  6. Pingback: Database User Interfaces – Pagination | Taming Serpents and Pachyderms

  7. Pingback: ANFSCD: Revisiting the Web Server | Taming Serpents and Pachyderms

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.