Die Kolumne
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 sich mit wsgi vertraut machen.
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 zum Verarbeiten von Browsern verwendet. 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 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.
![
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.
Application
__call__
Wir können das einfachste Beispiel einer Anwendung schreiben:
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]复制代码
Server
WSGI. Der Server empfängt jedes Mal eine HTTP-Anfrage, erstellt das Umgebungsobjekt, ruft dann das Anwendungsobjekt auf und gibt schließlich die HTTP-Antwort zurück zum Browser.
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()复制代码
Wenn Sie nur einen Server für die Entwicklungsumgebung schreiben, müssen Sie sich natürlich nicht die Mühe machen, das Rad selbst neu zu erfinden, da Python integriert ist Das Modul stellt die Funktion eines WSGI-Servers bereit.
from wsgiref.simple_server import make_server srv = make_server('localhost', 8080, application) srv.serve_forever()复制代码
Nur 3 Zeilen Code können einen WSGI-Server bereitstellen. Lassen Sie uns abschließend die Wirkung des Browsers testen, der eine Anfrage initiiert. Das Obige ist eine Einführung in WSGI Wenn Sie ein tieferes Verständnis von wsgi haben, können Sie sich mit PEP333 vertraut machen
Verwandte kostenlose Lernempfehlungen:Python-Video-Tutorial
Das obige ist der detaillierte Inhalt vonNachdem Sie dies gelesen haben, müssen Sie verstehen, was WSGI ist. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!