<ahref="https://databento.com/?utm_source=fastapi&utm_medium=sponsor&utm_content=display"target="_blank"title="Pay as you go for market data"><imgsrc="https://fastapi.tiangolo.com/img/sponsors/databento.svg"></a>
<ahref="https://databento.com/?utm_source=fastapi&utm_medium=sponsor&utm_content=display"target="_blank"title="Pay as you go for market data"><imgsrc="https://fastapi.tiangolo.com/img/sponsors/databento.svg"></a>
<ahref="https://www.svix.com/"target="_blank"title="Svix - Webhooks as a service"><imgsrc="https://fastapi.tiangolo.com/img/sponsors/svix.svg"></a>
<ahref="https://www.svix.com/"target="_blank"title="Svix - Webhooks as a service"><imgsrc="https://fastapi.tiangolo.com/img/sponsors/svix.svg"></a>
<ahref="https://www.permit.io/blog/implement-authorization-in-fastapi?utm_source=github&utm_medium=referral&utm_campaign=fastapi"target="_blank"title="Fine-Grained Authorization for FastAPI"><imgsrc="https://fastapi.tiangolo.com/img/sponsors/permit.png"></a>
<ahref="https://www.permit.io/blog/implement-authorization-in-fastapi?utm_source=github&utm_medium=referral&utm_campaign=fastapi"target="_blank"title="Fine-Grained Authorization for FastAPI"><imgsrc="https://fastapi.tiangolo.com/img/sponsors/permit.png"></a>
<ahref="https://dribia.com/en/"target="_blank"title="Dribia - Data Science within your reach"><imgsrc="https://fastapi.tiangolo.com/img/sponsors/dribia.png"></a>
<ahref="https://dribia.com/en/"target="_blank"title="Dribia - Data Science within your reach"><imgsrc="https://fastapi.tiangolo.com/img/sponsors/dribia.png"></a>
<ahref="https://www.rapidproxy.io/?ref=fastapi"target="_blank"title="Try RapidProxy for free - Residential Proxies with 90M+ Global IPs. Starting from $0.65/GB for web scraping, automation, and data collection."><imgsrc="https://fastapi.tiangolo.com/img/sponsors/rapidproxy.png"></a>
<ahref="https://www.rapidproxy.io/?ref=fastapi"target="_blank"title="Try RapidProxy for free - Residential Proxies with 90M+ Global IPs. Starting from $0.65/GB for web scraping, automation, and data collection."><imgsrc="https://fastapi.tiangolo.com/img/sponsors/rapidproxy.png"></a>
Dieses Dokument testet, ob das <abbrtitle="Large Language Model - Großes Sprachmodell">LLM</abbr>, das die Dokumentation übersetzt, den <abbrtitle="General Prompt - Allgemeiner Prompt">`general_prompt`</abbr> in `scripts/translate.py` und den sprachspezifischen Prompt in `docs/{language code}/llm-prompt.md` versteht. Der sprachsspezifische Prompt wird an `general_prompt` angehängt.
Dieses Dokument testet, ob das <abbrtitle="Large Language Model - Großes Sprachmodell">LLM</abbr>, das die Dokumentation übersetzt, den <abbrtitle="General Prompt - Allgemeiner Prompt">`general_prompt`</abbr> in `scripts/translate.py` und den sprachspezifischen Prompt in `docs/{language code}/llm-prompt.md` versteht. Der sprachspezifische Prompt wird an `general_prompt` angehängt.
Hier hinzugefügte Tests werden von allen Erstellern sprachsspezifischer Prompts gesehen.
Hier hinzugefügte Tests werden von allen Erstellern sprachspezifischer Prompts gesehen.
So verwenden:
So verwenden:
* Einen sprachsspezifischen Prompt haben – `docs/{language code}/llm-prompt.md`.
* Einen sprachspezifischen Prompt haben – `docs/{language code}/llm-prompt.md`.
* Eine frische Übersetzung dieses Dokuments in die gewünschte Zielsprache durchführen (siehe z. B. das Kommando `translate-page` der `translate.py`). Dadurch wird die Übersetzung unter `docs/{language code}/docs/_llm-test.md` erstellt.
* Eine frische Übersetzung dieses Dokuments in die gewünschte Zielsprache durchführen (siehe z. B. das Kommando `translate-page` der `translate.py`). Dadurch wird die Übersetzung unter `docs/{language code}/docs/_llm-test.md` erstellt.
* Prüfen Sie, ob in der Übersetzung alles in Ordnung ist.
* Prüfen Sie, ob in der Übersetzung alles in Ordnung ist.
* Verbessern Sie bei Bedarf Ihren sprachsspezifischen Prompt, den allgemeinen Prompt oder das englische Dokument.
* Verbessern Sie bei Bedarf Ihren sprachspezifischen Prompt, den allgemeinen Prompt oder das englische Dokument.
* Beheben Sie anschließend manuell die verbleibenden Probleme in der Übersetzung, sodass es eine gute Übersetzung ist.
* Beheben Sie anschließend manuell die verbleibenden Probleme in der Übersetzung, sodass es eine gute Übersetzung ist.
* Übersetzen Sie erneut, nachdem die gute Übersetzung vorliegt. Das ideale Ergebnis wäre, dass das LLM an der Übersetzung keine Änderungen mehr vornimmt. Das bedeutet, dass der allgemeine Prompt und Ihr sprachsspezifischer Prompt so gut sind, wie sie sein können (Es wird manchmal ein paar scheinbar zufällige Änderungen machen, der Grund ist, dass [LLMs keine deterministischen Algorithmen sind](https://doublespeak.chat/#/handbook#deterministic-output)).
* Übersetzen Sie erneut, nachdem die gute Übersetzung vorliegt. Das ideale Ergebnis wäre, dass das LLM an der Übersetzung keine Änderungen mehr vornimmt. Das bedeutet, dass der allgemeine Prompt und Ihr sprachspezifischer Prompt so gut sind, wie sie sein können (Es wird manchmal ein paar scheinbar zufällige Änderungen machen, der Grund ist, dass [LLMs keine deterministischen Algorithmen sind](https://doublespeak.chat/#/handbook#deterministic-output)).
Die Tests:
Die Tests:
@ -211,7 +211,7 @@ Siehe Abschnitt `### HTML abbr elements` im allgemeinen Prompt in `scripts/trans
////
////
## HTML„dfn“-Elemente { #html-dfn-elements }
## HTML-„dfn“-Elemente { #html-dfn-elements }
* <dfntitle="Eine Gruppe von Maschinen, die so konfiguriert sind, dass sie verbunden sind und in irgendeiner Weise zusammenarbeiten.">Cluster</dfn>
* <dfntitle="Eine Gruppe von Maschinen, die so konfiguriert sind, dass sie verbunden sind und in irgendeiner Weise zusammenarbeiten.">Cluster</dfn>
* <dfntitle="Eine Methode des Machine Learning, die künstliche neuronale Netze mit zahlreichen versteckten Schichten zwischen Eingabe- und Ausgabeschicht verwendet und so eine umfassende interne Struktur entwickelt">Deep Learning</dfn>
* <dfntitle="Eine Methode des Machine Learning, die künstliche neuronale Netze mit zahlreichen versteckten Schichten zwischen Eingabe- und Ausgabeschicht verwendet und so eine umfassende interne Struktur entwickelt">Deep Learning</dfn>
@ -240,7 +240,7 @@ Die einzige strenge Regel für Überschriften ist, dass das LLM den Hash-Teil in
Siehe Abschnitt `### Headings` im allgemeinen Prompt in `scripts/translate.py`.
Siehe Abschnitt `### Headings` im allgemeinen Prompt in `scripts/translate.py`.
Für einige sprachsspezifische Anweisungen, siehe z. B. den Abschnitt `### Headings` in `docs/de/llm-prompt.md`.
Für einige sprachspezifische Anweisungen, siehe z. B. den Abschnitt `### Headings` in `docs/de/llm-prompt.md`.
////
////
@ -363,12 +363,12 @@ Für einige sprachsspezifische Anweisungen, siehe z. B. den Abschnitt `### Headi
Standardmäßig liefert **FastAPI** die <abbrtitle="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Responses</abbr> als `JSONResponse` zurück und fügt den Inhalt, den Sie aus Ihrer *Pfadoperation* zurückgeben, in diese `JSONResponse` ein.
Standardmäßig liefert **FastAPI** die <abbrtitle="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Responses</abbr> als `JSONResponse` zurück und fügt den Inhalt, den Sie aus Ihrer *Pfadoperation* zurückgeben, in diese `JSONResponse` ein.
Es wird der Default-Statuscode oder derjenige verwendet, den Sie in Ihrer *Pfadoperation* festgelegt haben.
Es wird der Default-Statuscode oder derjenige verwendet, den Sie in Ihrer *Pfadoperation* festgelegt haben.
FastAPI basiert auf **Pydantic**, und ich habe Ihnen gezeigt, wie Sie Pydantic-Modelle verwenden können, um <abbrtitle="Request – Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> und <abbrtitle="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Responses</abbr> zu deklarieren.
FastAPI basiert auf **Pydantic**, und ich habe Ihnen gezeigt, wie Sie Pydantic-Modelle verwenden können, um <abbrtitle="Request – Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> und <abbrtitle="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Responses</abbr> zu deklarieren.
Aber FastAPI unterstützt auf die gleiche Weise auch die Verwendung von [`dataclasses`](https://docs.python.org/3/library/dataclasses.html):
Aber FastAPI unterstützt auf die gleiche Weise auch die Verwendung von [`dataclasses`](https://docs.python.org/3/library/dataclasses.html):
@ -150,7 +150,7 @@ Aus diesem Grund wird jetzt empfohlen, stattdessen `lifespan` wie oben erläuter
Nur ein technisches Detail für die neugierigen Nerds. 🤓
Nur ein technisches Detail für die neugierigen Nerds. 🤓
In der technischen ASGI-Spezifikation ist dies Teil des [LifespanProtokolls](https://asgi.readthedocs.io/en/latest/specs/lifespan.html) und definiert Events namens `startup` und `shutdown`.
In der technischen ASGI-Spezifikation ist dies Teil des [Lifespan-Protokolls](https://asgi.readthedocs.io/en/latest/specs/lifespan.html) und definiert Events namens `startup` und `shutdown`.
@ -20,20 +20,6 @@ FastAPI generiert automatisch **OpenAPI 3.1**-Spezifikationen, daher muss jedes
///
///
## SDK-Generatoren von FastAPI-Sponsoren { #sdk-generators-from-fastapi-sponsors }
Dieser Abschnitt hebt **venture-unterstützte** und **firmengestützte** Lösungen hervor, die von Unternehmen entwickelt werden, welche FastAPI sponsern. Diese Produkte bieten **zusätzliche Funktionen** und **Integrationen** zusätzlich zu hochwertig generierten SDKs.
Durch das ✨ [**Sponsoring von FastAPI**](../help-fastapi.md#sponsor-the-author) ✨ helfen diese Unternehmen sicherzustellen, dass das Framework und sein **Ökosystem** gesund und **nachhaltig** bleiben.
Ihr Sponsoring zeigt auch ein starkes Engagement für die FastAPI-**Community** (Sie), was bedeutet, dass sie nicht nur einen **großartigen Service** bieten möchten, sondern auch ein **robustes und florierendes Framework**, FastAPI, unterstützen möchten. 🙇
Einige dieser Lösungen sind möglicherweise auch Open Source oder bieten kostenlose Tarife an, sodass Sie diese ohne finanzielle Verpflichtung ausprobieren können. Andere kommerzielle SDK-Generatoren sind online verfügbar und können dort gefunden werden. 🤓
## Ein TypeScript-SDK erstellen { #create-a-typescript-sdk }
## Ein TypeScript-SDK erstellen { #create-a-typescript-sdk }
Beginnen wir mit einer einfachen FastAPI-Anwendung:
Beginnen wir mit einer einfachen FastAPI-Anwendung:
@ -4,7 +4,7 @@ Wenn Ihre App JSON-Daten empfangen und senden muss, Sie darin aber Binärdaten e
## Base64 vs Dateien { #base64-vs-files }
## Base64 vs Dateien { #base64-vs-files }
Prüfen Sie zunächst, ob Sie [Request Files](../tutorial/request-files.md) zum Hochladen von Binärdaten und [Benutzerdefinierte Response – FileResponse](./custom-response.md#fileresponse--fileresponse-) zum Senden von Binärdaten verwenden können, anstatt sie in JSON zu kodieren.
Prüfen Sie zunächst, ob Sie [Requestdateien](../tutorial/request-files.md) zum Hochladen von Binärdaten und [Benutzerdefinierte Response – FileResponse](./custom-response.md#fileresponse) zum Senden von Binärdaten verwenden können, anstatt sie in JSON zu kodieren.
JSON kann nur UTF-8-kodierte Strings enthalten, es kann daher keine rohen Bytes enthalten.
JSON kann nur UTF-8-kodierte Strings enthalten, es kann daher keine rohen Bytes enthalten.
@ -167,13 +167,13 @@ Beachten Sie, dass die verwendete Callback-URL die URL enthält, die als Query-P
An diesem Punkt haben Sie die benötigte(n) *Callback-Pfadoperation(en)* (diejenige(n), die der *externe Entwickler* in der *externen API* implementieren sollte) im Callback-Router, den Sie oben erstellt haben.
An diesem Punkt haben Sie die benötigte(n) *Callback-Pfadoperation(en)* (diejenige(n), die der *externe Entwickler* in der *externen API* implementieren sollte) im Callback-Router, den Sie oben erstellt haben.
Verwenden Sie nun den Parameter `callbacks` im *Pfadoperation-Dekorator Ihrer API*, um das Attribut `.routes`(das ist eigentlich nur eine `list`e von Routen/*Pfadoperationen*) dieses Callback-Routers zu übergeben:
Verwenden Sie nun den Parameter `callbacks` im *Pfadoperation-Dekorator Ihrer API*, um das Attribut `.routes` dieses Callback-Routers zu übergeben:
Beachten Sie, dass Sie nicht den Router selbst (`invoices_callback_router`) an `callback=` übergeben, sondern das Attribut`.routes`, wie in `invoices_callback_router.routes`. FastAPI wird diese Routen verwenden, um die Callback-OpenAPI-Dokumentation zu generieren.
Beachten Sie, dass Sie nicht den Router selbst (`invoices_callback_router`) an `callbacks=` übergeben, sondern dessen`.routes`, wie in `invoices_callback_router.routes`. FastAPI wird diese Routen verwenden, um die Callback-OpenAPI-Dokumentation zu generieren.
@ -38,4 +38,4 @@ Und da die `Response` häufig zum Setzen von Headern und Cookies verwendet wird,
Beachten Sie, dass benutzerdefinierte proprietäre Header [mit dem Präfix `X-`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers) hinzugefügt werden können.
Beachten Sie, dass benutzerdefinierte proprietäre Header [mit dem Präfix `X-`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers) hinzugefügt werden können.
Wenn Sie jedoch benutzerdefinierte Header haben, die ein Client in einem Browser sehen können soll, müssen Sie diese zu Ihrer CORS-Konfiguration hinzufügen (weitere Informationen finden Sie unter [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md)), unter Verwendung des Parameters `expose_headers`, dokumentiert in [Starlettes CORS-Dokumentation](https://www.starlette.dev/middleware/#corsmiddleware).
Wenn Sie jedoch benutzerdefinierte Header haben, die ein Client in einem Browser sehen können soll, müssen Sie diese zu Ihren CORS-Konfigurationen hinzufügen (weitere Informationen finden Sie unter [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md)), unter Verwendung des Parameters `expose_headers`, dokumentiert in [Starlettes CORS-Dokumentation](https://www.starlette.dev/middleware/#corsmiddleware).
@ -247,7 +247,7 @@ Das würde einer Drittanbieteranwendung passieren, die versucht, auf eine dieser
## Über Integrationen von Drittanbietern { #about-third-party-integrations }
## Über Integrationen von Drittanbietern { #about-third-party-integrations }
In diesem Beispiel verwenden wir den OAuth2-Flow „Password“.
In diesem Beispiel verwenden wir den OAuth2-Flow „password“.
Das ist angemessen, wenn wir uns bei unserer eigenen Anwendung anmelden, wahrscheinlich mit unserem eigenen Frontend.
Das ist angemessen, wenn wir uns bei unserer eigenen Anwendung anmelden, wahrscheinlich mit unserem eigenen Frontend.
@ -255,9 +255,9 @@ Weil wir darauf vertrauen können, dass es den `username` und das `password` erh
Wenn Sie jedoch eine OAuth2-Anwendung erstellen, mit der andere eine Verbindung herstellen würden (d.h. wenn Sie einen Authentifizierungsanbieter erstellen, der Facebook, Google, GitHub usw. entspricht), sollten Sie einen der anderen Flows verwenden.
Wenn Sie jedoch eine OAuth2-Anwendung erstellen, mit der andere eine Verbindung herstellen würden (d.h. wenn Sie einen Authentifizierungsanbieter erstellen, der Facebook, Google, GitHub usw. entspricht), sollten Sie einen der anderen Flows verwenden.
Am häufigsten ist der „Implicit“-Flow.
Am häufigsten ist der implicit Flow.
Am sichersten ist der „Code“-Flow, die Implementierung ist jedoch komplexer, da mehr Schritte erforderlich sind. Da er komplexer ist, schlagen viele Anbieter letztendlich den „Implicit“-Flow vor.
Am sichersten ist der code Flow, die Implementierung ist jedoch komplexer, da mehr Schritte erforderlich sind. Da er komplexer ist, schlagen viele Anbieter letztendlich den implicit Flow vor.
@ -14,13 +14,13 @@ Um Umgebungsvariablen zu verstehen, können Sie [Umgebungsvariablen](../environm
## Typen und Validierung { #types-and-validation }
## Typen und Validierung { #types-and-validation }
Diese Umgebungsvariablen können nur Text-Zeichenketten verarbeiten, da sie außerhalb von Python liegen und mit anderen Programmen und dem Rest des Systems (und sogar mit verschiedenen Betriebssystemen wie Linux, Windows, macOS) kompatibel sein müssen.
Diese Umgebungsvariablen können nur Text-Strings verarbeiten, da sie außerhalb von Python liegen und mit anderen Programmen und dem Rest des Systems (und sogar mit verschiedenen Betriebssystemen wie Linux, Windows, macOS) kompatibel sein müssen.
Das bedeutet, dass jeder in Python aus einer Umgebungsvariablen gelesene Wert ein `str` ist und jede Konvertierung in einen anderen Typ oder jede Validierung im Code erfolgen muss.
Das bedeutet, dass jeder in Python aus einer Umgebungsvariablen gelesene Wert ein `str` ist und jede Konvertierung in einen anderen Typ oder jede Validierung im Code erfolgen muss.
## Pydantic `Settings` { #pydantic-settings }
## Pydantic `Settings` { #pydantic-settings }
Glücklicherweise bietet Pydantic ein großartiges Werkzeug zur Verarbeitung dieser Einstellungen, die von Umgebungsvariablen stammen, mit [Pydantic: Settings Management](https://docs.pydantic.dev/latest/concepts/pydantic_settings/).
Glücklicherweise bietet Pydantic ein großartiges Werkzeug zur Verarbeitung dieser Einstellungen, die von Umgebungsvariablen stammen, mit [Pydantic: Settings-Verwaltung](https://docs.pydantic.dev/latest/concepts/pydantic_settings/).
Beachten Sie, dass wir jetzt keine Standardinstanz `settings = Settings()` erstellen.
Beachten Sie, dass wir jetzt keine Defaultinstanz `settings = Settings()` erstellen.
### Die Haupt-Anwendungsdatei { #the-main-app-file }
### Die Haupt-Anwendungsdatei { #the-main-app-file }
@ -158,7 +158,7 @@ Bei der Abhängigkeitsüberschreibung legen wir einen neuen Wert für `admin_ema
Dann können wir testen, ob das verwendet wird.
Dann können wir testen, ob das verwendet wird.
## Lesen einer `.env`-Datei { #reading-a-env-file }
## Eine `.env`-Datei lesen { #reading-a-env-file }
Wenn Sie viele Einstellungen haben, die sich möglicherweise oft ändern, vielleicht in verschiedenen Umgebungen, kann es nützlich sein, diese in eine Datei zu schreiben und sie dann daraus zu lesen, als wären sie Umgebungsvariablen.
Wenn Sie viele Einstellungen haben, die sich möglicherweise oft ändern, vielleicht in verschiedenen Umgebungen, kann es nützlich sein, diese in eine Datei zu schreiben und sie dann daraus zu lesen, als wären sie Umgebungsvariablen.
@ -172,7 +172,7 @@ Aber eine dotenv-Datei muss nicht unbedingt genau diesen Dateinamen haben.
///
///
Pydantic unterstützt das Lesen dieser Dateitypen mithilfe einer externen Bibliothek. Weitere Informationen finden Sie unter [Pydantic Settings: Dotenv (.env) support](https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support).
Pydantic unterstützt das Lesen dieser Dateitypen mithilfe einer externen Bibliothek. Weitere Informationen finden Sie unter [Pydantic Settings: Dotenv (.env)-Unterstützung](https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support).
/// tip | Tipp
/// tip | Tipp
@ -197,13 +197,13 @@ Und dann aktualisieren Sie Ihre `config.py` mit:
/// tip | Tipp
/// tip | Tipp
Das Attribut `model_config` wird nur für die Pydantic-Konfiguration verwendet. Weitere Informationen finden Sie unter [Pydantic: Concepts: Configuration](https://docs.pydantic.dev/latest/concepts/config/).
Das Attribut `model_config` wird nur für die Pydantic-Konfiguration verwendet. Weitere Informationen finden Sie unter [Pydantic: Konzepte: Konfiguration](https://docs.pydantic.dev/latest/concepts/config/).
///
///
Hier definieren wir die Konfiguration `env_file` innerhalb Ihrer Pydantic-`Settings`-Klasse und setzen den Wert auf den Dateinamen mit der dotenv-Datei, die wir verwenden möchten.
Hier definieren wir die Konfiguration `env_file` innerhalb Ihrer Pydantic-`Settings`-Klasse und setzen den Wert auf den Dateinamen mit der dotenv-Datei, die wir verwenden möchten.
### Die `Settings` nur einmal laden mittels `lru_cache` { #creating-the-settings-only-once-with-lru-cache }
### Die `Settings` nur einmal mittels `lru_cache` erstellen { #creating-the-settings-only-once-with-lru-cache }
Das Lesen einer Datei von der Festplatte ist normalerweise ein kostspieliger (langsamer) Vorgang, daher möchten Sie ihn wahrscheinlich nur einmal ausführen und dann dasselbe Einstellungsobjekt erneut verwenden, anstatt es für jeden <abbrtitle="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> zu lesen.
Das Lesen einer Datei von der Festplatte ist normalerweise ein kostspieliger (langsamer) Vorgang, daher möchten Sie ihn wahrscheinlich nur einmal ausführen und dann dasselbe Einstellungsobjekt erneut verwenden, anstatt es für jeden <abbrtitle="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> zu lesen.
@ -291,7 +291,7 @@ Im Fall unserer Abhängigkeit `get_settings()` akzeptiert die Funktion nicht ein
Auf diese Weise verhält es sich fast so, als wäre es nur eine globale Variable. Da es jedoch eine Abhängigkeitsfunktion verwendet, können wir diese zu Testzwecken problemlos überschreiben.
Auf diese Weise verhält es sich fast so, als wäre es nur eine globale Variable. Da es jedoch eine Abhängigkeitsfunktion verwendet, können wir diese zu Testzwecken problemlos überschreiben.
`@lru_cache` ist Teil von `functools`, welches Teil von Pythons Standardbibliothek ist. Weitere Informationen dazu finden Sie in der [PythonDokumentation für `@lru_cache`](https://docs.python.org/3/library/functools.html#functools.lru_cache).
`@lru_cache` ist Teil von `functools`, welches Teil von Pythons Standardbibliothek ist. Weitere Informationen dazu finden Sie in der [Python-Dokumentation für `@lru_cache`](https://docs.python.org/3/library/functools.html#functools.lru_cache).
@ -20,13 +20,13 @@ Sie könnten auf diese Weise auch **Video** oder **Audio** streamen, es könnte
## Eine `StreamingResponse` mit `yield` { #a-streamingresponse-with-yield }
## Eine `StreamingResponse` mit `yield` { #a-streamingresponse-with-yield }
Wenn Sie in Ihrer Pfadoperation-Funktion ein `response_class=StreamingResponse` deklarieren, können Sie `yield` verwenden, um nacheinander jeden Datenchunk zu senden.
Wenn Sie in Ihrer *Pfadoperation-Funktion* ein `response_class=StreamingResponse` deklarieren, können Sie `yield` verwenden, um nacheinander jeden Datenchunk zu senden.
@ -98,7 +98,7 @@ Aber in vielen Fällen würde das Lesen einer Datei oder eines dateiähnlichen O
///
///
Um die Event-Loop nicht zu blockieren, können Sie die Pfadoperation-Funktion einfach mit normalem `def` statt `async def` deklarieren, dadurch führt FastAPI sie in einem Threadpool-Worker aus, um die Haupt-Event-Loop nicht zu blockieren.
Um die Event-Loop nicht zu blockieren, können Sie die *Pfadoperation-Funktion* einfach mit normalem `def` statt `async def` deklarieren, dadurch führt FastAPI sie in einem Threadpool-Worker aus, um die Haupt-Event-Loop nicht zu blockieren.
# WSGI inkludieren – Flask, Django und andere { #including-wsgi-flask-django-others }
# WSGI inkludieren – Flask, Django und andere { #including-wsgi-flask-django-others }
Sie können WSGI-Anwendungen mounten, wie Sie es in [Unteranwendungen – Mounts](sub-applications.md), [Hinter einem Proxy](behind-a-proxy.md) gesehen haben.
Sie können WSGI-Anwendungen mounten, wie Sie es in [Unteranwendungen – Mounts](sub-applications.md), [Hinter einem Proxy](behind-a-proxy.md) gesehen haben.
Dazu können Sie die `WSGIMiddleware` verwenden und damit Ihre WSGI-Anwendung wrappen, zum Beispiel Flask, Django usw.
Dazu können Sie die `WSGIMiddleware` verwenden und damit Ihre WSGI-Anwendung wrappen, zum Beispiel Flask, Django usw.
@ -283,7 +283,7 @@ Aus diesem Grund basiert **FastAPI** auf Starlette, da dieses das schnellste ver
Falcon ist ein weiteres leistungsstarkes Python-Framework. Es ist minimalistisch konzipiert und dient als Grundlage für andere Frameworks wie Hug.
Falcon ist ein weiteres leistungsstarkes Python-Framework. Es ist minimalistisch konzipiert und dient als Grundlage für andere Frameworks wie Hug.
Es ist so konzipiert, dass es über Funktionen verfügt, welche zwei Parameter empfangen, einen <abbrtitle="Request - Anfrage: Daten, die der Client zum Server sendet">„Request“</abbr> und eine <abbrtitle="Response - Antwort: Daten, die der Server zum anfragenden Client zurücksendet">„Response“</abbr>. Dann „lesen“ Sie Teile des Requests und „schreiben“ Teile der Response. Aufgrund dieses Designs ist es nicht möglich, Request-Parameter und -Bodys mit Standard-Python-Typhinweisen als Funktionsparameter zu deklarieren.
Es ist so konzipiert, dass es über Funktionen verfügt, welche zwei Parameter empfangen, einen <abbrtitle="Request - Anfrage: Daten, die der Client zum Server sendet">„Request“</abbr> und eine <abbrtitle="Response - Antwort: Daten, die der Server zum anfragenden Client zurücksendet">„Response“</abbr>. Dann „lesen“ Sie Teile des Requests und „schreiben“ Teile der Response. Aufgrund dieses Designs ist es nicht möglich, Request-Parameter und Requestbodys mit Standard-Python-Typhinweisen als Funktionsparameter zu deklarieren.
Daher müssen Datenvalidierung, Serialisierung und Dokumentation im Code und nicht automatisch erfolgen. Oder sie müssen als Framework oberhalb von Falcon implementiert werden, so wie Hug. Dieselbe Unterscheidung findet auch in anderen Frameworks statt, die vom Design von Falcon inspiriert sind und ein Requestobjekt und ein Responseobjekt als Parameter haben.
Daher müssen Datenvalidierung, Serialisierung und Dokumentation im Code und nicht automatisch erfolgen. Oder sie müssen als Framework oberhalb von Falcon implementiert werden, so wie Hug. Dieselbe Unterscheidung findet auch in anderen Frameworks statt, die vom Design von Falcon inspiriert sind und ein Requestobjekt und ein Responseobjekt als Parameter haben.
@ -351,11 +351,11 @@ Hug inspirierte **FastAPI** dazu, einen `response`-Parameter in Funktionen zu de
Kurz bevor ich mich entschied, **FastAPI** zu erstellen, fand ich den **APIStar**-Server. Er hatte fast alles, was ich suchte, und ein tolles Design.
Kurz bevor ich mich entschied, **FastAPI** zu erstellen, fand ich den **APIStar**-Server. Er hatte fast alles, was ich suchte, und ein tolles Design.
Er war eine der ersten Implementierungen eines Frameworks, die ich je gesehen hatte (vor NestJS und Molten), welches Python-Typhinweise zur Deklaration von Parametern und Requests verwendeten. Ich habe ihn mehr oder weniger zeitgleich mit Hug gefunden. Aber APIStar nutzte den OpenAPI-Standard.
Er war eine der ersten Implementierungen eines Frameworks, die ich je gesehen hatte (vor NestJS und Molten), das Python-Typhinweise zur Deklaration von Parametern und Requests verwendete. Ich habe ihn mehr oder weniger zeitgleich mit Hug gefunden. Aber APIStar nutzte den OpenAPI-Standard.
Er verfügte an mehreren Stellen über automatische Datenvalidierung, Datenserialisierung und OpenAPI-Schemagenerierung, basierend auf denselben Typhinweisen.
Er verfügte an mehreren Stellen über automatische Datenvalidierung, Datenserialisierung und OpenAPI-Schemagenerierung, basierend auf denselben Typhinweisen.
Starlette ist derzeit das schnellste getestete Python-Framework. Nur übertroffen von Uvicorn, welches kein Framework, sondern ein Server ist.
Starlette ist derzeit das schnellste getestete Python-Framework. Nur übertroffen von Uvicorn, welches kein Framework, sondern ein Server ist.
@ -448,7 +448,7 @@ Das ist eines der wichtigsten Dinge, welche **FastAPI** hinzufügt, alles basier
ASGI ist ein neuer „Standard“, welcher von Mitgliedern des Django-Kernteams entwickelt wird. Es handelt sich immer noch nicht um einen „Python-Standard“ (ein PEP), obwohl sie gerade dabei sind, das zu tun.
ASGI ist ein neuer „Standard“, welcher von Mitgliedern des Django-Kernteams entwickelt wird. Es handelt sich immer noch nicht um einen „Python-Standard“ (ein PEP), obwohl sie gerade dabei sind, das zu tun.
Dennoch wird es bereits von mehreren Tools als „Standard“ verwendet. Das verbessert die Interoperabilität erheblich, da Sie Uvicorn mit jeden anderen ASGI-Server (wie Daphne oder Hypercorn) tauschen oder ASGI-kompatible Tools wie `python-socketio` hinzufügen können.
Dennoch wird es bereits von mehreren Tools als „Standard“ verwendet. Das verbessert die Interoperabilität erheblich, da Sie Uvicorn mit jedem anderen ASGI-Server (wie Daphne oder Hypercorn) tauschen oder ASGI-kompatible Tools wie `python-socketio` hinzufügen können.
@ -44,7 +44,7 @@ Wenn Ihre Anwendung (irgendwie) nicht mit etwas anderem kommunizieren und auf de
---
---
Wenn Sie sich unsicher sind, verwenden Sie einfach`def`.
Wenn Sie sich unsicher sind, verwenden Sie normales`def`.
---
---
@ -70,7 +70,7 @@ Asynchroner Code bedeutet lediglich, dass die Sprache 💬 eine Möglichkeit hat
Während der Zeit, die „Langsam-Datei“ 📝 benötigt, kann das System also andere Aufgaben erledigen.
Während der Zeit, die „Langsam-Datei“ 📝 benötigt, kann das System also andere Aufgaben erledigen.
Dann kommt der Computer / das Programm 🤖 bei jeder Gelegenheit zurück, weil es entweder wieder wartet oder wann immer es 🤖 die ganze Arbeit erledigt hat, die zu diesem Zeitpunkt zu tun war. Und es 🤖 wird nachschauen, ob eine der Aufgaben, auf die es gewartet hat, fertig ist.
Dann kommt der Computer / das Programm 🤖 bei jeder Gelegenheit zurück, weil es entweder wieder wartet oder wann immer es 🤖 die ganze Arbeit erledigt hat, die zu diesem Zeitpunkt zu tun war. Und es 🤖 wird nachschauen, ob eine der Aufgaben, auf die es gewartet hat, bereits fertig ist, und tun, was es zu tun hatte.
Dann nimmt es 🤖 die erste erledigte Aufgabe (sagen wir, unsere „Langsam-Datei“ 📝) und bearbeitet sie weiter.
Dann nimmt es 🤖 die erste erledigte Aufgabe (sagen wir, unsere „Langsam-Datei“ 📝) und bearbeitet sie weiter.
@ -361,7 +361,7 @@ Wenn Sie mit **FastAPI** arbeiten, müssen Sie sich darüber keine Sorgen machen
Wenn Sie jedoch `async` / `await` ohne FastAPI verwenden möchten, können Sie dies auch tun.
Wenn Sie jedoch `async` / `await` ohne FastAPI verwenden möchten, können Sie dies auch tun.
### Schreiben Sie Ihren eigenen asynchronen Code { #write-your-own-async-code }
### Ihren eigenen asynchronen Code schreiben { #write-your-own-async-code }
Starlette (und **FastAPI**) basieren auf [AnyIO](https://anyio.readthedocs.io/en/stable/), was bedeutet, dass es sowohl kompatibel mit der Python-Standardbibliothek [asyncio](https://docs.python.org/3/library/asyncio-task.html) als auch mit [Trio](https://trio.readthedocs.io/en/stable/) ist.
Starlette (und **FastAPI**) basieren auf [AnyIO](https://anyio.readthedocs.io/en/stable/), was bedeutet, dass es sowohl kompatibel mit der Python-Standardbibliothek [asyncio](https://docs.python.org/3/library/asyncio-task.html) als auch mit [Trio](https://trio.readthedocs.io/en/stable/) ist.
Bei dem Deployment – der Bereitstellung – einer **FastAPI**-Anwendung, oder eigentlich jeder Art von Web-API, gibt es mehrere Konzepte, die Sie wahrscheinlich interessieren, und mithilfe der Sie die **am besten geeignete** Methode zum **Deployment Ihrer Anwendung** finden können.
Beim Deployment einer **FastAPI**-Anwendung, oder eigentlich jeder Art von Web-API, gibt es mehrere Konzepte, die Sie wahrscheinlich interessieren, und mithilfe derer Sie die **am besten geeignete** Methode zum **Deployment Ihrer Anwendung** finden können.
Einige wichtige Konzepte sind:
Einige wichtige Konzepte sind:
@ -59,7 +59,7 @@ Die nächsten zu berücksichtigenden Konzepte drehen sich dann um das Programm,
Wir werden viel über den laufenden „**Prozess**“ sprechen, daher ist es nützlich, Klarheit darüber zu haben, was das bedeutet und was der Unterschied zum Wort „**Programm**“ ist.
Wir werden viel über den laufenden „**Prozess**“ sprechen, daher ist es nützlich, Klarheit darüber zu haben, was das bedeutet und was der Unterschied zum Wort „**Programm**“ ist.
### Was ist ein Programm { #what-is-a-program }
### Was ein Programm ist { #what-is-a-program }
Das Wort **Programm** wird häufig zur Beschreibung vieler Dinge verwendet:
Das Wort **Programm** wird häufig zur Beschreibung vieler Dinge verwendet:
@ -67,14 +67,14 @@ Das Wort **Programm** wird häufig zur Beschreibung vieler Dinge verwendet:
* Die **Datei**, die vom Betriebssystem **ausgeführt** werden kann, zum Beispiel: `python`, `python.exe` oder `uvicorn`.
* Die **Datei**, die vom Betriebssystem **ausgeführt** werden kann, zum Beispiel: `python`, `python.exe` oder `uvicorn`.
* Ein bestimmtes Programm, während es auf dem Betriebssystem **läuft**, die CPU nutzt und Dinge im Arbeitsspeicher ablegt. Dies wird auch als **Prozess** bezeichnet.
* Ein bestimmtes Programm, während es auf dem Betriebssystem **läuft**, die CPU nutzt und Dinge im Arbeitsspeicher ablegt. Dies wird auch als **Prozess** bezeichnet.
### Was ist ein Prozess { #what-is-a-process }
### Was ein Prozess ist { #what-is-a-process }
Das Wort **Prozess** wird normalerweise spezifischer verwendet und bezieht sich nur auf das, was im Betriebssystem ausgeführt wird (wie im letzten Punkt oben):
Das Wort **Prozess** wird normalerweise spezifischer verwendet und bezieht sich nur auf das, was im Betriebssystem ausgeführt wird (wie im letzten Punkt oben):
* Ein bestimmtes Programm, während es auf dem Betriebssystem **ausgeführt** wird.
* Ein bestimmtes Programm, während es auf dem Betriebssystem **ausgeführt** wird.
* Dies bezieht sich weder auf die Datei noch auf den Code, sondern **speziell** auf das, was vom Betriebssystem **ausgeführt** und verwaltet wird.
* Dies bezieht sich weder auf die Datei noch auf den Code, sondern **speziell** auf das, was vom Betriebssystem **ausgeführt** und verwaltet wird.
* Jedes Programm, jeder Code **kann nur dann Dinge tun**, wenn er **ausgeführt** wird, wenn also ein **Prozess läuft**.
* Jedes Programm, jeder Code **kann nur dann Dinge tun**, wenn er **ausgeführt** wird. Also dann, wenn ein **Prozess läuft**.
* Der Prozess kann von Ihnen oder vom Betriebssystem **terminiert** („beendet“, „gekillt“) werden. An diesem Punkt hört es auf zu laufen/ausgeführt zu werden und kann **keine Dinge mehr tun**.
* Der Prozess kann von Ihnen oder vom Betriebssystem **terminiert** („beendet“, „gekillt“) werden. An diesem Punkt hört er auf zu laufen/ausgeführt zu werden und kann **keine Dinge mehr tun**.
* Hinter jeder Anwendung, die Sie auf Ihrem Computer ausführen, steckt ein Prozess, jedes laufende Programm, jedes Fenster usw. Und normalerweise laufen viele Prozesse **gleichzeitig**, während ein Computer eingeschaltet ist.
* Hinter jeder Anwendung, die Sie auf Ihrem Computer ausführen, steckt ein Prozess, jedes laufende Programm, jedes Fenster usw. Und normalerweise laufen viele Prozesse **gleichzeitig**, während ein Computer eingeschaltet ist.
* Es können **mehrere Prozesse** desselben **Programms** gleichzeitig ausgeführt werden.
* Es können **mehrere Prozesse** desselben **Programms** gleichzeitig ausgeführt werden.
@ -117,7 +117,7 @@ Einige Beispiele für Tools, die diese Aufgabe übernehmen können, sind:
* Docker
* Docker
* Kubernetes
* Kubernetes
* Docker Compose
* Docker Compose
* Docker im Schwarm-Modus
* Docker im Swarm-Modus
* Systemd
* Systemd
* Supervisor
* Supervisor
* Es wird intern von einem Cloudanbieter im Rahmen seiner Dienste verwaltet
* Es wird intern von einem Cloudanbieter im Rahmen seiner Dienste verwaltet
@ -137,7 +137,7 @@ Und wir als Entwickler verbessern den Code ständig, wenn wir diese Bugs finden
### Kleine Fehler automatisch handhaben { #small-errors-automatically-handled }
### Kleine Fehler automatisch handhaben { #small-errors-automatically-handled }
Wenn beim Erstellen von Web-APIs mit FastAPI ein Fehler in unserem Code auftritt, wird FastAPI ihn normalerweise dem einzelnen <abbrtitle="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr>zurückgeben, der den Fehler ausgelöst hat. 🛡
Wenn beim Erstellen von Web-APIs mit FastAPI ein Fehler in unserem Code auftritt, wird FastAPI ihn normalerweise auf den einzelnen <abbrtitle="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr>beschränken, der den Fehler ausgelöst hat. 🛡
Der Client erhält für diesen Request einen **500 Internal Server Error**, aber die Anwendung arbeitet bei den nächsten Requests weiter, anstatt einfach komplett abzustürzen.
Der Client erhält für diesen Request einen **500 Internal Server Error**, aber die Anwendung arbeitet bei den nächsten Requests weiter, anstatt einfach komplett abzustürzen.
@ -170,7 +170,7 @@ Dies könnte zum Beispiel erledigt werden durch:
* Docker
* Docker
* Kubernetes
* Kubernetes
* Docker Compose
* Docker Compose
* Docker im Schwarm-Modus
* Docker im Swarm-Modus
* Systemd
* Systemd
* Supervisor
* Supervisor
* Intern von einem Cloudanbieter im Rahmen seiner Dienste
* Intern von einem Cloudanbieter im Rahmen seiner Dienste
@ -178,7 +178,7 @@ Dies könnte zum Beispiel erledigt werden durch:
## Replikation – Prozesse und Arbeitsspeicher { #replication-processes-and-memory }
## Replikation – Prozesse und Arbeitsspeicher { #replication-processes-and-memory }
Wenn Sie eine FastAPI-Anwendung verwenden und ein Serverprogramm wie den `fastapi`-Befehl, der Uvicorn ausführt, kann **ein einzelner Prozess** an mehrere Clients gleichzeitig ausliefern.
Wenn Sie eine FastAPI-Anwendung verwenden und ein Serverprogramm wie den `fastapi`-Befehl, der Uvicorn ausführt, kann die Ausführung in **einem Prozess** mehrere Clients gleichzeitig versorgen.
In vielen Fällen möchten Sie jedoch mehrere Workerprozesse gleichzeitig ausführen.
In vielen Fällen möchten Sie jedoch mehrere Workerprozesse gleichzeitig ausführen.
@ -200,7 +200,7 @@ Um also **mehrere Prozesse** gleichzeitig zu haben, muss es einen **einzelnen Pr
Wenn das Programm nun Dinge in den Arbeitsspeicher lädt, zum Beispiel ein Modell für maschinelles Lernen in einer Variablen oder den Inhalt einer großen Datei in einer Variablen, verbraucht das alles **einen Teil des Arbeitsspeichers (RAM – Random Access Memory)** des Servers.
Wenn das Programm nun Dinge in den Arbeitsspeicher lädt, zum Beispiel ein Modell für maschinelles Lernen in einer Variablen oder den Inhalt einer großen Datei in einer Variablen, verbraucht das alles **einen Teil des Arbeitsspeichers (RAM – Random Access Memory)** des Servers.
Und mehrere Prozesse teilen sich normalerweise keinen Speicher. Das bedeutet, dass jeder laufende Prozess seine eigenen Dinge, eigenen Variablen und eigenen Speicher hat. Und wenn Sie in Ihrem Code viel Speicher verbrauchen, verbraucht **jeder Prozess** die gleiche Menge Speicher.
Und mehrere Prozesse **teilen sich normalerweise keinen Speicher**. Das bedeutet, dass jeder laufende Prozess seine eigenen Dinge, eigenen Variablen und eigenen Speicher hat. Und wenn Sie in Ihrem Code viel Speicher verbrauchen, verbraucht **jeder Prozess** die gleiche Menge Speicher.
Container (hauptsächlich Linux-Container) sind eine sehr **leichtgewichtige** Möglichkeit, Anwendungen einschließlich aller ihrer Abhängigkeiten und erforderlichen Dateien zu verpacken und sie gleichzeitig von anderen Containern (anderen Anwendungen oder Komponenten) im selben System isoliert zu halten.
Container (hauptsächlich Linux-Container) sind eine sehr **leichtgewichtige** Möglichkeit, Anwendungen einschließlich aller ihrer Abhängigkeiten und erforderlichen Dateien zu verpacken und sie gleichzeitig von anderen Containern (anderen Anwendungen oder Komponenten) im selben System isoliert zu halten.
Linux-Container werden mit demselben Linux-Kernel des Hosts (Maschine, virtuellen Maschine, Cloud-Servers, usw.) ausgeführt. Das bedeutet einfach, dass sie sehr leichtgewichtig sind (im Vergleich zu vollständigen virtuellen Maschinen, die ein gesamtes Betriebssystem emulieren).
Linux-Container werden mit demselben Linux-Kernel des Hosts (Maschine, virtueller Maschine, Cloud-Server usw.) ausgeführt. Das bedeutet einfach, dass sie sehr leichtgewichtig sind (im Vergleich zu vollständigen virtuellen Maschinen, die ein gesamtes Betriebssystem emulieren).
Auf diese Weise verbrauchen Container **wenig Ressourcen**, eine Menge vergleichbar mit der direkten Ausführung der Prozesse (eine virtuelle Maschine würde viel mehr verbrauchen).
Auf diese Weise verbrauchen Container **wenig Ressourcen**, eine Menge vergleichbar mit der direkten Ausführung der Prozesse (eine virtuelle Maschine würde viel mehr verbrauchen).
@ -46,7 +46,7 @@ Container verfügen außerdem über ihre eigenen **isoliert** laufenden Prozesse
Ein **Container** wird von einem **Containerimage** ausgeführt.
Ein **Container** wird von einem **Containerimage** ausgeführt.
Ein Containerimage ist eine **statische** Version aller Dateien, Umgebungsvariablen und des Standardbefehls/-programms, welche in einem Container vorhanden sein sollten. **Statisch** bedeutet hier, dass das Container-**Image** nicht läuft, nicht ausgeführt wird, sondern nur die gepackten Dateien und Metadaten enthält.
Ein Containerimage ist eine **statische** Version aller Dateien, Umgebungsvariablen und des Standardbefehls/-programms, die in einem Container vorhanden sein sollten. **Statisch** bedeutet hier, dass das Container-**Image** nicht läuft, nicht ausgeführt wird, sondern nur die gepackten Dateien und Metadaten enthält.
Im Gegensatz zu einem „**Containerimage**“, bei dem es sich um den gespeicherten statischen Inhalt handelt, bezieht sich ein „**Container**“ normalerweise auf die laufende Instanz, das Ding, das **ausgeführt** wird.
Im Gegensatz zu einem „**Containerimage**“, bei dem es sich um den gespeicherten statischen Inhalt handelt, bezieht sich ein „**Container**“ normalerweise auf die laufende Instanz, das Ding, das **ausgeführt** wird.
@ -89,7 +89,7 @@ Ein Container läuft, solange der **Hauptprozess** (Befehl oder Programm) läuft
Ein Container hat normalerweise einen **einzelnen Prozess**, aber es ist auch möglich, Unterprozesse vom Hauptprozess aus zu starten, und auf diese Weise haben Sie **mehrere Prozesse** im selben Container.
Ein Container hat normalerweise einen **einzelnen Prozess**, aber es ist auch möglich, Unterprozesse vom Hauptprozess aus zu starten, und auf diese Weise haben Sie **mehrere Prozesse** im selben Container.
Es ist jedoch nicht möglich, einen laufenden Container, ohne **mindestens einen laufenden Prozess** zu haben. Wenn der Hauptprozess stoppt, stoppt der Container.
Es ist jedoch nicht möglich, einen laufenden Container ohne **mindestens einen laufenden Prozess** zu haben. Wenn der Hauptprozess stoppt, stoppt der Container.
## Ein Docker-Image für FastAPI erstellen { #build-a-docker-image-for-fastapi }
## Ein Docker-Image für FastAPI erstellen { #build-a-docker-image-for-fastapi }
1. Beginnen Sie mit dem offiziellen Python-Basisimage.
2. Setze das aktuelle Arbeitsverzeichnis auf `/code`.
2. Setzen Sie das aktuelle Arbeitsverzeichnis auf `/code`.
Hier platzieren wir die Datei `requirements.txt` und das Verzeichnis `app`.
Hier platzieren wir die Datei `requirements.txt` und das Verzeichnis `app`.
3. Kopiere die Datei mit den Paketanforderungen in das Verzeichnis `/code`.
3. Kopieren Sie die Datei mit den Paketanforderungen in das Verzeichnis `/code`.
Kopieren Sie zuerst **nur** die Datei mit den Anforderungen, nicht den Rest des Codes.
Kopieren Sie zuerst **nur** die Datei mit den Anforderungen, nicht den Rest des Codes.
Da sich diese Datei **nicht oft ändert**, erkennt Docker das und verwendet den **Cache** für diesen Schritt, wodurch der Cache auch für den nächsten Schritt aktiviert wird.
Da sich diese Datei **nicht oft ändert**, erkennt Docker das und verwendet den **Cache** für diesen Schritt, wodurch der Cache auch für den nächsten Schritt aktiviert wird.
4. Installiere die Paketabhängigkeiten aus der Anforderungsdatei.
4. Installieren Sie die Paketabhängigkeiten aus der Anforderungsdatei.
Die Option `--no-cache-dir` weist `pip` an, die heruntergeladenen Pakete nicht lokal zu speichern, da dies nur benötigt wird, sollte `pip` erneut ausgeführt werden, um dieselben Pakete zu installieren, aber das ist beim Arbeiten mit Containern nicht der Fall.
Die Option `--no-cache-dir` weist `pip` an, die heruntergeladenen Pakete nicht lokal zu speichern, da dies nur benötigt wird, sollte `pip` erneut ausgeführt werden, um dieselben Pakete zu installieren, aber das ist beim Arbeiten mit Containern nicht der Fall.
Durch die Verwendung des Caches in diesem Schritt **sparen** Sie viel **Zeit**, wenn Sie das Image während der Entwicklung immer wieder erstellen, anstatt **jedes Mal** alle Abhängigkeiten **herunterzuladen und zu installieren**.
Durch die Verwendung des Caches in diesem Schritt **sparen** Sie viel **Zeit**, wenn Sie das Image während der Entwicklung immer wieder erstellen, anstatt **jedes Mal** alle Abhängigkeiten **herunterzuladen und zu installieren**.
5. Kopiere das Verzeichnis `./app` in das Verzeichnis `/code`.
5. Kopieren Sie das Verzeichnis `./app` in das Verzeichnis `/code`.
Da hier der gesamte Code enthalten ist, der sich **am häufigsten ändert**, wird der Docker-**Cache** nicht ohne weiteres für diesen oder andere **folgende Schritte** verwendet.
Da hier der gesamte Code enthalten ist, der sich **am häufigsten ändert**, wird der Docker-**Cache** nicht ohne weiteres für diesen oder andere **folgende Schritte** verwendet.
Daher ist es wichtig, dies **nahe dem Ende** des `Dockerfile`s zu platzieren, um die Erstellungszeiten des Containerimages zu optimieren.
Daher ist es wichtig, dies **nahe dem Ende** des `Dockerfile`s zu platzieren, um die Erstellungszeiten des Containerimages zu optimieren.
6. Lege den **Befehl** fest, um `fastapi run` zu nutzen, welches Uvicorn darunter verwendet.
6. Legen Sie den **Befehl** fest, um `fastapi run` zu nutzen, welches Uvicorn darunter verwendet.
`CMD` nimmt eine Liste von Zeichenfolgen entgegen. Jede dieser Zeichenfolgen entspricht dem, was Sie durch Leerzeichen getrennt in die Befehlszeile eingeben würden.
`CMD` nimmt eine Liste von Zeichenfolgen entgegen. Jede dieser Zeichenfolgen entspricht dem, was Sie durch Leerzeichen getrennt in die Befehlszeile eingeben würden.
@ -405,7 +405,7 @@ COPY ./main.py /code/
CMD ["fastapi", "run", "main.py", "--port", "80"]
CMD ["fastapi", "run", "main.py", "--port", "80"]
```
```
1. Kopiere die Datei `main.py` direkt in das Verzeichnis `/code` (ohne ein Verzeichnis `./app`).
1. Kopieren Sie die Datei `main.py` direkt in das Verzeichnis `/code` (ohne ein Verzeichnis `./app`).
2. Verwenden Sie `fastapi run`, um Ihre Anwendung in der einzelnen Datei `main.py` bereitzustellen.
2. Verwenden Sie `fastapi run`, um Ihre Anwendung in der einzelnen Datei `main.py` bereitzustellen.
@ -440,7 +440,7 @@ Traefik verfügt über Integrationen mit Docker, Kubernetes und anderen, sodass
///
///
Alternativ könnte HTTPS von einem Cloud-Anbieter als einer seiner Dienste gehandhabt werden (während die Anwendung weiterhin in einem Container ausgeführt wird).
Alternativ könnte HTTPS von einem Cloudanbieter als einer seiner Dienste gehandhabt werden (während die Anwendung weiterhin in einem Container ausgeführt wird).
## Beim Hochfahren ausführen und Neustarts { #running-on-startup-and-restarts }
## Beim Hochfahren ausführen und Neustarts { #running-on-startup-and-restarts }
@ -488,7 +488,7 @@ Und normalerweise wäre dieser **Load Balancer** in der Lage, Requests zu verarb
In einem solchen Szenario möchten Sie wahrscheinlich **einen einzelnen (Uvicorn-)Prozess pro Container** haben, da Sie die Replikation bereits auf Cluster-Ebene durchführen würden.
In einem solchen Szenario möchten Sie wahrscheinlich **einen einzelnen (Uvicorn-)Prozess pro Container** haben, da Sie die Replikation bereits auf Cluster-Ebene durchführen würden.
In diesem Fall möchten Sie also **nicht** mehrere Worker im Container haben, z. B. mit der `--workers`Befehlszeilenoption. Sie möchten nur einen **einzelnen Uvicorn-Prozess** pro Container haben (wahrscheinlich aber mehrere Container).
In diesem Fall möchten Sie also **nicht** mehrere Worker im Container haben, z. B. mit der `--workers`-Befehlszeilenoption. Sie möchten nur einen **einzelnen Uvicorn-Prozess** pro Container haben (wahrscheinlich aber mehrere Container).
Ein weiterer Prozessmanager im Container (wie es bei mehreren Workern der Fall wäre) würde nur **unnötige Komplexität** hinzufügen, um welche Sie sich höchstwahrscheinlich bereits mit Ihrem Clustersystem kümmern.
Ein weiterer Prozessmanager im Container (wie es bei mehreren Workern der Fall wäre) würde nur **unnötige Komplexität** hinzufügen, um welche Sie sich höchstwahrscheinlich bereits mit Ihrem Clustersystem kümmern.
@ -496,7 +496,7 @@ Ein weiterer Prozessmanager im Container (wie es bei mehreren Workern der Fall w
Natürlich gibt es **Sonderfälle**, in denen Sie **einen Container** mit mehreren **Uvicorn-Workerprozessen** haben möchten.
Natürlich gibt es **Sonderfälle**, in denen Sie **einen Container** mit mehreren **Uvicorn-Workerprozessen** haben möchten.
In diesen Fällen können Sie die `--workers`Befehlszeilenoption verwenden, um die Anzahl der zu startenden Worker festzulegen:
In diesen Fällen können Sie die `--workers`-Befehlszeilenoption verwenden, um die Anzahl der zu startenden Worker festzulegen:
1. Hier verwenden wir die `--workers`Befehlszeilenoption, um die Anzahl der Worker auf 4 festzulegen.
1. Hier verwenden wir die `--workers`-Befehlszeilenoption, um die Anzahl der Worker auf 4 festzulegen.
Hier sind einige Beispiele, wann das sinnvoll sein könnte:
Hier sind einige Beispiele, wann das sinnvoll sein könnte:
@ -529,7 +529,7 @@ Dann möchten Sie vielleicht **einen einzelnen Container** mit einem **Prozessma
---
---
Der Hauptpunkt ist, dass **keine** dieser Regeln **in Stein gemeißelt** ist, der man blind folgen muss. Sie können diese Ideen verwenden, um **Ihren eigenen Anwendungsfall zu evaluieren**, zu entscheiden, welcher Ansatz für Ihr System am besten geeignet ist und herauszufinden, wie Sie folgende Konzepte verwalten:
Der Hauptpunkt ist, dass **keine** dieser Regeln **in Stein gemeißelt** ist, der man blind folgen muss. Sie können diese Ideen verwenden, um **I Ihren eigenen Anwendungsfall zu evaluieren**, zu entscheiden, welcher Ansatz für Ihr System am besten geeignet ist und herauszufinden, wie Sie folgende Konzepte verwalten:
* Sicherheit – HTTPS
* Sicherheit – HTTPS
* Beim Hochfahren ausführen
* Beim Hochfahren ausführen
@ -576,7 +576,7 @@ Sie sollten wahrscheinlich **nicht** dieses Basis-Docker-Image (oder ein anderes
Wenn Sie **Kubernetes** (oder andere) verwenden und bereits **Replikation** auf Cluster-Ebene mit mehreren **Containern** eingerichtet haben. In diesen Fällen ist es besser, **ein Image von Grund auf neu zu erstellen**, wie oben beschrieben: [Ein Docker-Image für FastAPI erstellen](#build-a-docker-image-for-fastapi).
Wenn Sie **Kubernetes** (oder andere) verwenden und bereits **Replikation** auf Cluster-Ebene mit mehreren **Containern** eingerichtet haben. In diesen Fällen ist es besser, **ein Image von Grund auf neu zu erstellen**, wie oben beschrieben: [Ein Docker-Image für FastAPI erstellen](#build-a-docker-image-for-fastapi).
Und wenn Sie mehrere Worker benötigen, können Sie einfach die `--workers`Befehlszeilenoption verwenden.
Und wenn Sie mehrere Worker benötigen, können Sie einfach die `--workers`-Befehlszeilenoption verwenden.
@ -21,10 +21,10 @@ Aus **Sicht des Entwicklers** sollten Sie beim Nachdenken über HTTPS Folgendes
* Und dann müssen sie vom Dritten **erneuert**, **erneut erworben** werden.
* Und dann müssen sie vom Dritten **erneuert**, **erneut erworben** werden.
* Die Verschlüsselung der Verbindung erfolgt auf **TCP-Ebene**.
* Die Verschlüsselung der Verbindung erfolgt auf **TCP-Ebene**.
* Das ist eine Schicht **unter HTTP**.
* Das ist eine Schicht **unter HTTP**.
* Die Handhabung von **Zertifikaten und Verschlüsselung** erfolgt also **vor HTTP**.
* Die **Zertifikats- und Verschlüsselungs**-Handhabung erfolgt also **vor HTTP**.
* **TCP weiß nichts über „Domains“**. Nur über IP-Adressen.
* **TCP weiß nichts über „Domains“**. Nur über IP-Adressen.
* Die Informationen über die angeforderte **spezifische Domain** befinden sich in den **HTTP-Daten**.
* Die Informationen über die angeforderte **spezifische Domain** befinden sich in den **HTTP-Daten**.
* Die **HTTPS-Zertifikate** „zertifizieren“ eine **bestimmte Domain**, aber das Protokoll und die Verschlüsselung erfolgen auf TCP-Ebene, **ohne zu wissen**, um welche Domain es sich handelt.
* Die **HTTPS-Zertifikate** „zertifizieren“ eine **bestimmte Domain**, aber das Protokoll und die Verschlüsselung erfolgen auf TCP-Ebene, **bevor bekannt ist**, um welche Domain es sich handelt.
* **Standardmäßig** bedeutet das, dass Sie nur **ein HTTPS-Zertifikat pro IP-Adresse** haben können.
* **Standardmäßig** bedeutet das, dass Sie nur **ein HTTPS-Zertifikat pro IP-Adresse** haben können.
* Ganz gleich, wie groß Ihr Server ist oder wie klein die einzelnen Anwendungen darauf sind.
* Ganz gleich, wie groß Ihr Server ist oder wie klein die einzelnen Anwendungen darauf sind.
* Hierfür gibt es jedoch eine **Lösung**.
* Hierfür gibt es jedoch eine **Lösung**.
@ -194,7 +194,7 @@ Dieser ganze Erneuerungsprozess, während die Anwendung weiterhin bereitgestellt
Wenn Sie einen Proxy zur Verarbeitung von HTTPS verwenden, weiß Ihr **Anwendungsserver** (z. B. Uvicorn über das FastAPI CLI) nichts über den HTTPS-Prozess, er kommuniziert per einfachem HTTP mit dem **TLS-Terminierungsproxy**.
Wenn Sie einen Proxy zur Verarbeitung von HTTPS verwenden, weiß Ihr **Anwendungsserver** (z. B. Uvicorn über das FastAPI CLI) nichts über den HTTPS-Prozess, er kommuniziert per einfachem HTTP mit dem **TLS-Terminierungsproxy**.
Dieser **Proxy** würde normalerweise unmittelbar vor dem Übermitteln der Anfrage an den **Anwendungsserver** einige HTTP-Header dynamisch setzen, um dem Anwendungsserver mitzuteilen, dass der Request vom Proxy **weitergeleitet** wird.
Dieser **Proxy** würde normalerweise unmittelbar vor dem Übermitteln des Requests an den **Anwendungsserver** einige HTTP-Header dynamisch setzen, um dem Anwendungsserver mitzuteilen, dass der Request vom Proxy **weitergeleitet** wird.
@ -55,7 +55,7 @@ Es gibt mehrere Alternativen, einschließlich:
* [Uvicorn](https://www.uvicorn.dev/): ein hochperformanter ASGI-Server.
* [Uvicorn](https://www.uvicorn.dev/): ein hochperformanter ASGI-Server.
* [Hypercorn](https://hypercorn.readthedocs.io/): ein ASGI-Server, der unter anderem kompatibel mit HTTP/2 und Trio ist.
* [Hypercorn](https://hypercorn.readthedocs.io/): ein ASGI-Server, der unter anderem kompatibel mit HTTP/2 und Trio ist.
* [Daphne](https://github.com/django/daphne): der für Django Channels entwickelte ASGI-Server.
* [Daphne](https://github.com/django/daphne): der für Django Channels entwickelte ASGI-Server.
* [Granian](https://github.com/emmett-framework/granian): Ein RustHTTP-Server für Python-Anwendungen.
* [Granian](https://github.com/emmett-framework/granian): Ein Rust-HTTP-Server für Python-Anwendungen.
## Servermaschine und Serverprogramm { #server-machine-and-server-program }
## Servermaschine und Serverprogramm { #server-machine-and-server-program }
@ -65,11 +65,11 @@ Das Wort „**Server**“ wird häufig verwendet, um sowohl den entfernten/Cloud
Denken Sie einfach daran, dass sich „Server“ im Allgemeinen auf eines dieser beiden Dinge beziehen kann.
Denken Sie einfach daran, dass sich „Server“ im Allgemeinen auf eines dieser beiden Dinge beziehen kann.
Wenn man sich auf die entfernte Maschine bezieht, wird sie üblicherweise als **Server**, aber auch als **Maschine**, **VM** (virtuelle Maschine) oder **Knoten** bezeichnet. Diese Begriffe beziehen sich auf irgendeine Art von entfernten Rechner, normalerweise unter Linux, auf dem Sie Programme ausführen.
Wenn man sich auf die entfernte Maschine bezieht, wird sie üblicherweise als **Server**, aber auch als **Maschine**, **VM** (virtuelle Maschine) oder **Knoten** bezeichnet. Diese Begriffe beziehen sich auf irgendeine Art von entferntem Rechner, normalerweise unter Linux, auf dem Sie Programme ausführen.
## Das Serverprogramm installieren { #install-the-server-program }
## Das Serverprogramm installieren { #install-the-server-program }
Wenn Sie FastAPI installieren, wird es mit einem Produktionsserver, Uvicorn, geliefert, und Sie können ihn mit dem `fastapi run`Befehl starten.
Wenn Sie FastAPI installieren, wird es mit einem Produktionsserver, Uvicorn, geliefert, und Sie können ihn mit dem `fastapi run`-Befehl starten.
Aber Sie können auch ein ASGI-Serverprogramm manuell installieren.
Aber Sie können auch ein ASGI-Serverprogramm manuell installieren.
Die offizielle [FastAPI-Erweiterung](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) verbessert Ihren FastAPI-Entwicklungsworkflow mit Pfadoperation-Erkennung und -Navigation sowie FastAPI-Cloud-Deployment und Live-Logstreaming.
Die offizielle [FastAPI-Erweiterung](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) verbessert Ihren FastAPI-Entwicklungsworkflow mit *Pfadoperation*-Erkennung und -Navigation sowie FastAPI-Cloud-Deployment und Live-Logstreaming.
Weitere Details zur Erweiterung finden Sie im README im [GitHub-Repository](https://github.com/fastapi/fastapi-vscode).
Weitere Details zur Erweiterung finden Sie im README im [GitHub-Repository](https://github.com/fastapi/fastapi-vscode).
@ -14,10 +14,10 @@ Standardmäßig erkennt die Erweiterung FastAPI-Anwendungen in Ihrem Workspace a
## Funktionen { #features }
## Funktionen { #features }
- Pfadoperation-Explorer – Eine Baumansicht in der Seitenleiste aller <dfntitle="Routen, Endpunkte">*Pfadoperationen*</dfn> in Ihrer Anwendung. Klicken Sie, um zu einer beliebigen Route- oder Router-Definition zu springen.
- **Pfadoperation-Explorer** – Eine Baumansicht in der Seitenleiste aller <dfntitle="Routen, Endpunkte">*Pfadoperationen*</dfn> in Ihrer Anwendung. Klicken Sie, um zu einer beliebigen Route- oder Router-Definition zu springen.
- Routensuche – Suchen Sie nach Pfad, Methode oder Namen mit <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>E</kbd> (unter macOS: <kbd>Cmd</kbd> + <kbd>Shift</kbd> + <kbd>E</kbd>).
- **Routensuche** – Suchen Sie nach Pfad, Methode oder Namen mit <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>E</kbd> (unter macOS: <kbd>Cmd</kbd> + <kbd>Shift</kbd> + <kbd>E</kbd>).
- CodeLens-Navigation – Anklickbare Links oberhalb von Testclient-Aufrufen (z. B. `client.get('/items')`), die zur passenden Pfadoperation springen und so eine schnelle Navigation zwischen Tests und Implementierung ermöglichen.
- **CodeLens-Navigation** – Anklickbare Links oberhalb von Testclient-Aufrufen (z. B. `client.get('/items')`), die zur passenden *Pfadoperation* springen und so eine schnelle Navigation zwischen Tests und Implementierung ermöglichen.
- Zu FastAPI Cloud deployen – Deployment Ihrer App mit einem Klick auf [FastAPI Cloud](https://fastapicloud.com/).
- **Zu FastAPI Cloud deployen** – Deployment Ihrer App mit einem Klick auf [FastAPI Cloud](https://fastapicloud.com/).
- Anwendungslogs streamen – Echtzeit-Logstreaming Ihrer auf FastAPI Cloud deployten Anwendung mit Loglevel-Filterung und Textsuche.
- **Anwendungslogs streamen** – Echtzeit-Logstreaming Ihrer auf FastAPI Cloud deployten Anwendung mit Loglevel-Filterung und Textsuche.
Wenn Sie sich mit den Funktionen der Erweiterung vertraut machen möchten, können Sie den Erweiterungs‑Walkthrough aufrufen, indem Sie die Befehlspalette öffnen (<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> oder unter macOS: <kbd>Cmd</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd>) und „Welcome: Open walkthrough …“ auswählen und anschließend den Walkthrough „Get started with FastAPI“ wählen.
Wenn Sie sich mit den Funktionen der Erweiterung vertraut machen möchten, können Sie den Erweiterungs‑Walkthrough aufrufen, indem Sie die Befehlspalette öffnen (<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> oder unter macOS: <kbd>Cmd</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd>) und „Welcome: Open walkthrough ...“ auswählen und anschließend den Walkthrough „Get started with FastAPI“ wählen.
### Basiert auf offenen Standards { #based-on-open-standards }
### Auf offenen Standards basieren { #based-on-open-standards }
* [**OpenAPI**](https://github.com/OAI/OpenAPI-Specification) für die Erstellung von APIs, inklusive Deklarationen von <dfntitle="auch bekannt als: Endpunkte, Routen">Pfad</dfn>-<dfntitle="auch bekannt als HTTP-Methoden, wie POST, GET, PUT, DELETE">Operationen</dfn>, Parametern, <abbrtitle="Requestbody">Requestbodys</abbr>, Sicherheit, usw.
* [**OpenAPI**](https://github.com/OAI/OpenAPI-Specification) für die Erstellung von APIs, inklusive Deklarationen von <dfntitle="auch bekannt als: Endpunkte, Routen">Pfad</dfn>-<dfntitle="auch bekannt als HTTP-Methoden, wie POST, GET, PUT, DELETE">Operationen</dfn>, Parametern, <abbrtitle="Requestbody">Requestbodys</abbr>, Sicherheit, usw.
* Automatische Dokumentation der Datenmodelle mit [**JSON Schema**](https://json-schema.org/) (da OpenAPI selbst auf JSON Schema basiert).
* Automatische Dokumentation der Datenmodelle mit [**JSON Schema**](https://json-schema.org/) (da OpenAPI selbst auf JSON Schema basiert).
@ -15,7 +15,7 @@
Interaktive API-Dokumentation und erkundbare Web-Benutzeroberflächen. Da das Framework auf OpenAPI basiert, gibt es mehrere Optionen, zwei sind standardmäßig vorhanden.
Interaktive API-Dokumentation und erkundbare Web-Benutzeroberflächen. Da das Framework auf OpenAPI basiert, gibt es mehrere Optionen, zwei sind standardmäßig vorhanden.
* [**Swagger UI**](https://github.com/swagger-api/swagger-ui), bietet interaktive Erkundung, testen und rufen Sie Ihre API direkt im Webbrowser auf.
* [**Swagger UI**](https://github.com/swagger-api/swagger-ui), mit interaktiver Erkundung, rufen Sie Ihre API direkt vom Browser aus auf und testen Sie sie.
# und bekommen Sie Editor-Unterstützung innerhalb der Funktion
# und bekommen Sie Editor-Unterstützung innerhalb der Funktion
def main(user_id: str):
def main(user_id: str):
return user_id
return user_id
@ -67,11 +67,11 @@ my_second_user: User = User(**second_user_data)
`**second_user_data` bedeutet:
`**second_user_data` bedeutet:
Nimm die Schlüssel-Wert-Paare des `second_user_data`<abbrtitle="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">Dicts</abbr>und übergebe sie direkt als Schlüsselwort-Argumente. Äquivalent zu: `User(id=4, name="Mary", joined="2018-11-30")`
Übergeben Sie die Schlüssel und Werte des `second_user_data`<abbrtitle="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">Dicts</abbr>direkt als Schlüssel-Wert-Argumente, äquivalent zu: `User(id=4, name="Mary", joined="2018-11-30")`
///
///
### Editor Unterstützung { #editor-support }
### Editorunterstützung { #editor-support }
Das ganze Framework wurde so entworfen, dass es einfach und intuitiv zu benutzen ist; alle Entscheidungen wurden auf mehreren Editoren getestet, sogar vor der Implementierung, um die bestmögliche Entwicklererfahrung zu gewährleisten.
Das ganze Framework wurde so entworfen, dass es einfach und intuitiv zu benutzen ist; alle Entscheidungen wurden auf mehreren Editoren getestet, sogar vor der Implementierung, um die bestmögliche Entwicklererfahrung zu gewährleisten.
@ -85,31 +85,31 @@ So kann Ihr Editor Sie unterstützen:
* in [Visual Studio Code](https://code.visualstudio.com/):
* in [Visual Studio Code](https://code.visualstudio.com/):
Sie bekommen sogar Autovervollständigung an Stellen, an denen Sie dies vorher nicht für möglich gehalten hätten. Zum Beispiel der `price` Schlüssel in einem JSON Datensatz (dieser könnte auch verschachtelt sein), der aus einem Request kommt.
Sie bekommen sogar Autovervollständigung an Stellen, an denen Sie dies vorher nicht für möglich gehalten hätten. Zum Beispiel der `price`-Schlüssel innerhalb eines JSON-Bodys (dieser könnte auch verschachtelt sein), der aus einem Request kommt.
Nie wieder falsche Schlüsselnamen tippen, Hin und Herhüpfen zwischen der Dokumentation, Hoch- und Runterscrollen, um herauszufinden, ob es `username` oder `user_name` war.
Nie wieder falsche Schlüsselnamen tippen, Hin und Herhüpfen zwischen der Dokumentation, Hoch- und Runterscrollen, um herauszufinden, ob es `username` oder `user_name` war.
### Kompakt { #short }
### Kompakt { #short }
Es gibt für alles sensible **Defaultwerte**, mit optionaler Konfiguration überall. Alle Parameter können feinjustiert werden, damit sie tun, was Sie benötigen, und die API definieren, die Sie brauchen.
Es gibt für alles sinnvolle **Defaultwerte**, mit optionaler Konfiguration überall. Alle Parameter können feinjustiert werden, damit sie tun, was Sie benötigen, und die API definieren, die Sie brauchen.
Aber standardmäßig **„funktioniert einfach alles“**.
Aber standardmäßig **„funktioniert einfach alles“**.
### Validierung { #validation }
### Validierung { #validation }
* Validierung für die meisten (oder alle?) Python-**Datentypen**, hierzu gehören:
* Validierung für die meisten (oder alle?) Python-**Datentypen**, hierzu gehören:
* JSONObjekte (`dict`).
* JSON-Objekte (`dict`).
* JSON Listen (`list`), die den Typ ihrer Elemente definieren.
* JSON-Array (`list`), das Elementtypen definiert.
* Strings (`str`) mit definierter minimaler und maximaler Länge.
* String-Felder (`str`) mit definierter minimaler und maximaler Länge.
* Zahlen (`int`, `float`) mit Mindest- und Maximalwerten, usw.
* Zahlen (`int`, `float`) mit Mindest- und Maximalwerten, usw.
* Validierung für mehr exotische Typen, wie:
* Validierung für exotischere Typen, wie:
* URL.
* URL.
* E-Mail.
* E-Mail.
* UUID.
* UUID.
@ -124,42 +124,42 @@ Sicherheit und Authentifizierung sind integriert. Ohne Kompromisse bei Datenbank
Alle in OpenAPI definierten Sicherheitsschemas, inklusive:
Alle in OpenAPI definierten Sicherheitsschemas, inklusive:
* HTTP Basic.
* HTTP Basic.
* **OAuth2** (auch mit **JWTTokens**). Siehe dazu das Tutorial zu [OAuth2 mit JWT](tutorial/security/oauth2-jwt.md).
* **OAuth2** (auch mit **JWT-Tokens**). Siehe dazu das Tutorial zu [OAuth2 mit JWT](tutorial/security/oauth2-jwt.md).
* APISchlüssel in:
* API-Schlüssel in:
* Headern.
* Headern.
* Query-Parametern.
* Query-Parametern.
* Cookies, usw.
* Cookies, usw.
Zusätzlich alle Sicherheitsfunktionen von Starlette (inklusive **SessionCookies**).
Zusätzlich alle Sicherheitsfunktionen von Starlette (inklusive **Session-Cookies**).
Alles als wiederverwendbare Tools und Komponenten gebaut, die einfach in Ihre Systeme, Datenspeicher, relationale und nicht-relationale Datenbanken, usw., integriert werden können.
Alles als wiederverwendbare Tools und Komponenten gebaut, die einfach in Ihre Systeme, Datenspeicher, relationale und NoSQL-Datenbanken, usw., integriert werden können.
FastAPI enthält ein extrem einfach zu verwendendes, aber extrem mächtiges <dfntitle='auch bekannt als: "Komponenten", "Ressourcen", "Dienste", "Dienstanbieter"'><strong>Dependency Injection</strong></dfn>System.
FastAPI enthält ein extrem einfach zu verwendendes, aber extrem mächtiges <dfntitle='auch bekannt als „Komponenten“, „Ressourcen“, „Dienste“, „Anbieter“'><strong>Dependency Injection</strong></dfn>-System.
* Selbst Abhängigkeiten können Abhängigkeiten haben, woraus eine Hierarchie oder ein **„Graph“ von Abhängigkeiten** entsteht.
* Selbst Abhängigkeiten können Abhängigkeiten haben, woraus eine Hierarchie oder ein **„Graph“ von Abhängigkeiten** entsteht.
* Alles **automatisch gehandhabt** durch das Framework.
* Alles **automatisch gehandhabt** durch das Framework.
* Alle Abhängigkeiten können Daten von Requests anfordern und das Verhalten von **Pfadoperationen** und der automatisierten Dokumentation **modifizieren**.
* Alle Abhängigkeiten können Daten von Requests anfordern und die Einschränkungen der **Pfadoperationen** sowie die automatische Dokumentation **erweitern**.
* **Automatische Validierung** selbst für solche Parameter von *Pfadoperationen*, welche in Abhängigkeiten definiert sind.
* **Automatische Validierung** selbst für solche Parameter von *Pfadoperationen*, welche in Abhängigkeiten definiert sind.
* Unterstützung für komplexe Authentifizierungssysteme, **Datenbankverbindungen**, usw.
* Unterstützung für komplexe Benutzerauthentifizierungssysteme, **Datenbankverbindungen**, usw.
* **Keine Kompromisse** bei Datenbanken, Frontends, usw., sondern einfache Integration mit allen.
* **Keine Kompromisse** bei Datenbanken, Frontends, usw., sondern einfache Integration mit allen.
Oder mit anderen Worten, sie werden nicht benötigt. Importieren und nutzen Sie den Code, den Sie brauchen.
Oder mit anderen Worten, sie werden nicht benötigt. Importieren und nutzen Sie den Code, den Sie brauchen.
Jede Integration wurde so entworfen, dass sie so einfach zu nutzen ist (mit Abhängigkeiten), dass Sie eine Erweiterung für Ihre Anwendung mit nur zwei Zeilen Code erstellen können. Hierbei nutzen Sie die gleiche Struktur und Syntax, wie bei *Pfadoperationen*.
Jede Integration wurde so entworfen, dass sie so einfach zu nutzen ist (mit Abhängigkeiten), dass Sie ein „Plug-in“ für Ihre Anwendung mit nur 2 Zeilen Code erstellen können. Hierbei nutzen Sie die gleiche Struktur und Syntax, wie bei *Pfadoperationen*.
### Getestet { #tested }
### Getestet { #tested }
* 100 % <dfntitle="Der Prozentsatz an Code, der automatisch getestet wird">Testabdeckung</dfn>.
* 100 % <dfntitle="Der Prozentsatz an Code, der automatisch getestet wird">Testabdeckung</dfn>.
* 100 % <dfntitle="Python-Typannotationen, mit denen Ihr Editor und andere externe Werkzeuge Sie besser unterstützen können">Typen annotiert</dfn>.
* Zu 100 % <dfntitle="Python-Typannotationen, mit denen Ihr Editor und andere externe Werkzeuge Sie besser unterstützen können">typannotierte</dfn> Codebasis.
* Verwendet in Produktionsanwendungen.
* Verwendet in Produktionsanwendungen.
## StarletteMerkmale { #starlette-features }
## Starlette-Merkmale { #starlette-features }
**FastAPI** ist vollkommen kompatibel (und basiert auf) [**Starlette**](https://www.starlette.dev/). Das bedeutet, wenn Sie eigenen Starlette Quellcode haben, funktioniert der.
**FastAPI** ist vollkommen kompatibel (und basiert auf) [**Starlette**](https://www.starlette.dev/). Das bedeutet, wenn Sie eigenen Starlette-Quellcode haben, funktioniert dieser auch.
`FastAPI` ist tatsächlich eine Unterklasse von `Starlette`. Wenn Sie also bereits Starlette kennen oder benutzen, das meiste funktioniert genau so.
`FastAPI` ist tatsächlich eine Unterklasse von `Starlette`. Wenn Sie also bereits Starlette kennen oder benutzen, das meiste funktioniert genau so.
@ -173,11 +173,11 @@ Mit **FastAPI** bekommen Sie alles von **Starlette** (da FastAPI nur Starlette a
**FastAPI** ist vollkommen kompatibel (und basiert auf) [**Pydantic**](https://docs.pydantic.dev/). Das bedeutet, wenn Sie eigenen Pydantic Quellcode haben, funktioniert der.
**FastAPI** ist vollkommen kompatibel (und basiert auf) [**Pydantic**](https://docs.pydantic.dev/). Das bedeutet, wenn Sie eigenen Pydantic-Quellcode haben, funktioniert dieser auch.
Inklusive externer Bibliotheken, die auf Pydantic basieren, wie <abbrtitle="Object-Relational Mapper - Objektrelationaler Mapper">ORM</abbr>s, <abbrtitle="Object-Document Mapper - Objekt-Dokument-Mapper">ODM</abbr>s für Datenbanken.
Inklusive externer Bibliotheken, die auf Pydantic basieren, wie <abbrtitle="Object-Relational Mapper - Objektrelationaler Mapper">ORM</abbr>s, <abbrtitle="Object-Document Mapper - Objekt-Dokument-Mapper">ODM</abbr>s für Datenbanken.
@ -188,14 +188,14 @@ Das gleiche gilt auch für die andere Richtung: Sie können in vielen Fällen da
Mit **FastAPI** bekommen Sie alle Funktionen von **Pydantic** (da FastAPI für die gesamte Datenverarbeitung Pydantic nutzt):
Mit **FastAPI** bekommen Sie alle Funktionen von **Pydantic** (da FastAPI für die gesamte Datenverarbeitung Pydantic nutzt):
* **Kein Kopfzerbrechen**:
* **Kein Kopfzerbrechen**:
* Keine neue Schemadefinition-Mikrosprache zu lernen.
* Keine neue Schemadefinitions-Mikrosprache zu lernen.
* Wenn Sie Pythons Typen kennen, wissen Sie, wie man Pydantic verwendet.
* Wenn Sie Pythons Typen kennen, wissen Sie, wie man Pydantic verwendet.
* Gutes Zusammenspiel mit Ihrer/Ihrem **<abbrtitle="Integrated Development Environment - Integrierte Entwicklungsumgebung: Ähnlich einem Code-Editor">IDE</abbr>/<dfntitle="Ein Programm, das Fehler im Quellcode sucht">Linter</dfn>/Gehirn**:
* Gutes Zusammenspiel mit Ihrer/Ihrem **<abbrtitle="Integrated Development Environment - Integrierte Entwicklungsumgebung: Ähnlich einem Code-Editor">IDE</abbr>/<dfntitle="Ein Programm, das Fehler im Quellcode sucht">Linter</dfn>/Gehirn**:
* Weil Pydantics Datenstrukturen einfach nur Instanzen ihrer definierten Klassen sind; Autovervollständigung, Linting, mypy und Ihre Intuition sollten alle einwandfrei mit Ihren validierten Daten funktionieren.
* Weil Pydantics Datenstrukturen einfach nur Instanzen ihrer definierten Klassen sind; Autovervollständigung, Linting, mypy und Ihre Intuition sollten alle einwandfrei mit Ihren validierten Daten funktionieren.
* Validierung von **komplexen Strukturen**:
* Validierung von **komplexen Strukturen**:
* Benutzung von hierarchischen Pydantic-Modellen, Python-`typing`s `List` und `Dict`, etc.
* Benutzung von hierarchischen Pydantic-Modellen, Python-`typing`s `List` und `Dict`, usw.
* Die Validierer erlauben es, komplexe Datenschemen klar und einfach zu definieren, überprüft und dokumentiert als JSON Schema.
* Die Validierer erlauben es, komplexe Datenschemas klar und einfach zu definieren, überprüft und dokumentiert als JSON Schema.
* Sie können tief **verschachtelte JSON**Objekte haben, die alle validiert und annotiert sind.
* Sie können tief **verschachtelte JSON**-Objekte haben, die alle validiert und annotiert sind.
* **Erweiterbar**:
* **Erweiterbar**:
* Pydantic erlaubt die Definition von eigenen Datentypen oder sie können die Validierung mit einer `validator`-dekorierten Methode im Modell erweitern.
* Pydantic erlaubt die Definition von eigenen Datentypen oder Sie können die Validierung mit Methoden in einem Modell erweitern, die mit dem Validator-Dekorator dekoriert sind.
Dabei handelt es sich um **JavaScript**-Objekte, nicht um Strings, daher können Sie diese nicht direkt vom Python-Code aus übergeben.
Dabei handelt es sich um **JavaScript**-Objekte, nicht um Strings, daher können Sie diese nicht direkt vom Python-Code aus übergeben.
Wenn Sie solche JavaScript-Konfigurationen verwenden müssen, können Sie einen der früher genannten Wege verwenden. Überschreiben Sie alle *Pfadoperationen* der Swagger-Oberfläche und schreiben Sie manuell jedes benötigte JavaScript.
Wenn Sie solche Nur-JavaScript-Konfigurationen verwenden müssen, können Sie einen der früher genannten Wege verwenden. Überschreiben Sie die gesamte *Pfadoperation* der Swagger-Oberfläche und schreiben Sie manuell jedes benötigte JavaScript.
@ -8,6 +8,8 @@ FastAPI Version 0.119.0 führte eine teilweise Unterstützung für Pydantic v1 i
FastAPI 0.126.0 entfernte die Unterstützung für Pydantic v1, während `pydantic.v1` noch eine Weile unterstützt wurde.
FastAPI 0.126.0 entfernte die Unterstützung für Pydantic v1, während `pydantic.v1` noch eine Weile unterstützt wurde.
FastAPI 0.128.0 entfernte ebenfalls die Unterstützung für `pydantic.v1`, daher erfordern die neuesten Versionen von FastAPI Pydantic v2.
/// warning | Achtung
/// warning | Achtung
Das Pydantic-Team hat die Unterstützung für Pydantic v1 in den neuesten Python-Versionen eingestellt, beginnend mit **Python 3.14**.
Das Pydantic-Team hat die Unterstützung für Pydantic v1 in den neuesten Python-Versionen eingestellt, beginnend mit **Python 3.14**.
@ -54,6 +56,16 @@ Das bedeutet, Sie können die neueste Version von Pydantic v2 installieren und d
### FastAPI-Unterstützung für Pydantic v1 in v2 { #fastapi-support-for-pydantic-v1-in-v2 }
### FastAPI-Unterstützung für Pydantic v1 in v2 { #fastapi-support-for-pydantic-v1-in-v2 }
/// warning | Achtung
Diese FastAPI-Unterstützung für `pydantic.v1`-Modelle wurde in **FastAPI 0.119.0** hinzugefügt und in **FastAPI 0.128.0** entfernt. Sie war als temporäre Hilfe für die Migration zu Pydantic v2 gedacht.
In aktuellen Versionen von FastAPI löst die Verwendung eines `pydantic.v1`-Modells in Ihrer App einen Fehler aus.
Der Rest dieses Abschnitts beschreibt die temporäre Unterstützung, die nur in diesen älteren Versionen verfügbar ist.
///
Seit FastAPI 0.119.0 gibt es außerdem eine teilweise Unterstützung für Pydantic v1 innerhalb von Pydantic v2, um die Migration auf v2 zu erleichtern.
Seit FastAPI 0.119.0 gibt es außerdem eine teilweise Unterstützung für Pydantic v1 innerhalb von Pydantic v2, um die Migration auf v2 zu erleichtern.
Sie könnten also Pydantic auf die neueste Version 2 aktualisieren und die Importe so ändern, dass das Untermodul `pydantic.v1` verwendet wird, und in vielen Fällen würde es einfach funktionieren.
Sie könnten also Pydantic auf die neueste Version 2 aktualisieren und die Importe so ändern, dass das Untermodul `pydantic.v1` verwendet wird, und in vielen Fällen würde es einfach funktionieren.
@ -122,6 +134,12 @@ Wenn Sie einige der FastAPI-spezifischen Tools für Parameter wie `Body`, `Query
### In Schritten migrieren { #migrate-in-steps }
### In Schritten migrieren { #migrate-in-steps }
/// warning | Achtung
Die unten beschriebene schrittweise Migration mit sowohl Pydantic‑v1‑ als auch Pydantic‑v2‑Modellen in derselben App funktioniert nur in **FastAPI 0.119.0 bis 0.127.x**. Sie wurde in **FastAPI 0.128.0** entfernt, die neuesten Versionen erfordern **Pydantic‑v2**-Modelle.
///
/// tip | Tipp
/// tip | Tipp
Probieren Sie zuerst `bump-pydantic` aus. Wenn Ihre Tests erfolgreich sind und das funktioniert, sind Sie mit einem einzigen Befehl fertig. ✨
Probieren Sie zuerst `bump-pydantic` aus. Wenn Ihre Tests erfolgreich sind und das funktioniert, sind Sie mit einem einzigen Befehl fertig. ✨
# Separate OpenAPI-Schemas für Eingabe und Ausgabe oder nicht { #separate-openapi-schemas-for-input-and-output-or-not }
# Separate OpenAPI-Schemas für Eingabe und Ausgabe oder nicht { #separate-openapi-schemas-for-input-and-output-or-not }
Seit der Veröffentlichung von **Pydantic v2** ist die generierte OpenAPI etwas genauer und **korrekter** als zuvor. 😎
Seit der Veröffentlichung von **Pydantic v2** ist die generierte OpenAPI etwas genauer und **korrekter** als zuvor. 😎
Tatsächlich gibt es in einigen Fällen sogar **zwei JSON-Schemas** in OpenAPI für dasselbe Pydantic-Modell, für Eingabe und Ausgabe, je nachdem, ob sie **Defaultwerte** haben.
Tatsächlich gibt es in einigen Fällen sogar **zwei JSON-Schemas** in OpenAPI für dasselbe Pydantic-Modell, für Eingabe und Ausgabe, je nachdem, ob sie **Defaultwerte** haben.
Wenn Sie eine <abbrtitle="Command Line Interface - Kommandozeilen-Schnittstelle">CLI</abbr>-Anwendung für das Terminal erstellen, anstelle einer Web-API, schauen Sie sich [**Typer**](https://typer.tiangolo.com/) an.
Wenn Sie eine <abbrtitle="Command Line Interface - Kommandozeileninterface">CLI</abbr>-Anwendung für das Terminal erstellen, anstelle einer Web-API, schauen Sie sich [**Typer**](https://typer.tiangolo.com/) an.
**Typer** ist die kleine Schwester von FastAPI. Und es soll das **FastAPI der CLIs** sein. ⌨️ 🚀
**Typer** ist die kleine Schwester von FastAPI. Und es soll das **FastAPI der CLIs** sein. ⌨️ 🚀
@ -44,7 +44,7 @@ Es ist ein sehr einfaches Programm.
Aber nun stellen Sie sich vor, Sie würden es selbst schreiben.
Aber nun stellen Sie sich vor, Sie würden es selbst schreiben.
Irgendwann sind die Funktions-Parameter fertig, Sie starten mit der Definition des Körpers ...
Irgendwann beginnen Sie, die Funktion zu definieren, und haben die Parameter bereit ...
Aber dann müssen Sie „diese Methode aufrufen, die den ersten Buchstaben in Großbuchstaben umwandelt“.
Aber dann müssen Sie „diese Methode aufrufen, die den ersten Buchstaben in Großbuchstaben umwandelt“.
@ -52,7 +52,7 @@ War es `upper`? War es `uppercase`? `first_uppercase`? `capitalize`?
Dann versuchen Sie es mit dem langjährigen Freund des Programmierers, der Editor-Autovervollständigung.
Dann versuchen Sie es mit dem langjährigen Freund des Programmierers, der Editor-Autovervollständigung.
Sie geben den ersten Parameter der Funktion ein, `first_name`, dann einen Punkt (`.`) und drücken `Strg+Leertaste`, um die Vervollständigung auszulösen.
Sie geben den ersten Parameter der Funktion ein, `first_name`, dann einen Punkt (`.`) und drücken `Ctrl+Space`, um die Vervollständigung auszulösen.
Aber leider erhalten Sie nichts Nützliches:
Aber leider erhalten Sie nichts Nützliches:
@ -62,7 +62,7 @@ Aber leider erhalten Sie nichts Nützliches:
Lassen Sie uns eine einzelne Zeile aus der vorherigen Version ändern.
Lassen Sie uns eine einzelne Zeile aus der vorherigen Version ändern.
Wir ändern den folgenden Teil, die Parameter der Funktion, von:
Wir ändern genau dieses Fragment, die Parameter der Funktion, von:
```Python
```Python
first_name, last_name
first_name, last_name
@ -94,7 +94,7 @@ Und das Hinzufügen von Typhinweisen ändert normalerweise nichts an dem, was oh
Aber jetzt stellen Sie sich vor, Sie sind wieder mitten in der Erstellung dieser Funktion, aber mit Typhinweisen.
Aber jetzt stellen Sie sich vor, Sie sind wieder mitten in der Erstellung dieser Funktion, aber mit Typhinweisen.
An derselben Stelle versuchen Sie, die Autovervollständigung mit „Strg+Leertaste“ auszulösen, und Sie sehen:
An derselben Stelle versuchen Sie, die Autovervollständigung mit `Ctrl+Space` auszulösen, und Sie sehen:
<imgsrc="/img/python-types/image02.png">
<imgsrc="/img/python-types/image02.png">
@ -116,7 +116,7 @@ Jetzt, da Sie wissen, dass Sie das reparieren müssen, konvertieren Sie `age` mi
Python selbst macht nichts mit `Annotated`. Für Editoren und andere Tools ist der Typ immer noch `str`.
Python selbst macht nichts mit diesem `Annotated`. Für Editoren und andere Tools ist der Typ immer noch `str`.
Aber Sie können `Annotated` nutzen, um **FastAPI**mit Metadaten zu versorgen, die ihm sagen, wie sich Ihre Anwendung verhalten soll.
Aber Sie können diesen Platz in `Annotated` nutzen, um **FastAPI**zusätzliche Metadaten darüber bereitzustellen, wie sich Ihre Anwendung verhalten soll.
Wichtig ist, dass **der erste *Typ-Parameter***, den Sie `Annotated` übergeben, der **tatsächliche Typ** ist. Der Rest sind Metadaten für andere Tools.
Wichtig ist, dass **der erste *Typ-Parameter***, den Sie `Annotated` übergeben, der **tatsächliche Typ** ist. Der Rest sind nur Metadaten für andere Tools.
Im Moment müssen Sie nur wissen, dass `Annotated` existiert, und dass es Standard-Python ist. 😎
Im Moment müssen Sie nur wissen, dass `Annotated` existiert, und dass es Standard-Python ist. 😎
@ -335,7 +335,7 @@ Mit **FastAPI** deklarieren Sie Parameter mit Typhinweisen, und Sie erhalten:
* **Daten zu validieren**: aus jedem Request:
* **Daten zu validieren**: aus jedem Request:
* **Automatische Fehler** generieren, die an den Client zurückgegeben werden, wenn die Daten ungültig sind.
* **Automatische Fehler** generieren, die an den Client zurückgegeben werden, wenn die Daten ungültig sind.
* Die API mit OpenAPI zu **dokumentieren**:
* Die API mit OpenAPI zu **dokumentieren**:
* Die dann von den Benutzeroberflächen der automatisch generierten interaktiven Dokumentation verwendet wird.
* die dann von den Benutzeroberflächen der automatisch generierten interaktiven Dokumentation verwendet wird.
Das mag alles abstrakt klingen. Machen Sie sich keine Sorgen. Sie werden all das in Aktion sehen im [Tutorial – Benutzerhandbuch](tutorial/index.md).
Das mag alles abstrakt klingen. Machen Sie sich keine Sorgen. Sie werden all das in Aktion sehen im [Tutorial – Benutzerhandbuch](tutorial/index.md).
@ -12,11 +12,12 @@ Das bewirkt, dass `tags` eine Liste ist, wenngleich es nichts über den Typ der
## Listen mit Typ-Parametern als Felder { #list-fields-with-type-parameter }
## Listen mit Typ-Parametern als Felder { #list-fields-with-type-parameter }
Aber Python erlaubt es, Listen mit inneren Typen, auch „Typ-Parameter“ genannt, zu deklarieren.
Aber Python hat eine spezifische Möglichkeit, Listen mit inneren Typen, auch „Typ-Parameter“ genannt, zu deklarieren:
### Eine `list` mit einem Typ-Parameter deklarieren { #declare-a-list-with-a-type-parameter }
### Eine `list` mit einem Typ-Parameter deklarieren { #declare-a-list-with-a-type-parameter }
Um Typen zu deklarieren, die Typ-Parameter (innere Typen) haben, wie `list`, `dict`, `tuple`, übergeben Sie den/die inneren Typ(en) als „Typ-Parameter“ in eckigen Klammern: `[` und `]`
Um Typen zu deklarieren, die Typ-Parameter (innere Typen) haben, wie `list`, `dict`, `tuple`,
übergeben Sie den/die inneren Typ(en) als „Typ-Parameter“ in eckigen Klammern: `[` und `]`
```Python
```Python
my_list: list[str]
my_list: list[str]
@ -32,19 +33,19 @@ In unserem Beispiel können wir also bewirken, dass `tags` spezifisch eine „Li
## Set-Typen { #set-types }
## Set-Typen { #set-types }
Aber dann denken wir darüber nach und stellen fest, dass sich die Tags nicht wiederholen sollen, es sollen eindeutige Strings sein.
Aber dann denken wir darüber nach und stellen fest, dass sich die Tags nicht wiederholen sollten, sie wären wahrscheinlich eindeutige Strings.
Python hat einen Datentyp speziell für Mengen eindeutiger Dinge: das <abbrtitle="Menge">`set`</abbr>.
Und Python hat einen speziellen Datentyp für Mengen eindeutiger Elemente, das <abbrtitle="Menge">`set`</abbr>.
Deklarieren wir also `tags` als Set von Strings.
Dann können wir `tags` als Set von Strings deklarieren:
Jetzt, selbst wenn Sie einen <abbrtitle="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> mit duplizierten Daten erhalten, werden diese zu einem Set eindeutiger Dinge konvertiert.
Damit wird, selbst wenn Sie einen <abbrtitle="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> mit duplizierten Daten erhalten, dieser zu einem Set eindeutiger Elemente konvertiert.
Und wann immer Sie diese Daten ausgeben, selbst wenn die Quelle Duplikate hatte, wird es als Set von eindeutigen Dingen ausgegeben.
Und wann immer Sie diese Daten ausgeben, selbst wenn die Quelle Duplikate hatte, wird es als Set von eindeutigen Elementen ausgegeben.
Und es wird entsprechend annotiert/dokumentiert.
Und es wird entsprechend annotiert/dokumentiert.
## Verschachtelte Modelle { #nested-models }
## Verschachtelte Modelle { #nested-models }
@ -52,13 +53,13 @@ Jedes Attribut eines Pydantic-Modells hat einen Typ.
Aber dieser Typ kann selbst ein anderes Pydantic-Modell sein.
Aber dieser Typ kann selbst ein anderes Pydantic-Modell sein.
Sie können also tief verschachtelte JSON-„Objekte“ deklarieren, mit spezifischen Attributnamen, -typen, und -validierungen.
Sie können also tief verschachtelte JSON-„Objekte“ deklarieren, mit spezifischen Attributnamen, Typen und Validierungen.
Alles das beliebig tief verschachtelt.
Alles das beliebig tief verschachtelt.
### Ein Kindmodell definieren { #define-a-submodel }
### Ein Kindmodell definieren { #define-a-submodel }
Für ein Beispiel können wir ein `Image`-Modell definieren.
Zum Beispiel können wir ein `Image`-Modell definieren:
@ -149,13 +150,13 @@ Sie können beliebig tief verschachtelte Modelle definieren:
/// note | Hinweis
/// note | Hinweis
Beachten Sie, wie `Offer` eine Liste von `Item`s hat, die ihrerseits eine optionale Liste von `Image`s haben.
Beachten Sie, wie `Offer` eine Liste von `Item`s hat, die ihrerseits eine optionale Liste von `Image`s haben
///
///
## Bodys aus reinen Listen { #bodies-of-pure-lists }
## Bodys aus reinen Listen { #bodies-of-pure-lists }
Wenn das äußerste Element des JSON-Bodys, das Sie erwarten, ein JSON-`array` (eine Python-`list`) ist, können Sie den Typ im Funktionsparameter deklarieren, mit der gleichen Syntax wie in Pydantic-Modellen:
Wenn der Wert auf oberster Ebene des JSON-Bodys, den Sie erwarten, ein JSON-`array` (eine Python-`list`) ist, können Sie den Typ im Parameter der Funktion deklarieren, genau wie in Pydantic-Modellen:
Sie würden diese Editor-Unterstützung nicht erhalten, wenn Sie direkt mit `dict`, statt mit Pydantic-Modellen arbeiten würden.
Sie würden diese Art von Editor-Unterstützung nicht erhalten, wenn Sie direkt mit `dict`, statt mit Pydantic-Modellen arbeiten würden.
Aber Sie müssen sich auch nicht weiter um die Modelle kümmern, hereinkommende Dicts werden automatisch in sie konvertiert. Und was Sie zurückgeben, wird automatisch nach JSON konvertiert.
Aber Sie müssen sich auch nicht um diese kümmern, hereinkommende Dicts werden automatisch konvertiert und Ihre Ausgabe wird ebenfalls automatisch nach JSON konvertiert.
## Bodys mit beliebigen `dict`s { #bodies-of-arbitrary-dicts }
## Bodys mit beliebigen `dict`s { #bodies-of-arbitrary-dicts }
Sie können einen Body auch als `dict` deklarieren, mit Schlüsseln eines Typs und Werten eines anderen Typs.
Sie können einen Body auch als `dict` deklarieren, mit Schlüsseln eines Typs und Werten eines anderen Typs.
So brauchen Sie vorher nicht zu wissen, wie die Feld-/Attributnamen lauten (wie es bei Pydantic-Modellen der Fall wäre).
So brauchen Sie vorher nicht zu wissen, wie die gültigen Feld-/Attributnamen lauten (wie es bei Pydantic-Modellen der Fall wäre).
Das ist nützlich, wenn Sie Schlüssel empfangen, deren Namen Sie nicht bereits kennen.
Das ist nützlich, wenn Sie Schlüssel empfangen wollen, die Sie nicht bereits kennen.
---
---
Ein anderer nützlicher Anwendungsfall ist, wenn Sie Schlüssel eines anderen Typs haben wollen, z. B. `int`.
Ein anderer nützlicher Anwendungsfall ist, wenn Sie Schlüssel eines anderen Typs haben wollen, z. B. `int`.
Das schauen wir uns mal an.
Das schauen wir uns hier an.
Im folgenden Beispiel akzeptieren Sie irgendein `dict`, solange es `int`-Schlüssel und `float`-Werte hat:
In diesem Fall akzeptieren Sie irgendein `dict`, solange es `int`-Schlüssel mit `float`-Werten hat:
@ -201,9 +202,9 @@ Bedenken Sie, dass JSON nur `str` als Schlüssel unterstützt.
Aber Pydantic hat automatische Datenkonvertierung.
Aber Pydantic hat automatische Datenkonvertierung.
Das bedeutet, dass Ihre API-Clients nur Strings senden können, aber solange diese Strings nur Zahlen enthalten, wird Pydantic sie konvertieren und validieren.
Das bedeutet, dass Ihre API-Clients zwar nur Strings als Schlüssel senden können, Pydantic diese aber konvertieren und validieren wird, solange diese Strings nur Ganzzahlen enthalten.
Und das `dict`, welches Sie als `weights` erhalten, wird `int`-Schlüssel und `float`-Werte haben.
Und das `dict`, welches Sie als `weights` erhalten, wird tatsächlich `int`-Schlüssel und `float`-Werte haben.
///
///
@ -213,8 +214,8 @@ Mit **FastAPI** haben Sie die maximale Flexibilität von Pydantic-Modellen, wäh
@ -14,7 +14,7 @@ Um Daten zu senden, sollten Sie eines von: `POST` (meistverwendet), `PUT`, `DELE
Das Senden eines Bodys mit einem `GET`-Request hat ein undefiniertes Verhalten in den Spezifikationen, wird aber dennoch von FastAPI unterstützt, nur für sehr komplexe/extreme Anwendungsfälle.
Das Senden eines Bodys mit einem `GET`-Request hat ein undefiniertes Verhalten in den Spezifikationen, wird aber dennoch von FastAPI unterstützt, nur für sehr komplexe/extreme Anwendungsfälle.
Da davon abgeraten wird, zeigt die interaktive Dokumentation mit Swagger-Benutzeroberfläche die Dokumentation für den Body nicht an, wenn `GET` verwendet wird, und zwischengeschaltete Proxys unterstützen es möglicherweise nicht.
Da davon abgeraten wird, zeigt die interaktive Dokumentation mit Swagger UI die Dokumentation für den Body nicht an, wenn `GET` verwendet wird, und zwischengeschaltete Proxys unterstützen es möglicherweise nicht.
///
///
@ -32,6 +32,7 @@ Verwenden Sie Standard-Python-Typen für alle Attribute:
Wie auch bei der Deklaration von Query-Parametern gilt: Wenn ein Modellattribut einen Defaultwert hat, ist das Attribut nicht erforderlich. Andernfalls ist es erforderlich. Verwenden Sie `None`, um es einfach optional zu machen.
Wie auch bei der Deklaration von Query-Parametern gilt: Wenn ein Modellattribut einen Defaultwert hat, ist das Attribut nicht erforderlich. Andernfalls ist es erforderlich. Verwenden Sie `None`, um es einfach optional zu machen.
Zum Beispiel deklariert das obige Modell ein JSON „`object`“ (oder Python-<abbrtitle="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr>) wie dieses:
Zum Beispiel deklariert das obige Modell ein JSON „`object`“ (oder Python-<abbrtitle="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr>) wie dieses:
@ -45,7 +46,7 @@ Zum Beispiel deklariert das obige Modell ein JSON „`object`“ (oder Python-<a
}
}
```
```
Da `description` und `tax` optional sind (mit `None` als Defaultwert), wäre folgendes JSON „`object`“ auch gültig:
... da `description` und `tax` optional sind (mit `None` als Defaultwert), wäre dieses JSON „`object`“ ebenfalls gültig:
```JSON
```JSON
{
{
@ -109,7 +110,7 @@ Aber Sie würden die gleiche Editor-Unterstützung in [PyCharm](https://www.jetb
/// tip | Tipp
/// tip | Tipp
Wenn Sie [PyCharm](https://www.jetbrains.com/pycharm/) als Ihren Editor verwenden, können Sie das [Pydantic PyCharm Plugin](https://github.com/koxudaxi/pydantic-pycharm-plugin/) ausprobieren.
Wenn Sie [PyCharm](https://www.jetbrains.com/pycharm/) als Ihren Editor verwenden, können Sie das [Pydantic PyCharm Plugin](https://github.com/koxudaxi/pydantic-pycharm-plugin/) verwenden.
Es verbessert die Editor-Unterstützung für Pydantic-Modelle, mit:
Es verbessert die Editor-Unterstützung für Pydantic-Modelle, mit:
@ -127,7 +128,7 @@ Innerhalb der Funktion können Sie alle Attribute des Modellobjekts direkt verwe
Sie können auch zur gleichen Zeit **Body-**, **Pfad-** und **Query-Parameter** deklarieren.
Sie können auch zur gleichen Zeit **Body-**, **Pfad-** und **Query-Parameter** deklarieren.
@ -152,7 +153,7 @@ Die Funktionsparameter werden wie folgt erkannt:
/// note | Hinweis
/// note | Hinweis
FastAPI weiß, dass der Wert von `q` nicht erforderlich ist, aufgrund des definierten Defaultwertes `= None`.
FastAPI weiß, dass der Wert von `q` nicht erforderlich ist, aufgrund des Defaultwertes `= None`.
Das `str | None` wird von FastAPI nicht verwendet, um zu bestimmen, dass der Wert nicht erforderlich ist. FastAPI weiß, dass er nicht erforderlich ist, weil er einen Defaultwert von `= None` hat.
Das `str | None` wird von FastAPI nicht verwendet, um zu bestimmen, dass der Wert nicht erforderlich ist. FastAPI weiß, dass er nicht erforderlich ist, weil er einen Defaultwert von `= None` hat.
Auf die gleiche Weise könnten Sie einige Abhängigkeiten mit `yield` und einige andere Abhängigkeiten mit `return` haben, und alle können beliebig voneinander abhängen.
Auf die gleiche Weise könnten Sie einige Abhängigkeiten mit `yield` und einige andere Abhängigkeiten mit `return` haben, und einige davon von einigen der anderen abhängen lassen.
Und Sie könnten eine einzelne Abhängigkeit haben, die auf mehreren ge`yield`eten Abhängigkeiten basiert, usw.
Und Sie könnten eine einzelne Abhängigkeit haben, die auf mehreren ge`yield`eten Abhängigkeiten basiert, usw.
@ -234,6 +234,7 @@ participant operation as Pfadoperation
Abhängigkeiten mit `yield` haben sich im Laufe der Zeit weiterentwickelt, um verschiedene Anwendungsfälle abzudecken und einige Probleme zu beheben.
Abhängigkeiten mit `yield` haben sich im Laufe der Zeit weiterentwickelt, um verschiedene Anwendungsfälle abzudecken und einige Probleme zu beheben.
Wenn Sie sehen möchten, was sich in verschiedenen Versionen von FastAPI geändert hat, lesen Sie mehr dazu im fortgeschrittenen Teil, unter [Fortgeschrittene Abhängigkeiten – Abhängigkeiten mit `yield`, `HTTPException`, `except` und Hintergrundtasks](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks).
Wenn Sie sehen möchten, was sich in verschiedenen Versionen von FastAPI geändert hat, lesen Sie mehr dazu im fortgeschrittenen Teil, unter [Fortgeschrittene Abhängigkeiten – Abhängigkeiten mit `yield`, `HTTPException`, `except` und Hintergrundtasks](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks).
## Kontextmanager { #context-managers }
## Kontextmanager { #context-managers }
### Was sind „Kontextmanager“ { #what-are-context-managers }
### Was sind „Kontextmanager“ { #what-are-context-managers }
@ -266,18 +267,19 @@ Wenn Sie gerade erst mit **FastAPI** beginnen, möchten Sie das vielleicht vorer
In Python können Sie Kontextmanager erstellen, indem Sie [eine Klasse mit zwei Methoden erzeugen: `__enter__()` und `__exit__()`](https://docs.python.org/3/reference/datamodel.html#context-managers).
In Python können Sie Kontextmanager erstellen, indem Sie [eine Klasse mit zwei Methoden erzeugen: `__enter__()` und `__exit__()`](https://docs.python.org/3/reference/datamodel.html#context-managers).
Sie können solche auch innerhalb von **FastAPI**-Abhängigkeiten mit `yield` verwenden, indem Sie `with`- oder `async with`-Anweisungen innerhalb der Abhängigkeits-Funktion verwenden:
Sie können solche auch innerhalb von **FastAPI**-Abhängigkeiten mit `yield` verwenden, indem Sie
`with`- oder `async with`-Anweisungen innerhalb der Abhängigkeits-Funktion verwenden:
@ -63,7 +63,7 @@ würden wir ein Python-`dict` erhalten mit:
#### Ein `dict` entpacken { #unpacking-a-dict }
#### Ein `dict` entpacken { #unpacking-a-dict }
Wenn wir ein `dict` wie `user_dict` nehmen und es einer Funktion (oder Klasse) mit `**user_dict` übergeben, wird Python es „entpacken“. Es wird die Schlüssel und Werte von `user_dict` direkt als Schlüsselwort-Argumente übergeben.
Wenn wir ein `dict` wie `user_dict` nehmen und es einer Funktion (oder Klasse) mit `**user_dict` übergeben, wird Python es „entpacken“. Es wird die Schlüssel und Werte von `user_dict` direkt als Schlüssel-Wert-Argumente übergeben.
Setzen wir also das `user_dict` von oben ein:
Setzen wir also das `user_dict` von oben ein:
@ -196,7 +196,7 @@ Dafür verwenden Sie Pythons Standard-`list`:
## Response mit beliebigem `dict` { #response-with-arbitrary-dict }
## Response mit beliebigem `dict` { #response-with-arbitrary-dict }
Sie können auch eine Response deklarieren, die ein beliebiges `dict` zurückgibt, indem Sie nur die Typen der Schlüssel und Werte ohne ein Pydantic-Modell deklarieren.
Sie können auch eine Response deklarieren, die ein einfaches beliebiges `dict` verwendet, indem Sie nur den Typ der Schlüssel und Werte deklarieren, ohne ein Pydantic-Modell zu verwenden.
Dies ist nützlich, wenn Sie die gültigen Feld-/Attributnamen nicht im Voraus kennen (die für ein Pydantic-Modell benötigt werden würden).
Dies ist nützlich, wenn Sie die gültigen Feld-/Attributnamen nicht im Voraus kennen (die für ein Pydantic-Modell benötigt werden würden).
@ -208,4 +208,4 @@ In diesem Fall können Sie `dict` verwenden:
Verwenden Sie gerne mehrere Pydantic-Modelle und vererben Sie je nach Bedarf.
Verwenden Sie gerne mehrere Pydantic-Modelle und vererben Sie je nach Bedarf.
Sie brauchen kein einzelnes Datenmodell pro Einheit, wenn diese Einheit in der Lage sein muss, verschiedene „Zustände“ zu haben. Wie im Fall der Benutzer-„Einheit“ mit einem Zustand einschließlich `password`, `password_hash` und ohne Passwort.
Sie brauchen kein einzelnes Datenmodell pro Entität, wenn diese Entität in der Lage sein muss, verschiedene „Zustände“ zu haben. Die **Benutzer**-„Entität“ ist ein Beispiel, mit Zuständen, die `password`, `password_hash` oder kein Passwort umfassen.
Sie können statische Frontend-Apps mit `app.frontend()` (oder `router.frontend()`) bereitstellen.
Das ist nützlich für Frontend-Tools, die statische Dateien generieren, wie React mit Vite, TanStack Router, Astro, Vue, Svelte, Angular, Solid und andere.
Mit diesen Tools haben Sie normalerweise einen Schritt, der das Frontend baut, mit einem Befehl wie:
```bash
npm run build
```
Das würde ein Verzeichnis wie `./dist/` mit Ihren Frontend-Dateien generieren.
Sie können `app.frontend()` verwenden, um dieses Verzeichnis gemäß den Konventionen bereitzustellen, die von diesen Frontend-Frameworks benötigt werden.
**FastAPI** prüft zuerst *Pfadoperationen*. Die Frontend-Dateien werden nur geprüft, wenn keine normale Route gepasst hat, sodass Ihre API nicht beeinträchtigt wird.
## Ein Frontend bereitstellen { #serve-a-frontend }
Nachdem Sie Ihr Frontend gebaut haben, zum Beispiel mit `npm run build`, legen Sie die generierten Dateien in ein Verzeichnis, zum Beispiel `dist`.
Viele Frontend-Apps, einschließlich **Single-Page-Apps** (SPAs), verwenden clientseitiges Routing. Ein Pfad wie `/dashboard/settings` ist möglicherweise keine echte Datei, aber das Framework würde sich darum kümmern, ihn zu handhaben.
Wenn also direkt auf diese URL zugegriffen wird (statt durch die App zu navigieren), sollte das Backend die Frontend-App von `index.html` bereitstellen, sodass das Frontend-Framework anschließend das clientseitige Routing handhaben kann.
**FastAPI** verwendet diesen Fallback nur für `GET`- und `HEAD`-Requests, die wie Browser-Navigation aussehen. Fehlende Dateien wie JavaScript, CSS und Bilder geben weiterhin `404` zurück.
Requests mit anderen Methoden, wie `POST` oder `PUT`, an Pfade, die nur zum Frontend-Fallback passen, geben ebenfalls `404` zurück. Reguläre **FastAPI**-*Pfadoperationen* haben weiterhin eine höhere Priorität als Frontend-Routen.
/// tip | Tipp
Standardmäßig hat `fallback` einen Wert von `fallback="auto"`. In den meisten Fällen müssen Sie `fallback` nicht angeben. Lesen Sie weiter unten die Details.
///
Das ist das, was Sie bei vielen Frontend-Apps möchten, die clientseitiges Routing verwenden, zum Beispiel React mit TanStack Router, Vue, Angular, SvelteKit oder Solid.
In diesem Fall liefert **FastAPI** für fehlende Frontend-Pfade nicht `index.html` aus. Stattdessen wird die Datei `404.html` zurückgegeben.
/// tip | Tipp
Standardmäßig hat `fallback` einen Wert von `fallback="auto"`. Damit wird, wenn eine `404.html`-Datei gefunden wird, diese automatisch als Fallback verwendet.
Sie können das `fallback`-Argument also normalerweise weglassen.
///
Das ist nützlich bei Frontend-Tools, die für jede Seite statische HTML-Dateien generieren, wie Astro.
## Automatischer Fallback { #fallback-auto }
Standardmäßig verwendet `app.frontend()``fallback="auto"`.
Wenn es im Frontend-Verzeichnis eine `404.html`-Datei gibt, liefern fehlende Frontend-Pfade diese Datei mit dem Statuscode `404` aus.
Andernfalls, wenn es eine `index.html`-Datei gibt, liefern fehlende Browser-Navigationspfade `index.html` aus, was viele Frontend-Apps mit clientseitigem Routing erwarten.
In den meisten Fällen können Sie also `app.frontend("/", directory="dist")` verwenden, ohne das `fallback`-Argument anzugeben.
Dann geben fehlende Frontend-Pfade das normale `404` zurück.
## Verzeichnis prüfen { #check-directory }
Standardmäßig prüft `app.frontend()`, dass das Verzeichnis existiert, wenn die App erstellt wird.
Das hilft, Konfigurationsfehler früh zu erkennen. Wenn zum Beispiel das Output-Verzeichnis des Frontend-Builds fehlt, löst **FastAPI** beim Startup einen Fehler aus.
Wenn Ihre Frontend-Dateien später erstellt werden, zum Beispiel durch einen separaten Build-Schritt, nachdem das App-Objekt erstellt wurde, setzen Sie `check_dir=False`:
Mit `check_dir=False` prüft **FastAPI** das Verzeichnis nicht, wenn die App erstellt wird. Wenn das konfigurierte Verzeichnis beim Verarbeiten eines Requests immer noch fehlt, löst **FastAPI** dann einen Fehler aus.
## Mit `APIRouter` verwenden { #use-it-with-apirouter }
Sie können Frontend-Dateien auch zu einem `APIRouter` hinzufügen und ihn mit einem Präfix einbinden:
In diesem Beispiel werden Frontend-Pfade unter `/app` bereitgestellt.
Alle regulären *Pfadoperationen* in der App haben weiterhin Vorrang, auch in anderen Routern.
## Nur statischer Build-Output { #static-build-output-only }
`app.frontend()` liefert Dateien aus, die bereits von Ihrem Frontend-Build generiert wurden.
Es führt kein serverseitiges Rendering aus. Es ist für Frontend-Frameworks gedacht, die statische Dateien generieren, nicht für Frameworks, die dynamisches Rendering auf dem Server für jeden Request benötigen.
@ -8,12 +8,12 @@ Sie könnten dem Client mitteilen müssen, dass:
* Der Client nicht genügend Berechtigungen für diese Operation hat.
* Der Client nicht genügend Berechtigungen für diese Operation hat.
* Der Client keinen Zugriff auf diese Ressource hat.
* Der Client keinen Zugriff auf diese Ressource hat.
* Die Ressource, auf die der Client versucht hat, zuzugreifen, nicht existiert.
* Das Item, auf das der Client versucht hat zuzugreifen, nicht existiert.
* usw.
* usw.
In diesen Fällen würden Sie normalerweise einen **HTTP-Statuscode** im Bereich **400** (von 400 bis 499) zurückgeben.
In diesen Fällen würden Sie normalerweise einen **HTTP-Statuscode** im Bereich **400** (von 400 bis 499) zurückgeben.
Dies ist vergleichbar mit den HTTP-Statuscodes im Bereich 200 (von 200 bis 299). Diese „200“-Statuscodes bedeuten, dass der <abbrtitle="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> in irgendeiner Weise erfolgreich war.
Dies ist vergleichbar mit den HTTP-Statuscodes im Bereich 200 (von 200 bis 299). Diese „200“-Statuscodes bedeuten, dass der <abbrtitle="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> irgendwie ein „Erfolg“ war.
Die Statuscodes im Bereich 400 bedeuten hingegen, dass es einen Fehler seitens des Clients gab.
Die Statuscodes im Bereich 400 bedeuten hingegen, dass es einen Fehler seitens des Clients gab.
@ -37,7 +37,7 @@ Das bedeutet auch, wenn Sie sich innerhalb einer Hilfsfunktion befinden, die Sie
Der Vorteil des Auslösens einer Exception gegenüber dem Zurückgeben eines Wertes wird im Abschnitt über Abhängigkeiten und Sicherheit deutlicher werden.
Der Vorteil des Auslösens einer Exception gegenüber dem Zurückgeben eines Wertes wird im Abschnitt über Abhängigkeiten und Sicherheit deutlicher werden.
In diesem Beispiel lösen wir eine Exception mit einem Statuscode von `404` aus, wenn der Client einen Artikel mit einer nicht existierenden ID anfordert:
In diesem Beispiel lösen wir eine Exception mit einem Statuscode von `404` aus, wenn der Client ein Item mit einer nicht existierenden ID anfordert:
@ -51,7 +51,7 @@ Wenn der Client `http://example.com/items/foo` anfordert (ein `item_id` `"foo"`)
}
}
```
```
Aber wenn der Client `http://example.com/items/bar` anfordert (ein nicht-existierendes `item_id``"bar"`), erhält er einen HTTP-Statuscode 404 (der „Not Found“-Error) und eine JSON-Response wie:
Aber wenn der Client `http://example.com/items/bar` anfordert (ein nicht-existierendes `item_id``"bar"`), erhält er einen HTTP-Statuscode 404 (der „not found“-Error) und eine JSON-Response wie:
```JSON
```JSON
{
{
@ -71,7 +71,7 @@ Diese werden von **FastAPI** automatisch gehandhabt und in JSON konvertiert.
Dieses Tutorial zeigt Ihnen Schritt für Schritt, wie Sie **FastAPI** mit den meisten seiner Funktionen verwenden können.
Dieses Tutorial zeigt Ihnen Schritt für Schritt, wie Sie **FastAPI** mit den meisten seiner Funktionen verwenden können.
Jeder Abschnitt baut schrittweise auf den vorhergehenden auf, ist jedoch in einzelne Themen gegliedert, sodass Sie direkt zu einem bestimmten Thema übergehen können, um Ihre spezifischen API-Anforderungen zu lösen.
Jeder Abschnitt baut schrittweise auf den vorhergehenden auf, ist jedoch in einzelne Themen gegliedert, sodass Sie direkt zu einem bestimmten Thema übergehen können, um Ihre spezifischen API-Anforderungen zu lösen.
@ -11,7 +11,7 @@ Sie können die folgenden Felder festlegen, die in der OpenAPI-Spezifikation und
| `title` | `str` | Der Titel der API. |
| `title` | `str` | Der Titel der API. |
| `summary` | `str` | Eine kurze Zusammenfassung der API. <small>Verfügbar seit OpenAPI 3.1.0, FastAPI 0.99.0.</small> |
| `summary` | `str` | Eine kurze Zusammenfassung der API. <small>Verfügbar seit OpenAPI 3.1.0, FastAPI 0.99.0.</small> |
| `description` | `str` | Eine kurze Beschreibung der API. Kann Markdown verwenden. |
| `description` | `str` | Eine kurze Beschreibung der API. Kann Markdown verwenden. |
| `version` | `string` | Die Version der API. Das ist die Version Ihrer eigenen Anwendung, nicht die von OpenAPI. Zum Beispiel `2.5.0`. |
| `version` | `str` | Die Version der API. Das ist die Version Ihrer eigenen Anwendung, nicht die von OpenAPI. Zum Beispiel `2.5.0`. |
| `terms_of_service` | `str` | Eine URL zu den Nutzungsbedingungen für die API. Falls angegeben, muss es sich um eine URL handeln. |
| `terms_of_service` | `str` | Eine URL zu den Nutzungsbedingungen für die API. Falls angegeben, muss es sich um eine URL handeln. |
| `contact` | `dict` | Die Kontaktinformationen für die freigegebene API. Kann mehrere Felder enthalten. <details><summary><code>contact</code>-Felder</summary><table><thead><tr><th>Parameter</th><th>Typ</th><th>Beschreibung</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td>Der identifizierende Name der Kontaktperson/Organisation.</td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>Die URL, die auf die Kontaktinformationen verweist. MUSS im Format einer URL vorliegen.</td></tr><tr><td><code>email</code></td><td><code>str</code></td><td>Die E-Mail-Adresse der Kontaktperson/Organisation. MUSS im Format einer E-Mail-Adresse vorliegen.</td></tr></tbody></table></details> |
| `contact` | `dict` | Die Kontaktinformationen für die freigegebene API. Kann mehrere Felder enthalten. <details><summary><code>contact</code>-Felder</summary><table><thead><tr><th>Parameter</th><th>Typ</th><th>Beschreibung</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td>Der identifizierende Name der Kontaktperson/Organisation.</td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>Die URL, die auf die Kontaktinformationen verweist. MUSS im Format einer URL vorliegen.</td></tr><tr><td><code>email</code></td><td><code>str</code></td><td>Die E-Mail-Adresse der Kontaktperson/Organisation. MUSS im Format einer E-Mail-Adresse vorliegen.</td></tr></tbody></table></details> |
| `license_info` | `dict` | Die Lizenzinformationen für die freigegebene API. Kann mehrere Felder enthalten. <details><summary><code>license_info</code>-Felder</summary><table><thead><tr><th>Parameter</th><th>Typ</th><th>Beschreibung</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>ERFORDERLICH</strong> (wenn eine <code>license_info</code> festgelegt ist). Der für die API verwendete Lizenzname.</td></tr><tr><td><code>identifier</code></td><td><code>str</code></td><td>Ein [SPDX](https://spdx.org/licenses/)-Lizenzausdruck für die API. Das Feld <code>identifier</code> und das Feld <code>url</code> schließen sich gegenseitig aus. <small>Verfügbar seit OpenAPI 3.1.0, FastAPI 0.99.0.</small></td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>Eine URL zur Lizenz, die für die API verwendet wird. MUSS im Format einer URL vorliegen.</td></tr></tbody></table></details> |
| `license_info` | `dict` | Die Lizenzinformationen für die freigegebene API. Kann mehrere Felder enthalten. <details><summary><code>license_info</code>-Felder</summary><table><thead><tr><th>Parameter</th><th>Typ</th><th>Beschreibung</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>ERFORDERLICH</strong> (wenn eine <code>license_info</code> festgelegt ist). Der für die API verwendete Lizenzname.</td></tr><tr><td><code>identifier</code></td><td><code>str</code></td><td>Ein [SPDX](https://spdx.org/licenses/)-Lizenzausdruck für die API. Das Feld <code>identifier</code> und das Feld <code>url</code> schließen sich gegenseitig aus. <small>Verfügbar seit OpenAPI 3.1.0, FastAPI 0.99.0.</small></td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>Eine URL zur Lizenz, die für die API verwendet wird. MUSS im Format einer URL vorliegen.</td></tr></tbody></table></details> |
Wenn Sie eine große Anwendung haben, können sich am Ende **viele Tags** anhäufen, und Sie möchten sicherstellen, dass Sie für verwandte *Pfadoperationen* immer den **gleichen Tag** verwenden.
Wenn Sie eine große Anwendung haben, können sich am Ende **mehrere Tags** anhäufen, und Sie möchten sicherstellen, dass Sie für verwandte *Pfadoperationen* immer den **gleichen Tag** verwenden.
In diesem Fall macht es Sinn, die Tags in einem `Enum` zu speichern.
In diesen Fällen kann es sinnvoll sein, die Tags in einem `Enum` zu speichern.
**FastAPI** unterstützt das auf die gleiche Weise wie einfache Strings:
**FastAPI** unterstützt das auf die gleiche Weise wie einfache Strings:
@ -104,4 +104,4 @@ Vergleichen Sie, wie deprecatete und nicht-deprecatete *Pfadoperationen* aussehe
## Zusammenfassung { #recap }
## Zusammenfassung { #recap }
Sie können auf einfache Weise Metadaten für Ihre *Pfadoperationen*definieren, indem Sie den *Pfadoperation-Dekoratoren* Parameter hinzufügen.
Sie können Ihre *Pfadoperationen* einfach konfigurieren und Metadaten hinzufügen, indem Sie den *Pfadoperation-Dekoratoren* Parameter übergeben.
* Die Daten **validieren**, um sicherzustellen, dass die Länge maximal 50 Zeichen beträgt
* Die Daten **validieren**, um sicherzustellen, dass die Länge maximal 50 Zeichen beträgt
* Einen **klaren Fehler** für den Client anzeigen, wenn die Daten ungültig sind
* Einen **klaren Fehler** für den Client anzeigen, wenn die Daten ungültig sind
* Den Parameter in der OpenAPI-Schema-*Pfadoperation* **dokumentieren** (sodass er in der **automatischen Dokumentation** angezeigt wird)
* Den Parameter in der OpenAPI-Schema-*Pfadoperation* **dokumentieren** (sodass er in der **automatischen Dokumentationsoberfläche** angezeigt wird)
## Alternative (alt): `Query` als Defaultwert { #alternative-old-query-as-the-default-value }
## Alternative (alt): `Query` als Defaultwert { #alternative-old-query-as-the-default-value }
@ -179,7 +179,7 @@ Dieses spezielle Suchmuster im regulären Ausdruck überprüft, dass der erhalte
Wenn Sie sich mit all diesen **„regulärer Ausdruck“**-Ideen verloren fühlen, keine Sorge. Sie sind ein schwieriges Thema für viele Menschen. Sie können noch viele Dinge tun, ohne reguläre Ausdrücke direkt zu benötigen.
Wenn Sie sich mit all diesen **„regulärer Ausdruck“**-Ideen verloren fühlen, keine Sorge. Sie sind ein schwieriges Thema für viele Menschen. Sie können noch viele Dinge tun, ohne reguläre Ausdrücke direkt zu benötigen.
Aber nun wissen Sie, dass Sie sie in **FastAPI** immer dann verwenden können, wenn Sie sie brauchen.
Nun wissen Sie, dass Sie sie in **FastAPI** immer dann verwenden können, wenn Sie sie brauchen.
## Defaultwerte { #default-values }
## Defaultwerte { #default-values }
@ -276,7 +276,7 @@ Wenn Sie zu:
http://localhost:8000/items/
http://localhost:8000/items/
```
```
gehen, wird der Default für `q` sein: `["foo", "bar"]`, und Ihre Response wird sein:
gehen, wird der Defaultwert für `q` sein: `["foo", "bar"]`, und Ihre Response wird sein:
```JSON
```JSON
{
{
@ -311,7 +311,7 @@ Diese Informationen werden in das generierte OpenAPI aufgenommen und von den Dok
Beachten Sie, dass verschiedene Tools möglicherweise unterschiedliche Unterstützungslevels für OpenAPI haben.
Beachten Sie, dass verschiedene Tools möglicherweise unterschiedliche Unterstützungslevels für OpenAPI haben.
Einige davon könnten noch nicht alle zusätzlichen Informationen anzuzeigen, die Sie erklärten, obwohl in den meisten Fällen die fehlende Funktionalität bereits in der Entwicklung geplant ist.
Einige davon könnten noch nicht alle zusätzlichen Informationen anzeigen, die Sie deklariert haben, obwohl in den meisten Fällen die fehlende Funktionalität bereits in der Entwicklung geplant ist.
Aber `item-query` ist kein gültiger Name für eine Variable in Python.
Aber `item-query` ist kein gültiger Name für eine Variable in Python.
Der am ähnlichsten wäre `item_query`.
Am ähnlichsten wäre `item_query`.
Aber Sie benötigen dennoch, dass er genau `item-query` ist ...
Aber Sie benötigen dennoch, dass er genau `item-query` ist ...
@ -347,7 +347,7 @@ Dann können Sie ein `alias` deklarieren, und dieser Alias wird verwendet, um de
Nehmen wir an, Ihnen gefällt dieser Parameter nicht mehr.
Nehmen wir an, Ihnen gefällt dieser Parameter nicht mehr.
Sie müssen ihn eine Weile dort belassen, da es Clients gibt, die ihn verwenden, aber Sie möchten, dass die Dokumentation ihn klar als <dfntitle="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</dfn> anzeigt.
Sie müssen ihn eine Weile dort belassen, da es Clients gibt, die ihn verwenden, aber Sie möchten, dass die Dokumentation ihn klar als <dfntitle="obsolet, es wird empfohlen, es nicht zu verwenden">deprecatet</dfn> anzeigt.
Dann übergeben Sie den Parameter `deprecated=True` an `Query`:
Dann übergeben Sie den Parameter `deprecated=True` an `Query`:
@ -395,7 +395,7 @@ Diese benutzerdefinierten Validatoren sind für Dinge gedacht, die einfach mit d
///
///
### Dieses Codebeispiel verstehen { #understand-that-code }
### Diesen Code verstehen { #understand-that-code }
Der wichtige Punkt ist einfach die Verwendung von **`AfterValidator` mit einer Funktion innerhalb von `Annotated`**. Fühlen Sie sich frei, diesen Teil zu überspringen. 🤸
Der wichtige Punkt ist einfach die Verwendung von **`AfterValidator` mit einer Funktion innerhalb von `Annotated`**. Fühlen Sie sich frei, diesen Teil zu überspringen. 🤸
@ -403,9 +403,9 @@ Der wichtige Punkt ist einfach die Verwendung von **`AfterValidator` mit einer F
Aber wenn Sie neugierig auf dieses spezielle Codebeispiel sind und immer noch Spaß haben, hier sind einige zusätzliche Details.
Aber wenn Sie neugierig auf dieses spezielle Codebeispiel sind und immer noch Spaß haben, hier sind einige zusätzliche Details.
#### Zeichenkette mit `value.startswith()` { #string-with-value-startswith }
#### String mit `value.startswith()` { #string-with-value-startswith }
Haben Sie bemerkt? Eine Zeichenkette mit `value.startswith()` kann ein Tuple übernehmen, und es wird jeden Wert im Tuple überprüfen:
Haben Sie bemerkt? Ein String mit `value.startswith()` kann ein Tuple übernehmen, und es wird jeden Wert im Tuple überprüfen:
@ -23,7 +23,7 @@ Aber wenn Sie sie mit Python-Typen deklarieren (im obigen Beispiel als `int`), w
Die gleichen Prozesse, die für Pfad-Parameter gelten, werden auch auf Query-Parameter angewendet:
Die gleichen Prozesse, die für Pfad-Parameter gelten, werden auch auf Query-Parameter angewendet:
* EditorUnterstützung (natürlich)
* Editor-Unterstützung (natürlich)
* Daten-<dfntitle="Konvertieren des Strings, der von einem HTTP-Request kommt, in Python-Daten">„Parsen“</dfn>
* Daten-<dfntitle="Konvertieren des Strings, der von einem HTTP-Request kommt, in Python-Daten">„Parsen“</dfn>
* Datenvalidierung
* Datenvalidierung
* Automatische Dokumentation
* Automatische Dokumentation
@ -67,17 +67,17 @@ In diesem Fall wird der Funktionsparameter `q` optional und standardmäßig `Non
/// tip | Tipp
/// tip | Tipp
Beachten Sie auch, dass **FastAPI** intelligent genug ist, um zu erkennen, dass `item_id` ein Pfad-Parameter ist und `q` keiner, daher muss letzteres ein Query-Parameter sein.
Beachten Sie auch, dass **FastAPI** intelligent genug ist, um zu erkennen, dass der Pfad-Parameter `item_id` ein Pfad-Parameter ist und `q` keiner, daher muss letzteres ein Query-Parameter sein.
gehen, oder zu irgendeiner anderen Variante der Groß-/Kleinschreibung (Alles groß, Anfangsbuchstabe groß, usw.), dann wird Ihre Funktion den Parameter `short` mit dem `bool`-Wert `True` sehen, ansonsten mit dem Wert `False`.
gehen, oder zu irgendeiner anderen Variante der Groß-/Kleinschreibung (Alles groß, Anfangsbuchstabe groß, usw.), dann wird Ihre Funktion den Parameter `short` mit dem `bool`-Wert `True` sehen, ansonsten mit dem Wert `False`.
## Mehrere Pfad- und Query-Parameter { #multiple-path-and-query-parameters }
## Mehrere Pfad- und Query-Parameter { #multiple-path-and-query-parameters }
Sie können mehrere Pfad-Parameter und Query-Parameter gleichzeitig deklarieren, **FastAPI** weiß, welches welcher ist.
Sie können mehrere Pfad-Parameter und Query-Parameter gleichzeitig deklarieren, **FastAPI** weiß, welches welcher ist.
@ -121,7 +122,7 @@ Parameter werden anhand ihres Namens erkannt:
Wenn Sie einen Defaultwert für Nicht-Pfad-Parameter deklarieren (Bis jetzt haben wir nur Query-Parameter gesehen), dann ist der Parameter nicht erforderlich.
Wenn Sie einen Defaultwert für Nicht-Pfad-Parameter deklarieren (bis jetzt haben wir nur Query-Parameter gesehen), dann ist der Parameter nicht erforderlich.
Wenn Sie keinen spezifischen Wert haben wollen, sondern der Parameter einfach optional sein soll, dann setzen Sie den Defaultwert auf `None`.
Wenn Sie keinen spezifischen Wert haben wollen, sondern der Parameter einfach optional sein soll, dann setzen Sie den Defaultwert auf `None`.
@ -129,7 +130,7 @@ Aber wenn Sie wollen, dass ein Query-Parameter erforderlich ist, vergeben Sie ei
@ -44,7 +44,7 @@ Um Dateibodys zu deklarieren, müssen Sie `File` verwenden, da diese Parameter s
Die Dateien werden als „Formulardaten“ hochgeladen.
Die Dateien werden als „Formulardaten“ hochgeladen.
Wenn Sie den Typ Ihrer *Pfadoperation-Funktion* als `bytes` deklarieren, wird **FastAPI** die Datei für Sie auslesen, und Sie erhalten den Inhalt als `bytes`.
Wenn Sie den Typ des Parameters Ihrer *Pfadoperation-Funktion* als `bytes` deklarieren, wird **FastAPI** die Datei für Sie auslesen, und Sie erhalten den Inhalt als `bytes`.
Bedenken Sie, dass das bedeutet, dass sich der gesamte Inhalt der Datei im Arbeitsspeicher befindet. Das wird für kleinere Dateien gut funktionieren.
Bedenken Sie, dass das bedeutet, dass sich der gesamte Inhalt der Datei im Arbeitsspeicher befindet. Das wird für kleinere Dateien gut funktionieren.
@ -63,27 +63,27 @@ Definieren Sie einen Datei-Parameter mit dem Typ `UploadFile`:
* Eine Datei, die bis zu einem bestimmten Größen-Limit im Arbeitsspeicher behalten wird, und wenn das Limit überschritten wird, auf der Festplatte gespeichert wird.
* Eine Datei, die bis zu einem bestimmten Größen-Limit im Arbeitsspeicher behalten wird, und wenn das Limit überschritten wird, auf der Festplatte gespeichert wird.
* Das bedeutet, es wird für große Dateien wie Bilder, Videos, große Binärdateien, usw. gut funktionieren, ohne den ganzen Arbeitsspeicher aufzubrauchen.
* Das bedeutet, es wird für große Dateien wie Bilder, Videos, große Binärdateien, usw. gut funktionieren, ohne den ganzen Arbeitsspeicher aufzubrauchen.
* Sie können Metadaten aus der hochgeladenen Datei auslesen.
* Sie können Metadaten aus der hochgeladenen Datei auslesen.
* Es hat eine [dateiartige](https://docs.python.org/3/glossary.html#term-file-like-object) `async`hrone Schnittstelle.
* Es hat eine [dateiartige](https://docs.python.org/3/glossary.html#term-file-like-object) `async`-Schnittstelle.
* Es stellt ein tatsächliches Python-[`SpooledTemporaryFile`](https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile)-Objekt bereit, welches Sie direkt anderen Bibliotheken übergeben können, die ein dateiartiges Objekt erwarten.
* Es stellt ein tatsächliches Python-[`SpooledTemporaryFile`](https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile)-Objekt bereit, welches Sie direkt anderen Bibliotheken übergeben können, die ein dateiartiges Objekt erwarten.
### `UploadFile` { #uploadfile }
### `UploadFile` { #uploadfile }
`UploadFile` hat die folgenden Attribute:
`UploadFile` hat die folgenden Attribute:
* `filename`: Ein `str` mit dem ursprünglichen Namen der hochgeladenen Datei (z. B. `meinbild.jpg`).
* `filename`: Ein `str` mit dem ursprünglichen Namen der hochgeladenen Datei (z. B. `myimage.jpg`).
* `content_type`: Ein `str` mit dem Inhaltstyp (MIME-Typ / Medientyp) (z. B. `image/jpeg`).
* `content_type`: Ein `str` mit dem Inhaltstyp (MIME-Typ / Medientyp) (z. B. `image/jpeg`).
* `file`: Ein [`SpooledTemporaryFile`](https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile) (ein [dateiartiges](https://docs.python.org/3/glossary.html#term-file-like-object) Objekt). Das ist das tatsächliche Python-Objekt, das Sie direkt anderen Funktionen oder Bibliotheken übergeben können, welche ein „file-like“-Objekt erwarten.
* `file`: Ein [`SpooledTemporaryFile`](https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile) (ein [dateiartiges](https://docs.python.org/3/glossary.html#term-file-like-object) Objekt). Das ist das tatsächliche Python-Dateiobjekt, das Sie direkt anderen Funktionen oder Bibliotheken übergeben können, welche ein „file-like“-Objekt erwarten.
`UploadFile` hat die folgenden `async`hronen Methoden. Sie alle rufen die entsprechenden Methoden des darunterliegenden Datei-Objekts auf (wobei intern `SpooledTemporaryFile` verwendet wird).
`UploadFile` hat die folgenden `async`-Methoden. Sie alle rufen die entsprechenden Methoden des darunterliegenden Datei-Objekts auf (wobei intern `SpooledTemporaryFile` verwendet wird).
* `write(daten)`: Schreibt `daten` (`str` oder `bytes`) in die Datei.
* `write(data)`: Schreibt `data` (`str` oder `bytes`) in die Datei.
* `read(anzahl)`: Liest `anzahl` (`int`) bytes/Zeichen aus der Datei.
* `read(size)`: Liest `size` (`int`) Bytes/Zeichen aus der Datei.
* `seek(versatz)`: Geht zur Position `versatz` (`int`) in der Datei.
* `seek(offset)`: Geht zur Byte-Position `offset` (`int`) in der Datei.
* z. B. würde `await myfile.seek(0)` zum Anfang der Datei gehen.
* z. B. würde `await myfile.seek(0)` zum Anfang der Datei gehen.
* Das ist besonders dann nützlich, wenn Sie `await myfile.read()` einmal ausführen und dann diese Inhalte erneut auslesen müssen.
* Das ist besonders dann nützlich, wenn Sie `await myfile.read()` einmal ausführen und dann diese Inhalte erneut auslesen müssen.
* `close()`: Schließt die Datei.
* `close()`: Schließt die Datei.
Da alle diese Methoden `async`hron sind, müssen Sie sie „await“en („erwarten“).
Da alle diese Methoden `async`-Methoden sind, müssen Sie sie „await“en („erwarten“).
Zum Beispiel können Sie innerhalb einer `async`*Pfadoperation-Funktion* den Inhalt wie folgt auslesen:
Zum Beispiel können Sie innerhalb einer `async`*Pfadoperation-Funktion* den Inhalt wie folgt auslesen:
@ -105,7 +105,7 @@ Wenn Sie die `async`-Methoden verwenden, führt **FastAPI** die Datei-Methoden i
/// note | Technische Details zu Starlette
/// note | Technische Details zu Starlette
FastAPIs `UploadFile` erbt direkt von Starlettes `UploadFile`, fügt aber ein paar notwendige Teile hinzu, um es kompatibel mit **Pydantic** und anderen Teilen von FastAPI zu machen.
**FastAPI**s `UploadFile` erbt direkt von **Starlette**s `UploadFile`, fügt aber ein paar notwendige Teile hinzu, um es kompatibel mit **Pydantic** und anderen Teilen von FastAPI zu machen.
///
///
@ -113,15 +113,15 @@ FastAPIs `UploadFile` erbt direkt von Starlettes `UploadFile`, fügt aber ein pa
Der Weg, wie HTML-Formulare (`<form></form>`) die Daten zum Server senden, verwendet normalerweise eine „spezielle“ Kodierung für diese Daten. Diese unterscheidet sich von JSON.
Der Weg, wie HTML-Formulare (`<form></form>`) die Daten zum Server senden, verwendet normalerweise eine „spezielle“ Kodierung für diese Daten. Diese unterscheidet sich von JSON.
**FastAPI** stellt sicher, dass diese Daten korrekt ausgelesen werden, statt JSON zu erwarten.
**FastAPI** stellt sicher, dass diese Daten von der richtigen Stelle ausgelesen werden, statt JSON zu erwarten.
/// note | Technische Details
/// note | Technische Details
Daten aus Formularen werden, wenn es keine Dateien sind, normalerweise mit dem <abbrtitle='Media type – Medientyp, Typ des Mediums'>„media type“</abbr>`application/x-www-form-urlencoded` kodiert.
Daten aus Formularen werden, wenn sie keine Dateien enthalten, normalerweise mit dem <abbrtitle='Media type – Medientyp, Typ des Mediums'>„media type“</abbr>`application/x-www-form-urlencoded` kodiert.
Sollte das Formular aber Dateien enthalten, dann werden diese mit `multipart/form-data` kodiert. Wenn Sie `File` verwenden, wird **FastAPI** wissen, dass es die Dateien vom korrekten Teil des Bodys holen muss.
Sollte das Formular aber Dateien enthalten, dann werden diese mit `multipart/form-data` kodiert. Wenn Sie `File` verwenden, wird **FastAPI** wissen, dass es die Dateien vom korrekten Teil des Bodys holen muss.
Wenn Sie mehr über diese Kodierungen und Formularfelder lesen möchten, besuchen Sie die [<abbr title="Mozilla Developer Network – Mozilla-Entwicklernetzwerk">MDN</abbr>-Webdokumentation für `POST`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST).
Wenn Sie mehr über diese Kodierungen und Formularfelder lesen möchten, besuchen Sie die [<abbr title="Mozilla Developer Network - Mozilla-Entwicklernetzwerk">MDN</abbr>-Webdokumentation für `POST`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST).
///
///
@ -149,7 +149,7 @@ Sie können auch `File()` mit `UploadFile` verwenden, um zum Beispiel zusätzlic
Es ist auch möglich, mehrere Dateien gleichzeitig hochzuladen.
Es ist auch möglich, mehrere Dateien gleichzeitig hochzuladen.
Diese werden demselben Formularfeld zugeordnet, welches mit den Formulardaten gesendet wird.
Diese werden demselben „Formularfeld“ zugeordnet, welches mittels „Formulardaten“ gesendet wird.
Um das zu machen, deklarieren Sie eine Liste von `bytes` oder `UploadFile`s:
Um das zu machen, deklarieren Sie eine Liste von `bytes` oder `UploadFile`s:
Genauso wie Sie ein Responsemodell angeben können, können Sie auch den HTTP-Statuscode für die <abbrtitle="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr> mit dem Parameter `status_code` in jeder der *Pfadoperationen* deklarieren:
Genauso wie Sie ein Responsemodell angeben können, können Sie auch den HTTP-Statuscode für die <abbrtitle="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr> mit dem Parameter `status_code` in jeder der *Pfadoperationen* deklarieren:
@ -14,7 +14,7 @@ Diese zusätzlichen Informationen werden unverändert zum für dieses Modell aus
Sie können das Attribut `model_config` verwenden, das ein <abbrtitle="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> akzeptiert, wie beschrieben in [Pydantic-Dokumentation: Configuration](https://docs.pydantic.dev/latest/api/config/).
Sie können das Attribut `model_config` verwenden, das ein <abbrtitle="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> akzeptiert, wie beschrieben in [Pydantic-Dokumentation: Configuration](https://docs.pydantic.dev/latest/api/config/).
Sie können `json_schema_extra` setzen, mit einem `dict`, das alle zusätzlichen Daten enthält, die im generierten JSON-Schema angezeigt werden sollen, einschließlich `examples`.
Sie können `"json_schema_extra"` setzen, mit einem `dict`, das alle zusätzlichen Daten enthält, die im generierten JSON-Schema angezeigt werden sollen, einschließlich `examples`.
/// tip | Tipp
/// tip | Tipp
@ -88,7 +88,7 @@ Das Format dieses OpenAPI-spezifischen Felds `examples` ist ein `dict` mit **meh
Dies erfolgt nicht innerhalb jedes in OpenAPI enthaltenen JSON-Schemas, sondern außerhalb, in der *Pfadoperation*.
Dies erfolgt nicht innerhalb jedes in OpenAPI enthaltenen JSON-Schemas, sondern außerhalb, in der *Pfadoperation*.
### Verwendung des Parameters `openapi_examples` { #using-the-openapi-examples-parameter }
### Den Parameter `openapi_examples` verwenden { #using-the-openapi-examples-parameter }
Sie können die OpenAPI-spezifischen `examples` in FastAPI mit dem Parameter `openapi_examples` deklarieren, für:
Sie können die OpenAPI-spezifischen `examples` in FastAPI mit dem Parameter `openapi_examples` deklarieren, für:
@ -189,9 +189,9 @@ In Versionen von FastAPI vor 0.99.0 (0.99.0 und höher verwenden das neuere Open
Aber jetzt, da FastAPI 0.99.0 und höher, OpenAPI 3.1.0 verwendet, das JSON Schema 2020-12 verwendet, und Swagger UI 5.0.0 und höher, ist alles konsistenter und die Beispiele sind in JSON Schema enthalten.
Aber jetzt, da FastAPI 0.99.0 und höher, OpenAPI 3.1.0 verwendet, das JSON Schema 2020-12 verwendet, und Swagger UI 5.0.0 und höher, ist alles konsistenter und die Beispiele sind in JSON Schema enthalten.
### Swagger-Benutzeroberfläche und OpenAPI-spezifische `examples` { #swagger-ui-and-openapi-specific-examples }
### Swagger UI und OpenAPI-spezifische `examples` { #swagger-ui-and-openapi-specific-examples }
Da die Swagger-Benutzeroberfläche derzeit nicht mehrere JSON Schema Beispiele unterstützt (Stand: 26.08.2023), hatten Benutzer keine Möglichkeit, mehrere Beispiele in der Dokumentation anzuzeigen.
Da Swagger UI derzeit nicht mehrere JSON Schema Beispiele unterstützt (Stand: 26.08.2023), hatten Benutzer keine Möglichkeit, mehrere Beispiele in der Dokumentation anzuzeigen.
Um dieses Problem zu lösen, hat FastAPI `0.103.0`**Unterstützung** für die Deklaration desselben alten **OpenAPI-spezifischen**`examples`-Felds mit dem neuen Parameter `openapi_examples` hinzugefügt. 🤓
Um dieses Problem zu lösen, hat FastAPI `0.103.0`**Unterstützung** für die Deklaration desselben alten **OpenAPI-spezifischen**`examples`-Felds mit dem neuen Parameter `openapi_examples` hinzugefügt. 🤓
@ -120,7 +120,7 @@ Und noch eine, um einen Benutzer zu authentifizieren und zurückzugeben.
Wenn `authenticate_user` mit einem Benutzernamen aufgerufen wird, der in der Datenbank nicht existiert, führen wir dennoch `verify_password` gegen einen Dummy-Hash aus.
Wenn `authenticate_user` mit einem Benutzernamen aufgerufen wird, der in der Datenbank nicht existiert, führen wir dennoch `verify_password` gegen einen Dummy-Hash aus.
So stellt man sicher, dass der Endpunkt ungefähr gleich viel Zeit für die Antwort benötigt, unabhängig davon, ob der Benutzername gültig ist oder nicht. Dadurch werden Timing-Angriffe verhindert, mit denen vorhandene Benutzernamen ermittelt werden könnten.
So stellt man sicher, dass der Endpunkt ungefähr gleich viel Zeit für die Antwort benötigt, unabhängig davon, ob der Benutzername gültig ist oder nicht. Dadurch werden **Timing-Angriffe** verhindert, mit denen vorhandene Benutzernamen ermittelt werden könnten.
/// note | Hinweis
/// note | Hinweis
@ -168,7 +168,7 @@ Wenn der Token ungültig ist, geben Sie sofort einen HTTP-Fehler zurück.
@ -20,7 +20,7 @@ Die Spezifikation besagt auch, dass `username` und `password` als Formulardaten
### `scope` { #scope }
### `scope` { #scope }
Ferner sagt die Spezifikation, dass der Client ein weiteres Formularfeld "`scope`" („Geltungsbereich“) senden kann.
Ferner sagt die Spezifikation, dass der Client ein weiteres Formularfeld „`scope`“ senden kann.
Der Name des Formularfelds lautet `scope` (im Singular), tatsächlich handelt es sich jedoch um einen langen String mit durch Leerzeichen getrennten „Scopes“.
Der Name des Formularfelds lautet `scope` (im Singular), tatsächlich handelt es sich jedoch um einen langen String mit durch Leerzeichen getrennten „Scopes“.
@ -120,7 +120,7 @@ Immer wenn Sie genau den gleichen Inhalt (genau das gleiche Passwort) übergeben
Sie können jedoch nicht vom Kauderwelsch zurück zum Passwort konvertieren.
Sie können jedoch nicht vom Kauderwelsch zurück zum Passwort konvertieren.
@ -8,7 +8,7 @@ Hier werden wir ein Beispiel mit [SQLModel](https://sqlmodel.tiangolo.com/) sehe
/// tip | Tipp
/// tip | Tipp
Sie könnten jede andere SQL- oder NoSQL-Datenbankbibliothek verwenden, die Sie möchten (in einigen Fällen als <abbrtitle="Object Relational Mapper – Objektrelationaler Mapper: Ein Fachbegriff für eine Bibliothek, in der einige Klassen SQL-Tabellen und Instanzen Zeilen in diesen Tabellen darstellen">„ORMs“</abbr> bezeichnet), FastAPI zwingt Sie nicht, irgendetwas zu verwenden. 😎
Sie könnten jede andere SQL- oder NoSQL-Datenbankbibliothek verwenden, die Sie möchten (in einigen Fällen als <abbrtitle="Objektrelationaler Mapper: Ein Fachbegriff für eine Bibliothek, in der einige Klassen SQL-Tabellen und Instanzen Zeilen in diesen Tabellen darstellen">„ORMs“</abbr> bezeichnet), FastAPI zwingt Sie nicht, irgendetwas zu verwenden. 😎
///
///
@ -121,7 +121,7 @@ Da jedes SQLModel-Modell auch ein Pydantic-Modell ist, können Sie es in denselb
Wenn Sie beispielsweise einen Parameter vom Typ `Hero` deklarieren, wird er aus dem **JSON-Body** gelesen.
Wenn Sie beispielsweise einen Parameter vom Typ `Hero` deklarieren, wird er aus dem **JSON-Body** gelesen.
Auf die gleiche Weise können Sie es als **Rückgabetyp** der Funktion deklarieren, und dann wird die Form der Daten in der automatischen API-Dokumentation angezeigt.
Auf die gleiche Weise können Sie es als **Rückgabetyp** der Funktion deklarieren, und dann wird die Form der Daten in der automatischen API-Dokumentations-UI angezeigt.
@ -266,7 +266,7 @@ In der vorherigen Version der App hatten wir keine Möglichkeit, einen Helden **
Das `HeroUpdate`-*Datenmodell* ist etwas Besonderes, es hat **die selben Felder**, die benötigt werden, um einen neuen Helden zu erstellen, aber alle Felder sind **optional** (sie haben alle einen Defaultwert). Auf diese Weise, wenn Sie einen Helden aktualisieren, können Sie nur die Felder senden, die Sie aktualisieren möchten.
Das `HeroUpdate`-*Datenmodell* ist etwas Besonderes, es hat **die selben Felder**, die benötigt werden, um einen neuen Helden zu erstellen, aber alle Felder sind **optional** (sie haben alle einen Defaultwert). Auf diese Weise, wenn Sie einen Helden aktualisieren, können Sie nur die Felder senden, die Sie aktualisieren möchten.
Da sich tatsächlich **alle Felder ändern** (der Typ enthält jetzt `None` und sie haben jetzt einen Standardwert von `None`), müssen wir sie erneut **deklarieren**.
Da sich tatsächlich **alle Felder ändern** (der Typ enthält jetzt `None` und sie haben jetzt einen Defaultwert von `None`), müssen wir sie erneut **deklarieren**.
Wir müssen wirklich nicht von `HeroBase` erben, weil wir alle Felder neu deklarieren. Ich lasse es aus Konsistenzgründen erben, aber das ist nicht notwendig. Es ist mehr eine Frage des persönlichen Geschmacks. 🤷
Wir müssen wirklich nicht von `HeroBase` erben, weil wir alle Felder neu deklarieren. Ich lasse es aus Konsistenzgründen erben, aber das ist nicht notwendig. Es ist mehr eine Frage des persönlichen Geschmacks. 🤷
Wenn Sie möchten, dass der Client Informationen im Request übergibt und Sie nicht wissen, wie das geht, können Sie suchen (googeln), wie es mit `httpx` gemacht wird, oder sogar, wie es mit `requests` gemacht wird, da das Design von HTTPX auf dem Design von Requests basiert.
Immer wenn der Client Informationen im Request übergeben soll und Sie nicht wissen, wie, können Sie danach suchen (googeln), wie es mit `httpx` gemacht wird, oder sogar, wie es mit `requests` gemacht wird, da das Design von HTTPX auf dem Design von Requests basiert.
Dann machen Sie in Ihren Tests einfach das gleiche.
Dann machen Sie in Ihren Tests einfach das gleiche.
Dieser Befehl erstellt oder ändert einige [Umgebungsvariablen](environment-variables.md), die für die nächsten Befehle verfügbar sein werden.
Dieser Befehl erstellt oder ändert einige [Umgebungsvariablen](environment-variables.md), die für die nächsten Befehle verfügbar sein werden.
Eine dieser Variablen ist die `PATH`-Umgebungsvariable.
Eine dieser Variablen ist die `PATH`-Variable.
/// tip | Tipp
/// tip | Tipp
@ -649,7 +651,7 @@ Sie können mehr über die `PATH`-Umgebungsvariable im Abschnitt [Umgebungsvaria
Das Aktivieren einer virtuellen Umgebung fügt deren Pfad `.venv/bin` (auf Linux und macOS) oder `.venv\Scripts` (auf Windows) zur `PATH`-Umgebungsvariable hinzu.
Das Aktivieren einer virtuellen Umgebung fügt deren Pfad `.venv/bin` (auf Linux und macOS) oder `.venv\Scripts` (auf Windows) zur `PATH`-Umgebungsvariable hinzu.
Angenommen, die `PATH`-Umgebungsvariable sah vor dem Aktivieren der Umgebung so aus:
Angenommen, die `PATH`-Variable sah vor dem Aktivieren der Umgebung so aus:
//// tab | Linux, macOS
//// tab | Linux, macOS
@ -678,7 +680,7 @@ Das bedeutet, dass das System nach Programmen sucht in:
////
////
Nach dem Aktivieren der virtuellen Umgebung würde die `PATH`-Umgebungsvariable folgendermaßen aussehen:
Nach dem Aktivieren der virtuellen Umgebung würde die `PATH`-Variable folgendermaßen aussehen:
//// tab | Linux, macOS
//// tab | Linux, macOS
@ -728,7 +730,7 @@ finden und dieses verwenden.
////
////
Ein wichtiger Punkt ist, dass es den Pfad der virtuellen Umgebung am **Anfang** der `PATH`-Umgebungsvariable platziert. Das System wird es **vor** allen anderen verfügbaren Pythons finden. Auf diese Weise, wenn Sie `python` ausführen, wird das Python **aus der virtuellen Umgebung** verwendet anstelle eines anderen `python` (zum Beispiel, einem `python` aus einer globalen Umgebung).
Ein wichtiger Punkt ist, dass es den Pfad der virtuellen Umgebung am **Anfang** der `PATH`-Variable platziert. Das System wird es **vor** allen anderen verfügbaren Pythons finden. Auf diese Weise, wenn Sie `python` ausführen, wird das Python **aus der virtuellen Umgebung** verwendet anstelle eines anderen `python` (zum Beispiel, einem `python` aus einer globalen Umgebung).
Das Aktivieren einer virtuellen Umgebung ändert auch ein paar andere Dinge, aber dies ist eines der wichtigsten Dinge, die es tut.
Das Aktivieren einer virtuellen Umgebung ändert auch ein paar andere Dinge, aber dies ist eines der wichtigsten Dinge, die es tut.
@ -20,20 +20,6 @@ FastAPI automatically generates **OpenAPI 3.1** specifications, so any tool you
///
///
## SDK Generators from FastAPI Sponsors { #sdk-generators-from-fastapi-sponsors }
This section highlights **venture-backed** and **company-supported** solutions from companies that sponsor FastAPI. These products provide **additional features** and **integrations** on top of high-quality generated SDKs.
By ✨ [**sponsoring FastAPI**](https://github.com/sponsors/tiangolo) ✨, these companies help ensure the framework and its **ecosystem** remain healthy and **sustainable**.
Their sponsorship also demonstrates a strong commitment to the FastAPI **community** (you), showing that they care not only about offering a **great service** but also about supporting a **robust and thriving framework**, FastAPI. 🙇
Some of these solutions may also be open source or offer free tiers, so you can try them without a financial commitment. Other commercial SDK generators are available and can be found online. 🤓
## Create a TypeScript SDK { #create-a-typescript-sdk }
## Create a TypeScript SDK { #create-a-typescript-sdk }
* ✨ Support dependencies in `app.frontend()`, e.g. for automatic cookie authentication for the frontend. PR [#15908](https://github.com/fastapi/fastapi/pull/15908) by [@tiangolo](https://github.com/tiangolo).
### Translations
* 🌐 Update translations for fr (update-outdated). PR [#15897](https://github.com/fastapi/fastapi/pull/15897) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for ja (update-outdated). PR [#15895](https://github.com/fastapi/fastapi/pull/15895) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for zh-hant (update-outdated). PR [#15896](https://github.com/fastapi/fastapi/pull/15896) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for de (update-outdated). PR [#15899](https://github.com/fastapi/fastapi/pull/15899) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for es (update-outdated). PR [#15892](https://github.com/fastapi/fastapi/pull/15892) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for tr (update-outdated). PR [#15891](https://github.com/fastapi/fastapi/pull/15891) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for pt (update-outdated). PR [#15893](https://github.com/fastapi/fastapi/pull/15893) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for zh (update-outdated). PR [#15898](https://github.com/fastapi/fastapi/pull/15898) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for uk (update-outdated). PR [#15900](https://github.com/fastapi/fastapi/pull/15900) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for ko (update-outdated). PR [#15890](https://github.com/fastapi/fastapi/pull/15890) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for ru (update-outdated). PR [#15894](https://github.com/fastapi/fastapi/pull/15894) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for ko (add-missing). PR [#15888](https://github.com/fastapi/fastapi/pull/15888) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for es (add-missing). PR [#15880](https://github.com/fastapi/fastapi/pull/15880) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for zh-hant (add-missing). PR [#15889](https://github.com/fastapi/fastapi/pull/15889) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for pt (add-missing). PR [#15883](https://github.com/fastapi/fastapi/pull/15883) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for zh (add-missing). PR [#15885](https://github.com/fastapi/fastapi/pull/15885) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for ja (add-missing). PR [#15882](https://github.com/fastapi/fastapi/pull/15882) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for tr (add-missing). PR [#15887](https://github.com/fastapi/fastapi/pull/15887) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for uk (add-missing). PR [#15886](https://github.com/fastapi/fastapi/pull/15886) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for fr (add-missing). PR [#15881](https://github.com/fastapi/fastapi/pull/15881) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for de (add-missing). PR [#15884](https://github.com/fastapi/fastapi/pull/15884) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for ru (add-missing). PR [#15879](https://github.com/fastapi/fastapi/pull/15879) by [@tiangolo](https://github.com/tiangolo).
### Internal
* 👥 Update FastAPI People - Experts. PR [#15909](https://github.com/fastapi/fastapi/pull/15909) by [@tiangolo](https://github.com/tiangolo).
* 👥 Update FastAPI People - Contributors and Translators. PR [#15878](https://github.com/fastapi/fastapi/pull/15878) by [@tiangolo](https://github.com/tiangolo).
* 👷 Remove not needed `allow-unsafe-pr-checkout: true`. PR [#15876](https://github.com/fastapi/fastapi/pull/15876) by [@YuriiMotov](https://github.com/YuriiMotov).
* ⬆ Bump the github-actions group with 5 updates. PR [#15872](https://github.com/fastapi/fastapi/pull/15872) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump the python-packages group across 1 directory with 10 updates. PR [#15870](https://github.com/fastapi/fastapi/pull/15870) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump CodSpeedHQ/action from 4.17.0 to 4.17.5 in the github-actions group. PR [#15826](https://github.com/fastapi/fastapi/pull/15826) by [@dependabot[bot]](https://github.com/apps/dependabot).
## 0.138.2 (2026-06-29)
### Refactors
* ♻️ Make `app.frontend()` return 404 for methods other than `GET` or `HEAD` with no static file matches. PR [#15863](https://github.com/fastapi/fastapi/pull/15863) by [@tiangolo](https://github.com/tiangolo).
### Internal
### Internal
* 🔧 Update sponsors: remove Stainless. PR [#15862](https://github.com/fastapi/fastapi/pull/15862) by [@tiangolo](https://github.com/tiangolo).
* ♻️ Refactor how sponsors data is handled for banners. PR [#15852](https://github.com/fastapi/fastapi/pull/15852) by [@tiangolo](https://github.com/tiangolo).
* ♻️ Refactor how sponsors data is handled for banners. PR [#15852](https://github.com/fastapi/fastapi/pull/15852) by [@tiangolo](https://github.com/tiangolo).
**FastAPI** uses this fallback only for requests that look like browser navigation. Missing files like JavaScript, CSS, and images still return `404`.
**FastAPI** uses this fallback only for `GET` and `HEAD` requests that look like browser navigation. Missing files like JavaScript, CSS, and images still return `404`.
Requests with other methods, like `POST` or `PUT`, to paths that only match the frontend fallback also return `404`. Regular **FastAPI***path operations* still have higher priority than frontend routes.
/// tip
/// tip
@ -124,6 +126,12 @@ In this example, frontend paths are served under `/app`.
Any regular *path operations* in the app will still take precedence, including in other routers.
Any regular *path operations* in the app will still take precedence, including in other routers.
## Dependencies and Middleware { #dependencies-and-middleware }
Frontend responses run inside the normal **FastAPI** application, so HTTP middleware applies to them.
Dependencies from the app, from an `APIRouter`, and from `include_router()` also apply to frontend responses. This can be useful for protecting a frontend with cookie authentication or similar.
## Static Build Output Only { #static-build-output-only }
## Static Build Output Only { #static-build-output-only }
`app.frontend()` serves files already generated by your frontend build.
`app.frontend()` serves files already generated by your frontend build.
@ -197,7 +197,7 @@ Aquí algunas cosas envueltas en elementos HTML "abbr" (algunas son inventadas):
### El abbr da una frase completa y una explicación { #the-abbr-gives-a-full-phrase-and-an-explanation }
### El abbr da una frase completa y una explicación { #the-abbr-gives-a-full-phrase-and-an-explanation }
* <abbrtitle="Mozilla Developer Network - Red de Desarrolladores de Mozilla: documentación para desarrolladores, escrita por la gente de Firefox">MDN</abbr>
* <abbrtitle="Mozilla Developer Network - Red de Desarrolladores de Mozilla: documentación para desarrolladores, escrita por la gente de Firefox">MDN</abbr>
* <abbrtitle="Input/Output - Entrada/Salida: lectura o escritura de disco, comunicaciones de red.">I/O</abbr>.
* <abbrtitle="Input/Output - I/O: lectura o escritura de disco, comunicaciones de red.">I/O</abbr>.
////
////
@ -464,7 +464,7 @@ Para instrucciones específicas del idioma, mira p. ej. la sección `### Heading
# Códigos de Estado Adicionales { #additional-status-codes }
# Códigos de Estado Adicionales { #additional-status-codes }
Por defecto, **FastAPI** devolverá los responses usando un `JSONResponse`, colocando el contenido que devuelves desde tu *path operation* dentro de ese `JSONResponse`.
Por defecto, **FastAPI** devolverá los responses usando un `JSONResponse`, colocando el contenido que devuelves desde tu *path operation* dentro de ese `JSONResponse`.
Usará el código de estado por defecto o el que configures en tu *path operation*.
Usará el código de estado por defecto o el que configures en tu *path operation*.
@ -10,7 +10,7 @@ Imaginemos que queremos tener una dependencia que revise si el parámetro de que
Pero queremos poder parametrizar ese contenido fijo.
Pero queremos poder parametrizar ese contenido fijo.
## Una *instance* "callable" { #a-callable-instance }
## Una instance "callable" { #a-callable-instance }
En Python hay una forma de hacer que una instance de una clase sea un "callable".
En Python hay una forma de hacer que una instance de una clase sea un "callable".
@ -108,7 +108,7 @@ Como verás abajo, esto es muy similar al comportamiento anterior a la versión
Hay algunos casos de uso con condiciones específicas que podrían beneficiarse del comportamiento antiguo de ejecutar el código de salida de dependencias con `yield` antes de enviar la response.
Hay algunos casos de uso con condiciones específicas que podrían beneficiarse del comportamiento antiguo de ejecutar el código de salida de dependencias con `yield` antes de enviar la response.
Por ejemplo, imagina que tienes código que usa una sesión de base de datos en una dependencia con `yield` solo para verificar un usuario, pero la sesión de base de datos no se vuelve a usar en la *path operation function*, solo en la dependencia, y la response tarda mucho en enviarse, como un `StreamingResponse` que envía datos lentamente, pero que por alguna razón no usa la base de datos.
Por ejemplo, imagina que tienes código que usa una sesión de base de datos en una dependencia con `yield` solo para verificar un usuario, pero la sesión de base de datos no se vuelve a usar en la *path operation function*, solo en la dependencia, **y** la response tarda mucho en enviarse, como un `StreamingResponse` que envía datos lentamente, pero que por alguna razón no usa la base de datos.
En este caso, la sesión de base de datos se mantendría hasta que la response termine de enviarse, pero si no la usas, entonces no sería necesario mantenerla.
En este caso, la sesión de base de datos se mantendría hasta que la response termine de enviarse, pero si no la usas, entonces no sería necesario mantenerla.
@ -6,13 +6,13 @@ De la misma manera, puedes definir lógica (código) que debería ser ejecutada
Debido a que este código se ejecuta antes de que la aplicación **comience** a tomar requests, y justo después de que **termine** de manejarlos, cubre todo el **lifespan** de la aplicación (la palabra "lifespan" será importante en un momento 😉).
Debido a que este código se ejecuta antes de que la aplicación **comience** a tomar requests, y justo después de que **termine** de manejarlos, cubre todo el **lifespan** de la aplicación (la palabra "lifespan" será importante en un momento 😉).
Esto puede ser muy útil para configurar **recursos** que necesitas usar para toda la app, y que son **compartidos** entre requests, y/o que necesitas **limpiar** después. Por ejemplo, un pool de conexiones a una base de datos, o cargando un modelo de machine learning compartido.
Esto puede ser muy útil para configurar **recursos** que necesitas usar para toda la app, y que son **compartidos** entre requests, y/o que necesitas **limpiar** después. Por ejemplo, un pool de conexiones a una base de datos, o cargando un modelo de Machine Learning compartido.
## Caso de Uso { #use-case }
## Caso de Uso { #use-case }
Empecemos con un ejemplo de **caso de uso** y luego veamos cómo resolverlo con esto.
Empecemos con un ejemplo de **caso de uso** y luego veamos cómo resolverlo con esto.
Imaginemos que tienes algunos **modelos de machine learning** que quieres usar para manejar requests. 🤖
Imaginemos que tienes algunos **modelos de Machine Learning** que quieres usar para manejar requests. 🤖
Los mismos modelos son compartidos entre requests, por lo que no es un modelo por request, o uno por usuario o algo similar.
Los mismos modelos son compartidos entre requests, por lo que no es un modelo por request, o uno por usuario o algo similar.
@ -32,7 +32,7 @@ Creamos una función asíncrona `lifespan()` con `yield` así:
Aquí estamos simulando la operación costosa de *startup* de cargar el modelo poniendo la función del (falso) modelo en el diccionario con modelos de machine learning antes del `yield`. Este código será ejecutado **antes** de que la aplicación **comience a tomar requests**, durante el *startup*.
Aquí estamos simulando la operación costosa de *startup* de cargar el modelo poniendo la función del (falso) modelo en el diccionario con modelos de Machine Learning antes del `yield`. Este código será ejecutado **antes** de que la aplicación **comience a tomar requests**, durante el *startup*.
Y luego, justo después del `yield`, quitaremos el modelo de memoria. Este código será ejecutado **después** de que la aplicación **termine de manejar requests**, justo antes del *shutdown*. Esto podría, por ejemplo, liberar recursos como la memoria o una GPU.
Y luego, justo después del `yield`, quitaremos el modelo de memoria. Este código será ejecutado **después** de que la aplicación **termine de manejar requests**, justo antes del *shutdown*. Esto podría, por ejemplo, liberar recursos como la memoria o una GPU.
@ -20,20 +20,6 @@ FastAPI genera automáticamente especificaciones **OpenAPI 3.1**, así que cualq
///
///
## Generadores de SDKs de sponsors de FastAPI { #sdk-generators-from-fastapi-sponsors }
Esta sección destaca soluciones **respaldadas por empresas** y **venture-backed** de compañías que sponsor FastAPI. Estos productos ofrecen **funcionalidades adicionales** e **integraciones** además de SDKs generados de alta calidad.
Al ✨ [**ser sponsor de FastAPI**](../help-fastapi.md#sponsor-the-author) ✨, estas compañías ayudan a asegurar que el framework y su **ecosistema** se mantengan saludables y **sustentables**.
Su sponsorship también demuestra un fuerte compromiso con la **comunidad** de FastAPI (tú), mostrando que no solo les importa ofrecer un **gran servicio**, sino también apoyar un **framework robusto y próspero**, FastAPI. 🙇
Algunas de estas soluciones también pueden ser open source u ofrecer niveles gratuitos, así que puedes probarlas sin un compromiso financiero. Hay otros generadores de SDK comerciales disponibles y se pueden encontrar en línea. 🤓
## Crea un SDK de TypeScript { #create-a-typescript-sdk }
## Crea un SDK de TypeScript { #create-a-typescript-sdk }
Empecemos con una aplicación simple de FastAPI:
Empecemos con una aplicación simple de FastAPI:
@ -52,7 +38,7 @@ Puedes ver esos esquemas porque fueron declarados con los modelos en la app.
Esa información está disponible en el **OpenAPI schema** de la app, y luego se muestra en la documentación de la API.
Esa información está disponible en el **OpenAPI schema** de la app, y luego se muestra en la documentación de la API.
Y esa misma información de los modelos que está incluida en OpenAPI es lo que puede usarse para **generar el código del cliente**.
Esa misma información de los modelos que está incluida en OpenAPI es lo que puede usarse para **generar el código del cliente**.
### Hey API { #hey-api }
### Hey API { #hey-api }
@ -131,7 +117,7 @@ Puedes **modificar** la forma en que estos operation IDs son **generados** para
En este caso tendrás que asegurarte de que cada operation ID sea **único** de alguna otra manera.
En este caso tendrás que asegurarte de que cada operation ID sea **único** de alguna otra manera.
Por ejemplo, podrías asegurarte de que cada *path operation* tenga un tag, y luego generar el operation ID basado en el **tag** y el **name** de la *path operation* (el nombre de la función).
Por ejemplo, podrías asegurarte de que cada *path operation* tenga un tag, y luego generar el operation ID basado en el **tag** y el **nombre** de la *path operation* (el nombre de la función).
### Función personalizada para generar ID único { #custom-generate-unique-id-function }
### Función personalizada para generar ID único { #custom-generate-unique-id-function }
@ -4,7 +4,7 @@ Si tu app necesita recibir y enviar datos JSON, pero necesitas incluir datos bin
## Base64 vs Archivos { #base64-vs-files }
## Base64 vs Archivos { #base64-vs-files }
Considera primero si puedes usar [Archivos en request](../tutorial/request-files.md) para subir datos binarios y [Response personalizada - FileResponse](./custom-response.md#fileresponse--fileresponse-) para enviar datos binarios, en lugar de codificarlos en JSON.
Considera primero si puedes usar [Archivos en request](../tutorial/request-files.md) para subir datos binarios y [Response personalizada - FileResponse](./custom-response.md#fileresponse) para enviar datos binarios, en lugar de codificarlos en JSON.
JSON solo puede contener strings codificados en UTF-8, así que no puede contener bytes crudos.
JSON solo puede contener strings codificados en UTF-8, así que no puede contener bytes crudos.
@ -14,7 +14,7 @@ Usa base64 solo si definitivamente necesitas incluir datos binarios en JSON y no
## Pydantic `bytes` { #pydantic-bytes }
## Pydantic `bytes` { #pydantic-bytes }
Puedes declarar un modelo de Pydantic con campos `bytes`, y luego usar `val_json_bytes` en la configuración del modelo para indicarle que use base64 para validar datos JSON de entrada; como parte de esa validación decodificará el string base64 en bytes.
Puedes declarar un modelo de Pydantic con campos `bytes`, y luego usar `val_json_bytes` en la configuración del modelo para indicarle que use base64 para *validar* datos JSON de entrada; como parte de esa validación decodificará el string base64 en bytes.
## Pydantic `bytes` para datos de salida { #pydantic-bytes-for-output-data }
## Pydantic `bytes` para datos de salida { #pydantic-bytes-for-output-data }
También puedes usar campos `bytes` con `ser_json_bytes` en la configuración del modelo para datos de salida, y Pydantic serializará los bytes como base64 al generar la response JSON.
También puedes usar campos `bytes` con `ser_json_bytes` en la configuración del modelo para datos de salida, y Pydantic *serializará* los bytes como base64 al generar la response JSON.
## Pydantic `bytes` para datos de entrada y salida { #pydantic-bytes-for-input-and-output-data }
## Pydantic `bytes` para datos de entrada y salida { #pydantic-bytes-for-input-and-output-data }
Y por supuesto, puedes usar el mismo modelo configurado para usar base64 para manejar tanto la entrada (*validate*) con `val_json_bytes` como la salida (*serialize*) con `ser_json_bytes` al recibir y enviar datos JSON.
Y por supuesto, puedes usar el mismo modelo configurado para usar base64 para manejar tanto la entrada (*validar*) con `val_json_bytes` como la salida (*serializar*) con `ser_json_bytes` al recibir y enviar datos JSON.
@ -173,7 +173,7 @@ Ahora usa el parámetro `callbacks` en el *decorador de path operation de tu API
/// tip | Consejo
/// tip | Consejo
Observa que no estás pasando el router en sí (`invoices_callback_router`) a `callbacks=`, sino su `.routes`, como en `invoices_callback_router.routes`. **FastAPI** usará esas rutas para generar la documentación OpenAPI del callback.
Observa que no estás pasando el router en sí (`invoices_callback_router`) a `callbacks=`, sino su `.routes`, como en `invoices_callback_router.routes`. FastAPI usará esas rutas para generar la documentación OpenAPI del callback.