wsgiref — WSGI-Hilfsprogramme und Referenzimplementierung¶
Quellcode: Lib/wsgiref
Das Web Server Gateway Interface (WSGI) ist eine standardisierte Schnittstelle zwischen Webserver-Software und in Python geschriebenen Webanwendungen. Eine standardisierte Schnittstelle erleichtert die Verwendung einer Anwendung, die WSGI unterstützt, mit einer Reihe verschiedener Webserver.
Nur Entwickler von Webservern und Programmierframeworks müssen jedes Detail und jeden Eckfall des WSGI-Designs kennen. Sie müssen nicht jedes Detail von WSGI verstehen, nur um eine WSGI-Anwendung zu installieren oder eine Webanwendung mit einem vorhandenen Framework zu schreiben.
wsgiref ist eine Referenzimplementierung der WSGI-Spezifikation, die verwendet werden kann, um einem Webserver oder Framework WSGI-Unterstützung hinzuzufügen. Es bietet Hilfsprogramme zur Manipulation von WSGI-Umgebungsvariablen und Antwortheadern, Basisklassen zur Implementierung von WSGI-Servern, einen Demo-HTTP-Server, der WSGI-Anwendungen bedient, Typen für die statische Typprüfung und ein Validierungstool, das WSGI-Server und -Anwendungen auf Konformität mit der WSGI-Spezifikation prüft (PEP 3333).
Siehe wsgi.readthedocs.io für weitere Informationen zu WSGI und Links zu Tutorials und anderen Ressourcen.
wsgiref.util – WSGI-Umgebungshilfsprogramme¶
Dieses Modul bietet eine Vielzahl von Hilfsfunktionen für die Arbeit mit WSGI-Umgebungen. Eine WSGI-Umgebung ist ein Dictionary, das HTTP-Anfragevariablen enthält, wie in PEP 3333 beschrieben. Alle Funktionen, die einen Parameter environ erwarten, gehen davon aus, dass ein WSGI-konformes Dictionary übergeben wird; siehe bitte PEP 3333 für eine detaillierte Spezifikation und WSGIEnvironment für einen Typalias, der in Typannotationen verwendet werden kann.
- wsgiref.util.guess_scheme(environ)¶
Gibt eine Vermutung zurück, ob
wsgi.url_scheme„http“ oder „https“ sein sollte, indem eine UmgebungsvariableHTTPSim environ-Dictionary überprüft wird. Der Rückgabewert ist ein String.Diese Funktion ist nützlich beim Erstellen eines Gateways, das CGI oder ein CGI-ähnliches Protokoll wie FastCGI umschließt. Typischerweise enthalten Server, die solche Protokolle bereitstellen, eine Variable
HTTPSmit dem Wert „1“, „yes“ oder „on“, wenn eine Anfrage über SSL empfangen wird. Daher gibt diese Funktion „https“ zurück, wenn ein solcher Wert gefunden wird, und andernfalls „http“.
- wsgiref.util.request_uri(environ, include_query=True)¶
Gibt die vollständige Anfrage-URI zurück, optional einschließlich der Abfragezeichenfolge, gemäß dem Algorithmus im Abschnitt „URL Reconstruction“ von PEP 3333. Wenn include_query falsch ist, wird die Abfragezeichenfolge nicht in die resultierende URI aufgenommen.
- wsgiref.util.application_uri(environ)¶
Ähnlich wie
request_uri(), außer dass die VariablenPATH_INFOundQUERY_STRINGignoriert werden. Das Ergebnis ist die Basis-URI des durch die Anfrage angesprochenen Anwendungsobjekts.
- wsgiref.util.shift_path_info(environ)¶
Verschiebt einen einzelnen Namen von
PATH_INFOnachSCRIPT_NAMEund gibt den Namen zurück. Das environ-Dictionary wird *in-place* modifiziert; verwenden Sie eine Kopie, wenn SiePATH_INFOoderSCRIPT_NAMEim Originalzustand beibehalten möchten.Wenn keine Pfadsegmente mehr in
PATH_INFOvorhanden sind, wirdNonezurückgegeben.Typischerweise wird diese Routine verwendet, um jeden Teil eines Anfrage-URI-Pfads zu verarbeiten, z. B. um den Pfad als eine Reihe von Dictionary-Schlüsseln zu behandeln. Diese Routine modifiziert die übergebene Umgebung, um sie für die Aufrufung einer anderen WSGI-Anwendung, die sich unter der Ziel-URI befindet, geeignet zu machen. Zum Beispiel, wenn eine WSGI-Anwendung unter
/fooexistiert und der Anfrage-URI-Pfad/foo/bar/bazlautet, und die WSGI-Anwendung unter/fooshift_path_info()aufruft, erhält sie den String „bar“, und die Umgebung wird so aktualisiert, dass sie für die Übergabe an eine WSGI-Anwendung unter/foo/bargeeignet ist. Das heißt,SCRIPT_NAMEändert sich von/foozu/foo/bar, undPATH_INFOändert sich von/bar/bazzu/baz.Wenn
PATH_INFOnur ein „/“ ist, gibt diese Routine einen leeren String zurück und hängt einen nachgestellten Schrägstrich anSCRIPT_NAMEan, obwohl leere Pfadsegmente normalerweise ignoriert werden undSCRIPT_NAMEnormalerweise nicht mit einem Schrägstrich endet. Dies ist ein beabsichtigtes Verhalten, um sicherzustellen, dass eine Anwendung den Unterschied zwischen URIs, die auf/xenden, und solchen, die auf/x/enden, erkennen kann, wenn diese Routine für die Objekt traversal verwendet wird.
- wsgiref.util.setup_testing_defaults(environ)¶
Aktualisiert environ mit trivialen Standardwerten für Testzwecke.
Diese Routine fügt verschiedene Parameter hinzu, die für WSGI erforderlich sind, darunter
HTTP_HOST,SERVER_NAME,SERVER_PORT,REQUEST_METHOD,SCRIPT_NAME,PATH_INFOund alle von PEP 3333 definiertenwsgi.*-Variablen. Sie liefert nur Standardwerte und ersetzt keine vorhandenen Einstellungen für diese Variablen.Diese Routine soll es für Unit-Tests von WSGI-Servern und -Anwendungen einfacher machen, Dummy-Umgebungen einzurichten. Sie sollte NICHT von tatsächlichen WSGI-Servern oder -Anwendungen verwendet werden, da die Daten gefälscht sind!
Beispielverwendung (siehe auch
demo_app()für ein weiteres Beispiel)from wsgiref.util import setup_testing_defaults from wsgiref.simple_server import make_server # A relatively simple WSGI application. It's going to print out the # environment dictionary after being updated by setup_testing_defaults def simple_app(environ, start_response): setup_testing_defaults(environ) status = '200 OK' headers = [('Content-type', 'text/plain; charset=utf-8')] start_response(status, headers) ret = [("%s: %s\n" % (key, value)).encode("utf-8") for key, value in environ.items()] return ret with make_server('', 8000, simple_app) as httpd: print("Serving on port 8000...") httpd.serve_forever()
Zusätzlich zu den oben genannten Umgebungsfunktionen bietet das Modul wsgiref.util diese weiteren Hilfsmittel
- wsgiref.util.is_hop_by_hop(header_name)¶
Gibt
Truezurück, wenn ‚header_name‘ ein HTTP/1.1 „Hop-by-Hop“-Header ist, wie in RFC 2616 definiert.
- class wsgiref.util.FileWrapper(filelike, blksize=8192)¶
Eine konkrete Implementierung des Protokolls
wsgiref.types.FileWrapperzur Konvertierung eines dateiähnlichen Objekts in einen Iterator. Die resultierenden Objekte sind iterierbar. Während des Iterierens wird der optionale Parameter blksize wiederholt an dieread()-Methode des filelike-Objekts übergeben, um Byte-Strings zu erhalten, die zurückgegeben werden. Wennread()einen leeren Byte-String zurückgibt, wird die Iteration beendet und ist nicht fortsetzbar.Wenn filelike eine
close()-Methode hat, hat das zurückgegebene Objekt ebenfalls eineclose()-Methode, und es ruft dieclose()-Methode des filelike-Objekts auf, wenn es aufgerufen wird.Beispielverwendung
from io import StringIO from wsgiref.util import FileWrapper # We're using a StringIO-buffer for as the file-like object filelike = StringIO("This is an example file-like object"*10) wrapper = FileWrapper(filelike, blksize=5) for chunk in wrapper: print(chunk)
Geändert in Version 3.11: Die Unterstützung für die Methode
__getitem__()wurde entfernt.
wsgiref.headers – WSGI-Antwortheader-Werkzeuge¶
Dieses Modul bietet eine einzelne Klasse, Headers, zur bequemen Manipulation von WSGI-Antwortheadern mit einer Mapping-ähnlichen Schnittstelle.
- class wsgiref.headers.Headers([headers])¶
Erstellt ein Mapping-ähnliches Objekt, das headers umschließt, welches eine Liste von Header-Namen/Wert-Tupeln sein muss, wie in PEP 3333 beschrieben. Der Standardwert für headers ist eine leere Liste.
Headers-Objekte unterstützen typische Mapping-Operationen einschließlich__getitem__(),get(),__setitem__(),setdefault(),__delitem__()und__contains__(). Für jede dieser Methoden ist der Schlüssel der Header-Name (case-insensitiv behandelt) und der Wert ist der erste Wert, der diesem Header-Namen zugeordnet ist. Das Setzen eines Headers löscht alle vorhandenen Werte für diesen Header und fügt dann einen neuen Wert am Ende der umschlossenen Header-Liste hinzu. Die bestehende Reihenfolge von Headern wird im Allgemeinen beibehalten, wobei neue Header am Ende der umschlossenen Liste hinzugefügt werden.Im Gegensatz zu einem Dictionary lösen
Headers-Objekte keinen Fehler aus, wenn Sie versuchen, einen Schlüssel abzurufen oder zu löschen, der nicht in der umschlossenen Header-Liste vorhanden ist. Das Abrufen eines nicht vorhandenen Headers gibt einfachNonezurück, und das Löschen eines nicht vorhandenen Headers tut nichts.Headers-Objekte unterstützen auch die Methodenkeys(),values()unditems(). Die vonkeys()unditems()zurückgegebenen Listen können denselben Schlüssel mehrmals enthalten, wenn ein mehrwertiger Header vorhanden ist. Die Länge einesHeaders-Objekts ist gleich der Länge seineritems(), was wiederum gleich der Länge der umschlossenen Header-Liste ist. Tatsächlich gibt die Methodeitems()einfach eine Kopie der umschlossenen Header-Liste zurück.Das Aufrufen von
bytes()auf einemHeaders-Objekt gibt einen formatierten Byte-String zurück, der für die Übertragung als HTTP-Antwortheader geeignet ist. Jeder Header wird mit seinem Wert in einer Zeile platziert, getrennt durch einen Doppelpunkt und ein Leerzeichen. Jede Zeile wird mit einem Wagenrücklauf und Zeilenvorschub abgeschlossen, und der Byte-String wird mit einer leeren Zeile beendet.Zusätzlich zu ihrer Mapping-Oberfläche und Formatierungsfunktionen verfügen
Headers-Objekte über die folgenden Methoden zum Abfragen und Hinzufügen von mehrwertigen Headern sowie zum Hinzufügen von Headern mit MIME-Parametern- get_all(name)¶
Gibt eine Liste aller Werte für den benannten Header zurück.
Die zurückgegebene Liste wird in der Reihenfolge sortiert, in der sie im ursprünglichen Header-Liste erschienen oder dieser Instanz hinzugefügt wurden, und kann Duplikate enthalten. Gelöschte und neu eingefügte Felder werden immer am Ende der Header-Liste angehängt. Wenn keine Felder mit dem angegebenen Namen existieren, wird eine leere Liste zurückgegeben.
- add_header(name, value, **_params)¶
Fügt einen (möglicherweise mehrwertigen) Header mit optionalen MIME-Parametern hinzu, die über Schlüsselwortargumente angegeben werden.
name ist das hinzuzufügende Header-Feld. Schlüsselwortargumente können verwendet werden, um MIME-Parameter für das Header-Feld festzulegen. Jeder Parameter muss ein String oder
Nonesein. Unterstriche in Parameternamen werden in Bindestriche umgewandelt, da Bindestriche in Python-Bezeichnern ungültig sind, aber viele MIME-Parameternamen Bindestriche enthalten. Wenn der Parameterwert ein String ist, wird er den Headerwertparametern in der Formname="value"hinzugefügt. Wenn erNoneist, wird nur der Parametername hinzugefügt. (Dies wird für MIME-Parameter ohne Wert verwendet.) Beispielverwendungh.add_header('content-disposition', 'attachment', filename='bud.gif')
Das Obige fügt einen Header hinzu, der wie folgt aussieht
Content-Disposition: attachment; filename="bud.gif"
Geändert in Version 3.5: Der Parameter headers ist optional.
wsgiref.simple_server – ein einfacher WSGI-HTTP-Server¶
Dieses Modul implementiert einen einfachen HTTP-Server (basierend auf http.server), der WSGI-Anwendungen bedient. Jede Serverinstanz bedient eine einzelne WSGI-Anwendung auf einem bestimmten Host und Port. Wenn Sie mehrere Anwendungen auf einem einzigen Host und Port bedienen möchten, sollten Sie eine WSGI-Anwendung erstellen, die PATH_INFO parst, um auszuwählen, welche Anwendung für jede Anfrage aufgerufen werden soll. (Z. B. unter Verwendung der Funktion shift_path_info() aus wsgiref.util.)
- wsgiref.simple_server.make_server(host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler)¶
Erstellt einen neuen WSGI-Server, der auf host und port lauscht und Verbindungen für app akzeptiert. Der Rückgabewert ist eine Instanz der übergebenen server_class und verarbeitet Anfragen mit der angegebenen handler_class. app muss ein WSGI-Anwendungsobjekt sein, wie in PEP 3333 definiert.
Beispielverwendung
from wsgiref.simple_server import make_server, demo_app with make_server('', 8000, demo_app) as httpd: print("Serving HTTP on port 8000...") # Respond to requests until process is killed httpd.serve_forever() # Alternative: serve one request, then exit httpd.handle_request()
- wsgiref.simple_server.demo_app(environ, start_response)¶
Diese Funktion ist eine kleine, aber vollständige WSGI-Anwendung, die eine Textseite mit der Nachricht „Hello world!“ und einer Liste der im environ-Parameter bereitgestellten Schlüssel/Wert-Paare zurückgibt. Sie ist nützlich, um zu überprüfen, ob ein WSGI-Server (wie
wsgiref.simple_server) eine einfache WSGI-Anwendung korrekt ausführen kann.Der aufrufbare start_response sollte dem Protokoll
StartResponsefolgen.
- class wsgiref.simple_server.WSGIServer(server_address, RequestHandlerClass)¶
Erstellt eine
WSGIServer-Instanz. server_address sollte ein(host,port)-Tupel sein, und RequestHandlerClass sollte die Unterklasse vonhttp.server.BaseHTTPRequestHandlersein, die zur Verarbeitung von Anfragen verwendet wird.Sie müssen diesen Konstruktor normalerweise nicht aufrufen, da die Funktion
make_server()alle Details für Sie erledigen kann.WSGIServerist eine Unterklasse vonhttp.server.HTTPServer, daher sind alle seine Methoden (wieserve_forever()undhandle_request()) verfügbar.WSGIServerbietet auch diese WSGI-spezifischen Methoden- set_app(application)¶
Legt die aufrufbare application als die WSGI-Anwendung fest, die Anfragen empfangen wird.
- get_app()¶
Gibt die aktuell festgelegte aufrufbare Anwendung zurück.
Normalerweise müssen Sie diese zusätzlichen Methoden jedoch nicht verwenden, da
set_app()normalerweise vonmake_server()aufgerufen wird, undget_app()hauptsächlich zum Nutzen von Anforderungshandler-Instanzen existiert.
- class wsgiref.simple_server.WSGIRequestHandler(request, client_address, server)¶
Erstellt einen HTTP-Handler für die gegebene request (d. h. einen Socket), client_address (ein
(host,port)-Tupel) und server (WSGIServer-Instanz).Sie müssen keine Instanzen dieser Klasse direkt erstellen; sie werden automatisch nach Bedarf von
WSGIServer-Objekten erstellt. Sie können diese Klasse jedoch unterklassifizieren und sie als handler_class an die Funktionmake_server()übergeben. Einige möglicherweise relevante Methoden für das Überschreiben in Unterklassen- get_environ()¶
Gibt ein
WSGIEnvironment-Dictionary für eine Anfrage zurück. Die Standardimplementierung kopiert den Inhalt des Dictionary-Attributsbase_environdesWSGIServer-Objekts und fügt dann verschiedene Header hinzu, die aus der HTTP-Anfrage abgeleitet werden. Jeder Aufruf dieser Methode sollte ein neues Dictionary zurückgeben, das alle relevanten CGI-Umgebungsvariablen gemäß PEP 3333 enthält.
- get_stderr()¶
Gibt das Objekt zurück, das als
wsgi.errors-Stream verwendet werden soll. Die Standardimplementierung gibt einfachsys.stderrzurück.
- handle()¶
Verarbeitet die HTTP-Anfrage. Die Standardimplementierung erstellt eine Handlerinstanz unter Verwendung einer Klasse aus
wsgiref.handlers, um die eigentliche WSGI-Schnittstelle zu implementieren.
wsgiref.validate — WSGI-Konformitätsprüfer¶
Beim Erstellen neuer WSGI-Anwendungsobjekte, Frameworks, Server oder Middleware kann es nützlich sein, die Konformität des neuen Codes mit wsgiref.validate zu validieren. Dieses Modul stellt eine Funktion bereit, die WSGI-Anwendungsobjekte erstellt, die die Kommunikation zwischen einem WSGI-Server oder Gateway und einem WSGI-Anwendungsobjekt validieren, um beide Seiten auf Protokollkonformität zu prüfen.
Beachten Sie, dass dieses Hilfsprogramm keine vollständige PEP 3333-Konformität garantiert; das Fehlen von Fehlern in diesem Modul bedeutet nicht zwangsläufig, dass keine Fehler vorhanden sind. Wenn dieses Modul jedoch einen Fehler ausgibt, ist es praktisch sicher, dass entweder der Server oder die Anwendung nicht zu 100 % konform ist.
Dieser Wrapper basiert auf dem Modul paste.lint aus Ian Bickings „Python Paste“-Bibliothek.
- wsgiref.validate.validator(application)¶
Umschließt application und gibt ein neues WSGI-Anwendungsobjekt zurück. Die zurückgegebene Anwendung leitet alle Anfragen an die ursprüngliche application weiter und prüft, ob sowohl die application als auch der sie aufrufende Server dem WSGI-Spezifikation und RFC 2616 entsprechen.
Jede erkannte Nichtkonformität führt zum Auslösen einer
AssertionError; beachten Sie jedoch, dass die Handhabung dieser Fehler serverspezifisch ist. Zum Beispiel gebenwsgiref.simple_serverund andere aufwsgiref.handlersbasierende Server (die die Fehlerbehandlungsroutinen nicht überschreiben, um etwas anderes zu tun) einfach eine Meldung aus, dass ein Fehler aufgetreten ist, und geben den Traceback nachsys.stderroder einen anderen Fehlerstrom aus.Dieser Wrapper kann auch Ausgaben über das Modul
warningsgenerieren, um fragwürdige Verhaltensweisen anzuzeigen, die jedoch möglicherweise nicht tatsächlich durch PEP 3333 verboten sind. Sofern sie nicht über Python-Befehlszeilenoptionen oder die API vonwarningsunterdrückt werden, werden solche Warnungen nachsys.stderrgeschrieben ( *nicht* nachwsgi.errors, es sei denn, sie sind zufällig dasselbe Objekt).Beispielverwendung
from wsgiref.validate import validator from wsgiref.simple_server import make_server # Our callable object which is intentionally not compliant to the # standard, so the validator is going to break def simple_app(environ, start_response): status = '200 OK' # HTTP Status headers = [('Content-type', 'text/plain')] # HTTP Headers start_response(status, headers) # This is going to break because we need to return a list, and # the validator is going to inform us return b"Hello World" # This is the application wrapped in a validator validator_app = validator(simple_app) with make_server('', 8000, validator_app) as httpd: print("Listening on port 8000....") httpd.serve_forever()
wsgiref.handlers – Server/Gateway-Basisklassen¶
Dieses Modul bietet Basis-Handlerklassen für die Implementierung von WSGI-Servern und -Gateways. Diese Basisklassen kümmern sich um den Großteil der Arbeit bei der Kommunikation mit einer WSGI-Anwendung, solange sie eine CGI-ähnliche Umgebung sowie Ein-, Ausgabe- und Fehlerströme erhalten.
- class wsgiref.handlers.CGIHandler¶
CGI-basierte Invokation über
sys.stdin,sys.stdout,sys.stderrundos.environ. Dies ist nützlich, wenn Sie eine WSGI-Anwendung haben und diese als CGI-Skript ausführen möchten. Rufen Sie einfachCGIHandler().run(app)auf, wobeiappdas WSGI-Anwendungsobjekt ist, das Sie aufrufen möchten.Diese Klasse ist eine Unterklasse von
BaseCGIHandler, diewsgi.run_onceauf true,wsgi.multithreadauf false undwsgi.multiprocessauf true setzt und immersysundosverwendet, um die notwendigen CGI-Streams und die Umgebung zu erhalten.
- class wsgiref.handlers.IISCGIHandler¶
Eine spezialisierte Alternative zu
CGIHandler, zur Verwendung bei der Bereitstellung auf dem IIS-Webserver von Microsoft, ohne die Konfigurationsoption allowPathInfo (IIS>=7) oder Metabase allowPathInfoForScriptMappings (IIS<7) gesetzt zu haben.Standardmäßig gibt IIS ein
PATH_INFOzurück, das demSCRIPT_NAMEvorne vorangestellt ist, was zu Problemen für WSGI-Anwendungen führt, die Routing implementieren möchten. Dieser Handler entfernt einen solchen duplizierten Pfad.IIS kann so konfiguriert werden, dass das korrekte
PATH_INFOübergeben wird, dies führt jedoch zu einem weiteren Fehler, bei demPATH_TRANSLATEDfalsch ist. Glücklicherweise wird diese Variable selten verwendet und ist nicht durch WSGI garantiert. Unter IIS<7 kann die Einstellung jedoch nur auf Vhost-Ebene vorgenommen werden, was sich auf alle anderen Skriptzuordnungen auswirkt, von denen viele fehlschlagen, wenn sie demPATH_TRANSLATED-Fehler ausgesetzt sind. Aus diesem Grund wird IIS<7 fast nie mit der Korrektur bereitgestellt (selbst IIS7 verwendet sie selten, da es immer noch keine Benutzeroberfläche dafür gibt).Es gibt keine Möglichkeit für CGI-Code, festzustellen, ob die Option gesetzt wurde, daher wird eine separate Handlerklasse bereitgestellt. Sie wird auf die gleiche Weise wie
CGIHandlerverwendet, d.h. durch Aufrufen vonIISCGIHandler().run(app), wobeiappdas WSGI-Anwendungsobjekt ist, das Sie aufrufen möchten.Hinzugefügt in Version 3.2.
- class wsgiref.handlers.BaseCGIHandler(stdin, stdout, stderr, environ, multithread=True, multiprocess=False)¶
Ähnlich wie
CGIHandler, verwendet aber anstelle der Modulesysundosdie explizit angegebenen CGI-Umgebungs- und I/O-Streams. Die Werte für multithread und multiprocess werden verwendet, um die Flagswsgi.multithreadundwsgi.multiprocessfür alle von der Handlerinstanz ausgeführten Anwendungen zu setzen.Diese Klasse ist eine Unterklasse von
SimpleHandlerund ist für die Verwendung mit Software vorgesehen, die keine HTTP-„Origin-Server“ sind. Wenn Sie eine Gateway-Protokollimplementierung (wie CGI, FastCGI, SCGI usw.) schreiben, die einenStatus:-Header zum Senden eines HTTP-Status verwendet, sollten Sie wahrscheinlich diese anstelle vonSimpleHandleruntererben.
- class wsgiref.handlers.SimpleHandler(stdin, stdout, stderr, environ, multithread=True, multiprocess=False)¶
Ähnlich wie
BaseCGIHandler, aber für die Verwendung mit HTTP-Origin-Servern konzipiert. Wenn Sie eine HTTP-Serverimplementierung schreiben, möchten Sie wahrscheinlich diese anstelle vonBaseCGIHandleruntererben.Diese Klasse ist eine Unterklasse von
BaseHandler. Sie überschreibt die Methoden__init__(),get_stdin(),get_stderr(),add_cgi_vars(),_write()und_flush(), um das explizite Setzen der Umgebung und der Streams über den Konstruktor zu unterstützen. Die übergebenen Umgebungs- und Streamvariablen werden in den Attributenstdin,stdout,stderrundenvirongespeichert.Die
write()-Methode von stdout sollte jeden Block vollständig schreiben, wieio.BufferedIOBase.
- class wsgiref.handlers.BaseHandler¶
Dies ist eine abstrakte Basisklasse zum Ausführen von WSGI-Anwendungen. Jede Instanz behandelt eine einzelne HTTP-Anfrage, obwohl Sie prinzipiell eine Unterklasse erstellen könnten, die für mehrere Anfragen wiederverwendbar ist.
BaseHandler-Instanzen haben nur eine Methode, die für die externe Verwendung bestimmt ist- run(app)¶
Führen Sie die angegebene WSGI-Anwendung, app, aus.
Alle anderen Methoden von
BaseHandlerwerden von dieser Methode im Prozess der Ausführung der Anwendung aufgerufen und existieren daher hauptsächlich, um die Anpassung des Prozesses zu ermöglichen.Die folgenden Methoden MÜSSEN in einer Unterklasse überschrieben werden
- _write(data)¶
Puffern Sie die Bytes data zur Übertragung an den Client. Es ist in Ordnung, wenn diese Methode die Daten tatsächlich überträgt;
BaseHandlertrennt Schreib- und Flush-Operationen nur zur größeren Effizienz, wenn das zugrunde liegende System tatsächlich eine solche Unterscheidung hat.
- _flush()¶
Erzwingen Sie die Übertragung gepufferter Daten an den Client. Es ist in Ordnung, wenn diese Methode eine No-Op ist (d.h. wenn
_write()die Daten tatsächlich sendet).
- get_stdin()¶
Gibt ein Objekt zurück, das mit
InputStreamkompatibel ist und alswsgi.inputder gerade verarbeiteten Anfrage verwendet werden kann.
- get_stderr()¶
Gibt ein Objekt zurück, das mit
ErrorStreamkompatibel ist und alswsgi.errorsder gerade verarbeiteten Anfrage verwendet werden kann.
- add_cgi_vars()¶
Fügt CGI-Variablen für die aktuelle Anfrage in das Attribut
environein.
Hier sind einige andere Methoden und Attribute, die Sie möglicherweise überschreiben möchten. Diese Liste ist jedoch nur eine Zusammenfassung und enthält nicht jede überschreibbare Methode. Sie sollten die Docstrings und den Quellcode für zusätzliche Informationen konsultieren, bevor Sie versuchen, eine angepasste
BaseHandler-Unterklasse zu erstellen.Attribute und Methoden zur Anpassung der WSGI-Umgebung
- wsgi_multithread¶
Der Wert, der für die Umgebungsvariable
wsgi.multithreadverwendet werden soll. Er ist standardmäßig true inBaseHandler, kann aber in den anderen Unterklassen eine andere Standardeinstellung haben (oder vom Konstruktor gesetzt werden).
- wsgi_multiprocess¶
Der Wert, der für die Umgebungsvariable
wsgi.multiprocessverwendet werden soll. Er ist standardmäßig true inBaseHandler, kann aber in den anderen Unterklassen eine andere Standardeinstellung haben (oder vom Konstruktor gesetzt werden).
- wsgi_run_once¶
Der Wert, der für die Umgebungsvariable
wsgi.run_onceverwendet werden soll. Er ist standardmäßig false inBaseHandler, aberCGIHandlersetzt ihn standardmäßig auf true.
- os_environ¶
Die Standard-Umgebungsvariablen, die in die WSGI-Umgebung jeder Anfrage aufgenommen werden sollen. Standardmäßig ist dies eine Kopie von
os.environzu dem Zeitpunkt, alswsgiref.handlersimportiert wurde, aber Unterklassen können ihre eigenen auf Klassen- oder Instanzebene erstellen. Beachten Sie, dass das Dictionary als schreibgeschützt betrachtet werden sollte, da der Standardwert zwischen mehreren Klassen und Instanzen geteilt wird.
- server_software¶
Wenn das Attribut
origin_servergesetzt ist, wird der Wert dieses Attributs verwendet, um die Standard-UmgebungsvariableSERVER_SOFTWAREund auch einen Standard-Server:-Header in HTTP-Antworten zu setzen. Er wird für Handler (wieBaseCGIHandlerundCGIHandler) ignoriert, die keine HTTP-Origin-Server sind.Geändert in Version 3.3: Der Begriff „Python“ wird durch implementierungsspezifische Begriffe wie „CPython“, „Jython“ usw. ersetzt.
- get_scheme()¶
Gibt das für die aktuelle Anfrage verwendete URL-Schema zurück. Die Standardimplementierung verwendet die Funktion
guess_scheme()auswsgiref.util, um zu erraten, ob das Schema „http“ oder „https“ sein sollte, basierend auf den Umgebungsvariablen der aktuellen Anfrage.
- setup_environ()¶
Setzt das Attribut
environauf eine vollständig aufgefüllte WSGI-Umgebung. Die Standardimplementierung verwendet alle oben genannten Methoden und Attribute, plus die Methodenget_stdin(),get_stderr()undadd_cgi_vars()sowie das Attributwsgi_file_wrapper. Außerdem fügt es einen SchlüsselSERVER_SOFTWAREein, falls dieser nicht vorhanden ist, solange das Attributorigin_servereinen wahren Wert hat und das Attributserver_softwaregesetzt ist.
Methoden und Attribute zur Anpassung der Ausnahmebehandlung
- log_exception(exc_info)¶
Protokolliert das exc_info-Tupel im Serverprotokoll. exc_info ist ein Tupel
(type, value, traceback). Die Standardimplementierung schreibt den Traceback einfach in denwsgi.errors-Stream der Anfrage und leert ihn. Unterklassen können diese Methode überschreiben, um das Format zu ändern, die Ausgabe umzuleiten, den Traceback per E-Mail an einen Administrator zu senden oder andere geeignete Maßnahmen zu ergreifen.
- traceback_limit¶
Die maximale Anzahl von Frames, die in Tracebacks enthalten sein sollen, die von der Standardmethode
log_exception()ausgegeben werden. WennNone, werden alle Frames eingeschlossen.
- error_output(environ, start_response)¶
Diese Methode ist eine WSGI-Anwendung, um eine Fehlerseite für den Benutzer zu generieren. Sie wird nur aufgerufen, wenn ein Fehler auftritt, bevor Header an den Client gesendet werden.
Diese Methode kann über
sys.exception()auf den aktuellen Fehler zugreifen und sollte diese Informationen an start_response übergeben, wenn diese aufgerufen wird (wie im Abschnitt „Fehlerbehandlung“ von PEP 3333 beschrieben). Insbesondere sollte der start_response-Callable demStartResponse-Protokoll folgen.Die Standardimplementierung verwendet einfach die Attribute
error_status,error_headersunderror_body, um eine Ausgabeseite zu generieren. Unterklassen können dies überschreiben, um dynamischere Fehlerausgaben zu erzeugen.Beachten Sie jedoch, dass es aus Sicherheitssicht nicht empfohlen wird, Diagnosen an beliebige Benutzer weiterzugeben. Idealerweise müssten Sie etwas Besonderes tun, um die Diagnoseausgabe zu aktivieren, weshalb die Standardimplementierung keine enthält.
- error_status¶
Der HTTP-Status, der für Fehlerantworten verwendet wird. Dies sollte ein Statusstring sein, wie in PEP 3333 definiert; er ist standardmäßig ein 500er-Code und eine Nachricht.
- error_headers¶
Die HTTP-Header, die für Fehlerantworten verwendet werden. Dies sollte eine Liste von WSGI-Antwortheadern sein (
(name, value)-Tupel), wie in PEP 3333 beschrieben. Die Standardliste setzt den Content-Type nur auftext/plain.
- error_body¶
Der Fehlerantwortkörper. Dies sollte ein Bytestring einer HTTP-Antwort sein. Standardmäßig ist dies der Klartext: „A server error occurred. Please contact the administrator.“
Methoden und Attribute für die Funktion „Optional Platform-Specific File Handling“ von PEP 3333
- wsgi_file_wrapper¶
Ein
wsgi.file_wrapper-Factory, kompatibel mitwsgiref.types.FileWrapper, oderNone. Der Standardwert dieses Attributs ist die Klassewsgiref.util.FileWrapper.
- sendfile()¶
Überschreiben Sie dies, um plattformspezifische Dateiübertragung zu implementieren. Diese Methode wird nur aufgerufen, wenn der Rückgabewert der Anwendung eine Instanz der durch das Attribut
wsgi_file_wrapperangegebenen Klasse ist. Sie sollte einen wahren Wert zurückgeben, wenn die Datei erfolgreich übertragen wurde, sodass der Standard-Übertragungscode nicht ausgeführt wird. Die Standardimplementierung dieser Methode gibt einfach einen falschen Wert zurück.
Verschiedene Methoden und Attribute
- origin_server¶
Dieses Attribut sollte auf einen wahren Wert gesetzt werden, wenn die Methoden
_write()und_flush()des Handlers direkt mit dem Client kommunizieren, anstatt über ein CGI-ähnliches Gateway-Protokoll, das den HTTP-Status in einem speziellen HeaderStatus:erwartet.Der Standardwert dieses Attributs ist true in
BaseHandler, aber false inBaseCGIHandlerundCGIHandler.
- http_version¶
Wenn
origin_servertrue ist, wird dieses String-Attribut verwendet, um die HTTP-Version der an den Client gesendeten Antwort festzulegen. Es ist standardmäßig"1.0".
- wsgiref.handlers.read_environ()¶
Wandelt CGI-Variablen aus
os.environin PEP 3333 „bytes in unicode“-Strings um und gibt ein neues Dictionary zurück. Diese Funktion wird vonCGIHandlerundIISCGIHandleranstelle der direkten Verwendung vonos.environverwendet, was nicht unbedingt WSGI-konform auf allen Plattformen und Webservern mit Python 3 ist – insbesondere auf denen, bei denen die tatsächliche Umgebung des Betriebssystems Unicode ist (z. B. Windows) oder bei denen die Umgebung Bytes sind, aber die vom System verwendete Kodierung von Python zum Dekodieren etwas anderes als ISO-8859-1 ist (z. B. Unix-Systeme mit UTF-8).Wenn Sie selbst einen CGI-basierten Handler implementieren, möchten Sie diese Routine wahrscheinlich anstelle des direkten Kopierens von Werten aus
os.environverwenden.Hinzugefügt in Version 3.2.
wsgiref.types – WSGI-Typen für statische Typüberprüfung¶
Dieses Modul stellt verschiedene Typen für die statische Typüberprüfung bereit, wie in PEP 3333 beschrieben.
Hinzugefügt in Version 3.11.
- class wsgiref.types.StartResponse¶
Ein
typing.Protocol, das start_response()-Aufrufe (PEP 3333) beschreibt.
- wsgiref.types.WSGIEnvironment¶
Ein Typalias, der ein WSGI-Umgebungsdictionary beschreibt.
- wsgiref.types.WSGIApplication¶
Ein Typalias, der einen WSGI-Anwendungs-Callable beschreibt.
- class wsgiref.types.InputStream¶
Ein
typing.Protocol, der einen WSGI Input Stream beschreibt.
- class wsgiref.types.ErrorStream¶
Ein
typing.Protocol, der einen WSGI Error Stream beschreibt.
- class wsgiref.types.FileWrapper¶
Ein
typing.Protocol, der einen File Wrapper beschreibt. Siehewsgiref.util.FileWrapperfür eine konkrete Implementierung dieses Protokolls.
Beispiele¶
Dies ist eine funktionierende „Hello World“-WSGI-Anwendung, bei der der start_response-Callable dem StartResponse-Protokoll folgen sollte
"""
Every WSGI application must have an application object - a callable
object that accepts two arguments. For that purpose, we're going to
use a function (note that you're not limited to a function, you can
use a class for example). The first argument passed to the function
is a dictionary containing CGI-style environment variables and the
second variable is the callable object.
"""
from wsgiref.simple_server import make_server
def hello_world_app(environ, start_response):
status = "200 OK" # HTTP Status
headers = [("Content-type", "text/plain; charset=utf-8")] # HTTP Headers
start_response(status, headers)
# The returned object is going to be printed
return [b"Hello World"]
with make_server("", 8000, hello_world_app) as httpd:
print("Serving on port 8000...")
# Serve until process is killed
httpd.serve_forever()
Beispiel für eine WSGI-Anwendung, die das aktuelle Verzeichnis bedient, wobei optionale Verzeichnisse und Portnummern (Standard: 8000) auf der Kommandozeile akzeptiert werden
"""
Small wsgiref based web server. Takes a path to serve from and an
optional port number (defaults to 8000), then tries to serve files.
MIME types are guessed from the file names, 404 errors are raised
if the file is not found.
"""
import mimetypes
import os
import sys
from wsgiref import simple_server, util
def app(environ, respond):
# Get the file name and MIME type
fn = os.path.join(path, environ["PATH_INFO"][1:])
if "." not in fn.split(os.path.sep)[-1]:
fn = os.path.join(fn, "index.html")
mime_type = mimetypes.guess_file_type(fn)[0]
# Return 200 OK if file exists, otherwise 404 Not Found
if os.path.exists(fn):
respond("200 OK", [("Content-Type", mime_type)])
return util.FileWrapper(open(fn, "rb"))
else:
respond("404 Not Found", [("Content-Type", "text/plain")])
return [b"not found"]
if __name__ == "__main__":
# Get the path and port from command-line arguments
path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()
port = int(sys.argv[2]) if len(sys.argv) > 2 else 8000
# Make and start the server until control-c
httpd = simple_server.make_server("", port, app)
print(f"Serving {path} on port {port}, control-C to stop")
try:
httpd.serve_forever()
except KeyboardInterrupt:
print("Shutting down.")
httpd.server_close()