Vous devez comprendre ce qu'est WSGI

coldplay.xixi
Libérer: 2020-11-10 17:01:04
avant
1943 Les gens l'ont consulté

La colonne

tutoriel vidéo Python présente WSGI.

Vous devez comprendre ce qu'est WSGI

J'écris du web python depuis plusieurs années, mais je ne sais toujours pas ce qu'est WSGI. Y a-t-il beaucoup de gens qui le font ? C'est normal, car en tant que développeur, vous avez rarement besoin de comprendre ce qu'est wsgi pour créer un site Web.

Mais si vous souhaitez écrire vous-même un framework web, vous devez vous renseigner sur wsgi.

Avec le recul, lorsque nous utilisons Python pour le développement Web, nous développons généralement sur la base d'un certain framework Web, tel que Django ou flask et d'autres frameworks. Une fois le développement commercial terminé, il doit être déployé sur un serveur pour fournir un accès externe.

Si vous effectuez une recherche en ligne à ce moment-là, ils vous diront que vous devez utiliser gunicorn ou uwsgi pour déployer. Alors, que sont Gunicorn et Uwsgi ?

Vous comprendrez en regardant cette photo. J'ai trouvé la photo sur Internet

Le rôle joué par uwsgi ou gunicorn ici est celui du serveur Web. Le serveur ici est un serveur de niveau logiciel, utilisé pour traiter les requêtes HTTP envoyées par le navigateur et renvoyer les résultats de la réponse au front-end. La tâche principale du framework Web est de traiter la logique métier et de générer des résultats vers le serveur Web, puis le serveur Web les renvoie au navigateur.

La communication entre le framework Web et le serveur Web doit suivre un ensemble de spécifications, et cette spécification est WSGI.

Pourquoi devrions-nous proposer un tel ensemble de réglementations ? Les normes visent à unifier les normes et à faciliter l'utilisation par tous

Imaginez que nos interfaces de chargement de téléphones portables sont désormais de type C. Les fabricants de téléphones portables produisent des téléphones portables et des chargeurs selon cette norme. des chargeurs conformes aux spécifications Type-c, et les téléphones mobiles de différents fabricants peuvent être utilisés avec des chargeurs de différents fabricants. Cependant, Apple a son propre ensemble de réglementations, ce qui fait que le chargeur Android ne peut pas charger Apple.

![

](p9-juejin.byteimg.com/tos-cn-i-k3…)

Ensuite, comment écrire une application conforme au WSGI spécification (qu'en est-il des frameworks) des programmes et des serveurs ?

Comme le montre l'image ci-dessus, la gauche est le serveur Web et la droite est le framework Web, ou l'application.

Application

WSGI stipule que l'application doit être un objet appelable (l'objet appelable peut être une fonction, une classe ou un objet instance qui implémente __call__), et elle doit accepter deux paramètres, et la valeur de retour de l'objet doit être un objet itérable.

Nous pouvons écrire l'exemple le plus simple d'une application

HELLO_WORLD = b"Hello world!\n"def application(environ, start_response):
    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)    return [HELLO_WORLD]复制代码
Copier après la connexion

l'application est une fonction, qui doit être un objet appelable, et reçoit ensuite deux paramètres, les deux paramètres sont : environ et start_response

  • environ est un dictionnaire qui stocke tout le contenu lié à la requête HTTP, tel que les en-têtes, les paramètres de requête, etc.
  • start_response est une fonction transmise par le serveur WSGI, utilisée pour l'en-tête de réponse, le code d'état est transmis au serveur.

L'appel de la fonction start_response est chargé de transmettre l'en-tête de réponse et le code d'état au serveur. Le corps de la réponse est renvoyé au serveur par la fonction d'application. Une réponse http complète est fournie par ces deux fonctions. .

Tout framework Web qui implémente wsgi aura un tel objet appelable

Serveur

Ce que fait le serveur WSGI est de recevoir des requêtes HTTP à chaque fois et de construire l'objet environ, puis appelez l'objet application et renvoyez enfin la réponse HTTP au navigateur.

Ce qui suit est le code d'un serveur wsgi complet

import socketimport sysfrom io import StringIOclass WSGIServer(object):
    address_family = socket.AF_INET
    socket_type = socket.SOCK_STREAM
    request_queue_size = 1

    def __init__(self, server_address):
        # Create a listening socket
        self.listen_socket = listen_socket = socket.socket(
            self.address_family,
            self.socket_type
        )        # Allow to reuse the same address
        listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)        # Bind
        listen_socket.bind(server_address)        # Activate
        listen_socket.listen(self.request_queue_size)        # Get server host name and port
        host, port = self.listen_socket.getsockname()[:2]
        self.server_name = socket.getfqdn(host)
        self.server_port = port        # Return headers set by Web framework/Web application
        self.headers_set = []    def set_app(self, application):
        self.application = application    def serve_forever(self):
        listen_socket = self.listen_socket        while True:            # New client connection
            self.client_connection, client_address = listen_socket.accept()            # Handle one request and close the client connection. Then
            # loop over to wait for another client connection
            self.handle_one_request()    def handle_one_request(self):
        self.request_data = request_data = self.client_connection.recv(1024)        # Print formatted request data a la 'curl -v'
        print(''.join(            '< {line}\n&#39;.format(line=line)            for line in request_data.splitlines()
        ))
        self.parse_request(request_data)        # Construct environment dictionary using request data
        env = self.get_environ()        # It&#39;s time to call our application callable and get
        # back a result that will become HTTP response body
        result = self.application(env, self.start_response)        # Construct a response and send it back to the client
        self.finish_response(result)    def parse_request(self, text):
        request_line = text.splitlines()[0]
        request_line = request_line.rstrip(&#39;\r\n&#39;)        # Break down the request line into components
        (self.request_method,  # GET
         self.path,  # /hello
         self.request_version  # HTTP/1.1
         ) = request_line.split()    def get_environ(self):
        env = {}        # The following code snippet does not follow PEP8 conventions
        # but it&#39;s formatted the way it is for demonstration purposes
        # to emphasize the required variables and their values
        #
        # Required WSGI variables
        env[&#39;wsgi.version&#39;] = (1, 0)
        env[&#39;wsgi.url_scheme&#39;] = &#39;http&#39;
        env[&#39;wsgi.input&#39;] = StringIO.StringIO(self.request_data)
        env[&#39;wsgi.errors&#39;] = sys.stderr
        env[&#39;wsgi.multithread&#39;] = False
        env[&#39;wsgi.multiprocess&#39;] = False
        env[&#39;wsgi.run_once&#39;] = False
        # Required CGI variables
        env[&#39;REQUEST_METHOD&#39;] = self.request_method  # GET
        env[&#39;PATH_INFO&#39;] = self.path  # /hello
        env[&#39;SERVER_NAME&#39;] = self.server_name  # localhost
        env[&#39;SERVER_PORT&#39;] = str(self.server_port)  # 8888
        return env    def start_response(self, status, response_headers, exc_info=None):
        # Add necessary server headers
        server_headers = [
            (&#39;Date&#39;, &#39;Tue, 31 Mar 2015 12:54:48 GMT&#39;),
            (&#39;Server&#39;, &#39;WSGIServer 0.2&#39;),
        ]
        self.headers_set = [status, response_headers + server_headers]        # To adhere to WSGI specification the start_response must return
        # a &#39;write&#39; callable. We simplicity&#39;s sake we&#39;ll ignore that detail
        # for now.
        # return self.finish_response

    def finish_response(self, result):
        try:
            status, response_headers = self.headers_set
            response = &#39;HTTP/1.1 {status}\r\n&#39;.format(status=status)            for header in response_headers:
                response += &#39;{0}: {1}\r\n&#39;.format(*header)
            response += &#39;\r\n&#39;
            for data in result:
                response += data            # Print formatted response data a la &#39;curl -v&#39;
            print(&#39;&#39;.join(                &#39;> {line}\n'.format(line=line)                for line in response.splitlines()
            ))
            self.client_connection.sendall(response)        finally:
            self.client_connection.close()


SERVER_ADDRESS = (HOST, PORT) = 'localhost', 8080def make_server(server_address, application):
    server = WSGIServer(server_address)
    server.set_app(application)    return serverif __name__ == '__main__':
    httpd = make_server(SERVER_ADDRESS, application)
    print('WSGIServer: Serving HTTP on port {port} ...\n'.format(port=PORT))
    httpd.serve_forever()复制代码
Copier après la connexion

Bien sûr, si vous écrivez simplement un serveur pour un environnement de développement, vous n'avez pas à vous donner autant de mal pour inventer le vôtre wheel, car il existe un module intégré dans python Fournit la fonctionnalité du serveur wsgi.

from wsgiref.simple_server import make_server
srv = make_server('localhost', 8080, application)
srv.serve_forever()复制代码
Copier après la connexion

Il suffit de 3 lignes de code pour fournir un serveur wsgi, n'est-ce pas super pratique ? Enfin, visitons et testons l'effet du navigateur qui lance une requête

Ci-dessus est une introduction à wsgi Si vous avez une compréhension approfondie de wsgi, vous pouvez vous familiariser avec PEP333

Recommandations d'apprentissage gratuites associées : Tutoriel vidéo Python<.>

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:juejin.im
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal