Basics of WSGI

In this post we will write a web app which will serve few urls. We will not use any Python framework for it. It’s only to illustrate how things work under the hood.

Before we start, let’s clarify few terms we will be using.

Web Server: When we say web server, we mean the software, and not the machine that stores your code. This server recieves the request from a client(Web browser) and returns a response. Web server doesn’t create the response, it only returns the response. So, a server needs to talk with a Web Application which can create a response.

Web Application: Web Server will get the response from it. It is the job of the Web Application to create a response based on the url and pass this response back to the Web Server. Web Server’s job is only to return this response to the client.

WSGI: WSGI is an interface. It is just a specification or a set of rules. WSGI is not a software. WSGI is not a library or a framework. WSGI is not something you can install via pip.

WSGI comes into picture because the Web Server needs to communicate with the Web Application. WSGI specifies the rules which needs to be implemented by the Web Application side and the Web Server side so that they can interact with each other. So, a WSGI compliant server will be able to communicate with a WSGI compliant Web Application.

In WSGI architecture, WSGI Application has to be a callable and it needs to be given to the Web Server, so the Web Server can call the Web Application whenever the server recieves a request.

For understanding more on why WSGI came into existence, read about WSGI on wikipedia.

Writing our Web Application. Just copy it for now and we will go through each line to see what exactly is happening.

The first and second argument to make_server specifies the host and port on which the server will listen for requests.

Third argument to make_server passes the Web Application which the Web Server would use to get the response.

In the last line we start the web server using serve_forever.

Whenever a request comes, Web Server running on port 8051 will call the Web Application which in our case is the callable application.

Web Application code details.

To interact with WSGI Web Server, Web Application needs to be WSGI compliant as well.

Server will call it with two arguments. So, it must accept two arguments. This is one condition for application to be WSGI compliant.

First argument passed to it will be a variable containing various information about the request. In our example, we used it to read the request path.

Second argument passed to it will be a callable. application must use this callable to notify the server of the status of response and for setting various headers. This is second condition for application to be WSGI compliant.

We satisfied both the conditions required for our application to be WSGI compliant.

Finally a response is returned by application to the WSGI server.

And server finally relays this response back to the client.

###Edit:

I overlooked one thing in the application code. It was pointed by defnull on reddit.

The last line of application should not be return response_body. Instead, it should be return [response_body]. Reason being:

WSGI server expects the return from application to be an iterable and sends each element of this iterable to the client in an unbufferred fashion.

If we keep return response_body, response_body is a string and hence an iterable and so our code still works. But every character of the response_body will be sent one by one.

If we keep return [response_body], the iterable is a list here, containing only one element which is the string response_body. So, in this case entire response_body will be sent at once.

That’s why we should replace return response_body with return [response_body]. Edited the code for this change.

###More Edit:

By now probably you would have read why WSGI came into existence.

Before WSGI, one Python web application would work with some web server and not work with other web server. WSGI was written to fix this. With WSGI, any wsgi compliant web application would work with any wsgi compliant web server.