Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is WSGI?

2025-03-04 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)05/31 Report--

This article mainly explains "what is WSGI". The content of the explanation is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "what is WSGI".

Why WSGI?

For those of you who have written web applications, you should know something about CGI. We know that the whole process of CGI is "Common Gateway Interface", that is, "universal Gateway Interface". Yes, the WSGI here is the web application interface "Python Web Server Gateway Interface" that is only aimed at Python. Through this analogy, we must know something about his status.

It is just an interface definition: it is not responsible for the implementation of the server, nor is it responsible for the implementation of web applications, it is just a convention of the interface mode on both sides. Therefore, it is not another WEB application framework. Generally speaking, the WEB application framework is only equivalent to an implementation of the WSGI web application.

What are the advantages of this? The explanation in PEP 0333 is that in order to implement an API similar to Java Servelet, applications that follow this interface have wider applicability. Yes, with this interface, you don't have to think about how the server's support for Python is implemented-- whether it's a "server directly implemented in Python", a "server embedded in Python", or "through a gateway interface (CGI, Fastcgi...)"-- applications have good applicability. Just like the beginning of today's story, we come across the cloud platform, which provides support for the WSGI interface, so as long as the application is based on WSGI, then the application can run directly.

In addition, the design of WSGI also offers another possibility, which is middleware (middleware). In other words, we can write modules that are compatible with both server and application, and we can deploy them on Server or Application to complete functions such as caching, character encoding conversion, application routing based on url, and so on. This design pattern is the product of WSGI after reducing the coupling between server and application. At the same time, it greatly improves the flexibility of the design from another point of view.

Outline of WSGI implementation

In the previous section, WSGI was briefly introduced. Here from application, server, middleware three angles of WSGI slightly in-depth, so that we have a more specific impression of it.

1) Application side

WSGI requires that the application side must provide an entity that can be called (PEP 0333 uses Object, which is specifically explained in the document as different from Object instance), which can be a function (function), a method (method), a class (class), or an object with a _ _ call__ method (Object instance).

Here are two examples of web application implementation, one is function object, and the other is class object:

Def simple_app (environ, start_response): status = '200 OK' response_headers = [(' Content-type', 'text/plain')] start_response (status, response_headers) return [' Hello world!\ n']

The above function only makes a direct "200ok" response to the request and does not deal with the various HTTP request parameters provided by the WSGI Server side in the incoming parameter environ--. It is important to note that at the end of this function, a list is returned (included with "[]") to guarantee the iterable of the result. The following class is similar.

In the following example, AppClass is used as the application entity. When the call occurs, the class is actually instantiated (the inherent characteristics of python can be further understood by referring to the later implementation code on the server side), and as we can see, the return value of this call (call) is also iterable-though only once (yield).

Class AppClass: def _ init__ (self, environ, start_response): self.environ = environ self.start = start_response def _ iter__ (self): status = '200 OK' response_headers = [(' Content-type', 'text/plain')] self.start (status, response_headers) yield "Hello world!\ n" In fact The interator 'ends' here because of no more yield field "

Different from the above two cases, when using object instance as an application entity, you need to add a _ _ call__ method for the class definition. At the same time, referring to the above case of using function as an entity, the return value of the _ _ call__ method should be iterable (for example, return [something]).

Finally, whether our app is function or class, application needs to handle two parameters, and there are two location-dependent parameters (not named parameters): a dictionary object that holds the CGI environment variable, and a callable entity (it needs to be given three location-related parameters, two must, one optional).

Where the callable entity (start_response in the previous example) must be called once, and the two required parameters are "status of HTTP Response (str type)" and "HTTP Response Header (list of tuples)", respectively.

An optional parameter exc_info, which must be Python sys.exc_info () tuple, is used only if an error requires an error message to be displayed. Full call: start_response (status, response_headers,exc_info).

2) Server side

The following is a simple WSGI container from PEP 0333, suitable for the application of Python as a CGI on a WEB Server.

Import os, sysdef run_with_cgi (application): environ = 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 if environ.get ('HTTPS') 'off') in (' on' '1'): environ [' wsgi.url_scheme'] = 'https' else: environ [' wsgi.url_scheme'] = 'http' headers_set = [] headers_sent = [] def write (data): if not headers_set: raise AssertionError ("write () before start_response ()") elif not headers_sent: # Before the first output Send the stored headers status Response_headers = headers_sent [:] = headers_set sys.stdout.write ('Status:% s\ r\ n'% status) for header in response_headers: sys.stdout.write ('% s:% s\ r\ n'% header) sys.stdout.write ('\ r\ n') sys.stdout.write (data) sys .stdout.flush () def start_response (status Response_headers, exc_info=None): if exc_info: try: if headers_sent: # Re-raise original exception if headers sent raise exc_info [0], exc_info [1] Exc_info [2] finally: exc_info = None # avoid dangling circular ref elif headers_set: raise AssertionError ("Headers already set!") Headers_set [:] = [status, response_headers] return write result = application (environ, start_response) try: for data in result: if data: # don't send headers until body appears write (data) if not headers_sent: write ('') # send headers now if body was empty finally: if hasattr (result 'close'): result.close ()

The container above probably implements:

A) put the CGI environment variable into dictionary object (environ) for use by Application entities

B) the start_response method is defined to be called by the Application entity

C) call the application entity to process the web request

D) write the return result of application, as well as the HTTP Response HEADER set through start_response, to stdout-- like other CGI, it is actually sent to the web page.

3) as middleware

Because of the loose coupling of WSGI, we can easily insert any intermediate plug-ins before Application and Server, and implement some special functions without changing Server and Application. However, this kind of module placed in the "middle" between Server and Application is not the middleware here; or it is only a special kind of middleware, because it only implements the function of the Application side as defined by middleware in PEP 0333. This kind of middleware, which is implemented only on one side, requires a special statement at the time of release.

As stipulated in PEP 0333, middleware is modules that can be implemented not only on the Server side, but also on the Application side. Therefore, in the design, the characteristics of both sides should be properly considered. Fortunately, the design of the WSGI interface is simple enough.

Class Router (): 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 wrapper "The above is the middleware" router = Router () @ router ('/ world') def world (environ, start_response): status = '200 OK' output =' Worldbread startresponse (status, response_headers) return [output] @ router ('/ hello') def hello (environ) Start_response): status = '200 OK' output =' Hello' response_headers = [('Content-type',' text/plain'), ('Content-Length', str (len (output))] start_response (status, response_headers) return [output]

A brief explanation:

-as an Application, we instantiate an object with Router. Then register the "PATH-APP", depending on the PATH, which App we want to choose further. Next, router.route () is fed to Server as a callable entity on the Application side. When a request arrives, it is applied and executed according to the registered "PATH-APP" pair.

-similar to the Server side, we need to instantiate and complete the registration. Then, for example, taking the WSGI container we implemented in the previous section as an example, we need to modify result = router.route (environ, start_response) to also complete the function of router.

Here is another example that implements postprocessor, adding another Header to the HTTP Header returned by Application.

Def myapp (environ, start_response): response_headers = [('content-type',' text/plain')] start_response ('200 OK', response_headers) return [' Check the headers'] class Middleware: def _ init__ (self, app): self.wrapped_app = app def _ call__ (self, environ, start_response): def custom_start_response (status, headers) Exc_info=None): headers.append (("1234567890")) return start_response (status, headers, exc_info) return self.wrapped_app (environ, custom_start_response) app = Middleware (myapp)

Here, the purpose of Application is achieved by rewriting the entity passed to postprocess.

Thank you for your reading, the above is the content of "what is WSGI", after the study of this article, I believe you have a deeper understanding of what WSGI is, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report