python script as wsgi, cgi, or standalone
EDIT:
See below for original, I realized this could be done cleanly with a decorator.
The decorator wrapplication takes the number of the port to use when called as a standalone server. The EMiddle class is unnecessary, it's just used as middleware to update the environ to show it came via wsgi. If there's a cleaner way, let me know.
ORIGINAL VERSION:
If you write a script with the application entry point that fits the wsgi spec, it's simple to make it run via mod_wsgi, cgi, or via standalone server depending on the context. I believe this is common knowledge, but for my own reference here's an example with the extra setup (which will work for any script) to do this:
To change between wsgi and cgi toggle between
For the stand alone server, just run it with an argument indicating the port:
to use the cherrypy server instead of the wsgiref, replace the make_server() line with:
That also handles the server shutdown more politely.
See below for original, I realized this could be done cleanly with a decorator.
The decorator wrapplication takes the number of the port to use when called as a standalone server. The EMiddle class is unnecessary, it's just used as middleware to update the environ to show it came via wsgi. If there's a cleaner way, let me know.
#!/usr/bin/python
import os
class EMiddle(object):
def __init__(self, app):
self.app = app
def __call__(self, env, start_response):
env['hello'] = 'wsgi'
return self.app(env, start_response)
def wrapplication(port):
def wrapper(wsgi_app):
if 'TERM' in os.environ:
print "serving on port: %i" % port
os.environ['hello'] = 'standalone'
from wsgiref.simple_server import make_server
make_server('', port, wsgi_app).serve_forever()
elif 'CGI' in os.environ.get('GATEWAY_INTERFACE',''):
os.environ['hello'] = 'cgi'
import wsgiref.handlers
wsgiref.handlers.CGIHandler().run(wsgi_app)
else:
return EMiddle(wsgi_app)
return wrapper
@wrapplication(3000)
def application(environ, start_response):
start_response("200 OK", [('Content-Type', 'text/plain')])
yield "How do you like the teaches of peaches?\n"
yield "from " + environ['hello']
ORIGINAL VERSION:
If you write a script with the application entry point that fits the wsgi spec, it's simple to make it run via mod_wsgi, cgi, or via standalone server depending on the context. I believe this is common knowledge, but for my own reference here's an example with the extra setup (which will work for any script) to do this:
#!/usr/bin/python
def application(environ, start_response):
start_response("200 OK", [('Content-Type', 'text/plain')])
yield environ['QUERY_STRING']
if __name__ == "__main__":
try:
from wsgiref.simple_server import make_server
import sys
port = int(sys.argv[1])
print "server on port: %i" % port
make_server('', port, application).serve_forever()
except Exception, e:
import wsgiref.handlers
wsgiref.handlers.CGIHandler().run(application)
To change between wsgi and cgi toggle between
AddHandler cgi-script .py
AddHandler wsgi-script .py
For the stand alone server, just run it with an argument indicating the port:
python app.py 3000
to use the cherrypy server instead of the wsgiref, replace the make_server() line with:
from cherrypy import wsgiserver
server = wsgiserver.CherryPyWSGIServer(('0.0.0.0', port), [('/', application)], server_name='')
try:
server.start()
except KeyboardInterrupt:
server.stop()
That also handles the server shutdown more politely.
Comments