[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