www.liaoxuefeng.com/wiki/101695… Knowing the HTTP protocol and HTML documents, we understand the essence of a Web application:

  1. The browser sends an HTTP request;
  2. The server receives the request and generates an HTML document;
  3. The server sends the HTML document to the browser as the Body of the HTTP response;
  4. The browser receives the HTTP response, pulls the HTML document from the HTTP Body and displays it.

So, the simplest Web application is to save the HTML file, use an off-the-shelf HTTP server software, receive the user’s request, read the HTML from the file, and return it. Apache, Nginx, Lighttpd, and other common static servers do just that. (That is, the HTML returned is fixed, save in the file first)

If you want to generate HTML dynamically, you need to do the above steps yourself. However, accepting HTTP requests, parsing HTTP requests, and sending HTTP responses are all hard work, and if we were to write the underlying code ourselves, it would take us months to read the HTTP specification before we even started writing dynamic HTML.

Instead, the underlying code is implemented by specialized server software, and we use Python to focus on generating HTML documents. Because we don’t want to be exposed to TCP connections, HTTP raw request and response formats, we need a unified interface that lets us focus on writing Web business in Python.

This Interface is WSGI: Web Server Gateway Interface.

The WSGI interface definition is very simple, requiring Web developers to implement a single function to respond to HTTP requests. Let’s take a look at the simplest Web version of the Hello, Web! :

def application(environ, start_response) :
    start_response('200 OK', [('Content-Type'.'text/html')])
    return [b'

Hello, web!

'
] Copy the code

The application() function above is a WSGI compliant HTTP handler that takes two arguments:

  • Environ: a dict object that contains all HTTP request information;
  • Start_response: a function that sends an HTTP response.

In the application() function, call:

start_response('200 OK', [('Content-Type'.'text/html')])
Copy the code

The Header of the HTTP response is sent. Note that the Header can only be sent once, that is, the start_response() function can only be called once. The start_response() function takes two arguments:

  • One is the HTTP response code (in this case, ‘200 OK’)
  • One is HTTP represented by a list Header, each Header is represented by a tuple containing two STR’s (in this case, the list is 1, each element is a binary tuple, in this case, the tuple is (‘ context-type ‘,’text/ HTML ‘)),I Guess means text text is transmitted.

In general, you should send the Content-Type hair to the browser. Many other commonly used HTTP headers should also be sent. The function then returns the value b’

Hello, web!

‘ is sent to the browser as the Body of the HTTP response.


With WSGI, all we care about is getting HTTP requests from environ dict objects, constructing HTML, sending headers via start_Response (), and returning the Body. The entire application() function itself is not involved in any part of parsing HTTP, which means that we don’t need to write the underlying code ourselves, just worry about how to respond to requests at a higher level.

But wait, how does the application() function get called? If we call environ and start_response ourselves, we cannot provide environ and start_Response, and the returned bytes cannot be sent to the browser. So the application() function must be called by the WSGI server. There are many WSGI compliant servers, and we can pick and choose one to use. But for now, we just want to test as soon as possible that the application() function we wrote can actually output HTML to the browser, so let’s find the simplest WSGI server we can and get our Web application up and running.

The good news is that Python has a WSGI server built in. This module is called WSGIref, which is a reference implementation of WSGI server written in pure Python. A “reference implementation” is an implementation that is fully compliant with WSGI standards, but is only for development and testing without regard to any operational efficiency.


Take a look at an example:

We’ll start by writing Hello. py to implement WSGI handlers for our Web application:

def application(environ, start_response) :
    start_response('200 OK', [('Content-Type'.'text/html')])
    return [b'

Hello, web!

'
] Copy the code

Then, write a server.py that starts the WSGI server and loads the application() function:

# import from wsGIref module:
from wsgiref.simple_server import make_server
# import our own application function:
from hello import application

Create a server where IP address is null and port 8000 is null.
httpd = make_server(' '.8000, application)
print('Serving HTTP on port 8000... ')
# start listening for HTTP requests:
httpd.serve_forever()

The server calls the application function every time an HTTP request is sent to the server
Copy the code

Start the WSGI server by typing python server.py on the command line

After successful startup, open your browser and type http://localhost:8000/ to see the result:

On the command line, you can see the log information printed by WSGIref:If you think this Web application is too simple, you can modify it a bit and read it from environPATH_INFOTo display more dynamic content:

# hello.py
def application(environ, start_response) :
    start_response('200 OK', [('Content-Type'.'text/html')])
    body = '

Hello, %s!

'
% (environ['PATH_INFO'] [1:] or 'web') return [body.encode('utf-8')] Copy the code

As you can see, we selected the Jony-j of the URL, as shown below:

Does it feel like a Web App?


Summary: No matter how complex a Web application, the entry is a WSGI handler function. All input information for an HTTP request is available through environ, and the output of an HTTP response is available through start_response() plus the return value of the function as the Body.

Complex Web applications are still too low-level to be handled by a WSGI function alone, so we need to abstract the Web framework on top of WSGI to further simplify Web development. wow