Die Kolumne „Python-Video-Tutorial“ stellt WSGI vor.
Ich schreibe seit mehreren Jahren Python-Web, aber ich weiß immer noch nicht, was WSGI ist und ob es viele Leute da draußen gibt. Das ist normal, denn als Entwickler müssen Sie selten verstehen, was wsgi ist, um eine Website zu erstellen.
Aber wenn Sie selbst ein Webframework schreiben möchten, müssen Sie wsgi verstehen. Zur Überprüfung: Wenn wir Python für die Webentwicklung verwenden, entwickeln wir normalerweise auf der Grundlage eines bestimmten Web-Frameworks wie Django oder Flask und anderen Frameworks. Nachdem die Geschäftsentwicklung abgeschlossen ist, muss sie auf einem Server bereitgestellt werden, um externen Zugriff zu ermöglichen. Wenn Sie zu diesem Zeitpunkt online suchen, werden Sie darauf hingewiesen, dass Sie für die Bereitstellung Gunicorn oder UWSGI verwenden müssen. Was sind Gunicorn und Uwsgi? Sie werden es verstehen, wenn Sie sich dieses Bild ansehen.Die Rolle, die uwsgi oder gunicorn hier spielt, ist ein Server auf Softwareebene wird verwendet, um Browser zu verarbeiten. Die gesendete HTTP-Anfrage und das Antwortergebnis werden an das Frontend zurückgegeben. Die Hauptaufgabe des Web-Frameworks besteht darin, Geschäftslogik zu verarbeiten und Ergebnisse an den Webserver zu generieren, und der Webserver gibt sie dann an den Browser zurück.
Die Kommunikation zwischen dem Webframework und dem Webserver muss einer Reihe von Spezifikationen folgen, und diese Spezifikation ist WSGI. Warum müssen wir ein solches Regelwerk erlassen? Standards sollen Standards vereinheitlichen und die Nutzung für alle erleichtern. Stellen Sie sich vor, dass unsere Mobiltelefon-Ladeschnittstellen jetzt Typ-C-Standards sind. Mobiltelefonhersteller produzieren Mobiltelefone gemäß dieser Spezifikation, und Ladegerätehersteller folgen Typ-C. Ladegeräte werden nach den Spezifikationen von c hergestellt und Mobiltelefone verschiedener Hersteller können mit Ladegeräten verschiedener Hersteller verwendet werden. Allerdings gibt es bei Apple eigene Vorschriften, die letztendlich dazu führen, dass das Android-Ladegerät Apple nicht aufladen kann. ![](p9-juejin.byteimg.com/tos-cn-i-k3…)Wie schreibt man also ein Anwendungsprogramm (Framework) und einen Server, der der WSGI-Spezifikation entspricht? Wie im Bild oben gezeigt, ist links der Webserver und rechts das Webframework bzw. die Webanwendung. ApplicationWSGI legt fest, dass die Anwendung ein aufrufbares Objekt sein muss (das aufrufbare Objekt kann eine Funktion, eine Klasse oder ein Instanzobjekt sein, dasimplementiert) und zwei Parameter akzeptieren muss. Der Rückgabewert des Objekts muss ein sein iterierbares Objekt.
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]复制代码
Anwendung ist eine Funktion, die ein aufrufbares Objekt sein muss und dann zwei Parameter empfängt: environ und start_response__call__
environ ist ein Wörterbuch. Es speichert alle Inhalte im Zusammenhang mit HTTP-Anforderungen, wie Header, Anforderungsparameter usw.
start_response ist eine vom WSGI-Server übergebene Funktion, mit der der Antwortheader und der Statuscode an den Server übergeben werden.
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()复制代码
from wsgiref.simple_server import make_server srv = make_server('localhost', 8080, application) srv.serve_forever()复制代码
Verwandte kostenlose Lernempfehlungen:
Python-Video-TutorialDas obige ist der detaillierte Inhalt vonSie müssen verstehen, was WSGI ist. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!