WSGI
What is WSGI?
WSGI[1] is not a server, a python module, a framework, an API or any kind of software. It is just an interface specification by which server and application communicate. Both server and application interface sides are specified in the PEP 3333.
WSGI applications (meaning WSGI compliant) can be stacked. Those in the middle of the stack are called middleware and must implement both sides of the WSGI interface, application and server. For the application in top of it it will behave as a server and for the application (or server) bellow as an application.
A WSGI server (meaning WSGI compliant) only receives the request from the client, pass it to the application and then send the response returned by the application to the client. It does nothing else. All the gory details must be supplied by the application or middleware.
WSGI & CGI
联系与区别
Application Interface
The WSGI application interface is implemented as a callable object: a function, a method, a class or an instance with an object.call() method. That callable must:
accept two positional parameters:
A dictionary containing CGI like variables; and
a callback function that will be used by the application to send HTTP status code/message and HTTP headers to the server.
return the response body to the server as strings wrapped in an iterable.
# The application interface is a callable object
def application ( # It accepts two arguments:
# environ points to a dictionary containing CGI like environment
# variables which is populated by the server for each
# received request from the client
environ,
# start_response is a callback function supplied by the server
# which takes the HTTP status and headers as arguments
start_response
):
# Build the response body possibly
# using the supplied environ dictionary
response_body = 'Request method: %s' % environ['REQUEST_METHOD']
# HTTP response code and message
status = '200 OK'
# HTTP headers expected by the client
# They must be wrapped as a list of tupled pairs:
# [(Header name, Header value)].
response_headers = [
('Content-Type', 'text/plain'),
('Content-Length', str(len(response_body)))
]
# Send them to the server using the supplied function
start_response(status, response_headers)
# Return the response body. Notice it is wrapped
# in a list although it could be any iterable.
return [response_body]
Make Server
# Instantiate the server
httpd = make_server (
'localhost', # The host name
8051, # A port number where to wait for the request
application # The application object name, in this case a function
)
# Wait for a single request, serve it and quit
httpd.handle_request()
Response Iterable
return [response_body]
如果改为
return response_body
那server就会按byte发送给client,导致相应速度变慢。
Parsing Request
Get
It is possible to write code to parse the query string and retrieve those values but it is easier to use the cgi.parse_qs() function which returns a dictionary with the values as lists.
Always beware of the user input. Sanitise it to avoid script injection. The cgi.escape() function can be used for that.
利用 escape 来防止脚本注入。
Post
When the request method is POST the query string will be sent in the HTTP request body in instead of in the URL. The request body is in the WSGI server supplied wsgi.input file like environment variable.
It is necessary to know the response body size as an integer to read it from wsgi.input. The PEP 3333 says that the CONTENT_LENGTH variable, which holds the body size, may be empty or missing so read it in a try/except block.
用 try except 来检查 CONTENT_LENGTH 变量是否大于0,否则返回 ValueError
What is uWSGI?
Servers that support WSGI
uWSGI 是一个支持WSGI协议的python服务器。
WSGI, uWSGI, nginx