This note is about Pep3333-python Web Server Gateway Interface. Refer to (source:http://legacy.python.org/dev/peps/pep-3333/) for the complete description.
1. From the application/framwork side
The Application object is simply a callable object that accepts the arguments, named environ, and Start_respo NSE, following the convention.
Example:
Hello_world = b"Hello world!\n"defSimple_app (environ, start_response):"""simplest possible Application object"""Status='OK'response_headers= [('Content-type','Text/plain')] Start_response (status, Response_headers)return[Hello_world]
2. From the Server/gateway side
The server or gateway invokes the application callable once for each request it receives from an HTTP client.
Exmple:
ImportOS, Sysenc, ESC= Sys.getfilesystemencoding (),'Surrogateescape'defUnicode_to_wsgi (u):#Convert an environment variable to a WSGI "Bytes-as-unicode" string returnU.encode (ENC, ESC). Decode ('iso-8859-1')defWsgi_to_bytes (s):returnS.encode ('iso-8859-1')defrun_with_cgi (application): Environ= {K:unicode_to_wsgi (v) forKvinchos.environ.items ()} environ['Wsgi.input'] =Sys.stdin.buffer environ['wsgi.errors'] =Sys.stderr environ['wsgi.version'] = (1, 0) environ['Wsgi.multithread'] =False environ['wsgi.multiprocess'] =True environ['wsgi.run_once'] =TrueifEnviron.get ('HTTPS','off')inch(' on','1'): environ['Wsgi.url_scheme'] ='HTTPS' Else: environ['Wsgi.url_scheme'] ='http'Headers_set=[] headers_sent= [] defWrite (data): Out=Sys.stdout.bufferif notHeaders_set:RaiseAssertionerror ("write () before Start_response ()") elif notheaders_sent:#before the first output, send the stored headersStatus, Response_headers = headers_sent[:] =Headers_set out.write (wsgi_to_bytes ('Status:%s\r\n'%status)) forHeaderinchResponse_headers:out.write (Wsgi_to_bytes ('%s:%s\r\n'%header)) Out.write (Wsgi_to_bytes ('\ r \ n') ) out.write (data) Out.flush ()defStart_response (Status, Response_headers, exc_info=None):ifExc_info:Try: ifheaders_sent:#re-raise Original exception if headers sent RaiseExc_info[1].with_traceback (exc_info[2]) finally: Exc_info= None#Avoid dangling circular ref elifHeaders_set:RaiseAssertionerror ("Headers already set!") headers_set[:]=[Status, Response_headers]#note:error checking on the headers should happen here, #*after* the headers is set. That's the, if an error #occurs, Start_response can only is re-called with #Exc_info set. returnWrite result=application (environ, start_response)Try: forDatainchResult:ifData#don ' t send headers until body appearsWrite (data)if notHeaders_sent:write ("')#Send headers Now if body is empty finally: ifHasattr (Result,'Close'): Result.close ()
3. Specification Details
The Application object must accept the positional arguments. For the sake of illustration, we had named them environ and start_response, but they is not required t o have these names. A server or gateway must invoke the Application object using positional(not keyword) arguments.
The environ parameter is a Dictonary object, containing Cgi-style enviroment variables. This object must was a builtin Python dictionary (not a subclass, or other dictionary simulation), and the application is a Llowed to modify the dictionary on any the IT desires. The dictionary must also include Cetain wsgi-required variables, and may also include server-specific extension variables, Named according to a covention.
The start_reponse parameter is a callable accepting Required positional arguments, and one optional argument. For the sake of illustration, we have named these Arguments status , response_headers , and exc_info , but they is not required to has these names, and the Applicati On must invoke the Start_response callable using positional arguments.
The status parameter is a status string of form ' 999 Message here ', and response_headers is a list of (h Eader_name, Head_value) tuples describing the HTTP response header. The optional exc_info parameter is used only when the application have trapped an error and are attempting to displ Ay an error message to the browser.
The start_response callable must return a write (body_data) callable that takes one postional parameter: A bytestring to being written as part of the HTTP response body.
When called by the server, the Application object must return a iterable yielding zero or more bytestrings. This can is accomplished in a variety of ways, such as by returning a list of bytestrings, or by the application being a G Enerator function that yields bytestrings, or by the application being a class whose instances is iterable. Regardless of how are accomplised, the Application object must always return a iterable yielding zero or more Bytestrin Gs.
The server or gateway must transmit the yielded bytestrings to the client in an unbuffered fashion, completing the Transmi Ssion of each bytestring before requesting another one. (In other words, applications should perform their own buffering.)
The application must invoke the Start_response () callable beforethe iteralbe yields its first body bytestring, s o The server can send the headers before any body content. However, this invocatio Nmay is performed by the Iterable's first iteration, so servers must isn't assume that Start_reponse () had been called before they begin iterating over the iterable.
If the iterable returned by the appliation have close() method, the server or gateway must call the method upon C Ompletion of the current request, whether the request is completed normally, or terminated early due to an application ER Ror during iteration or an early disconnect of the browser. (The close () method requirement is to support resource release by the application.)
Notes on PEP333 (Python Web Server Gateway Interface)