[Python-checkins] python/nondist/peps pep-0333.txt,1.15,1.16
pje at users.sourceforge.net
pje at users.sourceforge.net
Fri Sep 17 17:32:01 CEST 2004
Update of /cvsroot/python/python/nondist/peps
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20641
Modified Files:
pep-0333.txt
Log Message:
Moved middleware introduction to "Specification Overview" section,
adding a code example for a trivial middleware component.
Index: pep-0333.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/peps/pep-0333.txt,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- pep-0333.txt 16 Sep 2004 22:04:35 -0000 1.15
+++ pep-0333.txt 17 Sep 2004 15:31:58 -0000 1.16
@@ -125,6 +125,17 @@
mechanisms to specify where an application object should be
imported from, or otherwise obtained.
+In addition to "pure" servers/gateways and applications/frameworks,
+it is also possible to create "middleware" components that implement
+both sides of this specification. Such components act as an
+application to their containing server, and as a server to a
+contained application, and can be used to provide extended APIs,
+content transformation, navigation, and other useful functions.
+
+
+The Application/Framework Side
+------------------------------
+
The application object is simply a callable object that accepts
two arguments. The term "object" should not be misconstrued as
requiring an actual object instance: a function, method, class,
@@ -184,6 +195,10 @@
callable was provided to it. Callables are only to be called, not
introspected upon.
+
+The Server/Gateway Side
+-----------------------
+
The server or gateway invokes the application callable once for each
request it receives from an HTTP client, that is directed at the
application. To illustrate, here is a simple CGI gateway, implemented
@@ -254,8 +269,89 @@
if hasattr(result,'close'):
result.close()
-In the next section, we will specify the precise semantics that
-these illustrations are examples of.
+
+Middleware: Components that Play Both Sides
+-------------------------------------------
+
+Note that a single object may play the role of a server with respect
+to some application(s), while also acting as an application with
+respect to some server(s). Such "middleware" components can perform
+such functions as:
+
+* Routing a request to different application objects based on the
+ target URL, after rewriting the ``environ`` accordingly.
+
+* Allowing multiple applications or frameworks to run side-by-side
+ in the same process
+
+* Load balancing and remote processing, by forwarding requests and
+ responses over a network
+
+* Perform content postprocessing, such as applying XSL stylesheets
+
+The presence of middleware in general is transparent to both the
+"server/gateway" and the "application/framework" sides of the
+interface, and should require no special support. A user who
+desires to incorporate middleware into an application simply
+provides the middleware component to the server, as if it were
+an application, and configures the middleware component to
+invoke the application, as if the middleware component were a
+server. Of course, the "application" that the middleware wraps
+may in fact be another middleware component wrapping another
+application, and so on, creating what is referred to as a
+"middleware stack".
+
+For the most part, middleware must conform to the restrictions
+and requirements of both the server and application sides of
+WSGI. In some cases, however, requirements for middleware
+are more stringent than for a "pure" server or application,
+and these points will be noted in the specification.
+
+Here is a (tongue-in-cheek) example of a middleware component that
+converts ``text/plain`` responses to pig latin, using Joe Strout's
+``piglatin.py``. (Note: a "real" middleware component would
+probably use a more robust way of checking the content type, and
+should also check for a content encoding.)
+
+::
+
+ from piglatin import piglatin
+
+ class Latinator:
+
+ # by default, don't transform output
+ transform = str
+
+ def __init__(self, application):
+ self.application = application
+
+ def __call__(environ, start_response):
+
+ def write_latin(data):
+ self.write(self.transform(data))
+
+ def start_latin(status,headers,exc_info=None):
+
+ for name,value in headers:
+ if name.lower()=='content-type' and value=='text/plain':
+ self.transform = piglatin
+ # Strip content-length if present, else it'll be wrong
+ headers = [(name,value)
+ for name,value in headers
+ if name.lower()<>'content-length'
+ ]
+ break
+
+ self.write = start_response(status,headers,exc_info)
+ return write_latin
+
+ for data in self.application(environ,start_latin):
+ yield self.transform(data)
+
+ # Run foo_app under a Latinator's control, using the example CGI gateway
+ from foo_app import foo_app
+ run_with_cgi(Latinator(foo_app))
+
Specification Details
@@ -851,6 +947,8 @@
start_response(status, headers)
return ["normal body goes here"]
except:
+ # XXX should trap runtime issues like MemoryError, KeyboardInterrupt
+ # in a separate handler before this bare 'except:'...
status = "500 Oops"
headers = [("content-type","text/plain")]
start_response(status, headers, sys.exc_info())
@@ -976,30 +1074,6 @@
to re-read it upon each invocation.)
-Middleware
-----------
-
-Note that a single object may play the role of a server with respect
-to some application(s), while also acting as an application with
-respect to some server(s). Such "middleware" components can perform
-such functions as:
-
-* Routing a request to different application objects based on the
- target URL, after rewriting the ``environ`` accordingly.
-
-* Allowing multiple applications or frameworks to run side-by-side
- in the same process
-
-* Load balancing and remote processing, by forwarding requests and
- responses over a network
-
-* Perform content postprocessing, such as applying XSL stylesheets
-
-Given the existence of applications and servers conforming to this
-specification, the appearance of such reusable middleware becomes
-a possibility.
-
-
Supporting Older (<2.2) Versions of Python
------------------------------------------
More information about the Python-checkins
mailing list