A WSGI application is just a callable object the responds to requests
by taking two arguments. The first one is the WSGI
and the second is the
environment is a Python dictionary containing information about
the CGI environment.
start_response is a callback which takes two inputs the response
headers. The status is a string representation like
200 OK or any other HTTP status code followed by a word.
headers is a list of two values tuples or possible HTTP headers.
The return value of
start response is another callable which when
invoked return the body of the response.
It is the responsibility of the WSGI server to implement this callback. That is, the Python web application or the framework simply receive it.
The WSGI application is invoked with the
start_response, it may or may not use information from the
environment, when done it should return an iterable yielding zero
or more strings which then become the body of the response.
It may also manipulate the headers passed on to
before invoking it.
The following is a complete valid WSGI application:
def hello_world_app(environ, start_response): status = '200 OK' # HTTP Status # HTTP Headers headers = [('Content-type', 'text/plain; charset=utf-8')] start_response(status, headers) # The returned object is going to be printed return [b"Hello World"]
Running a WSGI application#
To actually make use of the above example, you need to invoke it with a valid WSGI server. Luckily, we don't need to fully setup a HTTP server, because the Python standard library already has already a simple HTTP server which implements the WSGI protocol which we can use to test our app. To make use of it you can do:
from wsgiref.simple_server import make_server def hello_world_app(environ, start_response): status = '200 OK' # HTTP Status # HTTP Headers headers = [('Content-type', 'text/plain; charset=utf-8')] start_response(status, headers) # The returned object is going to be printed return [b"Hello World"] httpd = make_server('', 8000, app) print("Serving on port 8000...") # Serve until process is killed httpd.serve_forever()
In reality, a WSGI server is usually deployed behind a full blown HTTP server, which serves as a reverse proxy for the WSGI server. That is, the HTTP server (for example NGinx) listen to HTTP or HTTPS requests on port 80 or 443 and then redirects them to the appropriate socket to which the WSGI server is bound to.
Write your own callable class which is a valid WSGI application.
class HelloWSGI: def __call__(self, environ, start_response): self.start_response('200 OK', [('Content-Type', 'text/plain')]) yield b"Hello World!\n"