Twisted web server: How to implement it
In the next paragraphs you will learn hot to run a simple Twisted web server. Twisted is an event-driven networking engine written in Python. It is a framework that provides extremely powerful, scalable and flexible enterprise application integration capabilities. At the core of Twisted is its network layer that can be used to rapidly integrate any existing protocol as well as model new ones.
Unlike other frameworks, that are designed to address a specific domain – email, Web sites, Web services – Twisted is designed to support both multiple frameworks and multiple protocols at the same time. Thus, Twisted can be used to implement web sites, web services, email servers, or instant messaging servers, and it’s capable of serial port access. Moreover, these services can all run in the same process. Twisted’s event-based, asynchronous framework makes it possible to write applications that stay responsive while processing events from multiple network connections, without using threads.
A Twisted web server
The HyperText Transfer Protocol (HTTP) is a request/response application-layer protocol, where requests are initiated by a client to a server, which responds with the requested resource. It is text-based and newline-delimited, and thus easy for humans to read. The browser interacts with a web server using HTTP, also by the use of RCP calls with Ajax (and then supporting xml-rcp).
Twisted includes some high-level APIs in twisted.web.server that facilitate the construction of sophisticated web servers. The simplest twisted web server one could create is a web server that serves static content (e.g. a directory content):
from twisted.internet import reactor
from twisted.web.server import Sitefrom twisted.web.static import File
resource = File('/var/www/mysite')factory = Site(resource)reactor.listenTCP(8000, factory)reactor.run()
We don’t have to worry about HTTP protocol details. Instead, we use a Site, which subclasses http.HTTPFactory and manages HTTP sessions and dispatching to resources for us. A Site is initialized with the resource to which it is managing access. A resource must provide the IResource interface, which describes how the resource gets rendered and how child resources in the resource hierarchy are added and accessed. In this case, we initialize our Site with a File resource representing a regular, non interpreted file. The Site is then registered with the reactor, which will then listen for requests on port 8000.
We can create a hierarchy of resources to serve at different URLs by registering Resources as children of the root resource using its putChild method:
Serving dynamic content looks very similar to serving static content. The big difference is that instead of using an existing Resource, like File, we will subclass Resource to define the new dynamic resource we want a Site to serve.
class DynamicResource(Resource):def render_GET(self, request):return "Hello World!"
It’s easy to respond to requests dynamically, serving different resources based on the URL, by defining the method get_child inside a Resource’s body. This method has access to the URL structure, so we can serve other Resource classes based on it. Also the GET or POST parameters can be read.
Using this approach, it can be possible to call every function we define from a URL, and this is the first step in allowing web requests to call methods that send packets though the serial port. We can add a Resource that takes care or the /command URL, forwarding the Request to some object. This method will perform the right actions based on the URL’s parameters and return an HTTP Response to the client.
class Command(resource.Resource):isLeaf = Truedef render_GET(self, request):return myObject.doSomething(request)resource.putChild("command", Command())
This document showed you how to implement a twisted web server in its simplest form. If you have any questions, ask them in the comments section below.