Table of Contents
Twisted Howto
Twisted is a powerful internet framework allowing you to develop networked applications quickly.
PyAMF features the TwistedGateway that allows you to bridge the gap between your Twisted application and AMF based programs.
Examples
Classic
The following example is the 'classic' way of setting up a Twisted web service, where you import the reactor manually and start it yourself. For the current, canonical way of setting up a service, see the next section.
The example below is a complete standalone twisted.web server that exposes various functions via PyAMF. We added comments to attempt to explain all relevant lines of code:
from twisted.internet import reactor, defer from twisted.web import server, static, resource from pyamf.remoting.gateway.twisted import TwistedGateway from pyamf.remoting.gateway import expose_request import logging logging.basicConfig( level=logging.DEBUG, format='%(asctime)s %(levelname)-5.5s [%(name)s] %(message)s' ) class example: """ An example class that can be used as a PyAMF service. """ def test1(self): return "Test 1 Success!" @expose_request def testn(self, request, n): """ This function is decorated to expose the underlying HTTP request, which provides access to things such as the requesting client's IP. """ ip = request.getClientIP() return "%s said %s!" % (ip, n) # A standalone function that can be bound to a service. def add(a, b): return a + b # Create a dictionary mapping the service namespaces to a function # or class instance services = { 'example': example(), 'myadd': add } # Place the namespace mapping into a TwistedGateway gateway = TwistedGateway(services, expose_request=False) # A base root resource for the twisted.web server root = resource.Resource() # Publish the PyAMF gateway at the root URL root.putChild('', gateway) # Start the twisted reactor and listen on HTTP port 8080 print 'Running AMF gateway on http://localhost:8080' reactor.listenTCP(8080, server.Site(root)) reactor.run()
The gateway supports returning a deferred from your callable. If you are not familiar with deferreds you should check out the Twisted Documentation
Hopefully this gives you a basic understanding of how to expose functions within Twisted.
Preferred Method
Here is the same service, designed to be run with twistd:
from twisted.web import resource, server from twisted.application import service, strports from pyamf.remoting.gateway.twisted import TwistedGateway from pyamf.remoting.gateway import expose_request import logging logging.basicConfig( level=logging.DEBUG, format='%(asctime)s %(levelname)-5.5s [%(name)s] %(message)s' ) class example: """ An example class that can be used as a PyAMF service. """ def test1(self, n): return "Test 1 Success!" @expose_request def testn(self, request, n): """ This function is decorated to expose the underlying HTTP request, which provides access to things such as the requesting client's IP. """ ip = request.getClientIP() return "%s said %s!" % (ip, n) # A standalone function that can be bound to a service. def add(a, b): return a + b # Create a dictionary mapping the service namespaces to a function # or class instance services = { 'example': example(), 'myadd': add } # Ideally, just the imports and the code below this comment would be # in the .tac file; the AMF service would be defined in a module of # your making # Place the namespace mapping into a TwistedGateway gateway = TwistedGateway(services, expose_request=False) # A base root resource for the twisted.web server root = resource.Resource() # Publish the PyAMF gateway at the root URL root.putChild('', gateway) print 'Running AMF gateway on http://localhost:8080' application = service.Application('PyAMF Sample Remoting Server') server = strports.service('tcp:8080', server.Site(root)) server.setServiceParent(application)
Run the example using twistd
Save this in a file called something like mytest.tac and then start the web server with the following command:
twistd -noy mytest.tac
Using Twisted's twistd commandline tool and a .tac file is good for many reasons. Here are some highlights:
- Using this infrastructure frees you from from having to write a large amount of boilerplate code by hooking your application into existing tools that manage daemonization, logging, choosing a reactor and more.
- This provides a convenient and standard methodology for separating Twisted services and service configuration from the rest of your project (i.e., the code upon which your service(s) depend).
- It's easy to run with a daemon manager (e.g., daemontools).
To read more, visit Using the Twisted Application Framework.
Test the example
To test the gateway you can use a Python AMF client like this:
import logging logging.basicConfig( level=logging.DEBUG, format='%(asctime)s %(levelname)-5.5s [%(name)s] %(message)s' ) from pyamf.remoting.client import RemotingService client = RemotingService('http://localhost:8080') service1 = client.getService('example') print service1.testn('Hello World') service2 = client.getService('myadd') print service2(1,2)
