1.1 --- a/docs/WSGI/NOTES.txt Thu Dec 02 16:39:50 2004 +0000
1.2 +++ b/docs/WSGI/NOTES.txt Thu Dec 02 16:40:09 2004 +0000
1.3 @@ -1,11 +1,19 @@
1.4 -Specifying the appropriate PYTHONPATH, invoke the application program. For
1.5 -example, in the WebStack distribution directory:
1.6 +Currently, the WSGI examples use the WSGI CGI handler code found in PEP 333
1.7 +and placed in the wsgi_cgi module. Deploying in other environments would
1.8 +require slightly different "glue code" to be written.
1.9
1.10 -PYTHONPATH=.:examples/Common python examples/WSGI/SimpleApp.py
1.11 +--------
1.12 +
1.13 +Declare the script in httpd.conf or equivalent Web server configuration file.
1.14 +For example:
1.15 +
1.16 +ScriptAlias /wsgi/simple "/home/paulb/Software/Python/WebStack/examples/WSGI/SimpleHandler.py"
1.17
1.18 The WebStack package must reside on the PYTHONPATH, along with the package
1.19 -containing the application itself.
1.20 +containing the application itself. Therefore, ensure that the handler uses the
1.21 +appropriate entries in sys.path.
1.22
1.23 -In addition, WSGI examples currently require wsgiServer from WSGI Utils to
1.24 -either reside on the PYTHONPATH or to have been installed using the WSGI
1.25 -Utils setup script.
1.26 +Ensure that the handler file for the application has the appropriate
1.27 +permissions:
1.28 +
1.29 +chmod u+x examples/WSGI/SimpleHandler.py
2.1 --- a/examples/WSGI/CalendarApp.py Thu Dec 02 16:39:50 2004 +0000
2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2.3 @@ -1,25 +0,0 @@
2.4 -#!/usr/bin/env python
2.5 -
2.6 -from WebStack.Adapters import WSGI
2.7 -from Calendar import DirectoryResource
2.8 -from wsgiutils import wsgiServer, wsgiAdaptor
2.9 -
2.10 -# Magic dictionary for WSGIServer.
2.11 -
2.12 -class MagicDict:
2.13 - def __init__(self, handler):
2.14 - self.handler = handler
2.15 - def has_key(self, name):
2.16 - return 1
2.17 - def __getitem__(self, name):
2.18 - return self.handler
2.19 -
2.20 -# Special magic incantation.
2.21 -
2.22 -handler = WSGI.WSGIAdapter(DirectoryResource())
2.23 -address = ("", 8080)
2.24 -server = wsgiServer.WSGIServer(address, MagicDict(handler))
2.25 -print "Serving..."
2.26 -server.serve_forever()
2.27 -
2.28 -# vim: tabstop=4 expandtab shiftwidth=4
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/examples/WSGI/CalendarHandler.py Thu Dec 02 16:40:09 2004 +0000
3.3 @@ -0,0 +1,18 @@
3.4 +#!/usr/bin/env python
3.5 +
3.6 +# NOTE: Path manipulation requires manual customisation.
3.7 +
3.8 +import sys
3.9 +sys.path.append("/home/paulb/Software/Python/WebStack")
3.10 +sys.path.append("/home/paulb/Software/Python/WebStack/examples/Common")
3.11 +
3.12 +from WebStack.Adapters import WSGI
3.13 +from Calendar import DirectoryResource
3.14 +from wsgi_cgi import run_with_cgi
3.15 +
3.16 +# Special magic incantation.
3.17 +
3.18 +handler = WSGI.WSGIAdapter(DirectoryResource())
3.19 +run_with_cgi(handler)
3.20 +
3.21 +# vim: tabstop=4 expandtab shiftwidth=4
4.1 --- a/examples/WSGI/CookiesApp.py Thu Dec 02 16:39:50 2004 +0000
4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
4.3 @@ -1,25 +0,0 @@
4.4 -#!/usr/bin/env python
4.5 -
4.6 -from WebStack.Adapters import WSGI
4.7 -from Cookies import CookiesResource
4.8 -from wsgiutils import wsgiServer, wsgiAdaptor
4.9 -
4.10 -# Magic dictionary for WSGIServer.
4.11 -
4.12 -class MagicDict:
4.13 - def __init__(self, handler):
4.14 - self.handler = handler
4.15 - def has_key(self, name):
4.16 - return 1
4.17 - def __getitem__(self, name):
4.18 - return self.handler
4.19 -
4.20 -# Special magic incantation.
4.21 -
4.22 -handler = WSGI.WSGIAdapter(CookiesResource())
4.23 -address = ("", 8080)
4.24 -server = wsgiServer.WSGIServer(address, MagicDict(handler))
4.25 -print "Serving..."
4.26 -server.serve_forever()
4.27 -
4.28 -# vim: tabstop=4 expandtab shiftwidth=4
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/examples/WSGI/CookiesHandler.py Thu Dec 02 16:40:09 2004 +0000
5.3 @@ -0,0 +1,18 @@
5.4 +#!/usr/bin/env python
5.5 +
5.6 +# NOTE: Path manipulation requires manual customisation.
5.7 +
5.8 +import sys
5.9 +sys.path.append("/home/paulb/Software/Python/WebStack")
5.10 +sys.path.append("/home/paulb/Software/Python/WebStack/examples/Common")
5.11 +
5.12 +from WebStack.Adapters import WSGI
5.13 +from Cookies import CookiesResource
5.14 +from wsgi_cgi import run_with_cgi
5.15 +
5.16 +# Special magic incantation.
5.17 +
5.18 +handler = WSGI.WSGIAdapter(CookiesResource())
5.19 +run_with_cgi(handler)
5.20 +
5.21 +# vim: tabstop=4 expandtab shiftwidth=4
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/examples/WSGI/FormHandler.py Thu Dec 02 16:40:09 2004 +0000
6.3 @@ -0,0 +1,18 @@
6.4 +#!/usr/bin/env python
6.5 +
6.6 +# NOTE: Path manipulation requires manual customisation.
6.7 +
6.8 +import sys
6.9 +sys.path.append("/home/paulb/Software/Python/WebStack")
6.10 +sys.path.append("/home/paulb/Software/Python/WebStack/examples/Common")
6.11 +
6.12 +from WebStack.Adapters import WSGI
6.13 +from Form import FormResource
6.14 +from wsgi_cgi import run_with_cgi
6.15 +
6.16 +# Special magic incantation.
6.17 +
6.18 +handler = WSGI.WSGIAdapter(FormResource())
6.19 +run_with_cgi(handler)
6.20 +
6.21 +# vim: tabstop=4 expandtab shiftwidth=4
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/examples/WSGI/LoginHandler.py Thu Dec 02 16:40:09 2004 +0000
7.3 @@ -0,0 +1,28 @@
7.4 +#!/usr/bin/env python
7.5 +
7.6 +# NOTE: Path manipulation requires manual customisation.
7.7 +
7.8 +import sys
7.9 +sys.path.append("/home/paulb/Software/Python/WebStack")
7.10 +sys.path.append("/home/paulb/Software/Python/WebStack/examples/Common")
7.11 +
7.12 +from WebStack.Adapters import WSGI
7.13 +from WebStack.Resources.Login import LoginResource, LoginAuthenticator
7.14 +from wsgi_cgi import run_with_cgi
7.15 +
7.16 +resource = LoginResource(
7.17 + LoginAuthenticator(
7.18 + secret_key="horses",
7.19 + credentials=(
7.20 + ("badger", "abc"),
7.21 + ("vole", "xyz"),
7.22 + )
7.23 + )
7.24 +)
7.25 +
7.26 +# Special magic incantation.
7.27 +
7.28 +handler = WSGI.WSGIAdapter(resource)
7.29 +run_with_cgi(handler)
7.30 +
7.31 +# vim: tabstop=4 expandtab shiftwidth=4
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/examples/WSGI/SessionsHandler.py Thu Dec 02 16:40:09 2004 +0000
8.3 @@ -0,0 +1,18 @@
8.4 +#!/usr/bin/env python
8.5 +
8.6 +# NOTE: Path manipulation requires manual customisation.
8.7 +
8.8 +import sys
8.9 +sys.path.append("/home/paulb/Software/Python/WebStack")
8.10 +sys.path.append("/home/paulb/Software/Python/WebStack/examples/Common")
8.11 +
8.12 +from WebStack.Adapters import WSGI
8.13 +from Sessions import SessionsResource
8.14 +from wsgi_cgi import run_with_cgi
8.15 +
8.16 +# Special magic incantation.
8.17 +
8.18 +handler = WSGI.WSGIAdapter(SessionsResource())
8.19 +run_with_cgi(handler)
8.20 +
8.21 +# vim: tabstop=4 expandtab shiftwidth=4
9.1 --- a/examples/WSGI/SimpleApp.py Thu Dec 02 16:39:50 2004 +0000
9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
9.3 @@ -1,25 +0,0 @@
9.4 -#!/usr/bin/env python
9.5 -
9.6 -from WebStack.Adapters import WSGI
9.7 -from Simple import SimpleResource
9.8 -from wsgiutils import wsgiServer, wsgiAdaptor
9.9 -
9.10 -# Magic dictionary for WSGIServer.
9.11 -
9.12 -class MagicDict:
9.13 - def __init__(self, handler):
9.14 - self.handler = handler
9.15 - def has_key(self, name):
9.16 - return 1
9.17 - def __getitem__(self, name):
9.18 - return self.handler
9.19 -
9.20 -# Special magic incantation.
9.21 -
9.22 -handler = WSGI.WSGIAdapter(SimpleResource())
9.23 -address = ("", 8080)
9.24 -server = wsgiServer.WSGIServer(address, MagicDict(handler))
9.25 -print "Serving..."
9.26 -server.serve_forever()
9.27 -
9.28 -# vim: tabstop=4 expandtab shiftwidth=4
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/examples/WSGI/SimpleHandler.py Thu Dec 02 16:40:09 2004 +0000
10.3 @@ -0,0 +1,18 @@
10.4 +#!/usr/bin/env python
10.5 +
10.6 +# NOTE: Path manipulation requires manual customisation.
10.7 +
10.8 +import sys
10.9 +sys.path.append("/home/paulb/Software/Python/WebStack")
10.10 +sys.path.append("/home/paulb/Software/Python/WebStack/examples/Common")
10.11 +
10.12 +from WebStack.Adapters import WSGI
10.13 +from Simple import SimpleResource
10.14 +from wsgi_cgi import run_with_cgi
10.15 +
10.16 +# Special magic incantation.
10.17 +
10.18 +handler = WSGI.WSGIAdapter(SimpleResource())
10.19 +run_with_cgi(handler)
10.20 +
10.21 +# vim: tabstop=4 expandtab shiftwidth=4
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/examples/WSGI/SimpleWithLoginHandler.py Thu Dec 02 16:40:09 2004 +0000
11.3 @@ -0,0 +1,28 @@
11.4 +#!/usr/bin/env python
11.5 +
11.6 +# NOTE: Path manipulation requires manual customisation.
11.7 +
11.8 +import sys
11.9 +sys.path.append("/home/paulb/Software/Python/WebStack")
11.10 +sys.path.append("/home/paulb/Software/Python/WebStack/examples/Common")
11.11 +
11.12 +from WebStack.Adapters import WSGI
11.13 +from WebStack.Resources.LoginRedirect import LoginRedirectResource, LoginRedirectAuthenticator
11.14 +from Simple import SimpleResource
11.15 +from wsgi_cgi import run_with_cgi
11.16 +
11.17 +resource = LoginRedirectResource(
11.18 + login_url="http://localhost/wsgi/login",
11.19 + app_url="http://localhost",
11.20 + resource=SimpleResource(),
11.21 + authenticator=LoginRedirectAuthenticator(secret_key="horses"),
11.22 + anonymous_parameter_name="anonymous",
11.23 + logout_parameter_name="logout"
11.24 +)
11.25 +
11.26 +# Special magic incantation.
11.27 +
11.28 +handler = WSGI.WSGIAdapter(resource)
11.29 +run_with_cgi(handler)
11.30 +
11.31 +# vim: tabstop=4 expandtab shiftwidth=4
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/examples/WSGI/UnicodeHandler.py Thu Dec 02 16:40:09 2004 +0000
12.3 @@ -0,0 +1,18 @@
12.4 +#!/usr/bin/env python
12.5 +
12.6 +# NOTE: Path manipulation requires manual customisation.
12.7 +
12.8 +import sys
12.9 +sys.path.append("/home/paulb/Software/Python/WebStack")
12.10 +sys.path.append("/home/paulb/Software/Python/WebStack/examples/Common")
12.11 +
12.12 +from WebStack.Adapters import WSGI
12.13 +from Unicode import UnicodeResource
12.14 +from wsgi_cgi import run_with_cgi
12.15 +
12.16 +# Special magic incantation.
12.17 +
12.18 +handler = WSGI.WSGIAdapter(UnicodeResource())
12.19 +run_with_cgi(handler)
12.20 +
12.21 +# vim: tabstop=4 expandtab shiftwidth=4
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/examples/WSGI/wsgi_cgi.py Thu Dec 02 16:40:09 2004 +0000
13.3 @@ -0,0 +1,69 @@
13.4 +#!/usr/local/bin/python
13.5 +
13.6 +"""
13.7 +WSGI CGI handler code originating from PEP 333, transcribed by Titus Brown.
13.8 +Previously a standalone CGI program, this is now a module imported by the actual
13.9 +CGI programs.
13.10 +"""
13.11 +
13.12 +import os, sys
13.13 +
13.14 +def run_with_cgi(application):
13.15 +
13.16 + environ = dict(os.environ.items())
13.17 + environ['wsgi.input'] = sys.stdin
13.18 + environ['wsgi.errors'] = sys.stderr
13.19 + environ['wsgi.version'] = (1,0)
13.20 + environ['wsgi.multithread'] = False
13.21 + environ['wsgi.multiprocess'] = True
13.22 + environ['wsgi.run_once'] = True
13.23 +
13.24 + if environ.get('HTTPS','off') in ('on','1'):
13.25 + environ['wsgi.url_scheme'] = 'https'
13.26 + else:
13.27 + environ['wsgi.url_scheme'] = 'http'
13.28 +
13.29 + headers_set = []
13.30 + headers_sent = []
13.31 +
13.32 + def write(data):
13.33 + if not headers_set:
13.34 + raise AssertionError("write() before start_response()")
13.35 +
13.36 + elif not headers_sent:
13.37 + # Before the first output, send the stored headers
13.38 + status, response_headers = headers_sent[:] = headers_set
13.39 + sys.stdout.write('Status: %s\r\n' % status)
13.40 + for header in response_headers:
13.41 + sys.stdout.write('%s: %s\r\n' % header)
13.42 + sys.stdout.write('\r\n')
13.43 +
13.44 + sys.stdout.write(data)
13.45 + sys.stdout.flush()
13.46 +
13.47 + def start_response(status,response_headers,exc_info=None):
13.48 + if exc_info:
13.49 + try:
13.50 + if headers_sent:
13.51 + # Re-raise original exception if headers sent
13.52 + raise exc_info[0], exc_info[1], exc_info[2]
13.53 + finally:
13.54 + exc_info = None # avoid dangling circular ref
13.55 + elif headers_set:
13.56 + raise AssertionError("Headers already set!")
13.57 +
13.58 + headers_set[:] = [status,response_headers]
13.59 + return write
13.60 +
13.61 + result = application(environ, start_response)
13.62 + try:
13.63 + for data in result:
13.64 + if data: # don't send headers until body appears
13.65 + write(data)
13.66 + if not headers_sent:
13.67 + write('') # send headers now if body was empty
13.68 + finally:
13.69 + if hasattr(result,'close'):
13.70 + result.close()
13.71 +
13.72 +# vim: tabstop=4 expandtab shiftwidth=4