watch this The wheels are turning, slowly turning. home
Twisted Web in 60 seconds: custom response codes 2009-09-24


Welcome to the sixth edition of “Twisted Web in 60 seconds”. In the previous installment I introduced NoResource, a Twisted Web error resource which responds with a 404 (not found) code. In this installment, I’ll show you the APIs which NoResource uses to do this so that you can generate your own custom response codes as desired.




First, the now-standard import preamble (see previous installments for details):

  from twisted.web.server import Site
  from twisted.web.resource import Resource
  from twisted.internet import reactor





Now I’ll define a new resource class which always returns a 402 (payment required) response. This is really not very different from the resources which I’ve defined in previous examples. The fact that it has a response code other than 200 doesn’t change anything else about its role. This will require using the request object, though, which none of the previous examples have done.




The request object has shown up in a couple places, but so far I’ve ignored it. It’s a parameter to the getChild API as well as to render methods such as render_GET. As you might have suspected, it represents the request for which a response is to be generated. Additionally, it also represents the response being generated. In this example, I’m going to use its setResponseCode method to - you guessed it - set the response’s status code.

  class PaymentRequired(Resource):
      def render_GET(self, request):
          request.setResponseCode(402)
          return "<html><body>Please swipe your credit card.</body></html>"


Just like the other resources I’ve demonstrated, this one returns a string from its render_GET method to define the body of the response. All that’s different is the call to setResponseCode to override the default response code, 200, with a different one.




Finally, the code to set up the site and reactor. I’ll put an instance of the above defined resource at /buy:

  root = Resource()
  root.putChild("buy", PaymentRequired())
  factory = Site(root)
  reactor.listenTCP(8880, factory)
  reactor.run()





Here’s the complete example:

from twisted.web.server import Site  
from twisted.web.resource import Resource  
from twisted.internet import reactor  

class PaymentRequired(Resource):  
    def render_GET(self, request):  
        request.setResponseCode(402)  
        return "<html><body>Please swipe your credit card.</body></html>"  

root = Resource()
root.putChild("buy", PaymentRequired())
factory = Site(root)
reactor.listenTCP(8880, factory)
reactor.run()                   





Run the server and visit http://localhost:8880/buy in your browser. It’ll look pretty boring, but if you use Firefox’s View Page Info right-click menu item (or your browser’s equivalent), you’ll be able to see that the server indeed sent back a 402 response code.




Check out the next installment to see how the request object can also be used to get the request body (eg, for form submissions).