I am trying to get my head round Twisted, particularly to use it as a simple web server (using http as a RPC mechanism, really). I was thinknig of using a "Rosetta Stone" approach, and am wondering if someone could translate this ordinary Python program into Twisted, please: ===================================================================== # simple_http.py = a simple http server import SimpleHTTPServer import BaseHTTPServer import StringIO template = """<html> <head> <title>%(title)s</title> </head><body> <h1>%(title)s</h1> <p>Path is [<tt>%(path)s</tt>] </body></html> """ portNum = 1450 class MyRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): def do_GET(self): args = { 'title': 'simple_http.py', 'path': self.path } result = template % args self.send_response(200) self.send_header("Content-type", "text/html") self.send_header("Content-Length", str(len(result))) self.end_headers() f = StringIO.StringIO() f.write(result) f.seek(0) self.copyfile(f, self.wfile) f.close() print "===== starting simple_http.py on port %d =====" % portNum server_address = ('', portNum) httpd = BaseHTTPServer.HTTPServer(server_address, MyRequestHandler) httpd.serve_forever() #end ===================================================================== As you can see, it's very simple. When it recieves a GET request it just sends back an HTML page saying what the path in the GET request was. -- Phil Hunt, phil.hunt@tech.mrc.ac.uk
On Tue, 2004-02-24 at 13:35, Phil Hunt wrote:
I am trying to get my head round Twisted, particularly to use it as a simple web server (using http as a RPC mechanism, really). I was thinknig of using a "Rosetta Stone" approach, and am wondering if someone could translate this ordinary Python program into Twisted, please:
Attached are two examples of what you've described, both of which are a lot easier on the eyes than SimpleHTTPServer code. rosetta1 just uses twisted.web's Resource object, which is relatively basic in its capabilities. If you want more scalable and flexible templating and web application design, you might want to start working with Nevow, which is what rosetta2 demonstrates. Both of these scripts should be run using the following command: $ twistd -ony rosettaX.tac.py Hope this helps. -- Alex Levy WWW: http://mesozoic.geecs.org "Never let your sense of morals prevent you from doing what is right." -- Salvor Hardin, Isaac Asimov's _Foundation_
On Tuesday 24 Feb 2004 7:28 pm, Alex Levy wrote:
On Tue, 2004-02-24 at 13:35, Phil Hunt wrote:
I am trying to get my head round Twisted, particularly to use it as a simple web server (using http as a RPC mechanism, really). I was thinknig of using a "Rosetta Stone" approach, and am wondering if someone could translate this ordinary Python program into Twisted, please:
Attached are two examples of what you've described, both of which are a lot easier on the eyes than SimpleHTTPServer code.
rosetta1 just uses twisted.web's Resource object, which is relatively basic in its capabilities. If you want more scalable and flexible templating and web application design, you might want to start working with Nevow, which is what rosetta2 demonstrates.
Both of these scripts should be run using the following command:
$ twistd -ony rosettaX.tac.py
rosetta1 kind-of does what I want, but not quite, when I try to fetch the URL <http://localhost:1450/xxx?aaa=bbb&c=12345> in my web browser, it says request.path = /xxx, whereas I'm interested in the variable/value pairs as well, i.e. /xxx?aaa=bbb&c=12345 If I wrote a program like this that was invoked by the ``python'' program rather than ``twistd'', would that make a difference it what it can do? I ask because I would like to get such a program to talk to other data sources. For example, I'm writing a test program that sends an http GET request, then tests whether it receives a response (also an http GET request, but from a 3rd process), within a certain time span, such as 2 seconds. IOW, I have three programs: TH -----------> P2 ^ | | | `------------- P3 TH is a test harness, that is both a web client and a web server. TH sends http GET requests to P2, then receives them (some time later) from P3. P2 is a web server; it receives GET requests but does not send them. P3 is a web client; it sends GET requests but does not receive them. (Am I barking up the wriong tree here? I'm using http because it is a simple protocol, and because one side of the protocol can be emulated by Mozilla, making it easier from me to test my software when not all the components have been written. But maybe there's a simpler way?) Also, how easy is it to write a full python [program with a reactor as opposed to a .tac.py? Are there advantages in doing so? (I'm assuming that with .tac.py programs, the stuff to do with the reactor is handled by twistd). I want to invoke my programs with options at the command line (the port number will be one of these options) -- can I do that with twistd? -- Phil Hunt, phil.hunt@tech.mrc.ac.uk
Phil Hunt <phil.hunt@tech.mrc.ac.uk> writes:
rosetta1 kind-of does what I want, but not quite, when I try to fetch the URL <http://localhost:1450/xxx?aaa=bbb&c=12345> in my web browser, it says request.path = /xxx, whereas I'm interested in the variable/value pairs as well, i.e. /xxx?aaa=bbb&c=12345
Ah, yeah, that would be a difference between that and the simpler HTTP handler object in the standard library. The Twisted support code automatically parses out the arguments for you and makes them available from the request object (passed in to the render method in rosetta1) in the args attribute. It's a dictionary keyed by variable, with the value being a list of values supplied. The value is always a list even if only one instance of the variable occurs in the URL. So in your example here, in the render() method, request.args would be set to {'aaa':['bbb'],'c':['12345']}.
If I wrote a program like this that was invoked by the ``python'' program rather than ``twistd'', would that make a difference it what it can do?
Not particularly - you can pretty much do anything in either case, but the sequence of how to initialize things (and how much work you might need to do to accomplish a particular initialization) will differ. twistd provides some standard startup handling, but you can initialize things and run the reactor yourself if you want. For example, one way to have a more standalone version would be to replace the bottom portion of rosetta1 (starting from "application = " down) with: site = server.Site(resource=MyResource()) reactor.listenTCP(1450, site) reactor.run() and you'd need a "from twisted.internet import reactor" at the top (and could remove the application imports). It's not exactly identical since the application/service approach is initializing a more flexible framework, but for this example, the end result is the same. With the above change you could just run the script with Python. You can pretty much do anything you want at that point, although you need to get to the reactor.run() for most stuff to start running. You can also hang other services off of your application object and do other initialization in the twistd/tac case. I don't tend to use twistd that much myself, but I'm sure for others it's what they prefer. Oh, and if you'd like to see some simple logging of requests and what not you can just enable logging by: import sys from twisted.python import log at the top, and log.startLogging(sys.stdout) before creating your site. I think the equivalent is just a command line option with twistd. -- David
participants (3)
-
Alex Levy
-
David Bolen
-
Phil Hunt