(reprint-Learn) Python Wsgi introduction

Source: Internet
Author: User
Tags error handling iterable prepare response code

Basic Knowledge python knowledge
    • Iterator and generator
    • Advanced usage of functions: nesting functions, passing as parameters, etc.
    • Understanding decorator will be very helpful in understanding WSGI.
    • The callable concept of Python
    • The concept of Classmethod and Staticmethod
    • Fundamentals of Web Programming
HTTP Basics

The most basic concept for a Web application is to send a request to the client and receive a server-side response (response).

The following is a simple HTTP request:

 GET /Index.html HTTP/1.1\r\n Connection: Keep-Alive\r\n Accept: */*\r\n User-Agent: Sample Application\r\n Host: www.microsoft.com\r\n\r\n

The content includes the method, URL, protocol version, and header information. The HTTP response (excluding data) might be something like this:

 HTTP/1.1 200 OK Server: Microsoft-IIS/5.0\r\n Content-Location: http://www.microsoft.com/default.htm\r\n Date: Tue, 25 Jun 2002 19:33:18 GMT\r\n Content-Type: text/html\r\n Accept-Ranges: bytes\r\n Last-Modified: Mon, 24 Jun 2002 20:27:23 GMT\r\n Content-Length: 26812\r\n

In actual production, the Python program is placed on the server's HTTP server (such as Apache, Nginx, etc.). The question now is how does the server program pass the received request to Python, and how does it switch between the network's data stream and the python structure? This is what WSGI does: a set of specifications on the terminal and server side, or a unified interface.

WSGI

Let's take a look at what the Python program for HTTP needs to care about:

    • Request
      • Method of Request
      • URL of the requested address
      • Content of the request
      • Header headers of the request
      • Requested environment information
    • Response
      • Status Code Status_code
      • Data in response
      • The head of the response

The task of WSGI (Web Server Gateway Interface) is to simply and amicably pass the above data between the HTTP Server and the Python program. It is a standard that is defined in Pep 333. HTTP server and Python programs are required to comply with certain specifications to achieve the standard of the agreed content, in order to work properly.

Application-Side

WSGI specifies that each Python program (application) must be a callable object (a __call__ method or class that implements the function), accepts two parameters environ (WSGI environment information), and (the function that start_response starts responding to the request), and returns Iterable. A few notes:

    1. environand start_response provided by HTTP server and implemented
    2. environA variable is a dictionary that contains information about the environment
    3. ApplicationCalled internally before returningstart_response
    4. start_responseAlso a callable that accepts two required parameters status (HTTP status) and response_headers (the header of the response message)
    5. Callable object to return a value, which is iterative.

Having said so many concepts, take a look at the implementation of the Code:

 # 1. Callable object is a function def application (environ, start_response): Response_body = ' The request method was%s '% environ[' Request_metho   D '] # HTTP response code and message status = ' OK ' # The header of the answer is a list, each pair of key values must be a tuple.  Response_headers = [(' Content-type ', ' Text/plain '), (' Content-length ', str (len (response_body)))] #   Call the server program provided by Start_response, fill in two parameters Start_response (status, response_headers) # return must be iterable return [response_body] # 2. The callable object is a class Appclass: "" The callable object here is the Appclass class, which is called to produce the result that can be iterated. Use a method similar to: for result in Appclass (env, Start_response): do_somthing (Result) "" "Def __init__ (self, environ, start_resp        Onse): Self.environ = Environ Self.start = Start_response def __iter__ (self): status = ' OK ' Response_headers = [(' Content-type ', ' Text/plain ')] Self.start (status, response_headers) yield "Hello W orld!\n "# 3. The callable object is an instance of class Appclass: "" The callable object here is an instance of Appclass, using a method similar to: app = Appclass () for REsult in App (environ, start_response): do_somthing (Result) "" "Def __init__ (self): Pass def __call__ (self, Environ, start_response): status = ' OK ' response_headers = [(' Content-type ', ' Text/plain ')] Self . Start (status, Response_headers) yield "Hello world!\n"
Server program Side

As already mentioned above, the standard to be able to implement exactly, must require both the terminal and the server side to abide by. As mentioned above, envrion and start_response both are provided on the server side. The following is a look at the server side to fulfill the obligations.

    • Prepare environ Parameters
    • Defining start_response Functions
    • Invokes a callable object on the terminal

PEP 333 gives a simple implementation of a WSGI server, and I've simplified it--removing some exception handling and judgment and adding a bit of comment:

Import OS, Sysdef run_with_cgi (application): # application is the terminal callable Object # Prepare the Environ parameter, this is a dictionary, inside the content is an HTTP request environment variable en    Viron = Dict (Os.environ.items ()) environ[' wsgi.input '] = Sys.stdin environ[' wsgi.errors '] = Sys.stderr    environ[' wsgi.version ' = (1, 0) environ[' wsgi.multithread '] = False environ[' wsgi.multiprocess '] = True environ[' wsgi.run_once ' = True environ[' wsgi.url_scheme '] = ' http ' headers_set = [] Headers_sent = []# outputs the result of the answer to the terminal def write: sys.stdout.write (data) Sys.stdout.flush () # implements the Start_response function, which is transmitted by the program end. Status and Response_headers parameters, # set state and head def start_response (status, Response_headers, Exc_info=none): Headers_se t[:] = [status, Response_headers] return write# invokes the client's callable object, passing the prepared parameters past result = Application (environ, start_respon    SE) # Processes The resulting results, which simply output the results to standard output.           Try:for data in result:if data: # don ' t send headers until body appears     Write (data) finally:if hasattr (result, ' close '): Result.close () 
Middle Middleware

Some programs may be between the server side and the terminal: for a server program, it is an application, and for an application it is a server program. This is the middle-tier middleware. Middleware is transparent to the server program and application, it is like a proxy/pipeline, the received request for some processing, and then passed, passed to the client program, and finally the program's client processing results returned. As shown in the following:

Related: Http://stackoverflow.com/questions/1303118/looking-for-a-diagram-to-explain-wsgi

http://www.python.org/dev/peps/pep-0333/

A picture wins thousands of words, a picture wins thousands of words

Middleware has done two things:

    1. Be called by the server program (possibly other middleware), return the result back
    2. Invoke the application (possibly other middleware) and pass the arguments past

PEP 333 shows the possible usage scenarios for middleware:

    • The request is given to a different client program (URL routing) based on the URL
    • Allowing multiple client programs to run concurrently with the/web framework is to pass the same request to multiple programs.
    • Load balancing and remoting: Transferring requests over the network
    • Filtering Processing of responses

So what is the simple implementation of middleware? The following code implements the middleware of a simple URL routing:

class Router(object):    def __init__(self):        self.path_info = {}    def route(self, environ, start_response):        application = self.path_info[environ[‘PATH_INFO‘]]        return application(environ, start_response)    def __call__(self, path):        def wrapper(application):            self.path_info[path] = application        return wrapperrouter = Router()

How to use it inside the program?

#here is the application@router(‘/hello‘)#调用 route 实例,把函数注册到 paht_info 字典def hello(environ, start_response):    status = ‘200 OK‘    output = ‘Hello‘    response_headers = [(‘Content-type‘, ‘text/plain‘),                        (‘Content-Length‘, str(len(output)))]    write = start_response(status, response_headers)    return [output]@router(‘/world‘)def world(environ, start_response):    status = ‘200 OK‘    output = ‘World!‘    response_headers = [(‘Content-type‘, ‘text/plain‘),                        (‘Content-Length‘, str(len(output)))]    write = start_response(status, response_headers)    return [output]#here run the applicationresult = router.route(environ, start_response)for value in result:     write(value)

Note: The above code is from this blog.

Learn more?

For ordinary developers, understanding the above knowledge is sufficient, and does not need to master every detail.

Only authors of Web servers and programming frameworks need to know every detail and corner case of the WSGI design. You don ' t need to understand every detail of WSGI just to install a WSGI application or to write a Web application using a N Existing framework.

If you want more, go to see PEP333, and the documentation has more knowledge:

    • Error handling
    • What are the values that the Environ variable contains, and what does it mean?
    • Details of inputs and outputs
    • More Specifications for Start_response
    • Content-length and other head specifications
    • Caching and text flow
    • Unicode and multi-lingual processing
    • ......
Resources
    • Official Document PEP333
    • Getting Started with WSGI
    • A very concise and easy-to-understand WSGI introduction
    • Wsgiref: Official WSGI implementations, including client and server side

(reprint-Learn) Python Wsgi introduction

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.