La colonne
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.
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]复制代码
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
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
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'.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'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('\r\n') # 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's formatted the way it is for demonstration purposes # to emphasize the required variables and their values # # Required WSGI variables env['wsgi.version'] = (1, 0) env['wsgi.url_scheme'] = 'http' env['wsgi.input'] = StringIO.StringIO(self.request_data) env['wsgi.errors'] = sys.stderr env['wsgi.multithread'] = False env['wsgi.multiprocess'] = False env['wsgi.run_once'] = False # Required CGI variables env['REQUEST_METHOD'] = self.request_method # GET env['PATH_INFO'] = self.path # /hello env['SERVER_NAME'] = self.server_name # localhost env['SERVER_PORT'] = str(self.server_port) # 8888 return env def start_response(self, status, response_headers, exc_info=None): # Add necessary server headers server_headers = [ ('Date', 'Tue, 31 Mar 2015 12:54:48 GMT'), ('Server', 'WSGIServer 0.2'), ] self.headers_set = [status, response_headers + server_headers] # To adhere to WSGI specification the start_response must return # a 'write' callable. We simplicity's sake we'll ignore that detail # for now. # return self.finish_response def finish_response(self, result): try: status, response_headers = self.headers_set response = 'HTTP/1.1 {status}\r\n'.format(status=status) for header in response_headers: response += '{0}: {1}\r\n'.format(*header) response += '\r\n' for data in result: response += data # Print formatted response data a la 'curl -v' print(''.join( '> {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()复制代码
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()复制代码
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!