wsgiref — WSGI-Hilfsmittel und Referenzimplementierung¶
Quellcode: Lib/wsgiref
Warnung
wsgiref ist eine Referenzimplementierung und für den Produktivbetrieb nicht empfehlenswert. Das Modul führt nur grundlegende Sicherheitsprüfungen durch.
Das Web Server Gateway Interface (WSGI) ist eine genormte Schnittstelle zwischen Webserver-Software und in Python geschriebenen Webanwendungen. Dank dieser Norm lässt sich eine Anwendung, die WSGI unterstützt, mit vielen verschiedenen Webservern betreiben.
Jede Feinheit und jeden Sonderfall des WSGI-Entwurfs müssen nur die kennen, die Webserver oder Programmierframeworks schreiben. Um eine WSGI-Anwendung zu installieren oder mit einem bestehenden Framework eine Webanwendung zu schreiben, musst du nicht jede Einzelheit von WSGI verstehen.
wsgiref ist eine Referenzimplementierung der WSGI-Spezifikation. Mit ihr lässt sich ein Webserver oder ein Framework um WSGI-Unterstützung erweitern. Sie bietet Hilfsmittel zum Bearbeiten von WSGI-Umgebungsvariablen und Antwort-Headern, Basisklassen für WSGI-Server, einen HTTP-Server zur Veranschaulichung, der WSGI-Anwendungen ausliefert, Typen für die statische Typprüfung sowie ein Prüfwerkzeug, das WSGI-Server und -Anwendungen auf Übereinstimmung mit der WSGI-Spezifikation (PEP 3333) prüft.
Mehr über WSGI sowie Verweise auf Tutorials und weitere Quellen stehen unter wsgi.readthedocs.io.
wsgiref.util – Hilfsmittel für die WSGI-Umgebung¶
Dieses Modul bietet verschiedene Hilfsfunktionen für die Arbeit mit WSGI-Umgebungen. Eine WSGI-Umgebung ist ein Dictionary mit den Variablen einer HTTP-Anfrage, wie in PEP 3333 beschrieben. Alle Funktionen mit einem Parameter environ erwarten ein WSGI-konformes Dictionary. Die genaue Spezifikation steht in PEP 3333, und WSGIEnvironment ist ein Typalias für Typannotationen.
- wsgiref.util.guess_scheme(environ)¶
Schätzt, ob
wsgi.url_scheme„http“ oder „https“ sein sollte, indem im Dictionary environ nach einer UmgebungsvariablenHTTPSgesucht wird. Zurückgegeben wird eine Zeichenkette.Diese Funktion ist nützlich, wenn man ein Gateway schreibt, das CGI oder ein CGI-ähnliches Protokoll wie FastCGI umhüllt. Server, die solche Protokolle anbieten, setzen bei einer Anfrage über SSL üblicherweise eine Variable
HTTPSmit dem Wert „1“, „yes“ oder „on“. Diese Funktion gibt daher „https“ zurück, wenn sie einen solchen Wert findet, sonst „http“.
- wsgiref.util.request_uri(environ, include_query=True)¶
Gibt die vollständige Anfrage-URI zurück, nach Wunsch samt Abfragezeichenkette, nach dem Verfahren aus dem Abschnitt „URL Reconstruction“ von PEP 3333. Ist include_query falsch, enthält die entstehende URI die Abfragezeichenkette nicht.
- wsgiref.util.application_uri(environ)¶
Ähnlich wie
request_uri(), nur bleiben die VariablenPATH_INFOundQUERY_STRINGaußer Betracht. Das Ergebnis ist die Basis-URI des Anwendungsobjekts, an das sich die Anfrage richtet.
- wsgiref.util.shift_path_info(environ)¶
Schiebt einen einzelnen Namen von
PATH_INFOnachSCRIPT_NAMEund gibt den Namen zurück. Das Dictionary environ wird dabei an seinem Ort geändert. Nimm eine Kopie, wenn das ursprünglichePATH_INFOoderSCRIPT_NAMEerhalten bleiben soll.Sind in
PATH_INFOkeine Pfadabschnitte mehr übrig, kommtNonezurück.Üblicherweise verarbeitet man mit dieser Routine jeden Teil des Pfades einer Anfrage-URI, etwa um den Pfad als Folge von Dictionary-Schlüsseln zu behandeln. Die Routine ändert die übergebene Umgebung so, dass sich damit eine weitere WSGI-Anwendung an der Ziel-URI aufrufen lässt. Liegt zum Beispiel eine WSGI-Anwendung unter
/foo, lautet der Pfad der Anfrage-URI/foo/bar/bazund ruft die Anwendung unter/fooshift_path_info()auf, erhält sie die Zeichenkette „bar“, und die Umgebung passt danach zur Übergabe an eine WSGI-Anwendung unter/foo/bar. Das heißt:SCRIPT_NAMEwechselt von/fooauf/foo/barundPATH_INFOvon/bar/bazauf/baz.Ist
PATH_INFOnur ein „/“, gibt die Routine eine leere Zeichenkette zurück und hängt anSCRIPT_NAMEeinen Schrägstrich an – obwohl leere Pfadabschnitte normalerweise übergangen werden undSCRIPT_NAMEnormalerweise nicht auf einen Schrägstrich endet. Das ist Absicht: So kann eine Anwendung, die mit dieser Routine durch Objekte wandert, URIs auf/xvon solchen auf/x/unterscheiden.
- wsgiref.util.setup_testing_defaults(environ)¶
Ergänzt environ um einfache Vorgabewerte für Testzwecke.
Diese Routine fügt verschiedene von WSGI benötigte Parameter hinzu, darunter
HTTP_HOST,SERVER_NAME,SERVER_PORT,REQUEST_METHOD,SCRIPT_NAME,PATH_INFOund alle in PEP 3333definiertenwsgi.*-Variablen. Sie setzt nur Vorgabewerte und ersetzt bestehende Werte dieser Variablen nicht.Diese Routine soll es Modultests von WSGI-Servern und -Anwendungen erleichtern, Scheinumgebungen einzurichten. Echte WSGI-Server und -Anwendungen sollten sie NICHT verwenden, denn die Daten sind erfunden!
Beispiel für die Verwendung. Ein weiteres Beispiel steht bei
demo_app():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()
Neben den obigen Funktionen zur Umgebung bietet das Modul wsgiref.util noch diese weiteren Hilfsmittel:
- wsgiref.util.is_hop_by_hop(header_name)¶
Gibt
Truezurück, wenn „header_name“ ein „Hop-by-Hop“-Header von HTTP/1.1 nach RFC 2616 ist.
- class wsgiref.util.FileWrapper(filelike, blksize=8192)¶
Eine konkrete Umsetzung des Protokolls
wsgiref.types.FileWrapper, mit der sich ein dateiähnliches Objekt in einen Iterator verwandeln lässt. Die entstehenden Objekte sind iterierbar. Beim Iterieren wird der optionale Parameter blksize wiederholt an die Methoderead()des Objekts filelike übergeben, um die Bytefolgen zu holen, die geliefert werden. Gibtread()eine leere Bytefolge zurück, endet das Iterieren und lässt sich nicht fortsetzen.Hat filelike eine Methode
close(), hat auch das zurückgegebene Objekt eine Methodeclose(), die beim Aufruf die Methodeclose()des Objekts filelike aufruft.Beispiel für die Verwendung:
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 – Werkzeuge für WSGI-Antwort-Header¶
Dieses Modul enthält eine einzige Klasse, Headers, mit der sich WSGI-Antwort-Header bequem über eine abbildungsähnliche Schnittstelle bearbeiten lassen.
- class wsgiref.headers.Headers([headers])¶
Erzeugt ein abbildungsähnliches Objekt um headers. Das muss eine Liste von Tupeln aus Headernamen und -wert sein, wie in PEP 3333 beschrieben. Vorgabewert von headers ist eine leere Liste.
Headers-Objekte unterstützen die üblichen Abbildungsoperationen, darunter__getitem__(),get(),__setitem__(),setdefault(),__delitem__()und__contains__(). Bei all diesen Methoden ist der Schlüssel der Headername, ohne Beachtung der Groß- und Kleinschreibung, und der Wert der erste zu diesem Headernamen gehörende Wert. Einen Header zu setzen löscht dessen bisherige Werte und fügt dann am Ende der umhüllten Headerliste einen neuen Wert hinzu. Die bestehende Reihenfolge der Header bleibt im Großen und Ganzen erhalten, neue Header kommen ans Ende der umhüllten Liste.Anders als ein Dictionary lösen
Headers-Objekte keinen Fehler aus, wenn du einen Schlüssel holen oder löschen willst, der nicht in der umhüllten Headerliste steht. Ein nicht vorhandener Header kommt einfach alsNonezurück, und ihn zu löschen tut nichts.Headers-Objekte unterstützen auch die Methodenkeys(),values()unditems(). Die vonkeys()unditems()zurückgegebenen Listen können denselben Schlüssel mehrfach enthalten, wenn ein Header mehrere Werte hat. Daslen()einesHeaders-Objekts entspricht der Länge seineritems()und damit der Länge der umhüllten Headerliste. Die Methodeitems()gibt nämlich einfach eine Kopie der umhüllten Headerliste zurück.bytes()auf einHeaders-Objekt angewandt gibt eine formatierte Bytefolge zurück, die sich als HTTP-Antwort-Header senden lässt. Jeder Header steht mit seinem Wert in einer Zeile, getrennt durch Doppelpunkt und Leerzeichen. Jede Zeile endet mit Wagenrücklauf und Zeilenvorschub, die Bytefolge endet mit einer Leerzeile.Neben der Abbildungsschnittstelle und der Formatierung haben
Headers-Objekte die folgenden Methoden, um Header mit mehreren Werten abzufragen und hinzuzufügen und um Header mit MIME-Parametern hinzuzufügen:- get_all(name)¶
Gibt eine Liste aller Werte des genannten Headers zurück.
Die zurückgegebene Liste ist in der Reihenfolge sortiert, in der die Werte in der ursprünglichen Headerliste standen oder dieser Instanz hinzugefügt wurden, und kann Doppelungen enthalten. Gelöschte und wieder eingefügte Felder kommen stets ans Ende der Headerliste. Gibt es keine Felder mit dem angegebenen Namen, kommt eine leere Liste zurück.
- add_header(name, value, **_params)¶
Fügt einen Header hinzu, der auch mehrere Werte haben kann, mit MIME-Parametern nach Bedarf über Schlüsselwortargumente.
name ist das hinzuzufügende Headerfeld. Über Schlüsselwortargumente lassen sich MIME-Parameter für das Headerfeld setzen. Jeder Parameter muss eine Zeichenkette oder
Nonesein. Unterstriche in Parameternamen werden zu Bindestrichen, denn Bindestriche sind in Python-Namen nicht erlaubt, viele MIME-Parameternamen enthalten aber welche. Ist der Wert des Parameters eine Zeichenkette, kommt er in der Formname="value"zu den Parametern des Headerwerts. Ist erNone, wird nur der Parametername hinzugefügt; das dient MIME-Parametern ohne Wert. Beispiel für die Verwendung:h.add_header('content-disposition', 'attachment', filename='bud.gif')
Das fügt einen Header hinzu, der so aussieht:
Content-Disposition: attachment; filename="bud.gif"
Geändert in Version 3.5: Der Parameter headers ist jetzt optional.
wsgiref.simple_server – ein einfacher WSGI-HTTP-Server¶
Dieses Modul enthält einen einfachen HTTP-Server auf der Grundlage von http.server, der WSGI-Anwendungen ausliefert. Jede Serverinstanz liefert eine einzelne WSGI-Anwendung auf einem bestimmten Host und Port aus. Willst du mehrere Anwendungen auf einem Host und Port anbieten, schreibe eine WSGI-Anwendung, die PATH_INFO auswertet und so für jede Anfrage die passende Anwendung aufruft, etwa mit der Funktion shift_path_info() aus wsgiref.util.
- wsgiref.simple_server.make_server(host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler)¶
Erzeugt einen neuen WSGI-Server, der auf host und port lauscht und Verbindungen für app annimmt. Zurückgegeben wird eine Instanz der angegebenen server_class, die Anfragen mit der angegebenen handler_class verarbeitet. app muss ein WSGI-Anwendungsobjekt nach PEP 3333 sein.
Beispiel für die Verwendung:
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. Sie gibt eine Textseite mit der Meldung „Hello world!“ und einer Liste der Schlüssel-Wert-Paare aus dem Parameter environ zurück. Damit lässt sich prüfen, ob ein WSGI-Server wie
wsgiref.simple_servereine einfache WSGI-Anwendung richtig ausführt.Das aufrufbare Objekt start_response sollte dem Protokoll
StartResponsefolgen.
- class wsgiref.simple_server.WSGIServer(server_address, RequestHandlerClass)¶
Erzeugt eine Instanz von
WSGIServer. server_address sollte ein Tupel(host,port)sein und RequestHandlerClass die Unterklasse vonhttp.server.BaseHTTPRequestHandler, mit der Anfragen verarbeitet werden.Diesen Konstruktor musst du normalerweise nicht aufrufen, denn die Funktion
make_server()erledigt alle Einzelheiten für dich.WSGIServerist eine Unterklasse vonhttp.server.HTTPServer, daher stehen alle deren Methoden zur Verfügung, etwaserve_forever()undhandle_request(). Zusätzlich bietetWSGIServerdiese WSGI-eigenen Methoden:- set_app(application)¶
Setzt das aufrufbare Objekt application als die WSGI-Anwendung, die die Anfragen erhält.
- get_app()¶
Gibt das gerade gesetzte aufrufbare Anwendungsobjekt zurück.
Normalerweise brauchst du diese zusätzlichen Methoden allerdings nicht:
set_app()ruft üblicherweisemake_server()auf, undget_app()gibt es vor allem für die Instanzen der Anfragebehandlung.
- class wsgiref.simple_server.WSGIRequestHandler(request, client_address, server)¶
Erzeugt einen HTTP-Handler für die gegebene request, also einen Socket, client_address, ein Tupel
(host,port), und server, eine Instanz vonWSGIServer.Instanzen dieser Klasse musst du nicht selbst erzeugen;
WSGIServer-Objekte erzeugen sie bei Bedarf von sich aus. Du kannst aber von dieser Klasse erben und sie der Funktionmake_server()als handler_class übergeben. Einige Methoden, die in Unterklassen zu überschreiben lohnen kann:- get_environ()¶
Gibt für eine Anfrage ein Dictionary
WSGIEnvironmentzurück. Die Standardausführung kopiert den Inhalt des Dictionary-Attributsbase_environdesWSGIServer-Objekts und fügt dann verschiedene Header aus der HTTP-Anfrage hinzu. Jeder Aufruf dieser Methode sollte ein neues Dictionary mit allen einschlägigen CGI-Umgebungsvariablen nach PEP 3333 zurückgeben.
- get_stderr()¶
Gibt das Objekt zurück, das als Strom
wsgi.errorsdienen soll. Die Standardausführung gibt einfachsys.stderrzurück.
- handle()¶
Verarbeitet die HTTP-Anfrage. Die Standardausführung erzeugt mit einer Klasse aus
wsgiref.handlerseine Handler-Instanz, die die eigentliche WSGI-Anwendungsschnittstelle bereitstellt.
wsgiref.validate — Prüfung der WSGI-Konformität¶
Wenn du neue WSGI-Anwendungsobjekte, Frameworks, Server oder Middleware schreibst, kann es nützlich sein, den neuen Code mit wsgiref.validate auf Konformität zu prüfen. Dieses Modul bietet eine Funktion, die WSGI-Anwendungsobjekte erzeugt. Diese prüfen die Verständigung zwischen einem WSGI-Server oder -Gateway und einem WSGI-Anwendungsobjekt und damit beide Seiten auf Konformität mit dem Protokoll.
Beachte, dass dieses Hilfsmittel keine vollständige Konformität mit PEP 3333 garantiert. Bleiben Fehlermeldungen aus, heißt das nicht zwangsläufig, dass es keine Fehler gibt. Meldet dieses Modul allerdings einen Fehler, ist so gut wie sicher, dass entweder der Server oder die Anwendung nicht vollständig konform ist.
Dieses Modul beruht auf dem Modul paste.lint aus Ian Bickings Bibliothek „Python Paste“.
- wsgiref.validate.validator(application)¶
Umhüllt 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 application als auch der aufrufende Server der WSGI-Spezifikation und RFC 2616 entsprechen.
Jede festgestellte Abweichung löst
AssertionErroraus. Wie mit diesen Fehlern umgegangen wird, hängt allerdings vom Server ab. So gebenwsgiref.simple_serverund andere Server auf der Grundlage vonwsgiref.handlers, die die Methoden zur Fehlerbehandlung nicht überschreiben, einfach eine Meldung über den Fehler aus und schreiben den Traceback nachsys.stderroder in einen anderen Fehlerstrom.Diese Hülle kann über das Modul
warningsauch Ausgaben erzeugen, um auf fragwürdiges Verhalten hinzuweisen, das PEP 3333 möglicherweise gar nicht verbietet. Solche Warnungen gehen nachsys.stderr– nicht nachwsgi.errors, es sei denn, beides ist dasselbe Objekt –, sofern sie nicht über Befehlszeilenoptionen von Python oder über die API vonwarningsunterdrückt werden.Beispiel für die Verwendung:
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 – Basisklassen für Server und Gateways¶
Dieses Modul bietet Basisklassen für die Behandlung von Anfragen, mit denen sich WSGI-Server und -Gateways schreiben lassen. Diese Basisklassen übernehmen die meiste Arbeit der Verständigung mit einer WSGI-Anwendung, solange sie eine CGI-ähnliche Umgebung sowie Ströme für Eingabe, Ausgabe und Fehler erhalten.
- class wsgiref.handlers.CGIHandler¶
Aufruf über CGI mittels
sys.stdin,sys.stdout,sys.stderrundos.environ. Das ist nützlich, wenn du eine WSGI-Anwendung als CGI-Skript laufen lassen willst. Rufe einfachCGIHandler().run(app)auf, wobeiappdas aufzurufende WSGI-Anwendungsobjekt ist.Diese Klasse ist eine Unterklasse von
BaseCGIHandler. Sie setztwsgi.run_onceauf wahr,wsgi.multithreadauf falsch undwsgi.multiprocessauf wahr und holt die nötigen CGI-Ströme und die Umgebung immer übersysundos.
- class wsgiref.handlers.IISCGIHandler¶
Eine besondere Alternative zu
CGIHandlerfür den Einsatz auf dem Webserver IIS von Microsoft, wenn die Konfigurationsoption allowPathInfo (IIS>=7) oder der Metabase-Eintrag allowPathInfoForScriptMappings (IIS<7) nicht gesetzt ist.Standardmäßig liefert IIS ein
PATH_INFO, dasSCRIPT_NAMEvorne doppelt enthält. Das macht WSGI-Anwendungen Schwierigkeiten, die Routing umsetzen wollen. Dieser Handler entfernt einen so gedoppelten Pfad.IIS lässt sich so einstellen, dass es das richtige
PATH_INFOübergibt, doch dann greift ein anderer Fehler, bei demPATH_TRANSLATEDfalsch ist. Zum Glück wird diese Variable selten verwendet und von WSGI nicht garantiert. Bei IIS<7 lässt sich die Einstellung allerdings nur auf vhost-Ebene vornehmen und betrifft damit alle anderen Skriptzuordnungen, von denen viele am Fehler mitPATH_TRANSLATEDscheitern. Deshalb wird IIS<7 so gut wie nie mit dieser Korrektur betrieben. Selbst IIS7 nutzt sie selten, weil es immer noch keine Oberfläche dafür gibt.CGI-Code kann nicht feststellen, ob die Option gesetzt wurde, daher gibt es eine eigene Handler-Klasse. Sie wird wie
CGIHandlerverwendet, also mit dem AufrufIISCGIHandler().run(app), wobeiappdas aufzurufende WSGI-Anwendungsobjekt ist.Added in version 3.2.
- class wsgiref.handlers.BaseCGIHandler(stdin, stdout, stderr, environ, multithread=True, multiprocess=False)¶
Ähnlich wie
CGIHandler, doch statt über die Modulesysundoswerden die CGI-Umgebung und die Ein- und Ausgabeströme ausdrücklich angegeben. Die Werte multithread und multiprocess setzen die Flagswsgi.multithreadundwsgi.multiprocessfür alle Anwendungen, die die Handler-Instanz ausführt.Diese Klasse ist eine Unterklasse von
SimpleHandlerund für Software gedacht, die kein HTTP-„Origin-Server“ ist. Schreibst du die Umsetzung eines Gateway-Protokolls wie CGI, FastCGI oder SCGI, das den HTTP-Status über einen HeaderStatus:sendet, willst du wahrscheinlich von dieser Klasse erben und nicht vonSimpleHandler.
- class wsgiref.handlers.SimpleHandler(stdin, stdout, stderr, environ, multithread=True, multiprocess=False)¶
Ähnlich wie
BaseCGIHandler, aber für HTTP-Origin-Server gedacht. Schreibst du einen HTTP-Server, willst du wahrscheinlich von dieser Klasse erben und nicht vonBaseCGIHandler.Diese Klasse ist eine Unterklasse von
BaseHandler. Sie überschreibt die Methoden__init__(),get_stdin(),get_stderr(),add_cgi_vars(),_write()und_flush(), damit sich Umgebung und Ströme ausdrücklich über den Konstruktor setzen lassen. Die übergebene Umgebung und die Ströme liegen in den Attributenstdin,stdout,stderrundenviron.Die Methode
write()von stdout sollte jeden Block vollständig schreiben, so wieio.BufferedIOBase.
- class wsgiref.handlers.BaseHandler¶
Das ist eine abstrakte Basisklasse, um WSGI-Anwendungen auszuführen. Jede Instanz bearbeitet eine einzelne HTTP-Anfrage, auch wenn man grundsätzlich eine Unterklasse schreiben könnte, die sich für mehrere Anfragen wiederverwenden lässt.
BaseHandler-Instanzen haben nur eine Methode, die für die Verwendung von außen gedacht ist:- run(app)¶
Führt die angegebene WSGI-Anwendung app aus.
Alle anderen Methoden von
BaseHandlerruft diese Methode beim Ausführen der Anwendung auf. Sie gibt es daher vor allem, damit sich der Ablauf anpassen lässt.Die folgenden Methoden MÜSSEN in einer Unterklasse überschrieben werden:
- _write(data)¶
Puffert die Bytes data für die Übertragung zum Client. Es ist in Ordnung, wenn diese Methode die Daten gleich überträgt.
BaseHandlertrennt Schreiben und Leeren nur, damit es zügiger geht, wenn das zugrundeliegende System diesen Unterschied tatsächlich kennt.
- _flush()¶
Erzwingt, dass gepufferte Daten zum Client übertragen werden. Es ist in Ordnung, wenn diese Methode nichts tut, also wenn
_write()die Daten bereits sendet.
- get_stdin()¶
Gibt ein zu
InputStreampassendes Objekt zurück, das sich alswsgi.inputder gerade verarbeiteten Anfrage eignet.
- get_stderr()¶
Gibt ein zu
ErrorStreampassendes Objekt zurück, das sich alswsgi.errorsder gerade verarbeiteten Anfrage eignet.
- add_cgi_vars()¶
Trägt die CGI-Variablen der aktuellen Anfrage in das Attribut
environein.
Hier sind weitere Methoden und Attribute, die du überschreiben möchtest. Diese Liste ist allerdings nur ein Überblick und nennt nicht jede überschreibbare Methode. Bevor du eine eigene Unterklasse von
BaseHandlerschreibst, solltest du die Docstrings und den Quellcode zu Rate ziehen.Attribute und Methoden, um die WSGI-Umgebung anzupassen:
- wsgi_multithread¶
Der Wert für die Umgebungsvariable
wsgi.multithread. InBaseHandlerist er standardmäßig wahr, in den anderen Unterklassen kann die Vorgabe abweichen oder der Konstruktor den Wert setzen.
- wsgi_multiprocess¶
Der Wert für die Umgebungsvariable
wsgi.multiprocess. InBaseHandlerist er standardmäßig wahr, in den anderen Unterklassen kann die Vorgabe abweichen oder der Konstruktor den Wert setzen.
- wsgi_run_once¶
Der Wert für die Umgebungsvariable
wsgi.run_once. InBaseHandlerist er standardmäßig falsch,CGIHandlersetzt ihn jedoch standardmäßig auf wahr.
- os_environ¶
Die Umgebungsvariablen, die standardmäßig in der WSGI-Umgebung jeder Anfrage enthalten sind. Standardmäßig ist das eine Kopie von
os.environzum Zeitpunkt des Imports vonwsgiref.handlers; Unterklassen können aber auf Klassen- oder Instanzebene eigene anlegen. Beachte, dass das Dictionary als nur lesbar zu betrachten ist, denn mehrere Klassen und Instanzen teilen sich den Vorgabewert.
- server_software¶
Ist das Attribut
origin_servergesetzt, dient der Wert dieses Attributs dazu, die WSGI-UmgebungsvariableSERVER_SOFTWAREvorzubelegen und in HTTP-Antworten einen HeaderServer:zu setzen. Bei Handlern, die keine HTTP-Origin-Server sind, etwaBaseCGIHandlerundCGIHandler, bleibt es außer Betracht.Geändert in Version 3.3: Der Begriff „Python“ wird durch einen Begriff der jeweiligen Implementierung ersetzt, etwa „CPython“ oder „Jython“.
- get_scheme()¶
Gibt das URL-Schema der aktuellen Anfrage zurück. Die Standardausführung schätzt mit der Funktion
guess_scheme()auswsgiref.utilanhand derenviron-Variablen der aktuellen Anfrage, ob das Schema „http“ oder „https“ sein sollte.
- setup_environ()¶
Setzt das Attribut
environauf eine vollständig gefüllte WSGI-Umgebung. Die Standardausführung verwendet dazu alle obigen Methoden und Attribute sowie die Methodenget_stdin(),get_stderr()undadd_cgi_vars()und das Attributwsgi_file_wrapper. Sie trägt außerdem den SchlüsselSERVER_SOFTWAREein, falls er fehlt, solange das Attributorigin_serverwahr und das Attributserver_softwaregesetzt ist.
Methoden und Attribute, um die Behandlung von Ausnahmen anzupassen:
- log_exception(exc_info)¶
Schreibt das Tupel exc_info ins Serverprotokoll. exc_info ist ein Tupel
(type, value, traceback). Die Standardausführung schreibt den Traceback einfach in den Stromwsgi.errorsder Anfrage und leert diesen. Unterklassen können diese Methode überschreiben, um das Format zu ändern, die Ausgabe umzuleiten, den Traceback an eine Administratorin zu mailen oder was auch immer sinnvoll erscheint.
- traceback_limit¶
Die größte Anzahl an Rahmen in den Tracebacks, die die Standardmethode
log_exception()ausgibt. BeiNonesind alle Rahmen enthalten.
- error_output(environ, start_response)¶
Diese Methode ist eine WSGI-Anwendung, die eine Fehlerseite für den Benutzer erzeugt. Sie wird nur aufgerufen, wenn ein Fehler auftritt, bevor Header an den Client gesendet wurden.
Diese Methode kommt mit
sys.exception()an den aktuellen Fehler und sollte diese Information beim Aufruf an start_response übergeben, wie im Abschnitt „Error Handling“ von PEP 3333 beschrieben. Insbesondere sollte das aufrufbare Objekt start_response dem ProtokollStartResponsefolgen.Die Standardausführung erzeugt die Ausgabeseite einfach aus den Attributen
error_status,error_headersunderror_body. Unterklassen können das überschreiben, um die Fehlerausgabe dynamischer zu gestalten.Beachte allerdings, dass es aus Sicherheitssicht nicht empfehlenswert ist, jedem beliebigen Benutzer Diagnoseausgaben vorzusetzen. Im Idealfall muss man etwas Besonderes tun, um Diagnoseausgaben einzuschalten. Darum enthält die Standardausführung keine.
- error_status¶
Der HTTP-Status für Fehlerantworten. Das sollte eine Statuszeichenkette nach PEP 3333 sein. Standardmäßig ist es Code 500 mit passender Meldung.
- error_headers¶
Die HTTP-Header für Fehlerantworten. Das sollte eine Liste von WSGI-Antwort-Headern sein, also Tupel
(name, value), wie in PEP 3333 beschrieben. Die Standardliste setzt nur den Inhaltstyp auftext/plain.
- error_body¶
Der Körper der Fehlerantwort. Das sollte eine Bytefolge für einen HTTP-Antwortkörper sein. Standardmäßig ist es der einfache Text „A server error occurred. Please contact the administrator.“
Methoden und Attribute für das Feature „Optional Platform-Specific File Handling“ aus PEP 3333:
- wsgi_file_wrapper¶
Eine Fabrik für
wsgi.file_wrapper, passend zuwsgiref.types.FileWrapper, oderNone. Vorgabewert dieses Attributs ist die Klassewsgiref.util.FileWrapper.
- sendfile()¶
Überschreibe diese Methode, um Dateien plattformeigen zu übertragen. Sie wird nur aufgerufen, wenn der Rückgabewert der Anwendung eine Instanz der Klasse ist, die das Attribut
wsgi_file_wrapperangibt. Sie sollte einen wahren Wert zurückgeben, wenn sie die Datei erfolgreich übertragen hat, damit der Standardcode zur Übertragung nicht läuft. Die Standardausführung dieser Methode gibt einfach einen falschen Wert zurück.
Verschiedene weitere Methoden und Attribute:
- origin_server¶
Dieses Attribut sollte wahr sein, wenn
_write()und_flush()des Handlers unmittelbar mit dem Client verkehren und nicht über ein CGI-ähnliches Gateway-Protokoll, das den HTTP-Status in einem besonderen HeaderStatus:erwartet.Der Vorgabewert dieses Attributs ist in
BaseHandlerwahr, inBaseCGIHandlerundCGIHandlerfalsch.
- http_version¶
Ist
origin_serverwahr, legt dieses Zeichenketten-Attribut die HTTP-Version der an den Client gesendeten Antwort fest. Vorgabe ist"1.0".
- wsgiref.handlers.read_environ()¶
Wandelt CGI-Variablen aus
os.environin „bytes in unicode“-Zeichenketten nach PEP 3333 um und gibt ein neues Dictionary zurück.CGIHandlerundIISCGIHandlerverwenden diese Funktion, stattos.environunmittelbar zu nutzen, denn das ist unter Python 3 nicht auf allen Plattformen und Webservern zwangsläufig WSGI-konform: nämlich dort, wo die eigentliche Umgebung des Betriebssystems Unicode ist, also unter Windows, oder wo die Umgebung aus Bytes besteht, Python sie aber mit einer anderen Systemkodierung als ISO-8859-1 dekodiert, etwa auf Unix-Systemen mit UTF-8.Schreibst du einen eigenen CGI-Handler, willst du wahrscheinlich diese Routine verwenden, statt Werte unmittelbar aus
os.environzu kopieren.Added in version 3.2.
wsgiref.types – WSGI-Typen für die statische Typprüfung¶
Dieses Modul bietet verschiedene Typen für die statische Typprüfung, wie in PEP 3333 beschrieben.
Added in version 3.11.
- class wsgiref.types.StartResponse¶
Ein
typing.Protocol, das aufrufbare Objekte start_response() beschreibt (PEP 3333).
- wsgiref.types.WSGIEnvironment¶
Ein Typalias, der ein Dictionary für eine WSGI-Umgebung beschreibt.
- wsgiref.types.WSGIApplication¶
Ein Typalias, der ein aufrufbares WSGI-Anwendungsobjekt beschreibt.
- class wsgiref.types.InputStream¶
Ein
typing.Protocol, das einen WSGI-Eingabestrom beschreibt.
- class wsgiref.types.ErrorStream¶
Ein
typing.Protocol, das einen WSGI-Fehlerstrom beschreibt.
- class wsgiref.types.FileWrapper¶
Ein
typing.Protocol, das eine Dateihülle beschreibt. Eine konkrete Umsetzung dieses Protokolls istwsgiref.util.FileWrapper.
Beispiele¶
Das ist eine funktionierende „Hello World“-WSGI-Anwendung. Das aufrufbare Objekt start_response sollte dem Protokoll StartResponse folgen:
"""
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 ausliefert und auf der Befehlszeile nach Bedarf ein Verzeichnis und eine Portnummer annimmt (Vorgabe: 8000):
"""
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()