Wsgi's understanding

Source: Internet
Author: User
In Python Web development, a service-side program can be divided into 2 parts:

Server program (used to receive, organize requests sent by clients)

Application (processing of requests passed by the server program)
When developing applications, we encapsulate common functions as frameworks, such as Flask,django,tornado (Web development using a framework, equivalent to developing server-side applications, processing background logic)
However, server programs and applications work with each other to provide services to users, and different applications (different frameworks) have different functions and functions. At this point, we need a standard for both the server program and the application to support this standard, then the two will be well matched

WSGI:WSGI is the standard for Python web development, similar to protocol. It is a convention for server programs and applications that specifies the interfaces and functions that are used in order for the two to mate with each other

Some provisions of the WSGI application

An application is a callable object
There are three types of objects that can be called:

a function

A class that must implement the __call__ () method

An instance of a class

This object receives two parameters
From the source, we can see that these two parameters are environ, start_response. Take the callable object as an example of a class:

Class Application:
def __call__ (self, Environ, start_response):
Pass

A callable object needs to return a value that can be iterated. Take the callable object as an example of a class:

Class Application:
def __call__ (self, Environ, start_response):
return [XXX]

Some provisions of the WSGI server program

The server program needs to invoke the application

def run (application): #服务器程序调用应用程序
Environ = {} #设定参数

def start_response (XXX): #设定参数
Pass
result = Application (environ, start_response) #调用应用程序的__call__函数 (here the application is a class)
def write (data):
Pass
def data in result: #迭代访问
Write (data)
The server program mainly does the following things:
1. Set the parameters required by the application
2. Invoking the application
3. Iterate through the returned results of the application and pass it on to the client

Middleware

Middleware is a part of the middle of a server program and application, and middleware is transparent to server programs and applications.

For a server program, middleware is the application, middleware needs to be disguised as an application, passed to the server program
For an application, middleware is a server program, middleware needs to be disguised as a server program, accepting and invoking the application

The server program obtains the URL of the client request and needs to give the URL to a different function, which can be implemented using middleware:

# URL Routing Middleware
def urlrouting (url_app_mapping):
def midware_app (environ, start_response): #函数可调用, contains 2 parameters, returns the values that can be iterated
url = environ[' path_info ']
App = Url_app_mapping[url] #获得对应url的应用程序
result = App (environ, start_response) #调用应用程序
return result
Return Midware_app

The function Midware_app is middleware:
On the one hand, the Midware_app function sets the variables required by the application and invokes the application. So for an application, it's a server program
On the other hand, the Midware_app function is a callable object that receives two parameters while the callable object returns a value that can be iterated. So for a server program, it's an application

Logic for writing middleware (middleware):
1. Middleware needs to be disguised as WSGI application-----1. Can call 2. Two parameters of 3. Returns the value of an iteration
2. Middleware need to disguise as a server program--WSGI Server program--Invoke application

We need to know about the environ variable. In Wsgi, an application requires two parameters: Environ and start_response, which need to be set before the server program invokes the application. Where Start_response is usually a callable method, and Environ is a dictionary, which is defined in CGI, view the CGI document the Common Gateway Interface specification, You can find a definition of environ.
The following are the parameters in Environ:

Auth_type
Content_length#http the content-length part of the request
Content_type#http the Content-tpye part of the request
Gateway_interface
Http_* #包含一系列变量, such as http_host,http_accept, etc.
The Path_info#url path, in addition to the remainder of the initial section, is used to locate the appropriate Application object if the requested path is the root path, and the value is an empty string
Path_translated
Query_string#url in the path? The latter part
Remote_addr
Remote_host
Remote_ident
Remote_user
Request_method#http request method, such as "GET", "POST"
Script_name#url the starting part of the path corresponds to the Application object, if the Application object corresponds to the root of the server, then this value can be an empty string
server_name
Server_port
server_protocol# Client-requested protocol (http/1.1 http/1.0)
Server_software

For example: http://localhost:5000/aaa?666, the variable value is:

request_method= ' GET '
script_name= '
server_name= ' localhost '
server_port= ' path_info= '
/aaa
query_string= ' 666 '
server_protocol= ' http/1.1 '
content_type= ' text/plain '
conten_length= '

Http_host = ' localhost:8000 '
http_accept = ' text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/ *;q=0.8 '
http_accept_encoding = ' gzip,deflate,sdch '
Http_accept_language = ' en-us,en;q=0.8,zh;q=0.6,zh-cn;q= 0.4,zh-tw;q=0.2 '
Http_connection = ' keep-alive '
Http_user_agent = ' mozilla/5.0 (X11; Linux i686) applewebkit/ 537.36 (khtml, like Gecko) chrome/32.0.1700.77 safari/537.36 '

For the Start_response () function:
Start_response is the beginning of the HTTP response, in the form of: Start_response (Status, Response_headers, Exc_info=none)
Status indicates an HTTP state code, such as a $ OK
Response_headers is a list, and the list element is a tuple: (Header_name, Header_value)
Exc_info is an optional parameter that is set when an error occurs during processing of the request and is called Start_response
To give an example of an official Werkzeug document, I'll make a little improvement to analyze it (this is a suggestion to look at the Shareddatamiddleware class in the second part of wsgi.py):

Class shortly (object):

def __init__ (self, config):
Self.redis = Redis. Redis (config[' redis_host '), config[' Redis_port '])

def dispatch_request (self, request):
Return Response (' Hello world! ') #初始化Response类

def wsgi_app (self, Environ, start_response):
Request = Request (environ)
Response = self.dispatch_request (Request) #response的类型为Response类
Print ('%%%%%%%%%%%%%%%%%%%%%%%%%%% ')
Return response (environ, start_response) #Response的__call__函数就是应用程序, returns the Iteration object

def __call__ (self, Environ, start_response):
Print (Self.wsgi_app)
Print (' Erghrgheoghegoierge ')
return self. Wsgi_app (environ, start_response)


def create_app (redis_host= ' localhost ', redis_port=6379, with_static=true):
App = shortly ({
' Redis_host ': Redis_host,
' Redis_port ': redis_port
})
If with_static:
Print (' Yes ')
App.wsgi_app = Shareddatamiddleware (App.wsgi_app, {
'/static ': Os.path.join (Os.path.dirname (__file__), ' static ')
})
Print (' 33333333333333333 ')
Return app
#开启本地服务器
if __name__ = = ' __main__ ':
From werkzeug.serving import run_simple
App = Create_app () #创建应用程序的实例
Run_simple (' 127.0.0.1 ', the app, Use_debugger=true, Use_reloader=true)

We look at the source code of response (response inherited Baseresponse, see the source of Baseresponse) can know: function dispatch_request () The value returned is the constructor of request, That is to return a response class, in function Wsgi_app (), the type of the request value is response, so the return value of Wsgi_app () response (environ, start_response) is actually called the __call__ () function of the response class.
Read the source we can find that __call__ () is a WSGI app!

When running this program:

22222222222222222
Yes
33333333333333333
* Running on http://127.0.0.1:5000/(press CTRL + C to quit)
* Restarting with stat
22222222222222222
Yes
33333333333333333

Let's not dwell on why we read it 2 times before.
When we open this webpage, the output of the console is:

<werkzeug.wsgi.shareddatamiddleware object at 0x1007be7b8> #说明wsgi_app是SharedDataMiddleware的实例!
Erghrgheoghegoierge
%%%%%%%%%%%%%%%%%%%%%%%%%%% #说明执行了原wsgi_app函数中的内容!
127.0.0.1--[22/may/2015 21:01:25] "get/http/1.1" 200-

It can be noted that in this case, the App.wsgi_app method has become an instance of the Shareddatamiddleware class, and I am curious to see why wsgi_ when the server passes Environ and Start_response to the app. Will pp also execute the contents of the original Wsgi_app?
When we access the host address, the server program accepts the user request and then passes Environ and start_response to the application App,app executes the __call__ function, in which App.wsgi_app is executed. Then Wsgi_app executes the sharedatamiddleware __call__ () function
This place needs us to look at the source code of Shareddatamiddleware class __call__ (). Read the source we can find that because the user did not request a static file, so will execute return Self.app (environ, start_response), in this case, we can see in Create_app (), The Sharedatamiddleware application we define is App.wsgi_app, so the original Wsgi_app function is returned here! So of course the original function is executed ~
At the same time, we can also put a file in the static folder, and then access to try: 127.0.0.1/static/file name, you can see the file now!
Through this example, we can understand the role of middleware more deeply:

Middleware between the server program and the application, it receives messages sent by the server (environ and
Start_response), and do some processing, and then pass the part that needs to be processed by the application to the application processing

In addition, the server program needs to define the relevant variables for the WSGI:

Wsgi.version
The value is in the form (1, 0) for WSGI version 1.0
Wsgi.url_scheme
A pattern that represents a URL, such as "https" or "http"
Wsgi.input
Input stream, the body part of the HTTP request can be read from here
Wsgi.erros
The output stream, if an error occurs, can be written here
Wsgi.multithread
True if the Application object can be called simultaneously by another thread in the same process
Wsgi.multiprocess
True if the Application object can be called by another process at the same time
Wsgi.run_once
True if the server wants the application object to be called only once in the process that contains it

The above is wsgi understanding of the content, more relevant articles please pay attention to topic.alibabacloud.com (www.php.cn)!

  • 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.