# Twisted.Web2 Introduction

## What is twisted.web2

Twisted.web2 is an asynchronous HTTP 1.1 server written for the Twisted internet framework. It provides a RFC 2616 compliant HTTP 1.1 protocol implementation, with pipelined and persistent request support, in a non-blocking threadless manner.

It also includes a simple web framework with request and response objects, static file support, error handling, form upload support, HTTP range support, pre-built parsers for all standard headers, and a bunch of other goodies.

It is deployable as a standalone HTTP or HTTPS server, as a HTTP[S] server proxied behind another server, or as a SCGI, FastCGI, or CGI script.

In addition to running native twisted.web2 applications, it can also run any WSGI or CGI application, or, via compatibility wrappers, most applications written for the older twisted.web API.

Currently, twisted.web2 does not include a HTTP client or proxy, but will at a future date.

## What twisted.web2 is not

Twisted.web2 is not a templating framework. It provides mechanisms for locating and running code associated with a URL, but does not provide any means for separating code and data or to ease the task of generating HTML.

Twisted.web2 is in general fairly speedy. However, keep in mind that it is a python program, and, while it is empirically "fast enough", it cannot match Apache in static file serving speed. <insert actual measurements here>

## Introduction

This tutorial should be readable by people who do not have much Twisted experience yet, but, you should know Python, and HTML, before starting. While it is hopefully redundant to say this, you also ought to have installed twisted, and twisted.web2.

When you have finished this tutorial, you should be able to write some simple resources and publish them with twisted.web2.

## Simple application

    from twisted.web2 import server, http, resource, channel

    class Toplevel(resource.Resource):
      addSlash = True
      def render(self, ctx):
    	return http.Response(stream="Hello monkey!")

    site = server.Site(Toplevel())

    # Standard twisted application Boilerplate
    from twisted.application import service, strports
    application = service.Application("demoserver")
    s = strports.service('tcp:8080', channel.HTTPFactory(site))
    s.setServiceParent(application)

Listing 1: A simple application - ../examples/intro/simple.py

You may run this program via `twistd -ny simple.py`. `twistd` is the Twisted runner; it knows how to execute applications by looking for the `application` variable declared at top-level. You can also run your server in the background (daemonized), via `twistd -y simple.py`. You can access your server via the url "http://localhost:8080/". For more deployment options, see the deployment chapter.

### What this is doing

A resource is responsible for handling one segment of the URL. Here, we have created a resource to handle the top level of the url hierarchy. The `addSlash = True` setting tells twisted.web2 that this is a directory-like resource. This means that it will add a "/" to the end of the URL automatically, if needed, and respond under that name. Root resources should always have `addSlash = True`.

The defined class has just a single method: `render`. This method takes a single argument: `request`, which contains all the state related to the current rendering operation. This particular render method always returns the same data, so we won't use `request`. We'll get back to it later.

Here, the `render` method simply returns a `http.Response` object containing the output.

After defining this class, next we need to tell twisted.web2 to serve it up. This is accomplished by creating the `server.Site` object, with an instance of your top-level resource as its argument, and then some standard boilerplate to tell Twisted what services to start and what port to serve them on.

### Child resources

Of course, what good is a webserver that can only serve up a single page? So, you can also add child resources to your top-level resource, via `child_<name>` attributes.

    import os.path, time
    from twisted.web2 import server, http, resource, channel
    from twisted.web2 import static, http_headers, responsecode

    class Child(resource.Resource):
      creation_time = time.time()
      text = 'Yo Ho Ho and a bottle of rum.'
      content_type = http_headers.MimeType('text', 'plain')

      def render(self, ctx):
        return http.Response(
          responsecode.OK,
          {'last-modified': self.creation_time,
          'etag': http_headers.ETag(str(hash(self.text))),
          'content-type': self.content_type},
          self.text)

    class Toplevel(resource.Resource):
      addSlash = True
      child_monkey = static.File(os.path.dirname(static.__file__)+'/static.py')
      child_elephant = Child()

      def render(self, ctx):
        return http.Response(
          200,
          {'content-type': http_headers.MimeType('text', 'html')},
          """<html><body>
          <a href="monkey">The source code of twisted.web2.static</a><br>
          <a href="elephant">A defined child</a></body></html>""")

    site = server.Site(Toplevel())

    # Standard twisted application Boilerplate
    from twisted.application import service, strports
    application = service.Application("demoserver")
    s = strports.service('tcp:8080', channel.HTTPFactory(site))
    s.setServiceParent(application)

Listing 2: Child Resources - ../examples/intro/children.py

Here a few new concepts have been introduced:

- Adding child resources. Any resource can have children, by adding child_name attributes. The child_foo attributes can also be methods, and, if even that is not powerful enough for you, it is possible to override the method lookup machinery at an even lower level. See Object Traversal for more details.
- `twisted.web2.static.File` lets you serve a file off the disk. With this, you get a lot of functionality: automatic Content-Type setting from the file extension, last-modified and etag calculation, and the ability to hook in custom processors for certain file types. It will also generate directory listings if you point it at a directory instead of a file.
- `twisted.web2.http.Response` takes three arguments: the response code, the output headers, and the output stream. For more information, see Resource APIs.

As an aside for those who know a bit about HTTP, note that just by setting the Last-Modified and ETag response headers, you enable automatic precondition checks which support the If-Modified-Since, If-Unmodified-Since, If-Match, and If-None-Match input headers. This allows the client to request that the resource only be sent if it has changed since the last time the client downloaded it, saving bandwidth. Also, the Range and If-Range headers are supported on every resource, allowing partial downloads, and default values for the "Server" and "Date" headers are added to the output for you automatically.

Index

Version: 8.1.0