Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
818066b271 | ||
|
|
632909b5f6 | ||
|
|
d71a936809 |
+2
-2
@@ -4,8 +4,8 @@ This is a mirror of the Fastapi repository.
|
||||
|
||||
**Synced from:** https://github.com/tiangolo/fastapi.git
|
||||
**Branch:** master
|
||||
**Commit:** d3e6a2931f95dcb044c09cbfc39e4b0e9e620fd4
|
||||
**Sync Date:** 2026-06-11
|
||||
**Commit:** 50113da16fec53b66b80d75e80a89296de4fa5a5
|
||||
**Sync Date:** 2026-09-11
|
||||
**Content:** Paths: docs, docs_src
|
||||
|
||||
---
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
# LLM-Testdatei { #llm-test-file }
|
||||
|
||||
Dieses Dokument testet, ob das <abbr title="Large Language Model - Großes Sprachmodell">LLM</abbr>, das die Dokumentation übersetzt, den <abbr title="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 <abbr title="Large Language Model - Großes Sprachmodell">LLM</abbr>, das die Dokumentation übersetzt, den <abbr title="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:
|
||||
|
||||
* 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.
|
||||
* 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.
|
||||
* Ü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:
|
||||
|
||||
@@ -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 }
|
||||
|
||||
* <dfn title="Eine Gruppe von Maschinen, die so konfiguriert sind, dass sie verbunden sind und in irgendeiner Weise zusammenarbeiten.">Cluster</dfn>
|
||||
* <dfn title="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`.
|
||||
|
||||
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
|
||||
* die Umgebungsvariable
|
||||
* die Umgebungsvariable
|
||||
* der `PATH`
|
||||
* die `PATH`-Umgebungsvariable
|
||||
* die `PATH`-Variable
|
||||
|
||||
* die Authentifizierung
|
||||
* der Authentifizierungsanbieter
|
||||
* die Autorisierung
|
||||
* das Anmeldeformular
|
||||
* das Autorisierungsformular
|
||||
* der Autorisierungsanbieter
|
||||
* der Benutzer authentisiert sich
|
||||
* das System authentifiziert den Benutzer
|
||||
|
||||
@@ -18,7 +18,7 @@ Für diese zusätzlichen Responses müssen Sie jedoch sicherstellen, dass Sie ei
|
||||
|
||||
Sie können Ihren *Pfadoperation-Dekoratoren* einen Parameter `responses` übergeben.
|
||||
|
||||
Der nimmt ein <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> entgegen, die Schlüssel sind Statuscodes für jede Response, wie etwa `200`, und die Werte sind andere `dict`s mit den Informationen für jede Response.
|
||||
Der nimmt ein <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> entgegen: Die Schlüssel sind Statuscodes für jede Response (wie etwa `200`), und die Werte sind andere `dict`s mit den Informationen für jede Response.
|
||||
|
||||
Jedes dieser Response-`dict`s kann einen Schlüssel `model` haben, welcher ein Pydantic-Modell enthält, genau wie `response_model`.
|
||||
|
||||
@@ -34,7 +34,7 @@ Beachten Sie, dass Sie die `JSONResponse` direkt zurückgeben müssen.
|
||||
|
||||
///
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Der `model`-Schlüssel ist nicht Teil von OpenAPI.
|
||||
|
||||
@@ -183,9 +183,9 @@ Beachten Sie, dass Sie das Bild direkt mit einer `FileResponse` zurückgeben mü
|
||||
|
||||
///
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Sofern Sie in Ihrem Parameter `responses` nicht explizit einen anderen Medientyp angeben, geht FastAPI davon aus, dass die Response denselben Medientyp wie die Haupt-Response-Klasse hat (Standardmäßig `application/json`).
|
||||
Sofern Sie in Ihrem Parameter `responses` nicht explizit einen anderen Medientyp angeben, geht FastAPI davon aus, dass die Response denselben Medientyp wie die Haupt-Response-Klasse hat (standardmäßig `application/json`).
|
||||
|
||||
Wenn Sie jedoch eine benutzerdefinierte Response-Klasse mit `None` als Medientyp angegeben haben, verwendet FastAPI `application/json` für jede zusätzliche Response, die über ein zugehöriges Modell verfügt.
|
||||
|
||||
@@ -195,7 +195,7 @@ Wenn Sie jedoch eine benutzerdefinierte Response-Klasse mit `None` als Medientyp
|
||||
|
||||
Sie können auch Response-Informationen von mehreren Stellen kombinieren, einschließlich der Parameter `response_model`, `status_code` und `responses`.
|
||||
|
||||
Sie können ein `response_model` deklarieren, indem Sie den Standardstatuscode `200` (oder bei Bedarf einen benutzerdefinierten) verwenden und dann zusätzliche Informationen für dieselbe Response in `responses` direkt im OpenAPI-Schema deklarieren.
|
||||
Sie können ein `response_model` deklarieren, indem Sie den Defaultstatuscode `200` (oder bei Bedarf einen benutzerdefinierten) verwenden und dann zusätzliche Informationen für dieselbe Response in `responses` direkt im OpenAPI-Schema deklarieren.
|
||||
|
||||
**FastAPI** behält die zusätzlichen Informationen aus `responses` und kombiniert sie mit dem JSON-Schema aus Ihrem Modell.
|
||||
|
||||
@@ -243,5 +243,5 @@ Zum Beispiel:
|
||||
|
||||
Um zu sehen, was genau Sie in die Responses aufnehmen können, können Sie die folgenden Abschnitte in der OpenAPI-Spezifikation überprüfen:
|
||||
|
||||
* [OpenAPI Responses Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responses-object), enthält das `Response Object`.
|
||||
* [OpenAPI Response Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#response-object), Sie können alles davon direkt in jede Response innerhalb Ihres `responses`-Parameter einfügen. Einschließlich `description`, `headers`, `content` (darin deklarieren Sie verschiedene Medientypen und JSON-Schemas) und `links`.
|
||||
* [OpenAPI Responses Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#responses-object), enthält das `Response Object`.
|
||||
* [OpenAPI Response Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#response-object), Sie können alles davon direkt in jede Response innerhalb Ihres `responses`-Parameters einfügen. Einschließlich `description`, `headers`, `content` (darin deklarieren Sie verschiedene Medientypen und JSON-Schemas) und `links`.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Zusätzliche Statuscodes { #additional-status-codes }
|
||||
|
||||
|
||||
Standardmäßig liefert **FastAPI** die <abbr title="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.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Fortgeschrittene Abhängigkeiten { #advanced-dependencies }
|
||||
|
||||
|
||||
## Parametrisierte Abhängigkeiten { #parameterized-dependencies }
|
||||
|
||||
Alle Abhängigkeiten, die wir bisher gesehen haben, waren festgelegte Funktionen oder Klassen.
|
||||
@@ -98,7 +99,7 @@ Wenn Sie beispielsweise eine Datenbanksession in einer Abhängigkeit mit `yield`
|
||||
|
||||
Dieses Verhalten wurde in 0.118.0 zurückgenommen, sodass der Exit-Code nach `yield` ausgeführt wird, nachdem die Response gesendet wurde.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Wie Sie unten sehen werden, ähnelt dies sehr dem Verhalten vor Version 0.106.0, jedoch mit mehreren Verbesserungen und Bugfixes für Sonderfälle.
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ Sie können Ihre Tests wie gewohnt ausführen mit:
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pytest
|
||||
$ uv run pytest
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
@@ -6,7 +6,7 @@ Diese Proxys könnten HTTPS-Zertifikate und andere Dinge handhaben.
|
||||
|
||||
## Proxy-<abbr title="weitergeleitete Header">Forwarded-Header</abbr> { #proxy-forwarded-headers }
|
||||
|
||||
Ein **Proxy** vor Ihrer Anwendung würde normalerweise einige Header on-the-fly setzen, bevor er die Requests an den **Server** sendet, um den Server wissen zu lassen, dass der Request vom Proxy **weitergeleitet** wurde, einschließlich der ursprünglichen (öffentlichen) URL, inklusive der Domain, dass HTTPS verwendet wird, usw.
|
||||
Ein **Proxy** vor Ihrer Anwendung würde normalerweise einige Header on-the-fly setzen, bevor er die Requests an Ihren **Server** sendet, um den Server wissen zu lassen, dass der Request vom Proxy **weitergeleitet** wurde, einschließlich der ursprünglichen (öffentlichen) URL, inklusive der Domain, dass HTTPS verwendet wird, usw.
|
||||
|
||||
Das **Server**-Programm (z. B. **Uvicorn** via **FastAPI CLI**) ist in der Lage, diese Header zu interpretieren und diese Information dann an Ihre Anwendung weiterzugeben.
|
||||
|
||||
@@ -33,7 +33,7 @@ Wenn Ihr **Server** hinter einem vertrauenswürdigen **Proxy** sitzt und nur der
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi run --forwarded-allow-ips="*"
|
||||
$ uv run fastapi run --forwarded-allow-ips="*"
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
@@ -82,7 +82,7 @@ sequenceDiagram
|
||||
|
||||
Note over Server: Server interpretiert die Header<br/>(wenn --forwarded-allow-ips gesetzt ist)
|
||||
|
||||
Server->>Proxy: HTTP-Response<br/>mit correkten HTTPS-URLs
|
||||
Server->>Proxy: HTTP-Response<br/>mit korrekten HTTPS-URLs
|
||||
|
||||
Proxy->>Client: HTTPS-Response
|
||||
```
|
||||
@@ -170,7 +170,7 @@ Um dies zu erreichen, können Sie die Kommandozeilenoption `--root-path` wie fol
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
||||
$ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
@@ -200,7 +200,7 @@ Wenn Sie Uvicorn dann starten mit:
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
||||
$ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
@@ -253,7 +253,7 @@ In einem solchen Fall (ohne ein abgetrenntes Pfadpräfix) würde der Proxy auf e
|
||||
|
||||
Sie können das Experiment mit einem abgetrennten Pfadpräfix einfach lokal ausführen, indem Sie [Traefik](https://docs.traefik.io/) verwenden.
|
||||
|
||||
[Laden Sie Traefik herunter](https://github.com/containous/traefik/releases), es ist eine einzelne Binärdatei, Sie können die komprimierte Datei extrahieren und sie direkt vom Terminal aus ausführen.
|
||||
[Laden Sie Traefik herunter](https://github.com/traefik/traefik/releases), es ist eine einzelne Binärdatei, Sie können die komprimierte Datei extrahieren und sie direkt vom Terminal aus ausführen.
|
||||
|
||||
Dann erstellen Sie eine Datei `traefik.toml` mit:
|
||||
|
||||
@@ -316,12 +316,12 @@ INFO[0000] Configuration loaded from file: /home/user/awesomeapi/traefik.toml
|
||||
|
||||
</div>
|
||||
|
||||
Und jetzt starten Sie Ihre Anwendung mit Uvicorn, indem Sie die Option `--root-path` verwenden:
|
||||
Und jetzt starten Sie Ihre Anwendung, indem Sie die Option `--root-path` verwenden:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
||||
$ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
@@ -461,6 +461,6 @@ Dann wird er nicht in das OpenAPI-Schema aufgenommen.
|
||||
|
||||
## Mounten einer Unteranwendung { #mounting-a-sub-application }
|
||||
|
||||
Wenn Sie gleichzeitig eine Unteranwendung mounten (wie beschrieben in [Unteranwendungen – Mounts](sub-applications.md)) und einen Proxy mit `root_path` verwenden wollen, können Sie das normal tun, wie Sie es erwarten würden.
|
||||
Wenn Sie eine Unteranwendung mounten müssen (wie beschrieben in [Unteranwendungen – Mounts](sub-applications.md)) und dabei auch einen Proxy mit `root_path` verwenden, können Sie das normal tun, wie Sie es erwarten würden.
|
||||
|
||||
FastAPI verwendet intern den `root_path` auf intelligente Weise, sodass es einfach funktioniert. ✨
|
||||
|
||||
@@ -41,7 +41,7 @@ Um eine Response mit HTML direkt von **FastAPI** zurückzugeben, verwenden Sie `
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Der Parameter `response_class` wird auch verwendet, um den „Medientyp“ der Response zu definieren.
|
||||
|
||||
@@ -65,7 +65,7 @@ Eine `Response`, die direkt von Ihrer *Pfadoperation-Funktion* zurückgegeben wi
|
||||
|
||||
///
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Natürlich stammen der eigentliche `Content-Type`-Header, der Statuscode, usw., aus dem `Response`-Objekt, das Sie zurückgegeben haben.
|
||||
|
||||
@@ -158,6 +158,7 @@ Sie können eine `RedirectResponse` direkt zurückgeben:
|
||||
|
||||
Oder Sie können sie im Parameter `response_class` verwenden:
|
||||
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial006b_py310.py hl[2,7,9] *}
|
||||
|
||||
Wenn Sie das tun, können Sie die URL direkt von Ihrer *Pfadoperation*-Funktion zurückgeben.
|
||||
|
||||
@@ -6,7 +6,7 @@ Aber FastAPI unterstützt auf die gleiche Weise auch die Verwendung von [`datacl
|
||||
|
||||
{* ../../docs_src/dataclasses_/tutorial001_py310.py hl[1,6:11,18:19] *}
|
||||
|
||||
Das ist dank **Pydantic** ebenfalls möglich, da es [„`dataclasses` intern unterstützt“](https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel).
|
||||
Das ist dank **Pydantic** ebenfalls möglich, da es [interne Unterstützung für `dataclasses`](https://pydantic.dev/docs/validation/latest/concepts/dataclasses/#usage-of-stdlib-dataclasses-with-basemodel) bietet.
|
||||
|
||||
Auch wenn im obigen Code Pydantic nicht explizit vorkommt, verwendet FastAPI Pydantic, um diese Standard-Datenklassen in Pydantics eigene Variante von Datenklassen zu konvertieren.
|
||||
|
||||
@@ -18,7 +18,7 @@ Und natürlich wird das gleiche unterstützt:
|
||||
|
||||
Das funktioniert genauso wie mit Pydantic-Modellen. Und tatsächlich wird es unter der Haube mittels Pydantic auf die gleiche Weise bewerkstelligt.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Bedenken Sie, dass Datenklassen nicht alles können, was Pydantic-Modelle können.
|
||||
|
||||
@@ -64,7 +64,7 @@ In diesem Fall können Sie einfach die Standard-`dataclasses` durch `pydantic.da
|
||||
|
||||
6. Hier geben wir ein <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">Dictionary</abbr> zurück, das `items` enthält, welches eine Liste von Datenklassen ist.
|
||||
|
||||
FastAPI ist weiterhin in der Lage, die Daten nach JSON zu <dfn title="Konvertieren der Daten in ein übertragbares Format">Serialisieren</dfn>.
|
||||
FastAPI ist weiterhin in der Lage, die Daten nach JSON zu <dfn title="die Daten in ein übertragbares Format konvertieren">serialisieren</dfn>.
|
||||
|
||||
7. Hier verwendet das `response_model` als Typannotation eine Liste von `Author`-Datenklassen.
|
||||
|
||||
@@ -74,7 +74,7 @@ In diesem Fall können Sie einfach die Standard-`dataclasses` durch `pydantic.da
|
||||
|
||||
Wie immer können Sie in FastAPI `def` und `async def` beliebig kombinieren.
|
||||
|
||||
Wenn Sie eine Auffrischung darüber benötigen, wann welche Anwendung sinnvoll ist, lesen Sie den Abschnitt „In Eile?“ in der Dokumentation zu [`async` und `await`](../async.md#in-a-hurry).
|
||||
Wenn Sie eine Auffrischung darüber benötigen, wann welche Anwendung sinnvoll ist, lesen Sie den Abschnitt _„In Eile?“_ in der Dokumentation zu [`async` und `await`](../async.md#in-a-hurry).
|
||||
|
||||
9. Diese *Pfadoperation-Funktion* gibt keine Datenklassen zurück (obwohl dies möglich wäre), sondern eine Liste von Dictionarys mit internen Daten.
|
||||
|
||||
@@ -82,13 +82,13 @@ In diesem Fall können Sie einfach die Standard-`dataclasses` durch `pydantic.da
|
||||
|
||||
Sie können `dataclasses` mit anderen Typannotationen auf vielfältige Weise kombinieren, um komplexe Datenstrukturen zu bilden.
|
||||
|
||||
Weitere Einzelheiten finden Sie in den Bemerkungen im Quellcode oben.
|
||||
Weitere spezifische Details finden Sie in den Annotationstipps im Code oben.
|
||||
|
||||
## Mehr erfahren { #learn-more }
|
||||
|
||||
Sie können `dataclasses` auch mit anderen Pydantic-Modellen kombinieren, von ihnen erben, sie in Ihre eigenen Modelle einbinden, usw.
|
||||
|
||||
Weitere Informationen finden Sie in der [Pydantic-Dokumentation zu Datenklassen](https://docs.pydantic.dev/latest/concepts/dataclasses/).
|
||||
Weitere Informationen finden Sie in der [Pydantic-Dokumentation zu Datenklassen](https://pydantic.dev/docs/validation/latest/concepts/dataclasses/).
|
||||
|
||||
## Version { #version }
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ Wir erstellen eine asynchrone Funktion `lifespan()` mit `yield` wie folgt:
|
||||
|
||||
{* ../../docs_src/events/tutorial003_py310.py hl[16,19] *}
|
||||
|
||||
Hier simulieren wir den langsamen *Startup*, das Laden des Modells, indem wir die (Fake-)Modellfunktion vor dem `yield` in das <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">Dictionary</abbr> mit Modellen für maschinelles Lernen einfügen. Dieser Code wird ausgeführt, **bevor** die Anwendung **beginnt, Requests entgegenzunehmen**, während des *Startups*.
|
||||
Hier simulieren wir den aufwendigen *Startup*-Vorgang des Ladens des Modells, indem wir die (Fake-)Modellfunktion vor dem `yield` in das <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">Dictionary</abbr> mit Modellen für maschinelles Lernen einfügen. Dieser Code wird ausgeführt, **bevor** die Anwendung **beginnt, Requests entgegenzunehmen**, während des *Startups*.
|
||||
|
||||
Und dann, direkt nach dem `yield`, entladen wir das Modell. Dieser Code wird ausgeführt, **nachdem** die Anwendung **die Bearbeitung von Requests abgeschlossen hat**, direkt vor dem *Shutdown*. Dadurch könnten beispielsweise Ressourcen wie Arbeitsspeicher oder eine GPU freigegeben werden.
|
||||
|
||||
@@ -102,7 +102,7 @@ Diese Funktionen können mit `async def` oder normalem `def` deklariert werden.
|
||||
|
||||
### `startup`-Event { #startup-event }
|
||||
|
||||
Um eine Funktion hinzuzufügen, die vor dem Start der Anwendung ausgeführt werden soll, deklarieren Sie diese mit dem Event `startup`:
|
||||
Um eine Funktion hinzuzufügen, die vor dem Start der Anwendung ausgeführt werden soll, deklarieren Sie diese mit dem Event `"startup"`:
|
||||
|
||||
{* ../../docs_src/events/tutorial001_py310.py hl[8] *}
|
||||
|
||||
@@ -114,13 +114,13 @@ Und Ihre Anwendung empfängt erst dann Requests, wenn alle `startup`-Eventhandle
|
||||
|
||||
### `shutdown`-Event { #shutdown-event }
|
||||
|
||||
Um eine Funktion hinzuzufügen, die beim Shutdown der Anwendung ausgeführt werden soll, deklarieren Sie sie mit dem Event `shutdown`:
|
||||
Um eine Funktion hinzuzufügen, die beim Shutdown der Anwendung ausgeführt werden soll, deklarieren Sie sie mit dem Event `"shutdown"`:
|
||||
|
||||
{* ../../docs_src/events/tutorial002_py310.py hl[6] *}
|
||||
|
||||
Hier schreibt die `shutdown`-Eventhandler-Funktion eine Textzeile `"Application shutdown"` in eine Datei `log.txt`.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
In der Funktion `open()` bedeutet `mode="a"` „append“ („anhängen“), sodass die Zeile nach dem, was sich in dieser Datei befindet, hinzugefügt wird, ohne den vorherigen Inhalt zu überschreiben.
|
||||
|
||||
@@ -140,7 +140,7 @@ Daher deklarieren wir die Eventhandler-Funktion mit Standard-`def` statt mit `as
|
||||
|
||||
### `startup` und `shutdown` zusammen { #startup-and-shutdown-together }
|
||||
|
||||
Es besteht eine hohe Wahrscheinlichkeit, dass die Logik für Ihr *Startup* und *Shutdown* miteinander verknüpft ist. Vielleicht möchten Sie etwas beginnen und es dann beenden, eine Ressource laden und sie dann freigeben usw.
|
||||
Es besteht eine hohe Wahrscheinlichkeit, dass die Logik für Ihr *Startup* und *Shutdown* miteinander verknüpft ist. Vielleicht möchten Sie etwas beginnen und es dann beenden, eine Ressource belegen und sie dann freigeben usw.
|
||||
|
||||
Bei getrennten Funktionen, die keine gemeinsame Logik oder Variablen haben, ist dies schwieriger, da Sie Werte in globalen Variablen speichern oder ähnliche Tricks verwenden müssen.
|
||||
|
||||
@@ -150,13 +150,13 @@ Aus diesem Grund wird jetzt empfohlen, stattdessen `lifespan` wie oben erläuter
|
||||
|
||||
Nur ein technisches Detail für die neugierigen Nerds. 🤓
|
||||
|
||||
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`.
|
||||
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`.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Weitere Informationen zu Starlettes `lifespan`-Handlern finden Sie in [Starlettes Lifespan-Dokumentation](https://www.starlette.dev/lifespan/).
|
||||
Weitere Informationen zu Starlettes `lifespan`-Handlern finden Sie in [Starlettes Lifespan-Dokumentation](https://starlette.dev/lifespan/).
|
||||
|
||||
Einschließlich, wie man Lifespan-Zustand handhabt, der in anderen Bereichen Ihres Codes verwendet werden kann.
|
||||
Einschließlich, wie Sie Lifespan-Zustand handhaben, der in anderen Bereichen Ihres Codes verwendet werden kann.
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@ Dies vereinfacht es, aktuelle **Dokumentation** und Client-Bibliotheken (<abbr t
|
||||
|
||||
In diesem Leitfaden erfahren Sie, wie Sie ein **TypeScript-SDK** für Ihr FastAPI-Backend generieren.
|
||||
|
||||
## Open Source SDK-Generatoren { #open-source-sdk-generators }
|
||||
## Open-Source-SDK-Generatoren { #open-source-sdk-generators }
|
||||
|
||||
Eine vielseitige Möglichkeit ist der [OpenAPI Generator](https://openapi-generator.tech/), der **viele Programmiersprachen** unterstützt und SDKs aus Ihrer OpenAPI-Spezifikation generieren kann.
|
||||
|
||||
Für **TypeScript-Clients** ist [Hey API](https://heyapi.dev/) eine speziell entwickelte Lösung, die ein optimiertes Erlebnis für das TypeScript-Ökosystem bietet.
|
||||
|
||||
Weitere SDK-Generatoren finden Sie auf [OpenAPI.Tools](https://openapi.tools/#sdk).
|
||||
Weitere SDK-Generatoren finden Sie auf [OpenAPI.Tools](https://openapi.tools/categories/sdk-generators).
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -20,21 +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. 🙇
|
||||
|
||||
Zum Beispiel könnten Sie ausprobieren:
|
||||
|
||||
* [Stainless](https://www.stainless.com/?utm_source=fastapi&utm_medium=referral)
|
||||
* [liblab](https://developers.liblab.com/tutorials/sdk-for-fastapi?utm_source=fastapi)
|
||||
|
||||
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 }
|
||||
|
||||
Beginnen wir mit einer einfachen FastAPI-Anwendung:
|
||||
@@ -65,7 +50,7 @@ npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client
|
||||
|
||||
Dies generiert ein TypeScript-SDK in `./src/client`.
|
||||
|
||||
Sie können lernen, wie man [`@hey-api/openapi-ts` installiert](https://heyapi.dev/openapi-ts/get-started) und über die [erzeugte Ausgabe](https://heyapi.dev/openapi-ts/output) auf deren Website lesen.
|
||||
Sie können lernen, wie Sie [`@hey-api/openapi-ts` installieren](https://heyapi.dev/openapi-ts/get-started) und über die [erzeugte Ausgabe](https://heyapi.dev/openapi-ts/output) auf deren Website lesen.
|
||||
|
||||
### Das SDK verwenden { #using-the-sdk }
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
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.
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
Im Haupttutorial haben Sie gelesen, wie Sie Ihrer Anwendung [benutzerdefinierte Middleware](../tutorial/middleware.md) hinzufügen können.
|
||||
|
||||
Und dann auch, wie man [CORS mittels der `CORSMiddleware`](../tutorial/cors.md) handhabt.
|
||||
Und dann haben Sie auch gelesen, wie Sie [CORS mittels der `CORSMiddleware`](../tutorial/cors.md) handhaben.
|
||||
|
||||
In diesem Abschnitt werden wir sehen, wie man andere Middlewares verwendet.
|
||||
In diesem Abschnitt werden wir sehen, wie Sie andere Middlewares verwenden.
|
||||
|
||||
## ASGI-Middleware hinzufügen { #adding-asgi-middlewares }
|
||||
|
||||
@@ -41,7 +41,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
|
||||
|
||||
## Integrierte Middleware { #integrated-middlewares }
|
||||
|
||||
**FastAPI** enthält mehrere Middlewares für gängige Anwendungsfälle. Wir werden als Nächstes sehen, wie man sie verwendet.
|
||||
**FastAPI** enthält mehrere Middlewares für gängige Anwendungsfälle. Wir werden als Nächstes sehen, wie Sie sie verwenden.
|
||||
|
||||
/// note | Technische Details
|
||||
|
||||
@@ -74,7 +74,7 @@ Wenn ein eingehender Request nicht korrekt validiert wird, wird eine `400`-<abbr
|
||||
|
||||
## `GZipMiddleware` { #gzipmiddleware }
|
||||
|
||||
Verarbeitet GZip-Responses für alle Requests, die „gzip“ im `Accept-Encoding`-Header enthalten.
|
||||
Verarbeitet GZip-Responses für alle Requests, die `"gzip"` im `Accept-Encoding`-Header enthalten.
|
||||
|
||||
Diese Middleware verarbeitet sowohl Standard- als auch Streaming-Responses.
|
||||
|
||||
@@ -91,7 +91,7 @@ Es gibt viele andere ASGI-Middlewares.
|
||||
|
||||
Zum Beispiel:
|
||||
|
||||
* [Uvicorns `ProxyHeadersMiddleware`](https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py)
|
||||
* [Uvicorns `ProxyHeadersMiddleware`](https://github.com/Kludex/uvicorn/blob/main/uvicorn/middleware/proxy_headers.py)
|
||||
* [MessagePack](https://github.com/florimondmanca/msgpack-asgi)
|
||||
|
||||
Um mehr über weitere verfügbare Middlewares herauszufinden, besuchen Sie [Starlettes Middleware-Dokumentation](https://www.starlette.dev/middleware/) und die [ASGI Awesome List](https://github.com/florimondmanca/awesome-asgi).
|
||||
Um mehr über weitere verfügbare Middlewares herauszufinden, besuchen Sie [Starlettes Middleware-Dokumentation](https://starlette.dev/middleware/) und die [ASGI Awesome List](https://github.com/florimondmanca/awesome-asgi).
|
||||
|
||||
@@ -12,7 +12,7 @@ Sehen wir uns das alles anhand eines Beispiels an.
|
||||
|
||||
Stellen Sie sich vor, Sie entwickeln eine Anwendung, mit der Sie Rechnungen erstellen können.
|
||||
|
||||
Diese Rechnungen haben eine `id`, einen optionalen `title`, einen `customer` (Kunde) und ein `total` (Gesamtsumme).
|
||||
Diese Rechnungen haben eine `id`, einen `title` (optional), einen `customer` und ein `total`.
|
||||
|
||||
Der Benutzer Ihrer API (ein externer Entwickler) erstellt mit einem POST-Request eine Rechnung in Ihrer API.
|
||||
|
||||
@@ -35,7 +35,7 @@ Dieser Teil ist ziemlich normal, der größte Teil des Codes ist Ihnen wahrschei
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Der Query-Parameter `callback_url` verwendet einen Pydantic-[Url](https://docs.pydantic.dev/latest/api/networks/)-Typ.
|
||||
Der Query-Parameter `callback_url` verwendet einen Pydantic-[Url](https://pydantic.dev/docs/validation/latest/api/pydantic/networks/)-Typ.
|
||||
|
||||
///
|
||||
|
||||
@@ -106,11 +106,11 @@ Sie sollte wie eine normale FastAPI-*Pfadoperation* aussehen:
|
||||
Es gibt zwei Hauptunterschiede zu einer normalen *Pfadoperation*:
|
||||
|
||||
* Es muss kein tatsächlicher Code vorhanden sein, da Ihre Anwendung diesen Code niemals aufruft. Sie wird nur zur Dokumentation der *externen API* verwendet. Die Funktion könnte also einfach `pass` enthalten.
|
||||
* Der *Pfad* kann einen [OpenAPI-3-Ausdruck](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression) enthalten (mehr dazu weiter unten), wo er Variablen mit Parametern und Teilen des ursprünglichen Requests verwenden kann, der an *Ihre API* gesendet wurde.
|
||||
* Der *Pfad* kann einen [OpenAPI-3-Ausdruck](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#key-expression) enthalten (mehr dazu weiter unten), wo er Variablen mit Parametern und Teilen des ursprünglichen Requests verwenden kann, der an *Ihre API* gesendet wurde.
|
||||
|
||||
### Der Callback-Pfadausdruck { #the-callback-path-expression }
|
||||
|
||||
Der Callback-*Pfad* kann einen [OpenAPI-3-Ausdruck](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression) enthalten, welcher Teile des ursprünglichen Requests enthalten kann, der an *Ihre API* gesendet wurde.
|
||||
Der Callback-*Pfad* kann einen [OpenAPI-3-Ausdruck](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#key-expression) enthalten, welcher Teile des ursprünglichen Requests enthalten kann, der an *Ihre API* gesendet wurde.
|
||||
|
||||
In diesem Fall ist es der `str`:
|
||||
|
||||
@@ -118,13 +118,13 @@ In diesem Fall ist es der `str`:
|
||||
"{$callback_url}/invoices/{$request.body.id}"
|
||||
```
|
||||
|
||||
Wenn Ihr API-Benutzer (der externe Entwickler) also einen Request an *Ihre API* sendet, via:
|
||||
Wenn Ihr API-Benutzer (der externe Entwickler) also einen Request an *Ihre API* sendet, an:
|
||||
|
||||
```
|
||||
https://yourapi.com/invoices/?callback_url=https://www.external.org/events
|
||||
```
|
||||
|
||||
mit einem JSON-Körper:
|
||||
mit einem JSON-Body:
|
||||
|
||||
```JSON
|
||||
{
|
||||
@@ -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.
|
||||
|
||||
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:
|
||||
|
||||
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Beachten Sie, dass Sie nicht den Router selbst (`invoices_callback_router`) an `callback=` übergeben, sondern das Attribut `.routes`, wie in `invoices_callback_router.routes`.
|
||||
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.
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ Mit **FastAPI**, mithilfe von OpenAPI, können Sie die Namen dieser Webhooks, di
|
||||
|
||||
Dies kann es Ihren Benutzern viel einfacher machen, **deren APIs zu implementieren**, um Ihre **Webhook**-Requests zu empfangen. Möglicherweise können diese sogar einen Teil ihres eigenen API-Codes automatisch generieren.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Webhooks sind in OpenAPI 3.1.0 und höher verfügbar und werden von FastAPI `0.99.0` und höher unterstützt.
|
||||
|
||||
@@ -36,7 +36,7 @@ Wenn Sie eine **FastAPI**-Anwendung erstellen, gibt es ein `webhooks`-Attribut,
|
||||
|
||||
Die von Ihnen definierten Webhooks landen im **OpenAPI**-Schema und der automatischen **Dokumentations-Oberfläche**.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Das `app.webhooks`-Objekt ist eigentlich nur ein `APIRouter`, derselbe Typ, den Sie verwenden würden, wenn Sie Ihre App mit mehreren Dateien strukturieren.
|
||||
|
||||
|
||||
@@ -16,17 +16,11 @@ Sie müssten sicherstellen, dass sie für jede Operation eindeutig ist.
|
||||
|
||||
### Verwendung des Namens der *Pfadoperation-Funktion* als operationId { #using-the-path-operation-function-name-as-the-operationid }
|
||||
|
||||
Wenn Sie die Funktionsnamen Ihrer API als `operationId`s verwenden möchten, können Sie über alle iterieren und die `operation_id` jeder *Pfadoperation* mit deren `APIRoute.name` überschreiben.
|
||||
Wenn Sie die Funktionsnamen Ihrer APIs als `operationId`s verwenden möchten, können Sie `FastAPI` eine eigene `generate_unique_id_function` übergeben.
|
||||
|
||||
Sie sollten dies tun, nachdem Sie alle Ihre *Pfadoperationen* hinzugefügt haben.
|
||||
Diese Funktion erhält jeweils die `APIRoute` und gibt die `operationId` zurück, die für diese Pfadoperation verwendet werden soll.
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2, 12:21, 24] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Wenn Sie `app.openapi()` manuell aufrufen, sollten Sie vorher die `operationId`s aktualisiert haben.
|
||||
|
||||
///
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2,5:6,9] *}
|
||||
|
||||
/// warning | Achtung
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Response – Statuscode ändern { #response-change-status-code }
|
||||
|
||||
|
||||
Sie haben wahrscheinlich schon vorher gelesen, dass Sie einen Default-[Response-Statuscode](../tutorial/response-status-code.md) festlegen können.
|
||||
|
||||
In manchen Fällen müssen Sie jedoch einen anderen als den Default-Statuscode zurückgeben.
|
||||
|
||||
@@ -48,4 +48,4 @@ Und da die `Response` häufig zum Setzen von Headern und Cookies verwendet wird,
|
||||
|
||||
///
|
||||
|
||||
Um alle verfügbaren Parameter und Optionen anzuzeigen, sehen Sie sich deren [Dokumentation in Starlette](https://www.starlette.dev/responses/#set-cookie) an.
|
||||
Um alle verfügbaren Parameter und Optionen anzuzeigen, sehen Sie sich deren [Dokumentation in Starlette](https://starlette.dev/responses/#set-cookie) an.
|
||||
|
||||
@@ -16,9 +16,9 @@ Normalerweise erzielen Sie eine deutlich bessere Leistung, wenn Sie ein [Respons
|
||||
|
||||
## Eine `Response` zurückgeben { #return-a-response }
|
||||
|
||||
Tatsächlich können Sie jede `Response` oder jede Unterklasse davon zurückgeben.
|
||||
Sie können eine `Response` oder jede Unterklasse davon zurückgeben.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
`JSONResponse` selbst ist eine Unterklasse von `Response`.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
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://starlette.dev/middleware/#corsmiddleware).
|
||||
|
||||
@@ -18,7 +18,7 @@ Sie benötigen nicht unbedingt OAuth2-Scopes, und Sie können die Authentifizier
|
||||
|
||||
Aber OAuth2 mit Scopes kann bequem in Ihre API (mit OpenAPI) und deren API-Dokumentation integriert werden.
|
||||
|
||||
Dennoch, verwenden Sie solche Scopes oder andere Sicherheits-/Autorisierungsanforderungen in Ihrem Code so wie Sie es möchten.
|
||||
Dennoch erzwingen Sie solche Scopes oder andere Sicherheits-/Autorisierungsanforderungen in Ihrem Code so, wie Sie es benötigen.
|
||||
|
||||
In vielen Fällen kann OAuth2 mit Scopes ein Overkill sein.
|
||||
|
||||
@@ -46,7 +46,7 @@ Er wird normalerweise verwendet, um bestimmte Sicherheitsberechtigungen zu dekla
|
||||
* `instagram_basic` wird von Facebook / Instagram verwendet.
|
||||
* `https://www.googleapis.com/auth/drive` wird von Google verwendet.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
In OAuth2 ist ein „Scope“ nur ein String, der eine bestimmte erforderliche Berechtigung deklariert.
|
||||
|
||||
@@ -126,7 +126,7 @@ Wir tun dies hier, um zu demonstrieren, wie **FastAPI** auf verschiedenen Ebenen
|
||||
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[5,141,172] *}
|
||||
|
||||
/// info | Technische Details
|
||||
/// note | Technische Details
|
||||
|
||||
`Security` ist tatsächlich eine Unterklasse von `Depends` und hat nur noch einen zusätzlichen Parameter, den wir später kennenlernen werden.
|
||||
|
||||
@@ -247,7 +247,7 @@ Das würde einer Drittanbieteranwendung passieren, die versucht, auf eine dieser
|
||||
|
||||
## Ü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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
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.
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
|
||||
@@ -2,45 +2,49 @@
|
||||
|
||||
In vielen Fällen benötigt Ihre Anwendung möglicherweise einige externe Einstellungen oder Konfigurationen, zum Beispiel geheime Schlüssel, Datenbank-Anmeldeinformationen, Anmeldeinformationen für E-Mail-Dienste, usw.
|
||||
|
||||
Die meisten dieser Einstellungen sind variabel (können sich ändern), wie z. B. Datenbank-URLs. Und vieles könnten schützenswerte, geheime Daten sein.
|
||||
Die meisten dieser Einstellungen sind variabel (können sich ändern), wie z. B. Datenbank-URLs. Und viele könnten schützenswerte, geheime Daten sein.
|
||||
|
||||
Aus diesem Grund werden diese üblicherweise in Umgebungsvariablen bereitgestellt, die von der Anwendung gelesen werden.
|
||||
|
||||
Eine **Umgebungsvariable** (auch bekannt als **Env-Var**) ist ein Wert, der außerhalb des Python-Codes, im Betriebssystem, existiert und von Ihrer Anwendung und anderen Programmen gelesen werden kann.
|
||||
|
||||
Sie können eine Umgebungsvariable für einen Befehl erstellen, wenn Sie ihn ausführen. Sie werden unten die plattformspezifischen Befehle sehen.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Um Umgebungsvariablen zu verstehen, können Sie [Umgebungsvariablen](../environment-variables.md) lesen.
|
||||
Lesen Sie den [Leitfaden zu Umgebungsvariablen](https://tiangolo.com/guides/environment-variables/) für eine detaillierte Erklärung, wie Umgebungsvariablen funktionieren.
|
||||
|
||||
///
|
||||
|
||||
## 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 und 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.
|
||||
|
||||
## 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://pydantic.dev/docs/validation/latest/concepts/pydantic_settings/).
|
||||
|
||||
### `pydantic-settings` installieren { #install-pydantic-settings }
|
||||
|
||||
Stellen Sie zunächst sicher, dass Sie Ihre [virtuelle Umgebung](../virtual-environments.md) erstellt und aktiviert haben, und installieren Sie dann das Package `pydantic-settings`:
|
||||
Fügen Sie Ihrem Projekt das Package `pydantic-settings` hinzu:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install pydantic-settings
|
||||
$ uv add pydantic-settings
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Es ist bereits enthalten, wenn Sie die `all`-Extras installiert haben, mit:
|
||||
Es ist auch enthalten, wenn Sie die `all`-Extras installieren mit:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "fastapi[all]"
|
||||
$ uv add "fastapi[all]"
|
||||
---> 100%
|
||||
```
|
||||
|
||||
@@ -76,25 +80,45 @@ Dann können Sie das neue `settings`-Objekt in Ihrer Anwendung verwenden:
|
||||
|
||||
Als Nächstes würden Sie den Server ausführen und die Konfigurationen als Umgebungsvariablen übergeben. Sie könnten beispielsweise `ADMIN_EMAIL` und `APP_NAME` festlegen mit:
|
||||
|
||||
//// tab | Linux, macOS, Windows Bash
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.py
|
||||
$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" uv run fastapi run main.py
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ $Env:ADMIN_EMAIL = "deadpool@example.com"
|
||||
$ $Env:APP_NAME = "ChimichangApp"
|
||||
$ uv run fastapi run main.py
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Um mehrere Umgebungsvariablen für einen einzelnen Befehl festzulegen, trennen Sie diese einfach durch ein Leerzeichen und fügen Sie alle vor dem Befehl ein.
|
||||
In Bash trennen Sie, um mehrere Umgebungsvariablen für einen einzelnen Befehl festzulegen, diese durch ein Leerzeichen und fügen sie alle vor dem Befehl ein.
|
||||
|
||||
///
|
||||
|
||||
Und dann würde die Einstellung `admin_email` auf „deadpool@example.com“ gesetzt.
|
||||
Und dann würde die Einstellung `admin_email` auf `"deadpool@example.com"` gesetzt.
|
||||
|
||||
Der `app_name` wäre „ChimichangApp“.
|
||||
Der `app_name` wäre `"ChimichangApp"`.
|
||||
|
||||
Und `items_per_user` würde seinen Defaultwert von `50` behalten.
|
||||
|
||||
@@ -128,7 +152,7 @@ Ausgehend vom vorherigen Beispiel könnte Ihre Datei `config.py` so aussehen:
|
||||
|
||||
{* ../../docs_src/settings/app02_an_py310/config.py hl[10] *}
|
||||
|
||||
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 }
|
||||
|
||||
@@ -158,7 +182,7 @@ Bei der Abhängigkeitsüberschreibung legen wir einen neuen Wert für `admin_ema
|
||||
|
||||
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.
|
||||
|
||||
@@ -172,11 +196,11 @@ 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://pydantic.dev/docs/validation/latest/concepts/pydantic_settings/#dotenv-env-support).
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Damit das funktioniert, müssen Sie `pip install python-dotenv` ausführen.
|
||||
Damit das funktioniert, fügen Sie Ihrem Projekt `python-dotenv` mit `uv add python-dotenv` hinzu.
|
||||
|
||||
///
|
||||
|
||||
@@ -197,13 +221,13 @@ Und dann aktualisieren Sie Ihre `config.py` mit:
|
||||
|
||||
/// 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://pydantic.dev/docs/validation/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.
|
||||
|
||||
### 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 <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> zu lesen.
|
||||
|
||||
@@ -291,7 +315,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.
|
||||
|
||||
`@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).
|
||||
`@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).
|
||||
|
||||
## Zusammenfassung { #recap }
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Wenn Sie Daten streamen möchten, die als JSON strukturiert werden können, soll
|
||||
|
||||
Wenn Sie jedoch **reine Binärdaten** oder Strings streamen möchten, so können Sie es machen.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Hinzugefügt in FastAPI 0.134.0.
|
||||
|
||||
@@ -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 }
|
||||
|
||||
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.
|
||||
|
||||
{* ../../docs_src/stream_data/tutorial001_py310.py ln[1:23] hl[20,23] *}
|
||||
|
||||
FastAPI übergibt jeden Datenchunk unverändert an die `StreamingResponse`, es wird nicht versucht, ihn in JSON oder etwas Ähnliches zu konvertieren.
|
||||
|
||||
### Nicht-async-Pfadoperation-Funktionen { #non-async-path-operation-functions }
|
||||
### Nicht-async-*Pfadoperation-Funktionen* { #non-async-path-operation-functions }
|
||||
|
||||
Sie können auch reguläre `def`-Funktionen (ohne `async`) verwenden und `yield` auf die gleiche Weise einsetzen.
|
||||
|
||||
@@ -58,7 +58,7 @@ Zum Beispiel können Sie eine `PNGStreamingResponse` erstellen, die den `Content
|
||||
|
||||
{* ../../docs_src/stream_data/tutorial002_py310.py ln[6,19:20] hl[20] *}
|
||||
|
||||
Dann können Sie diese neue Klasse mit `response_class=PNGStreamingResponse` in Ihrer Pfadoperation-Funktion verwenden:
|
||||
Dann können Sie diese neue Klasse mit `response_class=PNGStreamingResponse` in Ihrer *Pfadoperation-Funktion* verwenden:
|
||||
|
||||
{* ../../docs_src/stream_data/tutorial002_py310.py ln[23:27] hl[23] *}
|
||||
|
||||
@@ -90,7 +90,7 @@ Beispielsweise haben sie kein `await file.read()` oder `async for chunk in file`
|
||||
|
||||
Und in vielen Fällen wäre das Lesen eine blockierende Operation (die die Event-Loop blockieren könnte), weil von der Festplatte oder aus dem Netzwerk gelesen wird.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Das obige Beispiel ist tatsächlich eine Ausnahme, weil sich das `io.BytesIO`-Objekt bereits im Speicher befindet, daher blockiert sein Lesen nichts.
|
||||
|
||||
@@ -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.
|
||||
|
||||
{* ../../docs_src/stream_data/tutorial002_py310.py ln[30:34] hl[31] *}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ Wenn Sie Clients unterstützen müssen, die keinen `Content-Type`-Header senden,
|
||||
|
||||
Mit dieser Einstellung werden Requests ohne `Content-Type`-Header im Body als JSON geparst. Das entspricht dem Verhalten älterer FastAPI-Versionen.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Dieses Verhalten und diese Konfiguration wurden in FastAPI 0.132.0 hinzugefügt.
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@ Wenn Sie zwei unabhängige FastAPI-Anwendungen mit deren eigenen unabhängigen O
|
||||
|
||||
## Eine **FastAPI**-Anwendung mounten { #mounting-a-fastapi-application }
|
||||
|
||||
„Mounten“ („Einhängen“) bedeutet das Hinzufügen einer völlig „unabhängigen“ Anwendung an einem bestimmten Pfad, die sich dann um die Handhabung aller unter diesem Pfad liegenden _Pfadoperationen_ kümmert, welche in dieser Unteranwendung deklariert sind.
|
||||
„Mounten“ bedeutet das Hinzufügen einer völlig „unabhängigen“ Anwendung an einem bestimmten Pfad, die sich dann um die Handhabung aller unter diesem Pfad liegenden _Pfadoperationen_ kümmert, welche in dieser Unteranwendung deklariert sind.
|
||||
|
||||
### Hauptanwendung { #top-level-application }
|
||||
### Top-Level-Anwendung { #top-level-application }
|
||||
|
||||
Erstellen Sie zunächst die Hauptanwendung **FastAPI** und deren *Pfadoperationen*:
|
||||
Erstellen Sie zunächst die Haupt-, Top-Level-**FastAPI**-Anwendung und deren *Pfadoperationen*:
|
||||
|
||||
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[3, 6:8] *}
|
||||
|
||||
@@ -35,7 +35,7 @@ Führen Sie nun den Befehl `fastapi` aus:
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev
|
||||
$ uv run fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
@@ -8,12 +8,12 @@ Es gibt Werkzeuge zur einfachen Konfiguration, die Sie direkt in Ihrer **FastAPI
|
||||
|
||||
## Abhängigkeiten installieren { #install-dependencies }
|
||||
|
||||
Stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../virtual-environments.md) erstellen, sie aktivieren und `jinja2` installieren:
|
||||
Fügen Sie `jinja2` Ihrem Projekt hinzu:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install jinja2
|
||||
$ uv add jinja2
|
||||
|
||||
---> 100%
|
||||
```
|
||||
@@ -53,7 +53,7 @@ Sie können auch `from starlette.templating import Jinja2Templates` verwenden.
|
||||
|
||||
## Templates erstellen { #writing-templates }
|
||||
|
||||
Dann können Sie unter `templates/item.html` ein Template erstellen, mit z. B. folgendem Inhalt:
|
||||
Dann können Sie unter `templates/item.html` ein Template erstellen, mit z. B.:
|
||||
|
||||
```jinja hl_lines="7"
|
||||
{!../../docs_src/templates/templates/item.html!}
|
||||
@@ -123,4 +123,4 @@ Und da Sie `StaticFiles` verwenden, wird diese CSS-Datei automatisch von Ihrer *
|
||||
|
||||
## Mehr Details { #more-details }
|
||||
|
||||
Weitere Informationen, einschließlich, wie man Templates testet, finden Sie in [Starlettes Dokumentation zu Templates](https://www.starlette.dev/templates/).
|
||||
Weitere Informationen, einschließlich, wie man Templates testet, finden Sie in [Starlettes Dokumentation zu Templates](https://starlette.dev/templates/).
|
||||
|
||||
@@ -5,7 +5,7 @@ Wenn Sie `lifespan` in Ihren Tests ausführen müssen, können Sie den `TestClie
|
||||
{* ../../docs_src/app_testing/tutorial004_py310.py hl[9:15,18,27:28,30:32,41:43] *}
|
||||
|
||||
|
||||
Sie können mehr Details unter [„Lifespan in Tests ausführen in der offiziellen Starlette-Dokumentation.“](https://www.starlette.dev/lifespan/#running-lifespan-in-tests) nachlesen.
|
||||
Sie können mehr Details unter [„Lifespan in Tests ausführen auf der offiziellen Starlette-Dokumentationswebsite.“](https://starlette.dev/lifespan/#running-lifespan-in-tests) nachlesen.
|
||||
|
||||
Für die deprecateten Events <abbr title="Hochfahren">`startup`</abbr> und <abbr title="Herunterfahren">`shutdown`</abbr> können Sie den `TestClient` wie folgt verwenden:
|
||||
|
||||
|
||||
@@ -8,6 +8,6 @@ Dazu verwenden Sie den `TestClient` in einer `with`-Anweisung, eine Verbindung z
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
Weitere Informationen finden Sie in Starlettes Dokumentation zum [Testen von WebSockets](https://www.starlette.dev/testclient/#testing-websocket-sessions).
|
||||
Weitere Informationen finden Sie in Starlettes Dokumentation zum [Testen von WebSockets](https://starlette.dev/testclient/#testing-websocket-sessions).
|
||||
|
||||
///
|
||||
|
||||
@@ -15,7 +15,7 @@ Es gibt jedoch Situationen, in denen Sie möglicherweise direkt auf das `Request
|
||||
|
||||
## Details zum `Request`-Objekt { #details-about-the-request-object }
|
||||
|
||||
Da **FastAPI** unter der Haube eigentlich **Starlette** ist, mit einer Ebene von mehreren Tools darüber, können Sie Starlettes [`Request`](https://www.starlette.dev/requests/)-Objekt direkt verwenden, wenn Sie es benötigen.
|
||||
Da **FastAPI** unter der Haube eigentlich **Starlette** ist, mit einer Ebene von mehreren Tools darüber, können Sie Starlettes [`Request`](https://starlette.dev/requests/)-Objekt direkt verwenden, wenn Sie es benötigen.
|
||||
|
||||
Das bedeutet allerdings auch, dass, wenn Sie Daten direkt vom `Request`-Objekt nehmen (z. B. dessen Body lesen), diese von FastAPI nicht validiert, konvertiert oder dokumentiert werden (mit OpenAPI, für die automatische API-Benutzeroberfläche).
|
||||
|
||||
@@ -45,7 +45,7 @@ Auf die gleiche Weise können Sie wie gewohnt jeden anderen Parameter deklariere
|
||||
|
||||
## `Request`-Dokumentation { #request-documentation }
|
||||
|
||||
Weitere Details zum [`Request`-Objekt auf der offiziellen Starlette-Dokumentationsseite](https://www.starlette.dev/requests/).
|
||||
Weitere Details zum [`Request`-Objekt auf der offiziellen Starlette-Dokumentationsseite](https://starlette.dev/requests/).
|
||||
|
||||
/// note | Technische Details
|
||||
|
||||
|
||||
@@ -4,12 +4,12 @@ Sie können [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSoc
|
||||
|
||||
## `websockets` installieren { #install-websockets }
|
||||
|
||||
Stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../virtual-environments.md) erstellen, sie aktivieren und `websockets` installieren (eine Python-Bibliothek, die die Verwendung des „WebSocket“-Protokolls erleichtert):
|
||||
Fügen Sie `websockets` (eine Python-Bibliothek, die die Verwendung des „WebSocket“-Protokolls erleichtert) zu Ihrem Projekt hinzu:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install websockets
|
||||
$ uv add websockets
|
||||
|
||||
---> 100%
|
||||
```
|
||||
@@ -69,7 +69,7 @@ Legen Sie Ihren Code in einer Datei `main.py` ab und führen Sie dann Ihre Anwen
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev
|
||||
$ uv run fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
@@ -96,7 +96,7 @@ Sie können viele Nachrichten senden (und empfangen):
|
||||
|
||||
Und alle verwenden dieselbe WebSocket-Verbindung.
|
||||
|
||||
## Verwendung von `Depends` und anderen { #using-depends-and-others }
|
||||
## `Depends` und andere verwenden { #using-depends-and-others }
|
||||
|
||||
In WebSocket-Endpunkten können Sie Folgendes aus `fastapi` importieren und verwenden:
|
||||
|
||||
@@ -111,7 +111,7 @@ Diese funktionieren auf die gleiche Weise wie für andere FastAPI-Endpunkte/*Pfa
|
||||
|
||||
{* ../../docs_src/websockets_/tutorial002_an_py310.py hl[68:69,82] *}
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Da es sich um einen WebSocket handelt, macht es keinen Sinn, eine `HTTPException` auszulösen, stattdessen lösen wir eine `WebSocketException` aus.
|
||||
|
||||
@@ -126,7 +126,7 @@ Führen Sie Ihre Anwendung aus:
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev
|
||||
$ uv run fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
@@ -182,5 +182,5 @@ Wenn Sie etwas benötigen, das sich leicht in FastAPI integrieren lässt, aber r
|
||||
|
||||
Weitere Informationen zu Optionen finden Sie in der Dokumentation von Starlette:
|
||||
|
||||
* [Die `WebSocket`-Klasse](https://www.starlette.dev/websockets/).
|
||||
* [Klassen-basierte Handhabung von WebSockets](https://www.starlette.dev/endpoints/#websocketendpoint).
|
||||
* [Die `WebSocket`-Klasse](https://starlette.dev/websockets/).
|
||||
* [Klassen-basierte Handhabung von WebSockets](https://starlette.dev/endpoints/#websocketendpoint).
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
# 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.
|
||||
|
||||
Dazu können Sie die `WSGIMiddleware` verwenden und damit Ihre WSGI-Anwendung wrappen, zum Beispiel Flask, Django usw.
|
||||
|
||||
## `WSGIMiddleware` verwenden { #using-wsgimiddleware }
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Dafür muss `a2wsgi` installiert sein, z. B. mit `pip install a2wsgi`.
|
||||
Dafür muss `a2wsgi` zu Ihrem Projekt hinzugefügt werden, z. B. mit `uv add a2wsgi`.
|
||||
|
||||
///
|
||||
|
||||
Sie müssen `WSGIMiddleware` aus `a2wsgi` importieren.
|
||||
|
||||
Wrappen Sie dann die WSGI-Anwendung (z. B. Flask) mit der Middleware.
|
||||
Wrappen Sie dann die WSGI-App (z. B. Flask) mit der Middleware.
|
||||
|
||||
Und dann mounten Sie das auf einem Pfad.
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ Einen offenen Standard für API-Spezifikationen zu übernehmen und zu verwenden,
|
||||
Und Standard-basierte Tools für die Oberfläche zu integrieren:
|
||||
|
||||
* [Swagger UI](https://github.com/swagger-api/swagger-ui)
|
||||
* [ReDoc](https://github.com/Rebilly/ReDoc)
|
||||
* [ReDoc](https://github.com/Redocly/redoc)
|
||||
|
||||
Diese beiden wurden ausgewählt, weil sie ziemlich beliebt und stabil sind, aber bei einer schnellen Suche könnten Sie Dutzende alternativer Benutzeroberflächen für OpenAPI finden (welche Sie mit **FastAPI** verwenden können).
|
||||
|
||||
@@ -137,7 +137,7 @@ Es gibt mehrere Flask REST Frameworks, aber nachdem ich die Zeit und Arbeit inve
|
||||
|
||||
### [Marshmallow](https://marshmallow.readthedocs.io/en/stable/) { #marshmallow }
|
||||
|
||||
Eine der von API-Systemen benötigten Hauptfunktionen ist die Daten-<dfn title="auch genannt: Marshalling, Konvertierung">„Serialisierung“</dfn>, welche Daten aus dem Code (Python) entnimmt und in etwas umwandelt, was durch das Netzwerk gesendet werden kann. Beispielsweise das Konvertieren eines Objekts, welches Daten aus einer Datenbank enthält, in ein JSON-Objekt. Konvertieren von `datetime`-Objekten in Strings, usw.
|
||||
Eine der von API-Systemen benötigten Hauptfunktionen ist die Daten-„<dfn title="auch genannt: Marshalling, Konvertierung">Serialisierung</dfn>“, welche Daten aus dem Code (Python) entnimmt und in etwas umwandelt, was durch das Netzwerk gesendet werden kann. Beispielsweise das Konvertieren eines Objekts, welches Daten aus einer Datenbank enthält, in ein JSON-Objekt. Konvertieren von `datetime`-Objekten in Strings, usw.
|
||||
|
||||
Eine weitere wichtige Funktion, benötigt von APIs, ist die Datenvalidierung, welche sicherstellt, dass die Daten unter gegebenen Umständen gültig sind. Zum Beispiel, dass ein Feld ein `int` ist und kein zufälliger String. Das ist besonders nützlich für hereinkommende Daten.
|
||||
|
||||
@@ -237,7 +237,7 @@ Das OpenAPI-Schema automatisch zu generieren, aus demselben Code, welcher die Se
|
||||
|
||||
///
|
||||
|
||||
### [NestJS](https://nestjs.com/) (und [Angular](https://angular.io/)) { #nestjs-and-angular }
|
||||
### [NestJS](https://nestjs.com/) (und [Angular](https://angular.dev/)) { #nestjs-and-angular }
|
||||
|
||||
Dies ist nicht einmal Python, NestJS ist ein von Angular inspiriertes JavaScript (TypeScript) NodeJS Framework.
|
||||
|
||||
@@ -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.
|
||||
|
||||
Es ist so konzipiert, dass es über Funktionen verfügt, welche zwei Parameter empfangen, einen <abbr title="Request - Anfrage: Daten, die der Client zum Server sendet">„Request“</abbr> und eine <abbr title="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 <abbr title="Request - Anfrage: Daten, die der Client zum Server sendet">„Request“</abbr> und eine <abbr title="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.
|
||||
|
||||
@@ -337,7 +337,7 @@ Da es auf dem bisherigen Standard für synchrone Python-Webframeworks (WSGI) bas
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
Hug wurde von Timothy Crosley erstellt, demselben Schöpfer von [`isort`](https://github.com/timothycrosley/isort), einem großartigen Tool zum automatischen Sortieren von Importen in Python-Dateien.
|
||||
Hug wurde von Timothy Crosley erstellt, demselben Schöpfer von [`isort`](https://github.com/PyCQA/isort), einem großartigen Tool zum automatischen Sortieren von Importen in Python-Dateien.
|
||||
|
||||
///
|
||||
|
||||
@@ -351,11 +351,11 @@ Hug inspirierte **FastAPI** dazu, einen `response`-Parameter in Funktionen zu de
|
||||
|
||||
///
|
||||
|
||||
### [APIStar](https://github.com/encode/apistar) (≦ 0.5) { #apistar-0-5 }
|
||||
### [APIStar](https://github.com/encode/apistar) (<= 0.5) { #apistar-0-5 }
|
||||
|
||||
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.
|
||||
|
||||
@@ -401,7 +401,7 @@ Ich betrachte **FastAPI** als einen „spirituellen Nachfolger“ von APIStar, w
|
||||
|
||||
## Verwendet von **FastAPI** { #used-by-fastapi }
|
||||
|
||||
### [Pydantic](https://docs.pydantic.dev/) { #pydantic }
|
||||
### [Pydantic](https://pydantic.dev/docs/) { #pydantic }
|
||||
|
||||
Pydantic ist eine Bibliothek zum Definieren von Datenvalidierung, Serialisierung und Dokumentation (unter Verwendung von JSON Schema) basierend auf Python-Typhinweisen.
|
||||
|
||||
@@ -417,7 +417,7 @@ Die gesamte Datenvalidierung, Datenserialisierung und automatische Modelldokumen
|
||||
|
||||
///
|
||||
|
||||
### [Starlette](https://www.starlette.dev/) { #starlette }
|
||||
### [Starlette](https://starlette.dev/) { #starlette }
|
||||
|
||||
Starlette ist ein leichtgewichtiges <dfn title="Der neue Standard für die Erstellung asynchroner Python-Webanwendungen">ASGI</dfn>-Framework/Toolkit, welches sich ideal für die Erstellung hochperformanter asynchroner Dienste eignet.
|
||||
|
||||
@@ -433,7 +433,7 @@ Es bietet:
|
||||
* CORS, GZip, statische Dateien, Responses streamen.
|
||||
* Session- und Cookie-Unterstützung.
|
||||
* 100 % Testabdeckung.
|
||||
* 100 % Typannotierte Codebasis.
|
||||
* 100 % typannotierte Codebasis.
|
||||
* Wenige starke Abhängigkeiten.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
///
|
||||
|
||||
@@ -462,7 +462,7 @@ Alles, was Sie also mit Starlette machen können, können Sie direkt mit **FastA
|
||||
|
||||
///
|
||||
|
||||
### [Uvicorn](https://www.uvicorn.dev/) { #uvicorn }
|
||||
### [Uvicorn](https://uvicorn.dev) { #uvicorn }
|
||||
|
||||
Uvicorn ist ein blitzschneller ASGI-Server, der auf uvloop und httptools basiert.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
### 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.
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ FastAPI Cloud ist der Hauptsponsor und Finanzierungsgeber für die *FastAPI and
|
||||
|
||||
## Cloudanbieter – Sponsoren { #cloud-providers-sponsors }
|
||||
|
||||
Einige andere Cloudanbieter ✨ [**sponsern FastAPI**](../help-fastapi.md#sponsor-the-author) ✨ ebenfalls. 🙇
|
||||
Einige andere Cloudanbieter ✨ [**sponsern FastAPI**](https://github.com/sponsors/tiangolo) ✨ ebenfalls. 🙇
|
||||
|
||||
Sie könnten diese ebenfalls in Betracht ziehen, deren Anleitungen folgen und ihre Dienste ausprobieren:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Deployment-Konzepte { #deployments-concepts }
|
||||
|
||||
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:
|
||||
|
||||
@@ -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.
|
||||
|
||||
### 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:
|
||||
|
||||
@@ -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`.
|
||||
* 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):
|
||||
|
||||
* 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.
|
||||
* Jedes Programm, jeder Code **kann nur dann Dinge tun**, wenn er **ausgeführt** wird, wenn also 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**.
|
||||
* 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 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.
|
||||
* 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
|
||||
* Kubernetes
|
||||
* Docker Compose
|
||||
* Docker im Schwarm-Modus
|
||||
* Docker im Swarm-Modus
|
||||
* Systemd
|
||||
* Supervisor
|
||||
* 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 }
|
||||
|
||||
Wenn beim Erstellen von Web-APIs mit FastAPI ein Fehler in unserem Code auftritt, wird FastAPI ihn normalerweise dem einzelnen <abbr title="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 <abbr title="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.
|
||||
|
||||
@@ -170,7 +170,7 @@ Dies könnte zum Beispiel erledigt werden durch:
|
||||
* Docker
|
||||
* Kubernetes
|
||||
* Docker Compose
|
||||
* Docker im Schwarm-Modus
|
||||
* Docker im Swarm-Modus
|
||||
* Systemd
|
||||
* Supervisor
|
||||
* 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 }
|
||||
|
||||
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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
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.
|
||||
|
||||
### Serverspeicher { #server-memory }
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80"]
|
||||
|
||||
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).
|
||||
|
||||
@@ -46,7 +46,7 @@ Container verfügen außerdem über ihre eigenen **isoliert** laufenden Prozesse
|
||||
|
||||
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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
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 }
|
||||
|
||||
@@ -105,36 +105,32 @@ Das ist, was Sie in **den meisten Fällen** tun möchten, zum Beispiel:
|
||||
|
||||
### Paketanforderungen { #package-requirements }
|
||||
|
||||
Normalerweise befinden sich die **Paketanforderungen** für Ihre Anwendung in einer Datei.
|
||||
Wenn Sie Ihr Projekt mit `uv` verwalten, werden dessen direkte Abhängigkeiten in `pyproject.toml` deklariert und die exakt aufgelösten Versionen in `uv.lock` gespeichert.
|
||||
|
||||
Dies hängt hauptsächlich von dem Tool ab, mit dem Sie diese Anforderungen **installieren**.
|
||||
|
||||
Die gebräuchlichste Methode besteht darin, eine Datei `requirements.txt` mit den Namen der Packages und deren Versionen zu erstellen, eine pro Zeile.
|
||||
|
||||
Sie würden natürlich die gleichen Ideen verwenden, die Sie in [Über FastAPI-Versionen](versions.md) gelesen haben, um die Versionsbereiche festzulegen.
|
||||
|
||||
Ihre `requirements.txt` könnte beispielsweise so aussehen:
|
||||
|
||||
```
|
||||
fastapi[standard]>=0.113.0,<0.114.0
|
||||
pydantic>=2.7.0,<3.0.0
|
||||
```
|
||||
|
||||
Und normalerweise würden Sie diese Paketabhängigkeiten mit `pip` installieren, zum Beispiel:
|
||||
Sie können die Packages, die Ihre Anwendung benötigt, hinzufügen mit:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install -r requirements.txt
|
||||
$ uv add "fastapi[standard]" pydantic
|
||||
---> 100%
|
||||
Successfully installed fastapi pydantic
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Es gibt andere Formate und Tools zum Definieren und Installieren von Paketabhängigkeiten.
|
||||
Das Dockerfile unten verwendet `pip` innerhalb des Containers. Sie können die gelockten Abhängigkeiten aus Ihrem uv-Projekt in das erwartete Format `requirements.txt` exportieren:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uv export --format requirements-txt --no-dev --no-emit-project --output-file requirements.txt
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Die generierte `requirements.txt` ist ein Export für den Container-Build. Verwalten Sie Abhängigkeiten weiterhin mit `uv add` und generieren Sie sie neu, wenn sich `uv.lock` ändert.
|
||||
|
||||
///
|
||||
|
||||
@@ -184,19 +180,19 @@ COPY ./app /code/app
|
||||
CMD ["fastapi", "run", "app/main.py", "--port", "80"]
|
||||
```
|
||||
|
||||
1. Beginne mit dem offiziellen Python-Basisimage.
|
||||
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`.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
@@ -212,13 +208,13 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80"]
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
@@ -334,7 +330,7 @@ $ docker build -t myimage .
|
||||
|
||||
Beachten Sie das `.` am Ende, es entspricht `./` und teilt Docker mit, welches Verzeichnis zum Erstellen des Containerimages verwendet werden soll.
|
||||
|
||||
In diesem Fall handelt es sich um dasselbe aktuelle Verzeichnis (`.`).
|
||||
In diesem Case handelt es sich um dasselbe aktuelle Verzeichnis (`.`).
|
||||
|
||||
///
|
||||
|
||||
@@ -372,7 +368,7 @@ Sie sehen die automatische interaktive API-Dokumentation (bereitgestellt von [Sw
|
||||
|
||||
Sie können auch auf [http://192.168.99.100/redoc](http://192.168.99.100/redoc) oder [http://127.0.0.1/redoc](http://127.0.0.1/redoc) gehen (oder ähnlich, unter Verwendung Ihres Docker-Hosts).
|
||||
|
||||
Sie sehen die alternative automatische Dokumentation (bereitgestellt von [ReDoc](https://github.com/Rebilly/ReDoc)):
|
||||
Sie sehen die alternative automatische Dokumentation (bereitgestellt von [ReDoc](https://github.com/Redocly/redoc)):
|
||||
|
||||

|
||||
|
||||
@@ -405,7 +401,7 @@ COPY ./main.py /code/
|
||||
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.
|
||||
|
||||
@@ -440,7 +436,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 }
|
||||
|
||||
@@ -488,7 +484,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 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.
|
||||
|
||||
@@ -496,7 +492,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.
|
||||
|
||||
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:
|
||||
|
||||
```{ .dockerfile .annotate }
|
||||
FROM python:3.14
|
||||
@@ -513,7 +509,7 @@ COPY ./app /code/app
|
||||
CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
|
||||
```
|
||||
|
||||
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:
|
||||
|
||||
@@ -556,7 +552,7 @@ Wenn Sie Container (z. B. Docker, Kubernetes) verwenden, können Sie hauptsächl
|
||||
|
||||
Wenn Sie **mehrere Container** haben, von denen wahrscheinlich jeder einen **einzelnen Prozess** ausführt (z. B. in einem **Kubernetes**-Cluster), dann möchten Sie wahrscheinlich einen **separaten Container** haben, welcher die Arbeit der **Vorab-Schritte** in einem einzelnen Container, mit einem einzelnen Prozess ausführt, **bevor** die replizierten Workercontainer ausgeführt werden.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Wenn Sie Kubernetes verwenden, wäre dies wahrscheinlich ein [Init-Container](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/).
|
||||
|
||||
@@ -576,7 +572,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).
|
||||
|
||||
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.
|
||||
|
||||
/// note | Technische Details
|
||||
|
||||
|
||||
@@ -1,31 +1,11 @@
|
||||
# FastAPI Cloud { #fastapi-cloud }
|
||||
|
||||
Sie können Ihre FastAPI-App in der [FastAPI Cloud](https://fastapicloud.com) mit **einem einzigen Befehl** deployen – tragen Sie sich in die Warteliste ein, falls noch nicht geschehen. 🚀
|
||||
|
||||
## Anmelden { #login }
|
||||
|
||||
Stellen Sie sicher, dass Sie bereits ein **FastAPI-Cloud-Konto** haben (wir haben Sie von der Warteliste eingeladen 😉).
|
||||
|
||||
Melden Sie sich dann an:
|
||||
Sie können Ihre FastAPI-App in der [FastAPI Cloud](https://fastapicloud.com) mit **einem einzigen Befehl** deployen. 🚀
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi login
|
||||
|
||||
You are logged in to FastAPI Cloud 🚀
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## Deployen { #deploy }
|
||||
|
||||
Stellen Sie Ihre App jetzt mit **einem einzigen Befehl** bereit:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi deploy
|
||||
$ uv run fastapi deploy
|
||||
|
||||
Deploying to FastAPI Cloud...
|
||||
|
||||
@@ -36,6 +16,8 @@ Deploying to FastAPI Cloud...
|
||||
|
||||
</div>
|
||||
|
||||
Das CLI erkennt Ihre FastAPI-App automatisch und deployt sie in die Cloud. Wenn Sie nicht angemeldet sind, öffnet sich Ihr Browser, um den Authentifizierungsprozess abzuschließen.
|
||||
|
||||
Das war’s! Jetzt können Sie Ihre App unter dieser URL aufrufen. ✨
|
||||
|
||||
## Über FastAPI Cloud { #about-fastapi-cloud }
|
||||
@@ -62,4 +44,4 @@ Folgen Sie den Anleitungen Ihres Cloudanbieters, um dort FastAPI-Apps zu deploye
|
||||
|
||||
## Auf den eigenen Server deployen { #deploy-your-own-server }
|
||||
|
||||
Ich werde Ihnen später in diesem **Deployment-Leitfaden** auch alle Details zeigen, sodass Sie verstehen, was passiert, was geschehen muss und wie Sie FastAPI-Apps selbst deployen können, auch auf Ihre eigenen Server. 🤓
|
||||
Ich werde Ihnen später in diesem **Deployment**-Leitfaden auch alle Details zeigen, sodass Sie verstehen, was passiert, was geschehen muss und wie Sie FastAPI-Apps selbst deployen können, auch auf Ihre eigenen Server. 🤓
|
||||
|
||||
@@ -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.
|
||||
* Die Verschlüsselung der Verbindung erfolgt auf **TCP-Ebene**.
|
||||
* 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.
|
||||
* 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.
|
||||
* Ganz gleich, wie groß Ihr Server ist oder wie klein die einzelnen Anwendungen darauf sind.
|
||||
* 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**.
|
||||
|
||||
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.
|
||||
|
||||
/// note | Technische Details
|
||||
|
||||
|
||||
@@ -52,11 +52,10 @@ Das Wichtigste, was Sie benötigen, um eine **FastAPI**-Anwendung (oder eine and
|
||||
|
||||
Es gibt mehrere Alternativen, einschließlich:
|
||||
|
||||
* [Uvicorn](https://www.uvicorn.dev/): ein hochperformanter ASGI-Server.
|
||||
* [Uvicorn](https://uvicorn.dev): ein hochperformanter ASGI-Server.
|
||||
* [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.
|
||||
* [Granian](https://github.com/emmett-framework/granian): Ein Rust HTTP-Server für Python-Anwendungen.
|
||||
* [NGINX Unit](https://unit.nginx.org/howto/fastapi/): NGINX Unit ist eine leichte und vielseitige Laufzeitumgebung für Webanwendungen.
|
||||
* [Granian](https://github.com/emmett-framework/granian): Ein Rust-HTTP-Server für Python-Anwendungen.
|
||||
|
||||
## Servermaschine und Serverprogramm { #server-machine-and-server-program }
|
||||
|
||||
@@ -66,22 +65,22 @@ 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.
|
||||
|
||||
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 }
|
||||
|
||||
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.
|
||||
|
||||
Stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../virtual-environments.md) erstellen, sie aktivieren und dann die Serveranwendung installieren.
|
||||
Fügen Sie die Serveranwendung Ihrem Projekt hinzu.
|
||||
|
||||
Zum Beispiel, um Uvicorn zu installieren:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "uvicorn[standard]"
|
||||
$ uv add "uvicorn[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
@@ -96,7 +95,7 @@ Durch das Hinzufügen von `standard` installiert und verwendet Uvicorn einige em
|
||||
|
||||
Dazu gehört `uvloop`, der hochperformante Drop-in-Ersatz für `asyncio`, der den großen Nebenläufigkeits-Leistungsschub bietet.
|
||||
|
||||
Wenn Sie FastAPI mit etwas wie `pip install "fastapi[standard]"` installieren, erhalten Sie auch `uvicorn[standard]`.
|
||||
Wenn Sie FastAPI mit etwas wie `uv add "fastapi[standard]"` hinzufügen, erhalten Sie auch bereits `uvicorn[standard]`.
|
||||
|
||||
///
|
||||
|
||||
@@ -107,7 +106,7 @@ Wenn Sie einen ASGI-Server manuell installiert haben, müssen Sie normalerweise
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --host 0.0.0.0 --port 80
|
||||
$ uv run uvicorn main:app --host 0.0.0.0 --port 80
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
@@ -17,7 +17,7 @@ Wie Sie im vorherigen Kapitel über [Deployment-Konzepte](concepts.md) gesehen h
|
||||
|
||||
Hier zeige ich Ihnen, wie Sie **Uvicorn** mit **Workerprozessen** verwenden, indem Sie den `fastapi`-Befehl oder den `uvicorn`-Befehl direkt verwenden.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Wenn Sie Container verwenden, beispielsweise mit Docker oder Kubernetes, erzähle ich Ihnen mehr darüber im nächsten Kapitel: [FastAPI in Containern – Docker](docker.md).
|
||||
|
||||
@@ -86,7 +86,7 @@ Wenn Sie den `uvicorn`-Befehl direkt verwenden möchten:
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
|
||||
$ uv run uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
|
||||
<font color="#A6E22E">INFO</font>: Uvicorn running on <b>http://0.0.0.0:8080</b> (Press CTRL+C to quit)
|
||||
<font color="#A6E22E">INFO</font>: Started parent process [<font color="#A1EFE4"><b>27365</b></font>]
|
||||
<font color="#A6E22E">INFO</font>: Started server process [<font color="#A1EFE4">27368</font>]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Editor-Unterstützung { #editor-support }
|
||||
|
||||
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).
|
||||
|
||||
@@ -14,10 +14,10 @@ Standardmäßig erkennt die Erweiterung FastAPI-Anwendungen in Ihrem Workspace a
|
||||
|
||||
## Funktionen { #features }
|
||||
|
||||
- Pfadoperation-Explorer – Eine Baumansicht in der Seitenleiste aller <dfn title="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>).
|
||||
- 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/).
|
||||
- Anwendungslogs streamen – Echtzeit-Logstreaming Ihrer auf FastAPI Cloud deployten Anwendung mit Loglevel-Filterung und Textsuche.
|
||||
- **Pfadoperation-Explorer** – Eine Baumansicht in der Seitenleiste aller <dfn title="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>).
|
||||
- **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/).
|
||||
- **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.
|
||||
|
||||
@@ -1,298 +1,11 @@
|
||||
# Umgebungsvariablen { #environment-variables }
|
||||
|
||||
/// tip | Tipp
|
||||
Eine **Umgebungsvariable** (auch bekannt als **env var**) ist ein Wert, der außerhalb Ihres Python-Codes im Betriebssystem existiert und von Ihrer Anwendung und anderen Programmen gelesen werden kann.
|
||||
|
||||
Wenn Sie bereits wissen, was „Umgebungsvariablen“ sind und wie man sie verwendet, können Sie dies überspringen.
|
||||
FastAPI-Anwendungen verwenden häufig Umgebungsvariablen für Konfigurationen wie Datenbank-URLs, E-Mail-Zugangsdaten und Secret-Keys.
|
||||
|
||||
///
|
||||
Sie werden lernen, wie Sie sie für Anwendungskonfigurationen verwenden, in [Einstellungen und Umgebungsvariablen](advanced/settings.md).
|
||||
|
||||
Eine Umgebungsvariable (auch bekannt als „**env var**“) ist eine Variable, die **außerhalb** des Python-Codes im **Betriebssystem** lebt und von Ihrem Python-Code (oder auch von anderen Programmen) gelesen werden kann.
|
||||
## Mehr erfahren { #learn-more }
|
||||
|
||||
Umgebungsvariablen können nützlich sein, um **Einstellungen** der Anwendung zu handhaben, als Teil der **Installation** von Python usw.
|
||||
|
||||
## Umgebungsvariablen erstellen und verwenden { #create-and-use-env-vars }
|
||||
|
||||
Sie können Umgebungsvariablen in der **Shell (Terminal)** erstellen und verwenden, ohne Python zu benötigen:
|
||||
|
||||
//// tab | Linux, macOS, Windows Bash
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Sie können eine Umgebungsvariable MY_NAME erstellen mit
|
||||
$ export MY_NAME="Wade Wilson"
|
||||
|
||||
// Dann können Sie sie mit anderen Programmen verwenden, etwa
|
||||
$ echo "Hello $MY_NAME"
|
||||
|
||||
Hello Wade Wilson
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Erstellen Sie eine Umgebungsvariable MY_NAME
|
||||
$ $Env:MY_NAME = "Wade Wilson"
|
||||
|
||||
// Verwenden Sie sie mit anderen Programmen, etwa
|
||||
$ echo "Hello $Env:MY_NAME"
|
||||
|
||||
Hello Wade Wilson
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
## Umgebungsvariablen in Python lesen { #read-env-vars-in-python }
|
||||
|
||||
Sie können auch Umgebungsvariablen **außerhalb** von Python erstellen, im Terminal (oder mit jeder anderen Methode) und sie dann **in Python** lesen.
|
||||
|
||||
Zum Beispiel könnten Sie eine Datei `main.py` haben mit:
|
||||
|
||||
```Python hl_lines="3"
|
||||
import os
|
||||
|
||||
name = os.getenv("MY_NAME", "World")
|
||||
print(f"Hello {name} from Python")
|
||||
```
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Das zweite Argument von [`os.getenv()`](https://docs.python.org/3.8/library/os.html#os.getenv) ist der Defaultwert, der zurückgegeben wird.
|
||||
|
||||
Wenn er nicht angegeben wird, ist er standardmäßig `None`. Hier geben wir „World“ als den zu verwendenden Defaultwert an.
|
||||
|
||||
///
|
||||
|
||||
Dann könnten Sie das Python-Programm aufrufen:
|
||||
|
||||
//// tab | Linux, macOS, Windows Bash
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Hier setzen wir die Umgebungsvariable noch nicht
|
||||
$ python main.py
|
||||
|
||||
// Da wir die Umgebungsvariable nicht gesetzt haben, erhalten wir den Defaultwert
|
||||
|
||||
Hello World from Python
|
||||
|
||||
// Aber wenn wir zuerst eine Umgebungsvariable erstellen
|
||||
$ export MY_NAME="Wade Wilson"
|
||||
|
||||
// Und dann das Programm erneut aufrufen
|
||||
$ python main.py
|
||||
|
||||
// Jetzt kann es die Umgebungsvariable lesen
|
||||
|
||||
Hello Wade Wilson from Python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Hier setzen wir die Umgebungsvariable noch nicht
|
||||
$ python main.py
|
||||
|
||||
// Da wir die Umgebungsvariable nicht gesetzt haben, erhalten wir den Defaultwert
|
||||
|
||||
Hello World from Python
|
||||
|
||||
// Aber wenn wir zuerst eine Umgebungsvariable erstellen
|
||||
$ $Env:MY_NAME = "Wade Wilson"
|
||||
|
||||
// Und dann das Programm erneut aufrufen
|
||||
$ python main.py
|
||||
|
||||
// Jetzt kann es die Umgebungsvariable lesen
|
||||
|
||||
Hello Wade Wilson from Python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
Da Umgebungsvariablen außerhalb des Codes gesetzt werden können, aber vom Code gelesen werden können und nicht mit den restlichen Dateien gespeichert (in `git` committet) werden müssen, werden sie häufig für Konfigurationen oder **Einstellungen** verwendet.
|
||||
|
||||
Sie können auch eine Umgebungsvariable nur für einen **spezifischen Programmaufruf** erstellen, die nur für dieses Programm und nur für dessen Dauer verfügbar ist.
|
||||
|
||||
Um dies zu tun, erstellen Sie sie direkt vor dem Programmaufruf, in derselben Zeile:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Erstellen Sie eine Umgebungsvariable MY_NAME in der Zeile für diesen Programmaufruf
|
||||
$ MY_NAME="Wade Wilson" python main.py
|
||||
|
||||
// Jetzt kann es die Umgebungsvariable lesen
|
||||
|
||||
Hello Wade Wilson from Python
|
||||
|
||||
// Die Umgebungsvariable existiert danach nicht mehr
|
||||
$ python main.py
|
||||
|
||||
Hello World from Python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Sie können mehr darüber lesen auf [The Twelve-Factor App: Config](https://12factor.net/config).
|
||||
|
||||
///
|
||||
|
||||
## Typen und Validierung { #types-and-validation }
|
||||
|
||||
Diese Umgebungsvariablen können nur **Textstrings** handhaben, da sie extern zu Python sind und kompatibel mit anderen Programmen und dem Rest des Systems (und sogar mit verschiedenen Betriebssystemen, wie Linux, Windows, macOS) sein müssen.
|
||||
|
||||
Das bedeutet, dass **jeder Wert**, der in Python von einer Umgebungsvariablen gelesen wird, **ein `str` sein wird**, und jede Konvertierung in einen anderen Typ oder jede Validierung muss im Code vorgenommen werden.
|
||||
|
||||
Sie werden mehr darüber lernen, wie man Umgebungsvariablen zur Handhabung von **Anwendungseinstellungen** verwendet, im [Handbuch für fortgeschrittene Benutzer – Einstellungen und Umgebungsvariablen](./advanced/settings.md).
|
||||
|
||||
## `PATH`-Umgebungsvariable { #path-environment-variable }
|
||||
|
||||
Es gibt eine **spezielle** Umgebungsvariable namens **`PATH`**, die von den Betriebssystemen (Linux, macOS, Windows) verwendet wird, um Programme zu finden, die ausgeführt werden sollen.
|
||||
|
||||
Der Wert der Variable `PATH` ist ein langer String, der aus Verzeichnissen besteht, die auf Linux und macOS durch einen Doppelpunkt `:` und auf Windows durch ein Semikolon `;` getrennt sind.
|
||||
|
||||
Zum Beispiel könnte die `PATH`-Umgebungsvariable so aussehen:
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
```plaintext
|
||||
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
|
||||
```
|
||||
|
||||
Das bedeutet, dass das System nach Programmen in den Verzeichnissen suchen sollte:
|
||||
|
||||
* `/usr/local/bin`
|
||||
* `/usr/bin`
|
||||
* `/bin`
|
||||
* `/usr/sbin`
|
||||
* `/sbin`
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows
|
||||
|
||||
```plaintext
|
||||
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32
|
||||
```
|
||||
|
||||
Das bedeutet, dass das System nach Programmen in den Verzeichnissen suchen sollte:
|
||||
|
||||
* `C:\Program Files\Python312\Scripts`
|
||||
* `C:\Program Files\Python312`
|
||||
* `C:\Windows\System32`
|
||||
|
||||
////
|
||||
|
||||
Wenn Sie einen **Befehl** im Terminal eingeben, **sucht** das Betriebssystem nach dem Programm in **jedem dieser Verzeichnisse**, die in der `PATH`-Umgebungsvariablen aufgeführt sind.
|
||||
|
||||
Zum Beispiel, wenn Sie `python` im Terminal eingeben, sucht das Betriebssystem nach einem Programm namens `python` im **ersten Verzeichnis** in dieser Liste.
|
||||
|
||||
Wenn es es findet, wird es **benutzt**. Andernfalls sucht es weiter in den **anderen Verzeichnissen**.
|
||||
|
||||
### Python installieren und den `PATH` aktualisieren { #installing-python-and-updating-the-path }
|
||||
|
||||
Wenn Sie Python installieren, könnten Sie gefragt werden, ob Sie die `PATH`-Umgebungsvariable aktualisieren möchten.
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
Angenommen, Sie installieren Python und es landet in einem Verzeichnis `/opt/custompython/bin`.
|
||||
|
||||
Wenn Sie erlauben, die `PATH`-Umgebungsvariable zu aktualisieren, fügt der Installer `/opt/custompython/bin` zur `PATH`-Umgebungsvariable hinzu.
|
||||
|
||||
Das könnte so aussehen:
|
||||
|
||||
```plaintext
|
||||
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin
|
||||
```
|
||||
|
||||
Auf diese Weise, wenn Sie `python` im Terminal eingeben, findet das System das Python-Programm in `/opt/custompython/bin` (das letzte Verzeichnis) und verwendet dieses.
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows
|
||||
|
||||
Angenommen, Sie installieren Python und es landet in einem Verzeichnis `C:\opt\custompython\bin`.
|
||||
|
||||
Wenn Sie erlauben, die `PATH`-Umgebungsvariable zu aktualisieren, fügt der Installer `C:\opt\custompython\bin` zur `PATH`-Umgebungsvariable hinzu.
|
||||
|
||||
```plaintext
|
||||
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin
|
||||
```
|
||||
|
||||
Auf diese Weise, wenn Sie `python` im Terminal eingeben, findet das System das Python-Programm in `C:\opt\custompython\bin` (das letzte Verzeichnis) und verwendet dieses.
|
||||
|
||||
////
|
||||
|
||||
Also, wenn Sie tippen:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
Das System wird das `python` Programm in `/opt/custompython/bin` **finden** und es ausführen.
|
||||
|
||||
Es wäre ungefähr gleichbedeutend mit der Eingabe von:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ /opt/custompython/bin/python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows
|
||||
|
||||
Das System wird das `python` Programm in `C:\opt\custompython\bin\python` **finden** und es ausführen.
|
||||
|
||||
Es wäre ungefähr gleichbedeutend mit der Eingabe von:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ C:\opt\custompython\bin\python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
Diese Informationen werden nützlich sein, wenn Sie über [Virtuelle Umgebungen](virtual-environments.md) lernen.
|
||||
|
||||
## Fazit { #conclusion }
|
||||
|
||||
Mit diesem Wissen sollten Sie ein grundlegendes Verständnis davon haben, was **Umgebungsvariablen** sind und wie man sie in Python verwendet.
|
||||
|
||||
Sie können auch mehr darüber in der [Wikipedia zu Umgebungsvariablen](https://en.wikipedia.org/wiki/Environment_variable) lesen.
|
||||
|
||||
In vielen Fällen ist es nicht sehr offensichtlich, wie Umgebungsvariablen nützlich und sofort anwendbar sein könnten. Aber sie tauchen immer wieder in vielen verschiedenen Szenarien auf, wenn Sie entwickeln, deshalb ist es gut, darüber Bescheid zu wissen.
|
||||
|
||||
Zum Beispiel werden Sie diese Informationen im nächsten Abschnitt über [Virtuelle Umgebungen](virtual-environments.md) benötigen.
|
||||
Lesen Sie den [Leitfaden zu Umgebungsvariablen](https://tiangolo.com/guides/environment-variables/) für eine detaillierte, plattformübergreifende Erklärung, einschließlich der Erstellung und des Lesens von Umgebungsvariablen und wie die `PATH`-Umgebungsvariable funktioniert.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**FastAPI <abbr title="command line interface - Kommandozeileninterface">CLI</abbr>** ist ein Kommandozeilenprogramm, mit dem Sie Ihre FastAPI-App bereitstellen, Ihr FastAPI-Projekt verwalten und mehr.
|
||||
|
||||
Wenn Sie FastAPI installieren (z. B. mit `pip install "fastapi[standard]"`), erhalten Sie ein Kommandozeilenprogramm, das Sie im Terminal ausführen können.
|
||||
Wenn Sie FastAPI zu Ihrem Projekt hinzufügen (z. B. mit `uv add "fastapi[standard]"`), erhalten Sie ein Kommandozeilenprogramm, das Sie im Terminal ausführen können.
|
||||
|
||||
Um Ihre FastAPI-App für die Entwicklung auszuführen, können Sie den Befehl `fastapi dev` verwenden:
|
||||
|
||||
@@ -52,7 +52,7 @@ Für die Produktion würden Sie statt `fastapi dev` `fastapi run` verwenden.
|
||||
|
||||
///
|
||||
|
||||
Intern verwendet das **FastAPI CLI** [Uvicorn](https://www.uvicorn.dev), einen leistungsstarken, produktionsreifen, ASGI-Server. 😎
|
||||
Intern verwendet das **FastAPI CLI** [Uvicorn](https://uvicorn.dev), einen leistungsstarken, produktionsreifen, ASGI-Server. 😎
|
||||
|
||||
Das `fastapi`-CLI versucht automatisch, die auszuführende FastAPI-App zu erkennen, und geht davon aus, dass es sich um ein Objekt namens `app` in einer Datei `main.py` handelt (oder ein paar weitere Varianten).
|
||||
|
||||
@@ -100,13 +100,13 @@ from backend.main import app
|
||||
Sie können auch den Dateipfad an den Befehl `fastapi dev` übergeben, dann wird das zu verwendende FastAPI-App-Objekt erraten:
|
||||
|
||||
```console
|
||||
$ fastapi dev main.py
|
||||
$ uv run fastapi dev main.py
|
||||
```
|
||||
|
||||
Oder Sie können auch die Option `--entrypoint` an den Befehl `fastapi dev` übergeben:
|
||||
|
||||
```console
|
||||
$ fastapi dev --entrypoint main:app
|
||||
$ uv run fastapi dev --entrypoint main:app
|
||||
```
|
||||
|
||||
Aber Sie müssten sich merken, bei jedem Aufruf des `fastapi`-Befehls den korrekten Pfad\entrypoint zu übergeben.
|
||||
@@ -119,6 +119,10 @@ Das Ausführen von `fastapi dev` startet den Entwicklermodus.
|
||||
|
||||
Standardmäßig ist **Autoreload** aktiviert, das den Server automatisch neu lädt, wenn Sie Änderungen an Ihrem Code vornehmen. Dies ist ressourcenintensiv und könnte weniger stabil sein als wenn es deaktiviert ist. Sie sollten es nur für die Entwicklung verwenden. Es horcht auch auf der IP-Adresse `127.0.0.1`, die die IP für Ihre Maschine ist, um nur mit sich selbst zu kommunizieren (`localhost`).
|
||||
|
||||
Vor dem Importieren Ihrer App setzt `fastapi dev` die Umgebungsvariable `FASTAPI_ENV` auf `development`. Wenn `FASTAPI_ENV` bereits gesetzt ist, bleibt der vorhandene Wert erhalten. Dadurch kann App-Startup-Code entwicklungsfreundliches Verhalten wählen, während Sie eine app-spezifische Umgebung wie `staging` bereitstellen können.
|
||||
|
||||
Die konventionellen `FASTAPI_ENV`-Werte sind `development` und `production`. `fastapi run` lässt `FASTAPI_ENV` derzeit unverändert, setzen Sie es also explizit, wenn Ihre App den Produktionsmodus erkennen muss.
|
||||
|
||||
## `fastapi run` { #fastapi-run }
|
||||
|
||||
Das Ausführen von `fastapi run` startet FastAPI im Produktionsmodus.
|
||||
|
||||
+40
-40
@@ -1,10 +1,10 @@
|
||||
# Merkmale { #features }
|
||||
|
||||
## FastAPI Merkmale { #fastapi-features }
|
||||
## FastAPI-Merkmale { #fastapi-features }
|
||||
|
||||
**FastAPI** ermöglicht Ihnen Folgendes:
|
||||
|
||||
### 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 <dfn title="auch bekannt als: Endpunkte, Routen">Pfad</dfn>-<dfn title="auch bekannt als HTTP-Methoden, wie POST, GET, PUT, DELETE">Operationen</dfn>, Parametern, <abbr title="Requestbody">Requestbodys</abbr>, Sicherheit, usw.
|
||||
* Automatische Dokumentation der Datenmodelle mit [**JSON Schema**](https://json-schema.org/) (da OpenAPI selbst auf JSON Schema basiert).
|
||||
@@ -15,19 +15,19 @@
|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
* Alternative API-Dokumentation mit [**ReDoc**](https://github.com/Rebilly/ReDoc).
|
||||
* Alternative API-Dokumentation mit [**ReDoc**](https://github.com/Redocly/redoc).
|
||||
|
||||

|
||||
|
||||
### Nur modernes Python { #just-modern-python }
|
||||
|
||||
Alles basiert auf Standard-**Python-Typ**deklarationen (dank Pydantic). Es muss keine neue Syntax gelernt werden, nur standardisiertes modernes Python.
|
||||
Alles basiert auf Standard-**Python-Typ**deklarationen (dank Pydantic). Es muss keine neue Syntax gelernt werden. Nur modernes Standard-Python.
|
||||
|
||||
Wenn Sie eine zweiminütige Auffrischung benötigen, wie man Python-Typen verwendet (auch wenn Sie FastAPI nicht benutzen), schauen Sie sich das kurze Tutorial an: [Einführung in Python-Typen](python-types.md).
|
||||
Wenn Sie eine zweiminütige Auffrischung benötigen, wie man Python-Typen verwendet (auch wenn Sie FastAPI nicht benutzen), schauen Sie sich das kurze Tutorial an: [Python-Typen](python-types.md).
|
||||
|
||||
Sie schreiben Standard-Python mit Typen:
|
||||
|
||||
@@ -36,7 +36,7 @@ from datetime import date
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
# Deklarieren Sie eine Variable als ein str
|
||||
# Deklarieren Sie eine Variable vom Typ str
|
||||
# und bekommen Sie Editor-Unterstützung innerhalb der Funktion
|
||||
def main(user_id: str):
|
||||
return user_id
|
||||
@@ -67,11 +67,11 @@ my_second_user: User = User(**second_user_data)
|
||||
|
||||
`**second_user_data` bedeutet:
|
||||
|
||||
Nimm die Schlüssel-Wert-Paare des `second_user_data` <abbr title="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` <abbr title="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.
|
||||
|
||||
@@ -85,31 +85,31 @@ So kann Ihr Editor Sie unterstützen:
|
||||
|
||||
* in [Visual Studio Code](https://code.visualstudio.com/):
|
||||
|
||||

|
||||

|
||||
|
||||
* in [PyCharm](https://www.jetbrains.com/pycharm/):
|
||||
|
||||

|
||||

|
||||
|
||||
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.
|
||||
|
||||
### 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“**.
|
||||
|
||||
### Validierung { #validation }
|
||||
|
||||
* Validierung für die meisten (oder alle?) Python-**Datentypen**, hierzu gehören:
|
||||
* JSON Objekte (`dict`).
|
||||
* JSON Listen (`list`), die den Typ ihrer Elemente definieren.
|
||||
* Strings (`str`) mit definierter minimaler und maximaler Länge.
|
||||
* JSON-Objekte (`dict`).
|
||||
* JSON-Array (`list`), das Elementtypen definiert.
|
||||
* String-Felder (`str`) mit definierter minimaler und maximaler Länge.
|
||||
* Zahlen (`int`, `float`) mit Mindest- und Maximalwerten, usw.
|
||||
|
||||
* Validierung für mehr exotische Typen, wie:
|
||||
* Validierung für exotischere Typen, wie:
|
||||
* URL.
|
||||
* E-Mail.
|
||||
* UUID.
|
||||
@@ -124,42 +124,42 @@ Sicherheit und Authentifizierung sind integriert. Ohne Kompromisse bei Datenbank
|
||||
Alle in OpenAPI definierten Sicherheitsschemas, inklusive:
|
||||
|
||||
* HTTP Basic.
|
||||
* **OAuth2** (auch mit **JWT Tokens**). Siehe dazu das Tutorial zu [OAuth2 mit JWT](tutorial/security/oauth2-jwt.md).
|
||||
* API Schlüssel in:
|
||||
* **OAuth2** (auch mit **JWT-Tokens**). Siehe dazu das Tutorial zu [OAuth2 mit JWT](tutorial/security/oauth2-jwt.md).
|
||||
* API-Schlüssel in:
|
||||
* Headern.
|
||||
* Query-Parametern.
|
||||
* Cookies, usw.
|
||||
|
||||
Zusätzlich alle Sicherheitsfunktionen von Starlette (inklusive **Session Cookies**).
|
||||
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.
|
||||
|
||||
### Dependency Injection { #dependency-injection }
|
||||
|
||||
FastAPI enthält ein extrem einfach zu verwendendes, aber extrem mächtiges <dfn title='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 <dfn title='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.
|
||||
* 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 **Pfadoperation** sowie die automatische Dokumentation **erweitern**.
|
||||
* **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.
|
||||
|
||||
### Unbegrenzte Erweiterungen { #unlimited-plug-ins }
|
||||
### Unbegrenzte „Plug-ins“ { #unlimited-plug-ins }
|
||||
|
||||
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 }
|
||||
|
||||
* 100 % <dfn title="Der Prozentsatz an Code, der automatisch getestet wird">Testabdeckung</dfn>.
|
||||
* 100 % <dfn title="Python-Typannotationen, mit denen Ihr Editor und andere externe Werkzeuge Sie besser unterstützen können">Typen annotiert</dfn>.
|
||||
* Zu 100 % <dfn title="Python-Typannotationen, mit denen Ihr Editor und andere externe Werkzeuge Sie besser unterstützen können">typannotierte</dfn> Codebasis.
|
||||
* Verwendet in Produktionsanwendungen.
|
||||
|
||||
## Starlette Merkmale { #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://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.
|
||||
|
||||
@@ -173,29 +173,29 @@ Mit **FastAPI** bekommen Sie alles von **Starlette** (da FastAPI nur Starlette a
|
||||
* **CORS**, GZip, statische Dateien, Responses streamen.
|
||||
* **Sitzungs- und Cookie**-Unterstützung.
|
||||
* 100 % Testabdeckung.
|
||||
* 100 % Typen annotierte Codebasis.
|
||||
* Zu 100 % typannotierte Codebasis.
|
||||
|
||||
## Pydantic Merkmale { #pydantic-features }
|
||||
## Pydantic-Merkmale { #pydantic-features }
|
||||
|
||||
**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://pydantic.dev/docs/). Das bedeutet, wenn Sie eigenen Pydantic-Quellcode haben, funktioniert dieser auch.
|
||||
|
||||
Inklusive externer Bibliotheken, die auf Pydantic basieren, wie <abbr title="Object-Relational Mapper - Objektrelationaler Mapper">ORM</abbr>s, <abbr title="Object-Document Mapper - Objekt-Dokument-Mapper">ODM</abbr>s für Datenbanken.
|
||||
Inklusive externer Bibliotheken, die auf Pydantic basieren, wie <abbr title="Object-Relational Mapper - Objektrelationaler Mapper">ORM</abbr>s und <abbr title="Object-Document Mapper - Objekt-Dokument-Mapper">ODM</abbr>s für Datenbanken.
|
||||
|
||||
Daher können Sie in vielen Fällen das Objekt eines Requests **direkt zur Datenbank** schicken, weil alles automatisch validiert wird.
|
||||
Das bedeutet auch, dass Sie in vielen Fällen dasselbe Objekt, das Sie von einem Request erhalten, **direkt an die Datenbank** übergeben können, da alles automatisch validiert wird.
|
||||
|
||||
Das gleiche gilt auch für die andere Richtung: Sie können in vielen Fällen das Objekt aus der Datenbank **direkt zum Client** senden.
|
||||
Das Gleiche gilt auch umgekehrt: In vielen Fällen können Sie einfach das Objekt, das Sie aus der Datenbank erhalten, **direkt an den Client** übergeben.
|
||||
|
||||
Mit **FastAPI** bekommen Sie alle Funktionen von **Pydantic** (da FastAPI für die gesamte Datenverarbeitung Pydantic nutzt):
|
||||
|
||||
* **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.
|
||||
* Gutes Zusammenspiel mit Ihrer/Ihrem **<abbr title="Integrated Development Environment - Integrierte Entwicklungsumgebung: Ähnlich einem Code-Editor">IDE</abbr>/<dfn title="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.
|
||||
* Validierung von **komplexen Strukturen**:
|
||||
* Benutzung von hierarchischen Pydantic-Modellen, Python-`typing`s `List` und `Dict`, etc.
|
||||
* Die Validierer erlauben es, komplexe Datenschemen 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.
|
||||
* Benutzung von hierarchischen Pydantic-Modellen, Python-`typing`s `List` und `Dict`, usw.
|
||||
* 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.
|
||||
* **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.
|
||||
* 100 % Testabdeckung.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Helfen { #help }
|
||||
|
||||
|
||||
Möchten Sie FastAPI helfen oder Hilfe zu FastAPI erhalten?
|
||||
|
||||
Es gibt sehr einfache Möglichkeiten, zu helfen und Hilfe zu bekommen.
|
||||
@@ -45,20 +46,6 @@ Sie können [mir (Sebastián Ramírez / `tiangolo`)](https://tiangolo.com), dem
|
||||
* [@tiangolo.com auf **Bluesky**](https://bsky.app/profile/tiangolo.com)
|
||||
* [@tiangolo auf **LinkedIn**](https://www.linkedin.com/in/tiangolo/).
|
||||
|
||||
## Anderen bei Fragen auf GitHub helfen { #help-others-with-questions-in-github }
|
||||
|
||||
Sie können versuchen, anderen bei ihren Fragen in [GitHub-Diskussionen](https://github.com/fastapi/fastapi/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered) zu helfen.
|
||||
|
||||
In vielen Fällen kennen Sie möglicherweise bereits die Antwort auf diese Fragen. 🤓
|
||||
|
||||
Wenn Sie vielen Menschen bei ihren Fragen helfen, werden Sie offizieller [FastAPI-Experte](fastapi-people.md#fastapi-experts). 🎉
|
||||
|
||||
Denken Sie daran, der wichtigste Punkt ist: Versuchen Sie, freundlich zu sein. 🤗
|
||||
|
||||
### So helfen { #how-to-help }
|
||||
|
||||
Folgen Sie der [Anleitung, wie Sie helfen können](https://tiangolo.com/open-source/help/#help-others-with-questions-in-github) hier.
|
||||
|
||||
## Fragen stellen { #ask-questions }
|
||||
|
||||
Sie können im GitHub-Repository [eine neue Frage erstellen](https://github.com/fastapi/fastapi/discussions/new?category=questions), zum Beispiel um:
|
||||
@@ -68,7 +55,7 @@ Sie können im GitHub-Repository [eine neue Frage erstellen](https://github.com/
|
||||
|
||||
## Am Chat teilnehmen { #join-the-chat }
|
||||
|
||||
Treten Sie dem 👥 [Discord-Chatserver](https://discord.gg/VQjSZaeJmf) 👥 bei und treffen Sie sich mit anderen Mitgliedern der FastAPI-Community.
|
||||
Treten Sie dem 👥 [Discord-Chatserver](https://discord.com/invite/VQjSZaeJmf) 👥 bei und treffen Sie sich mit anderen Mitgliedern der FastAPI-Community.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -85,3 +72,9 @@ Bedenken Sie, dass Sie in Chats, die „freie Konversation“ erlauben, leicht F
|
||||
Auf GitHub hilft Ihnen die Vorlage dabei, die richtige Frage zu stellen, sodass Sie leichter eine gute Antwort erhalten können, oder sogar das Problem selbst lösen, bevor Sie überhaupt fragen.
|
||||
|
||||
Unterhaltungen in den Chat-Systemen sind auch nicht so leicht durchsuchbar wie auf GitHub, sie gehen verloren.
|
||||
|
||||
## FastAPI Cloud ausprobieren { #try-fastapi-cloud }
|
||||
|
||||
Die Hauptfinanzierung für FastAPI und Freunde kommt von [**FastAPI Cloud**](https://fastapicloud.com), einer Plattform, um FastAPI-Anwendungen auf einfache und schnelle Weise zu deployen, mit einem einzigen Kommando, `fastapi deploy`.
|
||||
|
||||
FastAPI Cloud wird vom selben Team hinter FastAPI entwickelt. Sie können es ausprobieren und für Ihre Projekte in Betracht ziehen.
|
||||
|
||||
@@ -54,11 +54,11 @@ Alles auf eine Weise, die allen Entwicklern das beste Entwicklungserlebnis bot.
|
||||
|
||||
## Anforderungen { #requirements }
|
||||
|
||||
Nachdem ich mehrere Alternativen getestet hatte, entschied ich, dass ich [**Pydantic**](https://docs.pydantic.dev/) wegen seiner Vorteile verwenden würde.
|
||||
Nachdem ich mehrere Alternativen getestet hatte, entschied ich, dass ich [**Pydantic**](https://pydantic.dev/docs/) wegen seiner Vorteile verwenden würde.
|
||||
|
||||
Dann habe ich zu dessen Code beigetragen, um es vollständig mit JSON Schema kompatibel zu machen, und so verschiedene Möglichkeiten zum Definieren von einschränkenden Deklarationen (Constraints) zu unterstützen, und die Editorunterstützung (Typprüfungen, Codevervollständigung) zu verbessern, basierend auf den Tests in mehreren Editoren.
|
||||
|
||||
Während der Entwicklung habe ich auch zu [**Starlette**](https://www.starlette.dev/) beigetragen, die andere Schlüsselanforderung.
|
||||
Während der Entwicklung habe ich auch zu [**Starlette**](https://starlette.dev/) beigetragen, die andere Schlüsselanforderung.
|
||||
|
||||
## Entwicklung { #development }
|
||||
|
||||
|
||||
@@ -67,4 +67,4 @@ presets: [
|
||||
|
||||
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.
|
||||
|
||||
@@ -66,7 +66,7 @@ Das `scope`-`dict` und die `receive`-Funktion sind beide Teil der ASGI-Spezifika
|
||||
|
||||
Und diese beiden Dinge, `scope` und `receive`, werden benötigt, um eine neue `Request`-Instanz zu erstellen.
|
||||
|
||||
Um mehr über den `Request` zu erfahren, schauen Sie sich [Starlettes Dokumentation zu Requests](https://www.starlette.dev/requests/) an.
|
||||
Um mehr über den `Request` zu erfahren, schauen Sie sich [Starlettes Dokumentation zu Requests](https://starlette.dev/requests/) an.
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -25,9 +25,17 @@ Diese Funktion `get_openapi()` erhält als Parameter:
|
||||
* `openapi_version`: Die Version der verwendeten OpenAPI-Spezifikation. Standardmäßig die neueste Version: `3.1.0`.
|
||||
* `summary`: Eine kurze Zusammenfassung der API.
|
||||
* `description`: Die Beschreibung Ihrer API. Dies kann Markdown enthalten und wird in der Dokumentation angezeigt.
|
||||
* `routes`: Eine Liste von Routen, dies sind alle registrierten *Pfadoperationen*. Sie stammen von `app.routes`.
|
||||
* `routes`: Die Routen der Anwendung, entnommen aus `app.routes`. FastAPI nutzt sie, um die registrierten *Pfadoperationen* zu sammeln, einschließlich derer aus eingebundenen Routern.
|
||||
|
||||
/// info | Info
|
||||
/// tip | Technische Details
|
||||
|
||||
`app.routes` ist eine Routenstruktur auf niedrigerer Ebene. Sie kann Routenkandidaten enthalten, die FastAPI intern für eingebundene Router verwendet, nicht nur endgültige `APIRoute`-Objekte.
|
||||
|
||||
Sie können dennoch `app.routes` an `get_openapi()` übergeben. FastAPI durchläuft diesen Routenbaum, um die tatsächlich wirksamen Pfadoperationen zu sammeln.
|
||||
|
||||
///
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
Der Parameter `summary` ist in OpenAPI 3.1.0 und höher verfügbar und wird von FastAPI 0.99.0 und höher unterstützt.
|
||||
|
||||
@@ -37,7 +45,7 @@ Der Parameter `summary` ist in OpenAPI 3.1.0 und höher verfügbar und wird von
|
||||
|
||||
Mithilfe der oben genannten Informationen können Sie dieselbe Hilfsfunktion verwenden, um das OpenAPI-Schema zu generieren und jeden benötigten Teil zu überschreiben.
|
||||
|
||||
Fügen wir beispielsweise [ReDocs OpenAPI-Erweiterung zum Einbinden eines benutzerdefinierten Logos](https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md#x-logo) hinzu.
|
||||
Fügen wir beispielsweise [ReDocs OpenAPI-Erweiterung zum Einbinden eines benutzerdefinierten Logos](https://github.com/Redocly/redoc/blob/main/docs/redoc-vendor-extensions.md#x-logo) hinzu.
|
||||
|
||||
### Normales **FastAPI** { #normal-fastapi }
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# GraphQL { #graphql }
|
||||
|
||||
|
||||
Da **FastAPI** auf dem **ASGI**-Standard basiert, ist es sehr einfach, jede **GraphQL**-Bibliothek zu integrieren, die auch mit ASGI kompatibel ist.
|
||||
|
||||
Sie können normale FastAPI-*Pfadoperationen* mit GraphQL in derselben Anwendung kombinieren.
|
||||
@@ -21,7 +22,7 @@ Hier sind einige der **GraphQL**-Bibliotheken, die **ASGI**-Unterstützung haben
|
||||
* [Strawberry](https://strawberry.rocks/) 🍓
|
||||
* Mit [Dokumentation für FastAPI](https://strawberry.rocks/docs/integrations/fastapi)
|
||||
* [Ariadne](https://ariadnegraphql.org/)
|
||||
* Mit [Dokumentation für FastAPI](https://ariadnegraphql.org/docs/fastapi-integration)
|
||||
* Mit [Dokumentation für FastAPI](https://ariadnegraphql.org/server/Integrations/fastapi-integration)
|
||||
* [Tartiflette](https://tartiflette.io/)
|
||||
* Mit [Tartiflette ASGI](https://tartiflette.github.io/tartiflette-asgi/) für ASGI-Integration
|
||||
* [Graphene](https://graphene-python.org/)
|
||||
|
||||
@@ -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.128.0 entfernte ebenfalls die Unterstützung für `pydantic.v1`, daher erfordern die neuesten Versionen von FastAPI Pydantic v2.
|
||||
|
||||
/// warning | Achtung
|
||||
|
||||
Das Pydantic-Team hat die Unterstützung für Pydantic v1 in den neuesten Python-Versionen eingestellt, beginnend mit **Python 3.14**.
|
||||
@@ -22,7 +24,7 @@ Wenn Sie eine ältere FastAPI-App mit Pydantic v1 haben, zeige ich Ihnen hier, w
|
||||
|
||||
## Offizieller Leitfaden { #official-guide }
|
||||
|
||||
Pydantic hat einen offiziellen [Migrationsleitfaden](https://docs.pydantic.dev/latest/migration/) von v1 zu v2.
|
||||
Pydantic hat einen offiziellen [Migrationsleitfaden](https://pydantic.dev/docs/validation/latest/get-started/migration/) von v1 zu v2.
|
||||
|
||||
Er enthält auch, was sich geändert hat, wie Validierungen nun korrekter und strikter sind, mögliche Stolpersteine, usw.
|
||||
|
||||
@@ -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 }
|
||||
|
||||
/// 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.
|
||||
|
||||
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 }
|
||||
|
||||
/// 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
|
||||
|
||||
Probieren Sie zuerst `bump-pydantic` aus. Wenn Ihre Tests erfolgreich sind und das funktioniert, sind Sie mit einem einzigen Befehl fertig. ✨
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# 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. 😎
|
||||
|
||||
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.
|
||||
@@ -85,7 +86,7 @@ Der Hauptanwendungsfall hierfür besteht wahrscheinlich darin, dass Sie das mal
|
||||
|
||||
In diesem Fall können Sie diese Funktion in **FastAPI** mit dem Parameter `separate_input_output_schemas=False` deaktivieren.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Unterstützung für `separate_input_output_schemas` wurde in FastAPI `0.102.0` hinzugefügt. 🤓
|
||||
|
||||
|
||||
+24
-28
@@ -110,7 +110,7 @@ Seine Schlüssel-Merkmale sind:
|
||||
</div>
|
||||
<div class="fastapi-opinions__panel" id="fo-panel-uber" role="tabpanel" aria-labelledby="fo-tab-uber" tabindex="0" hidden>
|
||||
<blockquote class="fastapi-opinions__quote">„Wir haben die <strong>FastAPI</strong>-Bibliothek übernommen, um einen <strong>REST</strong>-Server zu erstellen, der für <strong>Vorhersagen</strong> abgefragt werden kann.“ <em>[für Ludwig]</em></blockquote>
|
||||
<div class="fastapi-opinions__attr">— Piero Molino, Yaroslav Dudin, Sai Sumanth Miryala, <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/">(Ref.)</a></div>
|
||||
<div class="fastapi-opinions__attr">— Piero Molino, Yaroslav Dudin, Sai Sumanth Miryala, <strong>Uber</strong> <a href="https://www.uber.com/us/en/blog/ludwig-v0-2/">(Ref.)</a></div>
|
||||
</div>
|
||||
<div class="fastapi-opinions__panel" id="fo-panel-netflix" role="tabpanel" aria-labelledby="fo-tab-netflix" tabindex="0" hidden>
|
||||
<blockquote class="fastapi-opinions__quote">„<strong>Netflix</strong> freut sich, die Open-Source-Veröffentlichung unseres <strong>Krisenmanagement</strong>-Orchestrierungsframeworks bekannt zu geben: <strong>Dispatch</strong>!“ <em>[erstellt mit FastAPI]</em></blockquote>
|
||||
@@ -133,7 +133,7 @@ Seine Schlüssel-Merkmale sind:
|
||||
|
||||
„_Wir haben die **FastAPI**-Bibliothek übernommen, um einen **REST**-Server zu erstellen, der für **Vorhersagen** abgefragt werden kann. [für Ludwig]_“
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, und Sai Sumanth Miryala – <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/"><small>(Ref.)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, und Sai Sumanth Miryala – <strong>Uber</strong> <a href="https://www.uber.com/us/en/blog/ludwig-v0-2/"><small>(Ref.)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
@@ -151,12 +151,6 @@ Seine Schlüssel-Merkmale sind:
|
||||
|
||||
</div>
|
||||
|
||||
## FastAPI Conf { #fastapi-conf }
|
||||
|
||||
[**FastAPI Conf ’26**](https://fastapiconf.com) findet am **28. Oktober 2026** in **Amsterdam, NL** statt. Alles über FastAPI, direkt von der Quelle. 🎤
|
||||
|
||||
<a class="fastapi-feature-banner" href="https://fastapiconf.com"><img src="https://fastapi.tiangolo.com/img/fastapi-conf.jpeg" alt="FastAPI Conf ’26 - 28. Oktober 2026 - Amsterdam, NL"></a>
|
||||
|
||||
## FastAPI Mini-Dokumentarfilm { #fastapi-mini-documentary }
|
||||
|
||||
Es gibt einen [FastAPI-Mini-Dokumentarfilm](https://www.youtube.com/watch?v=mpR8ngthqiE), veröffentlicht Ende 2025, Sie können ihn online ansehen:
|
||||
@@ -167,7 +161,7 @@ Es gibt einen [FastAPI-Mini-Dokumentarfilm](https://www.youtube.com/watch?v=mpR8
|
||||
|
||||
<a href="https://typer.tiangolo.com"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
|
||||
|
||||
Wenn Sie eine <abbr title="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 <abbr title="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. ⌨️ 🚀
|
||||
|
||||
@@ -175,17 +169,17 @@ Wenn Sie eine <abbr title="Command Line Interface - Kommandozeilen-Schnittstelle
|
||||
|
||||
FastAPI steht auf den Schultern von Giganten:
|
||||
|
||||
* [Starlette](https://www.starlette.dev/) für die Webanteile.
|
||||
* [Pydantic](https://docs.pydantic.dev/) für die Datenanteile.
|
||||
* [Starlette](https://starlette.dev/) für die Webanteile.
|
||||
* [Pydantic](https://pydantic.dev/docs/) für die Datenanteile.
|
||||
|
||||
## Installation { #installation }
|
||||
|
||||
Erstellen und aktivieren Sie eine [virtuelle Umgebung](https://fastapi.tiangolo.com/de/virtual-environments/) und installieren Sie dann FastAPI:
|
||||
Installieren Sie zuerst [`uv`](https://docs.astral.sh/uv/getting-started/installation/) und fügen Sie dann FastAPI zu Ihrem Projekt hinzu:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "fastapi[standard]"
|
||||
$ uv add "fastapi[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
@@ -194,9 +188,11 @@ $ pip install "fastapi[standard]"
|
||||
|
||||
**Hinweis**: Stellen Sie sicher, dass Sie `"fastapi[standard]"` in Anführungszeichen setzen, damit es in allen Terminals funktioniert.
|
||||
|
||||
Wenn Sie lieber `pip` verwenden, installieren Sie `fastapi[standard]` innerhalb einer virtuellen Umgebung. Siehe die [Installationsanleitung](tutorial/#install-fastapi) für die alternativen Schritte.
|
||||
|
||||
## Beispiel { #example }
|
||||
|
||||
### Erstellung { #create-it }
|
||||
### Erstellen { #create-it }
|
||||
|
||||
Erstellen Sie eine Datei `main.py` mit:
|
||||
|
||||
@@ -250,7 +246,7 @@ Starten Sie den Server mit:
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev
|
||||
$ uv run fastapi dev
|
||||
|
||||
╭────────── FastAPI CLI - Development mode ───────────╮
|
||||
│ │
|
||||
@@ -277,7 +273,7 @@ INFO: Application startup complete.
|
||||
<details markdown="1">
|
||||
<summary>Über den Befehl <code>fastapi dev</code> ...</summary>
|
||||
|
||||
Der Befehl `fastapi dev` liest Ihre `main.py`-Datei, erkennt die **FastAPI**-App darin und startet einen Server mit [Uvicorn](https://www.uvicorn.dev).
|
||||
Der Befehl `fastapi dev` liest Ihre `main.py`-Datei automatisch, erkennt die **FastAPI**-App darin und startet einen Server mit [Uvicorn](https://uvicorn.dev).
|
||||
|
||||
Standardmäßig wird `fastapi dev` mit aktiviertem Auto-Reload für die lokale Entwicklung gestartet.
|
||||
|
||||
@@ -314,7 +310,7 @@ Sie sehen die automatische interaktive API-Dokumentation (bereitgestellt von [Sw
|
||||
|
||||
Und jetzt gehen Sie auf [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc).
|
||||
|
||||
Sie sehen die alternative automatische Dokumentation (bereitgestellt von [ReDoc](https://github.com/Rebilly/ReDoc)):
|
||||
Sie sehen die alternative automatische Dokumentation (bereitgestellt von [ReDoc](https://github.com/Redocly/redoc)):
|
||||
|
||||

|
||||
|
||||
@@ -492,14 +488,12 @@ Für ein vollständigeres Beispiel, mit weiteren Funktionen, siehe das <a href="
|
||||
|
||||
### Ihre App deployen (optional) { #deploy-your-app-optional }
|
||||
|
||||
Optional können Sie Ihre FastAPI-App in die [FastAPI Cloud](https://fastapicloud.com) deployen, gehen Sie und treten Sie der Warteliste bei, falls noch nicht geschehen. 🚀
|
||||
|
||||
Wenn Sie bereits ein **FastAPI Cloud**-Konto haben (wir haben Sie von der Warteliste eingeladen 😉), können Sie Ihre Anwendung mit einem einzigen Befehl deployen.
|
||||
Optional können Sie Ihre FastAPI-App mit einem einzigen Befehl in die [FastAPI Cloud](https://fastapicloud.com) deployen. 🚀
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi deploy
|
||||
$ uv run fastapi deploy
|
||||
|
||||
Deploying to FastAPI Cloud...
|
||||
|
||||
@@ -510,6 +504,8 @@ Deploying to FastAPI Cloud...
|
||||
|
||||
</div>
|
||||
|
||||
Das CLI erkennt Ihre FastAPI-Anwendung automatisch und deployt sie in die Cloud. Wenn Sie nicht eingeloggt sind, wird Ihr Browser geöffnet, um den Authentifizierungsprozess abzuschließen.
|
||||
|
||||
Das war’s! Jetzt können Sie unter dieser URL auf Ihre App zugreifen. ✨
|
||||
|
||||
#### Über FastAPI Cloud { #about-fastapi-cloud }
|
||||
@@ -540,7 +536,7 @@ FastAPI hängt von Pydantic und Starlette ab.
|
||||
|
||||
### `standard`-Abhängigkeiten { #standard-dependencies }
|
||||
|
||||
Wenn Sie FastAPI mit `pip install "fastapi[standard]"` installieren, kommt es mit der `standard`-Gruppe optionaler Abhängigkeiten:
|
||||
Wenn Sie FastAPI mit `uv add "fastapi[standard]"` installieren, kommt es mit der `standard`-Gruppe optionaler Abhängigkeiten:
|
||||
|
||||
Verwendet von Pydantic:
|
||||
|
||||
@@ -554,17 +550,17 @@ Verwendet von Starlette:
|
||||
|
||||
Verwendet von FastAPI:
|
||||
|
||||
* [`uvicorn`](https://www.uvicorn.dev) – für den Server, der Ihre Anwendung lädt und bereitstellt. Dies umfasst `uvicorn[standard]`, das einige Abhängigkeiten (z. B. `uvloop`) beinhaltet, die für eine Bereitstellung mit hoher Performanz benötigt werden.
|
||||
* [`uvicorn`](https://uvicorn.dev) – für den Server, der Ihre Anwendung lädt und bereitstellt. Dies umfasst `uvicorn[standard]`, das einige Abhängigkeiten (z. B. `uvloop`) beinhaltet, die für eine Bereitstellung mit hoher Performanz benötigt werden.
|
||||
* `fastapi-cli[standard]` – um den `fastapi`-Befehl bereitzustellen.
|
||||
* Dies beinhaltet `fastapi-cloud-cli`, das es Ihnen ermöglicht, Ihre FastAPI-Anwendung auf [FastAPI Cloud](https://fastapicloud.com) bereitzustellen.
|
||||
|
||||
### Ohne `standard`-Abhängigkeiten { #without-standard-dependencies }
|
||||
|
||||
Wenn Sie die `standard` optionalen Abhängigkeiten nicht einschließen möchten, können Sie mit `pip install fastapi` statt `pip install "fastapi[standard]"` installieren.
|
||||
Wenn Sie die `standard` optionalen Abhängigkeiten nicht einschließen möchten, können Sie mit `uv add fastapi` statt `uv add "fastapi[standard]"` installieren.
|
||||
|
||||
### Ohne `fastapi-cloud-cli` { #without-fastapi-cloud-cli }
|
||||
|
||||
Wenn Sie FastAPI mit den Standardabhängigkeiten, aber ohne das `fastapi-cloud-cli` installieren möchten, können Sie mit `pip install "fastapi[standard-no-fastapi-cloud-cli]"` installieren.
|
||||
Wenn Sie FastAPI mit den Standardabhängigkeiten, aber ohne das `fastapi-cloud-cli` installieren möchten, können Sie mit `uv add "fastapi[standard-no-fastapi-cloud-cli]"` installieren.
|
||||
|
||||
### Zusätzliche optionale Abhängigkeiten { #additional-optional-dependencies }
|
||||
|
||||
@@ -572,13 +568,13 @@ Es gibt einige zusätzliche Abhängigkeiten, die Sie installieren möchten.
|
||||
|
||||
Zusätzliche optionale Pydantic-Abhängigkeiten:
|
||||
|
||||
* [`pydantic-settings`](https://docs.pydantic.dev/latest/usage/pydantic_settings/) – für die Verwaltung von Einstellungen.
|
||||
* [`pydantic-extra-types`](https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/) – für zusätzliche Typen zur Verwendung mit Pydantic.
|
||||
* [`pydantic-settings`](https://pydantic.dev/docs/validation/latest/concepts/pydantic_settings/) – für die Verwaltung von Einstellungen.
|
||||
* [`pydantic-extra-types`](https://github.com/pydantic/pydantic-extra-types) – für zusätzliche Typen zur Verwendung mit Pydantic.
|
||||
|
||||
Zusätzliche optionale FastAPI-Abhängigkeiten:
|
||||
|
||||
* [`orjson`](https://github.com/ijl/orjson) – erforderlich, wenn Sie `ORJSONResponse` verwenden möchten.
|
||||
* [`ujson`](https://github.com/esnme/ultrajson) – erforderlich, wenn Sie `UJSONResponse` verwenden möchten.
|
||||
* [`ujson`](https://github.com/ultrajson/ultrajson) – erforderlich, wenn Sie `UJSONResponse` verwenden möchten.
|
||||
|
||||
## Lizenz { #license }
|
||||
|
||||
|
||||
@@ -4,20 +4,20 @@ Vorlagen, die normalerweise mit einem bestimmten Setup geliefert werden, sind so
|
||||
|
||||
Sie können diese Vorlage verwenden, um loszulegen, da sie bereits vieles der anfänglichen Einrichtung, Sicherheit, Datenbank und einige API-Endpunkte für Sie eingerichtet hat.
|
||||
|
||||
GitHub-Repository: [Full Stack FastAPI Template](https://github.com/tiangolo/full-stack-fastapi-template)
|
||||
GitHub-Repository: [Full Stack FastAPI Template](https://github.com/fastapi/full-stack-fastapi-template)
|
||||
|
||||
## Full Stack FastAPI Template – Technologiestack und Funktionen { #full-stack-fastapi-template-technology-stack-and-features }
|
||||
|
||||
- ⚡ [**FastAPI**](https://fastapi.tiangolo.com/de) für die Python-Backend-API.
|
||||
- 🧰 [SQLModel](https://sqlmodel.tiangolo.com) für die Interaktion mit der Python-SQL-Datenbank (ORM).
|
||||
- 🔍 [Pydantic](https://docs.pydantic.dev), verwendet von FastAPI, für die Datenvalidierung und das Einstellungsmanagement.
|
||||
- 🔍 [Pydantic](https://pydantic.dev/docs/), verwendet von FastAPI, für die Datenvalidierung und das Einstellungsmanagement.
|
||||
- 💾 [PostgreSQL](https://www.postgresql.org) als SQL-Datenbank.
|
||||
- 🚀 [React](https://react.dev) für das Frontend.
|
||||
- 💃 Verwendung von TypeScript, Hooks, Vite und anderen Teilen eines modernen Frontend-Stacks.
|
||||
- 🎨 [Tailwind CSS](https://tailwindcss.com) und [shadcn/ui](https://ui.shadcn.com) für die Frontend-Komponenten.
|
||||
- 🤖 Ein automatisch generierter Frontend-Client.
|
||||
- 🧪 [Playwright](https://playwright.dev) für End-to-End-Tests.
|
||||
- 🦇 „Dark-Mode“-Unterstützung.
|
||||
- 🦇 Dark-Mode-Unterstützung.
|
||||
- 🐋 [Docker Compose](https://www.docker.com) für Entwicklung und Produktion.
|
||||
- 🔒 Sicheres Passwort-Hashing standardmäßig.
|
||||
- 🔑 JWT (JSON Web Token)-Authentifizierung.
|
||||
|
||||
@@ -44,7 +44,7 @@ Es ist ein sehr einfaches Programm.
|
||||
|
||||
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“.
|
||||
|
||||
@@ -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.
|
||||
|
||||
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:
|
||||
|
||||
@@ -62,7 +62,7 @@ Aber leider erhalten Sie nichts Nützliches:
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
<img src="/img/python-types/image02.png">
|
||||
|
||||
@@ -116,7 +116,7 @@ Jetzt, da Sie wissen, dass Sie das reparieren müssen, konvertieren Sie `age` mi
|
||||
|
||||
{* ../../docs_src/python_types/tutorial004_py310.py hl[2] *}
|
||||
|
||||
## Deklarieren von Typen { #declaring-types }
|
||||
## Typen deklarieren { #declaring-types }
|
||||
|
||||
Sie haben gerade den Haupt-Einsatzort für die Deklaration von Typhinweisen gesehen. Als Funktionsparameter.
|
||||
|
||||
@@ -180,7 +180,7 @@ In diesem Fall ist `str` der Typ-Parameter, der an `list` übergeben wird.
|
||||
|
||||
///
|
||||
|
||||
Das bedeutet: Die Variable `items` ist eine Liste – `list` – und jedes der Elemente in dieser Liste ist ein String – `str`.
|
||||
Das bedeutet: „Die Variable `items` ist eine `list`, und jedes der Elemente in dieser Liste ist ein `str`“.
|
||||
|
||||
Auf diese Weise kann Ihr Editor Sie auch bei der Bearbeitung von Einträgen aus der Liste unterstützen:
|
||||
|
||||
@@ -263,13 +263,13 @@ Und wiederum bekommen Sie die volle Editor-Unterstützung:
|
||||
|
||||
<img src="/img/python-types/image06.png">
|
||||
|
||||
Beachten Sie, das bedeutet: „`one_person` ist eine **Instanz** der Klasse `Person`“.
|
||||
Beachten Sie, dass das bedeutet: „`one_person` ist eine **Instanz** der Klasse `Person`“.
|
||||
|
||||
Es bedeutet nicht: „`one_person` ist die **Klasse** genannt `Person`“.
|
||||
Es bedeutet nicht: „`one_person` ist die **Klasse** namens `Person`“.
|
||||
|
||||
## Pydantic-Modelle { #pydantic-models }
|
||||
|
||||
[Pydantic](https://docs.pydantic.dev/) ist eine Python-Bibliothek für die Validierung von Daten.
|
||||
[Pydantic](https://pydantic.dev/docs/) ist eine Python-Bibliothek für die Validierung von Daten.
|
||||
|
||||
Sie deklarieren die „Form“ der Daten als Klassen mit Attributen.
|
||||
|
||||
@@ -279,13 +279,13 @@ Dann erzeugen Sie eine Instanz dieser Klasse mit einigen Werten, und Pydantic va
|
||||
|
||||
Und Sie erhalten volle Editor-Unterstützung für dieses Objekt.
|
||||
|
||||
Ein Beispiel aus der offiziellen Pydantic Dokumentation:
|
||||
Ein Beispiel aus der offiziellen Pydantic-Dokumentation:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial011_py310.py *}
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
Um mehr über [Pydantic zu erfahren, schauen Sie sich dessen Dokumentation an](https://docs.pydantic.dev/).
|
||||
Um mehr über [Pydantic zu erfahren, schauen Sie sich dessen Dokumentation an](https://pydantic.dev/docs/).
|
||||
|
||||
///
|
||||
|
||||
@@ -301,11 +301,11 @@ Sie können `Annotated` von `typing` importieren.
|
||||
|
||||
{* ../../docs_src/python_types/tutorial013_py310.py hl[1,4] *}
|
||||
|
||||
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. 😎
|
||||
|
||||
@@ -335,7 +335,7 @@ Mit **FastAPI** deklarieren Sie Parameter mit Typhinweisen, und Sie erhalten:
|
||||
* **Daten zu validieren**: aus jedem Request:
|
||||
* **Automatische Fehler** generieren, die an den Client zurückgegeben werden, wenn die Daten ungültig sind.
|
||||
* 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).
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ Und dann schreibt ein weiterer Hintergrundtask, der in der *Pfadoperation-Funkti
|
||||
|
||||
## Technische Details { #technical-details }
|
||||
|
||||
Die Klasse `BackgroundTasks` stammt direkt von [`starlette.background`](https://www.starlette.dev/background/).
|
||||
Die Klasse `BackgroundTasks` stammt direkt von [`starlette.background`](https://starlette.dev/background/).
|
||||
|
||||
Sie wird direkt in FastAPI importiert/inkludiert, sodass Sie sie von `fastapi` importieren können und vermeiden, versehentlich das alternative `BackgroundTask` (ohne das `s` am Ende) von `starlette.background` zu importieren.
|
||||
|
||||
@@ -71,7 +71,7 @@ Indem Sie nur `BackgroundTasks` (und nicht `BackgroundTask`) verwenden, ist es d
|
||||
|
||||
Es ist immer noch möglich, `BackgroundTask` allein in FastAPI zu verwenden, aber Sie müssen das Objekt in Ihrem Code erstellen und eine Starlette-`Response` zurückgeben, die es enthält.
|
||||
|
||||
Weitere Details finden Sie in [Starlettes offizieller Dokumentation für Hintergrundtasks](https://www.starlette.dev/background/).
|
||||
Weitere Details finden Sie in [Starlettes offizieller Dokumentation für Hintergrundtasks](https://starlette.dev/background/).
|
||||
|
||||
## Vorbehalt { #caveat }
|
||||
|
||||
|
||||
@@ -17,16 +17,16 @@ Nehmen wir an, Sie haben eine Dateistruktur wie diese:
|
||||
```
|
||||
.
|
||||
├── app
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py
|
||||
│ ├── dependencies.py
|
||||
│ └── routers
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── items.py
|
||||
│ │ └── users.py
|
||||
│ └── internal
|
||||
│ ├── __init__.py
|
||||
│ └── admin.py
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py
|
||||
│ ├── dependencies.py
|
||||
│ └── routers
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── items.py
|
||||
│ │ └── users.py
|
||||
│ └── internal
|
||||
│ ├── __init__.py
|
||||
│ └── admin.py
|
||||
```
|
||||
|
||||
/// tip | Tipp
|
||||
@@ -396,9 +396,9 @@ Es wird alle Routen von diesem Router als Teil von dieser inkludieren.
|
||||
|
||||
/// note | Technische Details
|
||||
|
||||
Tatsächlich wird intern eine *Pfadoperation* für jede *Pfadoperation* erstellt, die im `APIRouter` deklariert wurde.
|
||||
FastAPI behält den ursprünglichen `APIRouter` und seine `APIRoute`s aktiv, wenn der Router in die Hauptanwendung eingebunden wird.
|
||||
|
||||
Hinter den Kulissen wird es also tatsächlich so funktionieren, als ob alles dieselbe einzige Anwendung wäre.
|
||||
Das bedeutet, dass benutzerdefinierte Subklassen von `APIRouter` und `APIRoute` auch nach dem Einbinden weiterhin beteiligt sein können.
|
||||
|
||||
///
|
||||
|
||||
@@ -406,7 +406,7 @@ Hinter den Kulissen wird es also tatsächlich so funktionieren, als ob alles die
|
||||
|
||||
Bei der Einbindung von Routern müssen Sie sich keine Gedanken über die Leistung machen.
|
||||
|
||||
Dies dauert Mikrosekunden und geschieht nur beim Start.
|
||||
Dies ist so konzipiert, dass es leichtgewichtig ist und keinen Overhead pro Request hinzufügt.
|
||||
|
||||
Es hat also keinen Einfluss auf die Leistung. ⚡
|
||||
|
||||
@@ -459,9 +459,9 @@ und es wird korrekt funktionieren, zusammen mit allen anderen *Pfadoperationen*,
|
||||
|
||||
Die `APIRouter` sind nicht „gemountet“, sie sind nicht vom Rest der Anwendung isoliert.
|
||||
|
||||
Das liegt daran, dass wir deren *Pfadoperationen* in das OpenAPI-Schema und die Benutzeroberflächen einbinden möchten.
|
||||
Das liegt daran, dass wir ihre *Pfadoperationen* im OpenAPI-Schema und in den Benutzeroberflächen inkludieren möchten.
|
||||
|
||||
Da wir sie nicht einfach isolieren und unabhängig vom Rest „mounten“ können, werden die *Pfadoperationen* „geklont“ (neu erstellt) und nicht direkt einbezogen.
|
||||
FastAPI behält die ursprünglichen Router und Pfadoperationen aktiv und kombiniert Router-Präfixe, Abhängigkeiten, Tags, Responses und weitere Metadaten beim Bearbeiten von Requests und beim Generieren von OpenAPI.
|
||||
|
||||
///
|
||||
|
||||
@@ -487,7 +487,7 @@ Auf diese Weise weiß der `fastapi`-Befehl, wo er Ihre App findet.
|
||||
Sie könnten auch den Pfad an den Befehl übergeben, etwa:
|
||||
|
||||
```console
|
||||
$ fastapi dev app/main.py
|
||||
$ uv run fastapi dev app/main.py
|
||||
```
|
||||
|
||||
Aber dann müssten Sie sich jedes Mal, wenn Sie den `fastapi`-Befehl aufrufen, an den korrekten Pfad erinnern.
|
||||
@@ -503,7 +503,7 @@ Führen Sie nun Ihre App aus:
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev
|
||||
$ uv run fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
@@ -532,4 +532,16 @@ Auf die gleiche Weise, wie Sie einen `APIRouter` in eine `FastAPI`-Anwendung ein
|
||||
router.include_router(other_router)
|
||||
```
|
||||
|
||||
Stellen Sie sicher, dass Sie dies tun, bevor Sie `router` in die `FastAPI`-App einbinden, damit auch die *Pfadoperationen* von `other_router` inkludiert werden.
|
||||
Sie können dies vor oder nach dem Einbinden von `router` in die `FastAPI`-App tun. FastAPI inkludiert die *Pfadoperationen* von `other_router` dennoch in Routing und OpenAPI.
|
||||
|
||||
Gleiches gilt für später zu den Routern hinzugefügte *Pfadoperationen*. Sie sind auch über die frühere Inklusion sichtbar.
|
||||
|
||||
/// warning | Technische Details
|
||||
|
||||
Vermeiden Sie es, `router.routes` direkt zu mutieren, nachdem ein Router inkludiert wurde. FastAPI behandelt Router-Inklusion als „live“, sodass der ursprüngliche Router und seine Routen Teil des Routings und der OpenAPI-Generierung bleiben.
|
||||
|
||||
Verwenden Sie dokumentierte APIs wie Pfadoperation-Dekoratoren und `.include_router()`, um Routen und Router hinzuzufügen.
|
||||
|
||||
Betrachten Sie `router.routes` als eine Low-Level-Routenstruktur, die sowohl Routendefinitionen als auch inkludierte Router enthalten kann, und verlassen Sie sich nicht darauf als flache Liste endgültiger Pfadoperationen.
|
||||
|
||||
///
|
||||
|
||||
@@ -108,7 +108,7 @@ Zum Beispiel:
|
||||
|
||||
{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *}
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
`Body` hat die gleichen zusätzlichen Validierungs- und Metadaten-Parameter wie `Query`, `Path` und andere, die Sie später kennenlernen werden.
|
||||
|
||||
@@ -123,7 +123,7 @@ Standardmäßig wird **FastAPI** dann seinen Body direkt erwarten.
|
||||
Aber wenn Sie möchten, dass es einen JSON-Body mit einem Schlüssel `item` erwartet, und darin den Inhalt des Modells, so wie es das tut, wenn Sie mehrere Body-Parameter deklarieren, dann können Sie den speziellen `Body`-Parameter `embed` setzen:
|
||||
|
||||
```Python
|
||||
item: Item = Body(embed=True)
|
||||
item: Annotated[Item, Body(embed=True)]
|
||||
```
|
||||
|
||||
so wie in:
|
||||
|
||||
@@ -4,7 +4,7 @@ Mit **FastAPI** können Sie (dank Pydantic) beliebig tief verschachtelte Modelle
|
||||
|
||||
## Listen als Felder { #list-fields }
|
||||
|
||||
Sie können ein Attribut als Kindtyp definieren, zum Beispiel eine Python-`list`.
|
||||
Sie können ein Attribut als Kindtyp definieren. Zum Beispiel eine Python-`list`:
|
||||
|
||||
{* ../../docs_src/body_nested_models/tutorial001_py310.py hl[12] *}
|
||||
|
||||
@@ -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 }
|
||||
|
||||
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 }
|
||||
|
||||
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
|
||||
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 }
|
||||
|
||||
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 <abbr title="Menge">`set`</abbr>.
|
||||
Und Python hat einen speziellen Datentyp für Mengen eindeutiger Elemente, das <abbr title="Menge">`set`</abbr>.
|
||||
|
||||
Deklarieren wir also `tags` als Set von Strings.
|
||||
Dann können wir `tags` als Set von Strings deklarieren:
|
||||
|
||||
{* ../../docs_src/body_nested_models/tutorial003_py310.py hl[12] *}
|
||||
|
||||
Jetzt, selbst wenn Sie einen <abbr title="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 <abbr title="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 }
|
||||
|
||||
@@ -52,13 +53,13 @@ Jedes Attribut eines Pydantic-Modells hat einen Typ.
|
||||
|
||||
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.
|
||||
|
||||
### 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:
|
||||
|
||||
{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[7:9] *}
|
||||
|
||||
@@ -68,7 +69,7 @@ Und dann können wir es als Typ eines Attributes verwenden:
|
||||
|
||||
{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[18] *}
|
||||
|
||||
Das würde bedeuten, dass **FastAPI** einen Body wie folgt erwartet:
|
||||
Das würde bedeuten, dass **FastAPI** einen Body ähnlich dem folgenden erwartet:
|
||||
|
||||
```JSON
|
||||
{
|
||||
@@ -84,7 +85,7 @@ Das würde bedeuten, dass **FastAPI** einen Body wie folgt erwartet:
|
||||
}
|
||||
```
|
||||
|
||||
Wiederum, nur mit dieser Deklaration erhalten Sie von **FastAPI**:
|
||||
Wiederum, nur mit dieser Deklaration erhalten Sie mit **FastAPI**:
|
||||
|
||||
* Editor-Unterstützung (Codevervollständigung, usw.), selbst für verschachtelte Modelle
|
||||
* Datenkonvertierung
|
||||
@@ -95,7 +96,7 @@ Wiederum, nur mit dieser Deklaration erhalten Sie von **FastAPI**:
|
||||
|
||||
Abgesehen von normalen einfachen Typen wie `str`, `int`, `float`, usw. können Sie komplexere einfache Typen verwenden, die von `str` erben.
|
||||
|
||||
Um alle Optionen kennenzulernen, die Sie haben, schauen Sie sich [Pydantics Typübersicht](https://docs.pydantic.dev/latest/concepts/types/) an. Sie werden einige Beispiele im nächsten Kapitel kennenlernen.
|
||||
Um alle Optionen kennenzulernen, die Sie haben, schauen Sie sich [Pydantics Typübersicht](https://pydantic.dev/docs/validation/latest/concepts/types/) an. Sie werden einige Beispiele im nächsten Kapitel kennenlernen.
|
||||
|
||||
Zum Beispiel, da wir im `Image`-Modell ein Feld `url` haben, können wir deklarieren, dass das eine Instanz von Pydantics `HttpUrl` sein soll, anstelle eines `str`:
|
||||
|
||||
@@ -105,7 +106,7 @@ Es wird getestet, ob der String eine gültige URL ist, und als solche wird er in
|
||||
|
||||
## Attribute mit Listen von Kindmodellen { #attributes-with-lists-of-submodels }
|
||||
|
||||
Sie können Pydantic-Modelle auch als Typen innerhalb von `list`, `set`, usw. verwenden:
|
||||
Sie können Pydantic-Modelle auch als Kindtypen von `list`, `set`, usw. verwenden:
|
||||
|
||||
{* ../../docs_src/body_nested_models/tutorial006_py310.py hl[18] *}
|
||||
|
||||
@@ -135,7 +136,7 @@ Das wird einen JSON-Body erwarten (konvertieren, validieren, dokumentieren, usw.
|
||||
}
|
||||
```
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Beachten Sie, dass der `images`-Schlüssel jetzt eine Liste von Bild-Objekten hat.
|
||||
|
||||
@@ -147,15 +148,15 @@ Sie können beliebig tief verschachtelte Modelle definieren:
|
||||
|
||||
{* ../../docs_src/body_nested_models/tutorial007_py310.py hl[7,12,18,21,25] *}
|
||||
|
||||
/// info | Info
|
||||
/// 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 }
|
||||
|
||||
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:
|
||||
|
||||
```Python
|
||||
images: list[Image]
|
||||
@@ -169,29 +170,29 @@ so wie in:
|
||||
|
||||
Und Sie erhalten Editor-Unterstützung überall.
|
||||
|
||||
Selbst für Dinge in Listen:
|
||||
Selbst für Elemente innerhalb von Listen:
|
||||
|
||||
<img src="/img/tutorial/body-nested-models/image01.png">
|
||||
|
||||
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 }
|
||||
|
||||
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`.
|
||||
|
||||
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:
|
||||
|
||||
{* ../../docs_src/body_nested_models/tutorial009_py310.py hl[7] *}
|
||||
|
||||
@@ -201,9 +202,9 @@ Bedenken Sie, dass JSON nur `str` als Schlüssel unterstützt.
|
||||
|
||||
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
|
||||
|
||||
Aber mit all den Vorzügen:
|
||||
|
||||
* Editor-Unterstützung (Codevervollständigung überall)
|
||||
* Datenkonvertierung (auch bekannt als Parsen, Serialisierung)
|
||||
* Editor-Unterstützung (Codevervollständigung überall!)
|
||||
* Datenkonvertierung (auch bekannt als Parsen / Serialisierung)
|
||||
* Datenvalidierung
|
||||
* Schema-Dokumentation
|
||||
* Automatische Dokumentation
|
||||
|
||||
@@ -6,15 +6,15 @@ Ein <abbr title="Anfragekörper">**Request**body</abbr> sind Daten, die vom Clie
|
||||
|
||||
Ihre API muss fast immer einen **Response**body senden. Aber Clients müssen nicht unbedingt immer **Requestbodys** senden, manchmal fordern sie nur einen Pfad an, vielleicht mit einigen Query-Parametern, aber senden keinen Body.
|
||||
|
||||
Um einen **Request**body zu deklarieren, verwenden Sie [Pydantic](https://docs.pydantic.dev/)-Modelle mit all deren Fähigkeiten und Vorzügen.
|
||||
Um einen **Request**body zu deklarieren, verwenden Sie [Pydantic](https://pydantic.dev/docs/)-Modelle mit all deren Fähigkeiten und Vorzügen.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Um Daten zu senden, sollten Sie eines von: `POST` (meistverwendet), `PUT`, `DELETE` oder `PATCH` verwenden.
|
||||
|
||||
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:
|
||||
|
||||
{* ../../docs_src/body/tutorial001_py310.py hl[5:9] *}
|
||||
|
||||
|
||||
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-<abbr title="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
|
||||
{
|
||||
@@ -109,7 +110,7 @@ Aber Sie würden die gleiche Editor-Unterstützung in [PyCharm](https://www.jetb
|
||||
|
||||
/// 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:
|
||||
|
||||
@@ -127,7 +128,7 @@ Innerhalb der Funktion können Sie alle Attribute des Modellobjekts direkt verwe
|
||||
|
||||
{* ../../docs_src/body/tutorial002_py310.py *}
|
||||
|
||||
## Requestbody- + Pfad-Parameter { #request-body-path-parameters }
|
||||
## Requestbody + Pfad-Parameter { #request-body-path-parameters }
|
||||
|
||||
Sie können Pfad-Parameter und den Requestbody gleichzeitig deklarieren.
|
||||
|
||||
@@ -136,7 +137,7 @@ Sie können Pfad-Parameter und den Requestbody gleichzeitig deklarieren.
|
||||
{* ../../docs_src/body/tutorial003_py310.py hl[15:16] *}
|
||||
|
||||
|
||||
## Requestbody- + Pfad- + Query-Parameter { #request-body-path-query-parameters }
|
||||
## Requestbody + Pfad- + Query-Parameter { #request-body-path-query-parameters }
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ Sie können die definierten Cookies in der Dokumentationsoberfläche unter `/doc
|
||||
<img src="/img/tutorial/cookie-param-models/image01.png">
|
||||
</div>
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Bitte beachten Sie, dass Browser Cookies auf spezielle Weise und im Hintergrund bearbeiten, sodass sie **nicht** leicht **JavaScript** erlauben, diese zu berühren.
|
||||
|
||||
|
||||
@@ -24,13 +24,13 @@ Aber denken Sie daran, dass, wenn Sie `Query`, `Path`, `Cookie` und andere von `
|
||||
|
||||
///
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Um Cookies zu deklarieren, müssen Sie `Cookie` verwenden, da die Parameter sonst als Query-Parameter interpretiert würden.
|
||||
|
||||
///
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Beachten Sie, dass **Browser Cookies auf besondere Weise und hinter den Kulissen handhaben** und **JavaScript** **nicht** ohne Weiteres erlauben, auf sie zuzugreifen.
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ Der Hauptzweck von `__name__ == "__main__"` ist, dass Code ausgeführt wird, wen
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python myapp.py
|
||||
$ uv run python myapp.py
|
||||
```
|
||||
|
||||
</div>
|
||||
@@ -35,7 +35,7 @@ Wenn Sie sie mit folgendem Befehl ausführen:
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python myapp.py
|
||||
$ uv run python myapp.py
|
||||
```
|
||||
|
||||
</div>
|
||||
@@ -88,7 +88,7 @@ Zum Beispiel können Sie in Visual Studio Code:
|
||||
|
||||
* Zum „Debug“-Panel gehen.
|
||||
* „Konfiguration hinzufügen ...“ auswählen.
|
||||
* „Python“ auswählen.
|
||||
* „Python“ auswählen
|
||||
* Den Debugger mit der Option „`Python: Current File (Integrated Terminal)`“ ausführen.
|
||||
|
||||
Der Server wird dann mit Ihrem **FastAPI**-Code gestartet, an Ihren Haltepunkten angehalten, usw.
|
||||
@@ -99,7 +99,7 @@ So könnte es aussehen:
|
||||
|
||||
---
|
||||
|
||||
Wenn Sie Pycharm verwenden, können Sie:
|
||||
Wenn Sie PyCharm verwenden, können Sie:
|
||||
|
||||
* Das Menü „Run“ öffnen.
|
||||
* Die Option „Debug ...“ auswählen.
|
||||
|
||||
@@ -28,7 +28,7 @@ Damit wird auch vermieden, neue Entwickler möglicherweise zu verwirren, die ein
|
||||
|
||||
///
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
In diesem Beispiel verwenden wir zwei erfundene benutzerdefinierte Header `X-Key` und `X-Token`.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
FastAPI unterstützt Abhängigkeiten, die einige <dfn title="manchmal auch genannt: „Exit Code“, „Cleanup Code“, „Teardown Code“, „Closing Code“, „Kontextmanager Exit Code“, usw.">zusätzliche Schritte nach Abschluss</dfn> ausführen.
|
||||
|
||||
Verwenden Sie dazu `yield` statt `return` und schreiben Sie die zusätzlichen Schritte / den zusätzlichen Code danach.
|
||||
Verwenden Sie dazu `yield` statt `return` und schreiben Sie die zusätzlichen Schritte (Code) danach.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -77,7 +77,7 @@ Und wiederum benötigt `dependency_b` den Wert von `dependency_a` (hier `dep_a`
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[18:19,26:27] *}
|
||||
|
||||
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.
|
||||
|
||||
@@ -170,7 +170,7 @@ participant tasks as Hintergrundtasks
|
||||
end
|
||||
```
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Es wird nur **eine Response** an den Client gesendet. Es kann eine Error-Response oder die Response der *Pfadoperation* sein.
|
||||
|
||||
@@ -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.
|
||||
|
||||
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 }
|
||||
|
||||
### 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).
|
||||
|
||||
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:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial010_py310.py hl[1:9,13] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Andere Möglichkeiten, einen Kontextmanager zu erstellen, sind:
|
||||
Eine weitere Möglichkeit, einen Kontextmanager zu erstellen, ist:
|
||||
|
||||
* [`@contextlib.contextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager) oder
|
||||
* [`@contextlib.asynccontextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager)
|
||||
|
||||
Verwenden Sie diese, um eine Funktion zu dekorieren, die ein einziges `yield` hat.
|
||||
indem Sie damit eine Funktion dekorieren, die ein einziges `yield` hat.
|
||||
|
||||
Das ist es auch, was **FastAPI** intern für Abhängigkeiten mit `yield` verwendet.
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ In diesem Fall erwartet diese Abhängigkeit:
|
||||
|
||||
Und dann wird einfach ein <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> zurückgegeben, welches diese Werte enthält.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
FastAPI unterstützt (und empfiehlt die Verwendung von) `Annotated` seit Version 0.95.0.
|
||||
|
||||
@@ -105,7 +105,7 @@ common_parameters --> read_users
|
||||
|
||||
Auf diese Weise schreiben Sie gemeinsam genutzten Code nur einmal, und **FastAPI** kümmert sich darum, ihn für Ihre *Pfadoperationen* aufzurufen.
|
||||
|
||||
/// check | Testen
|
||||
/// tip | Tipp
|
||||
|
||||
Beachten Sie, dass Sie keine spezielle Klasse erstellen und diese irgendwo an **FastAPI** übergeben müssen, um sie zu „registrieren“ oder so ähnlich.
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ Diese Abhängigkeit verwenden wir nun wie folgt:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[23] *}
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Beachten Sie, dass wir in der *Pfadoperation-Funktion* nur eine einzige Abhängigkeit deklarieren, den `query_or_cookie_extractor`.
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ Hier sind einige der zusätzlichen Datentypen, die Sie verwenden können:
|
||||
* `datetime.timedelta`:
|
||||
* Ein Python-`datetime.timedelta`.
|
||||
* Wird in Requests und Responses als `float` der Gesamtsekunden dargestellt.
|
||||
* Pydantic ermöglicht auch die Darstellung als „ISO 8601 Zeitdifferenz-Kodierung“, [siehe die Dokumentation für weitere Informationen](https://docs.pydantic.dev/latest/concepts/serialization/#custom-serializers).
|
||||
* Pydantic ermöglicht auch die Darstellung als „ISO 8601 Zeitdifferenz-Kodierung“, [siehe die Dokumentation für weitere Informationen](https://pydantic.dev/docs/validation/latest/concepts/serialization/#custom-serializers).
|
||||
* `frozenset`:
|
||||
* Wird in Requests und Responses wie ein `set` behandelt:
|
||||
* Bei Requests wird eine Liste gelesen, Duplikate entfernt und in ein `set` umgewandelt.
|
||||
@@ -49,7 +49,7 @@ Hier sind einige der zusätzlichen Datentypen, die Sie verwenden können:
|
||||
* `Decimal`:
|
||||
* Standard-Python-`Decimal`.
|
||||
* In Requests und Responses wird es wie ein `float` behandelt.
|
||||
* Sie können alle gültigen Pydantic-Datentypen hier überprüfen: [Pydantic-Datentypen](https://docs.pydantic.dev/latest/usage/types/types/).
|
||||
* Sie können alle gültigen Pydantic-Datentypen hier überprüfen: [Pydantic-Datentypen](https://pydantic.dev/docs/validation/latest/concepts/types/).
|
||||
|
||||
## Beispiel { #example }
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ würden wir ein Python-`dict` erhalten mit:
|
||||
|
||||
#### 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:
|
||||
|
||||
@@ -166,7 +166,7 @@ Um das zu tun, verwenden Sie den Standard-Python-Typhinweis [`typing.Union`](htt
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
Wenn Sie eine [`Union`](https://docs.pydantic.dev/latest/concepts/types/#unions) definieren, listen Sie den spezifischeren Typ zuerst auf, gefolgt vom weniger spezifischen Typ. Im Beispiel unten steht `PlaneItem` vor `CarItem` in `Union[PlaneItem, CarItem]`.
|
||||
Wenn Sie eine [`Union`](https://pydantic.dev/docs/validation/latest/concepts/unions/) definieren, listen Sie den spezifischsten Typ zuerst auf, gefolgt vom weniger spezifischen Typ. Im folgenden Beispiel kommt der spezifischere `PlaneItem` vor `CarItem` in `Union[PlaneItem, CarItem]`.
|
||||
|
||||
///
|
||||
|
||||
@@ -196,7 +196,7 @@ Dafür verwenden Sie Pythons Standard-`list`:
|
||||
|
||||
## 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).
|
||||
|
||||
@@ -208,4 +208,4 @@ In diesem Fall können Sie `dict` verwenden:
|
||||
|
||||
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.
|
||||
|
||||
@@ -6,12 +6,18 @@ Die einfachste FastAPI-Datei könnte wie folgt aussehen:
|
||||
|
||||
Kopieren Sie das in eine Datei `main.py`.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
FastAPI hat eine [offizielle Erweiterung für VS Code](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) (und Cursor), die viele Features bereitstellt, darunter einen Pfadoperation-Explorer, Pfadoperation-Suche, CodeLens-Navigation in Tests (Sprung zur Definition aus Tests) sowie Deployment und Logs von FastAPI Cloud, alles aus Ihrem Editor heraus.
|
||||
|
||||
///
|
||||
|
||||
Starten Sie den Live-Server:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ <font color="#4E9A06">fastapi</font> dev
|
||||
$ <font color="#4E9A06">uv run fastapi</font> dev
|
||||
|
||||
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting development server 🚀
|
||||
|
||||
@@ -78,7 +84,7 @@ Sie werden die automatisch erzeugte, interaktive API-Dokumentation sehen (bereit
|
||||
|
||||
Gehen Sie nun auf [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc).
|
||||
|
||||
Dort sehen Sie die alternative, automatische Dokumentation (bereitgestellt durch [ReDoc](https://github.com/Rebilly/ReDoc)):
|
||||
Dort sehen Sie die alternative, automatische Dokumentation (bereitgestellt durch [ReDoc](https://github.com/Redocly/redoc)):
|
||||
|
||||

|
||||
|
||||
@@ -180,42 +186,32 @@ was äquivalent wäre zu:
|
||||
from backend.main import app
|
||||
```
|
||||
|
||||
### `fastapi dev` mit Pfad { #fastapi-dev-with-path }
|
||||
### `fastapi dev` mit Pfad oder mit der CLI-Option `--entrypoint` { #fastapi-dev-with-path-or-with-entrypoint-cli-option }
|
||||
|
||||
Sie können auch den Dateipfad an den Befehl `fastapi dev` übergeben, und er wird das zu verwendende FastAPI-App-Objekt erraten:
|
||||
|
||||
```console
|
||||
$ fastapi dev main.py
|
||||
$ uv run fastapi dev main.py
|
||||
```
|
||||
|
||||
Aber Sie müssten sich daran erinnern, bei jedem Aufruf des `fastapi`-Befehls den korrekten Pfad zu übergeben.
|
||||
Oder Sie können die Option `--entrypoint` an den Befehl `fastapi dev` übergeben:
|
||||
|
||||
```console
|
||||
$ uv run fastapi dev --entrypoint main:app
|
||||
```
|
||||
|
||||
Aber Sie müssten sich daran erinnern, bei jedem Aufruf des `fastapi`-Befehls den korrekten Pfad\entrypoint zu übergeben.
|
||||
|
||||
Zusätzlich könnten andere Tools es nicht finden, z. B. die [VS Code-Erweiterung](../editor-support.md) oder [FastAPI Cloud](https://fastapicloud.com). Daher wird empfohlen, den `entrypoint` in `pyproject.toml` zu verwenden.
|
||||
|
||||
### Ihre App deployen (optional) { #deploy-your-app-optional }
|
||||
|
||||
Sie können optional Ihre FastAPI-App in der [FastAPI Cloud](https://fastapicloud.com) deployen, treten Sie der Warteliste bei, falls Sie es noch nicht getan haben. 🚀
|
||||
|
||||
Wenn Sie bereits ein **FastAPI Cloud**-Konto haben (wir haben Sie von der Warteliste eingeladen 😉), können Sie Ihre Anwendung mit einem Befehl deployen.
|
||||
|
||||
Vor dem Deployen, stellen Sie sicher, dass Sie eingeloggt sind:
|
||||
Sie können optional Ihre FastAPI-App in der [FastAPI Cloud](https://fastapicloud.com) mit einem einzigen Befehl deployen. 🚀
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi login
|
||||
|
||||
You are logged in to FastAPI Cloud 🚀
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Dann stellen Sie Ihre App bereit:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi deploy
|
||||
$ uv run fastapi deploy
|
||||
|
||||
Deploying to FastAPI Cloud...
|
||||
|
||||
@@ -226,7 +222,9 @@ Deploying to FastAPI Cloud...
|
||||
|
||||
</div>
|
||||
|
||||
Das war's! Jetzt können Sie Ihre App unter dieser URL aufrufen. ✨
|
||||
Das CLI erkennt Ihre FastAPI-Anwendung automatisch und deployt sie in die Cloud. Wenn Sie nicht eingeloggt sind, wird Ihr Browser geöffnet, um die Authentifizierung abzuschließen.
|
||||
|
||||
Das war’s! Jetzt können Sie Ihre App unter dieser URL aufrufen. ✨
|
||||
|
||||
## Zusammenfassung, Schritt für Schritt { #recap-step-by-step }
|
||||
|
||||
@@ -240,11 +238,11 @@ Das war's! Jetzt können Sie Ihre App unter dieser URL aufrufen. ✨
|
||||
|
||||
`FastAPI` ist eine Klasse, die direkt von `Starlette` erbt.
|
||||
|
||||
Sie können alle [Starlette](https://www.starlette.dev/)-Funktionalitäten auch mit `FastAPI` nutzen.
|
||||
Sie können alle [Starlette](https://starlette.dev/)-Funktionalitäten auch mit `FastAPI` nutzen.
|
||||
|
||||
///
|
||||
|
||||
### Schritt 2: Erzeugen einer `FastAPI`-„Instanz“ { #step-2-create-a-fastapi-instance }
|
||||
### Schritt 2: Eine `FastAPI`-„Instanz“ erstellen { #step-2-create-a-fastapi-instance }
|
||||
|
||||
{* ../../docs_src/first_steps/tutorial001_py310.py hl[3] *}
|
||||
|
||||
@@ -252,7 +250,7 @@ In diesem Beispiel ist die Variable `app` eine „Instanz“ der Klasse `FastAPI
|
||||
|
||||
Dies wird der Hauptinteraktionspunkt für die Erstellung all Ihrer APIs sein.
|
||||
|
||||
### Schritt 3: Erstellen einer *Pfadoperation* { #step-3-create-a-path-operation }
|
||||
### Schritt 3: Eine *Pfadoperation* erstellen { #step-3-create-a-path-operation }
|
||||
|
||||
#### Pfad { #path }
|
||||
|
||||
@@ -270,7 +268,7 @@ https://example.com/items/foo
|
||||
/items/foo
|
||||
```
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Ein „Pfad“ wird häufig auch als „Endpunkt“ oder „Route“ bezeichnet.
|
||||
|
||||
@@ -313,7 +311,7 @@ In OpenAPI wird folglich jede dieser HTTP-Methoden als „Operation“ bezeichne
|
||||
|
||||
Wir werden sie auch „**Operationen**“ nennen.
|
||||
|
||||
#### Definieren eines *Pfadoperation-Dekorators* { #define-a-path-operation-decorator }
|
||||
#### Einen *Pfadoperation-Dekorator* definieren { #define-a-path-operation-decorator }
|
||||
|
||||
{* ../../docs_src/first_steps/tutorial001_py310.py hl[6] *}
|
||||
|
||||
@@ -322,7 +320,7 @@ Das `@app.get("/")` sagt **FastAPI**, dass die Funktion direkt darunter für die
|
||||
* den Pfad `/`
|
||||
* unter der Verwendung der <dfn title="eine HTTP-GET-Methode"><code>get</code>-Operation</dfn> gehen
|
||||
|
||||
/// info | `@decorator` Info
|
||||
/// note | `@decorator` Info
|
||||
|
||||
Diese `@something`-Syntax wird in Python „Dekorator“ genannt.
|
||||
|
||||
@@ -357,11 +355,11 @@ Es steht Ihnen frei, jede Operation (HTTP-Methode) so zu verwenden, wie Sie es m
|
||||
|
||||
Die hier aufgeführten Informationen dienen als Leitfaden und sind nicht verbindlich.
|
||||
|
||||
Wenn Sie beispielsweise GraphQL verwenden, führen Sie normalerweise alle Aktionen nur mit „POST“-Operationen durch.
|
||||
Wenn Sie beispielsweise GraphQL verwenden, führen Sie normalerweise alle Aktionen nur mit `POST`-Operationen durch.
|
||||
|
||||
///
|
||||
|
||||
### Schritt 4: Definieren der **Pfadoperation-Funktion** { #step-4-define-the-path-operation-function }
|
||||
### Schritt 4: Die **Pfadoperation-Funktion** definieren { #step-4-define-the-path-operation-function }
|
||||
|
||||
Das ist unsere „**Pfadoperation-Funktion**“:
|
||||
|
||||
@@ -407,11 +405,11 @@ Stellen Sie Ihre App in der **[FastAPI Cloud](https://fastapicloud.com)** mit ei
|
||||
|
||||
**[FastAPI Cloud](https://fastapicloud.com)** wird vom selben Autor und Team hinter **FastAPI** entwickelt.
|
||||
|
||||
Es vereinfacht den Prozess des Erstellens, Deployens und des Zugriffs auf eine API mit minimalem Aufwand.
|
||||
Es vereinfacht den Prozess des **Erstellens**, **Deployens** und des **Zugriffs** auf eine API mit minimalem Aufwand.
|
||||
|
||||
Es bringt die gleiche **Developer-Experience** beim Erstellen von Apps mit FastAPI auch zum **Deployment** in der Cloud. 🎉
|
||||
|
||||
FastAPI Cloud ist der Hauptsponsor und Finanzierer der „FastAPI and friends“ Open-Source-Projekte. ✨
|
||||
FastAPI Cloud ist der Hauptsponsor und Finanzierer der *FastAPI and friends*-Open-Source-Projekte. ✨
|
||||
|
||||
#### Zu anderen Cloudanbietern deployen { #deploy-to-other-cloud-providers }
|
||||
|
||||
@@ -422,7 +420,7 @@ Folgen Sie den Anleitungen Ihres Cloudanbieters, um dort FastAPI-Apps bereitzust
|
||||
## Zusammenfassung { #recap }
|
||||
|
||||
* Importieren Sie `FastAPI`.
|
||||
* Erstellen Sie eine `app` Instanz.
|
||||
* Erstellen Sie eine `app`-Instanz.
|
||||
* Schreiben Sie einen **Pfadoperation-Dekorator** unter Verwendung von Dekoratoren wie `@app.get("/")`.
|
||||
* Definieren Sie eine **Pfadoperation-Funktion**, zum Beispiel `def root(): ...`.
|
||||
* Starten Sie den Entwicklungsserver mit dem Befehl `fastapi dev`.
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
# Frontend { #frontend }
|
||||
|
||||
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`.
|
||||
|
||||
Ihre Projektstruktur könnte so aussehen:
|
||||
|
||||
```text
|
||||
.
|
||||
├── pyproject.toml
|
||||
├── app
|
||||
│ ├── __init__.py
|
||||
│ └── main.py
|
||||
└── dist
|
||||
├── index.html
|
||||
└── assets
|
||||
└── app.js
|
||||
```
|
||||
|
||||
Stellen Sie es dann mit `app.frontend()` bereit:
|
||||
|
||||
{* ../../docs_src/frontend/tutorial001_py310.py hl[5] *}
|
||||
|
||||
Damit kann ein Request für `/assets/app.js` `dist/assets/app.js` ausliefern.
|
||||
|
||||
Wenn Sie außerdem eine **FastAPI**-*Pfadoperation* haben, gewinnt die *Pfadoperation*.
|
||||
|
||||
## Clientseitiges Routing { #client-side-routing }
|
||||
|
||||
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.
|
||||
|
||||
Verwenden Sie dafür `fallback="index.html"`:
|
||||
|
||||
{* ../../docs_src/frontend/tutorial002_py310.py hl[5] *}
|
||||
|
||||
**FastAPI** verwendet diesen Fallback nur für `GET`- und `HEAD`-Requests, die explizit HTML mit `Accept: text/html` oder `Accept: application/xhtml+xml` akzeptieren, wie Browser-Navigationsrequests es normalerweise tun. 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.
|
||||
|
||||
## Benutzerdefinierte 404-Seite { #custom-404-page }
|
||||
|
||||
Sie können auch eine statische `404.html`-Seite für fehlende Frontend-Pfade ausliefern:
|
||||
|
||||
{* ../../docs_src/frontend/tutorial003_py310.py hl[5] *}
|
||||
|
||||
Diese Response behält einen Statuscode von `404`.
|
||||
|
||||
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.
|
||||
|
||||
{* ../../docs_src/frontend/tutorial001_py310.py hl[5] *}
|
||||
|
||||
## Fallback deaktivieren { #disable-fallback }
|
||||
|
||||
Wenn Sie keine Fallback-Datei für fehlende Frontend-Pfade ausliefern möchten, verwenden Sie `fallback=None`:
|
||||
|
||||
{* ../../docs_src/frontend/tutorial005_py310.py hl[5] *}
|
||||
|
||||
Dann geben fehlende Frontend-Pfade das normale `404` zurück.
|
||||
|
||||
## Verzeichnis prüfen { #check-directory }
|
||||
|
||||
Standardmäßig verwendet `app.frontend()` `check_dir="auto"`.
|
||||
|
||||
Wenn die `FASTAPI_ENV`-Umgebungsvariable auf `development` gesetzt ist, zeigt **FastAPI** nur eine Warnung an, wenn das Output-Verzeichnis des Frontend-Builds fehlt. Der [`fastapi dev`-Befehl](https://github.com/fastapi/fastapi-cli#fastapi-dev) setzt diese Umgebungsvariable für Sie, wenn sie nicht bereits gesetzt ist. Dadurch können Sie während der Entwicklung das Backend starten, bevor Sie das Frontend bauen oder starten.
|
||||
|
||||
In jeder anderen Umgebung löst **FastAPI** einen Fehler aus, wenn die App erstellt wird. Das hilft, Konfigurationsfehler früh zu erkennen, bevor eine App ohne ihre Frontend-Dateien deployt wird.
|
||||
|
||||
Sie können auch `check_dir=True` setzen, um das Verzeichnis immer zu prüfen, wenn die App erstellt wird.
|
||||
|
||||
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`:
|
||||
|
||||
{* ../../docs_src/frontend/tutorial006_py310.py hl[5] *}
|
||||
|
||||
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:
|
||||
|
||||
{* ../../docs_src/frontend/tutorial004_py310.py hl[6,7] *}
|
||||
|
||||
In diesem Beispiel werden Frontend-Pfade unter `/app` bereitgestellt.
|
||||
|
||||
Alle regulären *Pfadoperationen* in der App haben weiterhin Vorrang, auch in anderen Routern.
|
||||
|
||||
## Abhängigkeiten und Middleware { #dependencies-and-middleware }
|
||||
|
||||
Frontend-Responses laufen innerhalb der normalen **FastAPI**-Anwendung, daher gilt HTTP-Middleware für sie.
|
||||
|
||||
Abhängigkeiten aus der App, aus einem `APIRouter` und aus `include_router()` gelten ebenfalls für Frontend-Responses. Das kann nützlich sein, um ein Frontend mit Cookie-Authentifizierung oder Ähnlichem zu schützen.
|
||||
|
||||
Abhängigkeiten können auch Response-Header ändern und Hintergrundtasks hinzufügen, wie bei normalen *Pfadoperationen*.
|
||||
|
||||
## 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 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.
|
||||
|
||||
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 <abbr title="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 <abbr title="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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
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:
|
||||
|
||||
{* ../../docs_src/handling_errors/tutorial001_py310.py hl[11] *}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -71,7 +71,7 @@ Diese werden von **FastAPI** automatisch gehandhabt und in JSON konvertiert.
|
||||
|
||||
## Benutzerdefinierte Header hinzufügen { #add-custom-headers }
|
||||
|
||||
Es gibt Situationen, in denen es nützlich ist, dem HTTP-Error benutzerdefinierte Header hinzuzufügen. Zum Beispiel in einigen Sicherheitsszenarien.
|
||||
Es gibt Situationen, in denen es nützlich ist, dem HTTP-Error benutzerdefinierte Header hinzuzufügen. Zum Beispiel für einige Arten von Sicherheit.
|
||||
|
||||
Sie werden es wahrscheinlich nicht direkt in Ihrem Code verwenden müssen.
|
||||
|
||||
@@ -81,7 +81,7 @@ Aber falls Sie es für ein fortgeschrittenes Szenario benötigen, können Sie be
|
||||
|
||||
## Benutzerdefinierte Exceptionhandler installieren { #install-custom-exception-handlers }
|
||||
|
||||
Sie können benutzerdefinierte Exceptionhandler mit [denselben Exception-Werkzeugen von Starlette](https://www.starlette.dev/exceptions/) hinzufügen.
|
||||
Sie können benutzerdefinierte Exceptionhandler mit [denselben Exception-Werkzeugen von Starlette](https://starlette.dev/exceptions/) hinzufügen.
|
||||
|
||||
Angenommen, Sie haben eine benutzerdefinierte Exception `UnicornException`, die Sie (oder eine Bibliothek, die Sie verwenden) `raise`n könnten.
|
||||
|
||||
@@ -117,7 +117,7 @@ Diese Handler sind dafür verantwortlich, die Default-JSON-Responses zurückzuge
|
||||
|
||||
Sie können diese Exceptionhandler mit Ihren eigenen überschreiben.
|
||||
|
||||
### Überschreiben von Request-Validierungs-Exceptions { #override-request-validation-exceptions }
|
||||
### Request-Validierungs-Exceptions überschreiben { #override-request-validation-exceptions }
|
||||
|
||||
Wenn ein Request ungültige Daten enthält, löst **FastAPI** intern einen `RequestValidationError` aus.
|
||||
|
||||
@@ -153,7 +153,7 @@ Validation errors:
|
||||
Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to parse string as an integer
|
||||
```
|
||||
|
||||
### Überschreiben des `HTTPException`-Fehlerhandlers { #override-the-httpexception-error-handler }
|
||||
### Den `HTTPException`-Fehlerhandler überschreiben { #override-the-httpexception-error-handler }
|
||||
|
||||
Auf die gleiche Weise können Sie den `HTTPException`-Handler überschreiben.
|
||||
|
||||
@@ -177,7 +177,7 @@ Das bedeutet aber auch, dass, wenn Sie ihn einfach in einen String umwandeln und
|
||||
|
||||
///
|
||||
|
||||
### Verwenden des `RequestValidationError`-Bodys { #use-the-requestvalidationerror-body }
|
||||
### Den `RequestValidationError`-Body verwenden { #use-the-requestvalidationerror-body }
|
||||
|
||||
Der `RequestValidationError` enthält den empfangenen `body` mit den ungültigen Daten.
|
||||
|
||||
@@ -185,7 +185,7 @@ Sie könnten diesen während der Entwicklung Ihrer Anwendung verwenden, um den B
|
||||
|
||||
{* ../../docs_src/handling_errors/tutorial005_py310.py hl[14] *}
|
||||
|
||||
Versuchen Sie nun, einen ungültigen Artikel zu senden:
|
||||
Versuchen Sie nun, ein ungültiges Item zu senden:
|
||||
|
||||
```JSON
|
||||
{
|
||||
@@ -194,7 +194,7 @@ Versuchen Sie nun, einen ungültigen Artikel zu senden:
|
||||
}
|
||||
```
|
||||
|
||||
Sie erhalten eine Response, die Ihnen sagt, dass die Daten ungültig sind und die den empfangenen Body enthält:
|
||||
Sie erhalten eine Response, die Ihnen sagt, dass die Daten ungültig sind, und die den empfangenen Body enthält:
|
||||
|
||||
```JSON hl_lines="12-15"
|
||||
{
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
# Tutorial – Benutzerhandbuch { #tutorial-user-guide }
|
||||
|
||||
Dieses Tutorial zeigt Ihnen Schritt für Schritt, wie Sie **FastAPI** mit den meisten seiner Funktionen verwenden können.
|
||||
This tutorial shows you how to use **FastAPI** with most of its features, step by step.
|
||||
|
||||
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.
|
||||
Each section gradually builds on the previous ones, but it's structured to separate topics, so that you can go directly to any specific one to solve your specific API needs.
|
||||
|
||||
Es ist auch so gestaltet, dass es als zukünftige Referenz dient, sodass Sie jederzeit zurückkommen und genau das sehen, was Sie benötigen.
|
||||
It is also built to work as a future reference so you can come back and see exactly what you need.
|
||||
|
||||
## Den Code ausführen { #run-the-code }
|
||||
|
||||
Alle Codeblöcke können kopiert und direkt verwendet werden (es sind tatsächlich getestete Python-Dateien).
|
||||
|
||||
Um eines der Beispiele auszuführen, kopieren Sie den Code in eine Datei `main.py`, und starten Sie `fastapi dev`:
|
||||
Um eines der Beispiele auszuführen, kopieren Sie den Code in eine Datei `main.py`, und starten Sie `fastapi dev` mit `uv run`:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ <font color="#4E9A06">fastapi</font> dev
|
||||
$ <font color="#4E9A06">uv run fastapi</font> dev
|
||||
|
||||
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting development server 🚀
|
||||
|
||||
@@ -60,35 +60,75 @@ Die Verwendung in Ihrem eigenen Editor zeigt Ihnen die Vorteile von FastAPI am b
|
||||
|
||||
## FastAPI installieren { #install-fastapi }
|
||||
|
||||
Der erste Schritt besteht darin, FastAPI zu installieren.
|
||||
Der erste Schritt besteht darin, Ihr Projekt einzurichten und FastAPI hinzuzufügen.
|
||||
|
||||
Stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../virtual-environments.md) erstellen, sie aktivieren und dann **FastAPI installieren**:
|
||||
Installieren Sie [`uv`](https://docs.astral.sh/uv/getting-started/installation/), erstellen Sie dann ein Projekt und fügen Sie FastAPI hinzu:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "fastapi[standard]"
|
||||
$ uv init awesome-project --bare
|
||||
$ cd awesome-project
|
||||
$ uv add "fastapi[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
`uv add` erstellt die virtuelle Umgebung des Projekts in `.venv`, fügt FastAPI zu `pyproject.toml` hinzu und erstellt `uv.lock`, sodass dieselben Packageversionen später installiert werden können.
|
||||
|
||||
/// details | Was diese Befehle tun
|
||||
|
||||
* `uv init`: Erstellt ein neues Python-Projekt.
|
||||
* `awesome-project`: Erstellt das Projekt in einem neuen Verzeichnis mit diesem Namen.
|
||||
* `--bare`: Erstellt nur die minimale Datei `pyproject.toml`, ohne eine Beispiel-`main.py`, `README.md` oder andere Dateien zu generieren. Sie erstellen die Anwendungsdateien in den nächsten Schritten dieses Tutorials selbst.
|
||||
|
||||
Dann betritt `cd awesome-project` das neue Projektverzeichnis, bevor FastAPI hinzugefügt wird.
|
||||
|
||||
`uv` verwendet eine kompatible Python-Version, die bereits auf Ihrem System installiert ist, oder lädt bei Bedarf eine herunter.
|
||||
|
||||
Wenn Sie `uv add` ausführen, wählt es kompatible Versionen von FastAPI und aller Packages aus, von denen FastAPI abhängt. Es zeichnet die exakten Versionen in `uv.lock` auf, wodurch es möglich wird, dieselben Packageversionen später auf einem anderen Computer oder beim Deployen der Anwendung zu installieren.
|
||||
|
||||
Das Erstellen oder Aktualisieren dieser Datei wird [**Locking** der Projektabhängigkeiten](https://docs.astral.sh/uv/concepts/projects/sync/) genannt. `uv` erledigt dies automatisch, wenn Sie ein Package hinzufügen.
|
||||
|
||||
///
|
||||
|
||||
/// details | FastAPI-Installationsoptionen
|
||||
|
||||
Wenn Sie mit `uv add "fastapi[standard]"` installieren, werden einige optionale Standard-Abhängigkeiten mit installiert, einschließlich `fastapi-cloud-cli`, welches Ihnen das Deployment in der [FastAPI Cloud](https://fastapicloud.com) ermöglicht.
|
||||
|
||||
Wenn Sie diese optionalen Abhängigkeiten nicht haben möchten, können Sie stattdessen `uv add fastapi` installieren.
|
||||
|
||||
Wenn Sie die Standard-Abhängigkeiten, aber ohne das `fastapi-cloud-cli` installieren möchten, können Sie mit `uv add "fastapi[standard-no-fastapi-cloud-cli]"` installieren.
|
||||
|
||||
///
|
||||
|
||||
/// details | Stattdessen `pip` verwenden
|
||||
|
||||
Wenn Sie es bevorzugen, eine virtuelle Umgebung und Packages manuell zu verwalten, erstellen und aktivieren Sie eine virtuelle Umgebung und installieren Sie dann FastAPI mit `pip install "fastapi[standard]"`.
|
||||
|
||||
Lesen Sie den [Leitfaden zu virtuellen Umgebungen](https://tiangolo.com/guides/virtual-environments/) für die detaillierten Schritte.
|
||||
|
||||
///
|
||||
|
||||
## Skills für AI-Agenten { #ai-agent-skills }
|
||||
|
||||
FastAPI enthält einen offiziellen Skill für AI-Coding-Agenten. Er ist mit dem Package gebündelt, sodass seine Anleitung mit der in Ihrem Projekt installierten FastAPI-Version übereinstimmt und aktualisiert wird, wenn Sie FastAPI aktualisieren.
|
||||
|
||||
Nachdem Sie FastAPI in Ihrem Projekt installiert haben, können Sie den Skill mit <a href="https://library-skills.io">Library Skills</a> installieren:
|
||||
|
||||
```bash
|
||||
uvx library-skills
|
||||
```
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
Wenn Sie mit `pip install "fastapi[standard]"` installieren, werden einige optionale Standard-Abhängigkeiten mit installiert, einschließlich `fastapi-cloud-cli`, welches Ihnen das Deployment in der [FastAPI Cloud](https://fastapicloud.com) ermöglicht.
|
||||
|
||||
Wenn Sie diese optionalen Abhängigkeiten nicht haben möchten, können Sie stattdessen `pip install fastapi` installieren.
|
||||
|
||||
Wenn Sie die Standard-Abhängigkeiten, aber ohne das `fastapi-cloud-cli` installieren möchten, können Sie mit `pip install "fastapi[standard-no-fastapi-cloud-cli]"` installieren.
|
||||
`uvx` ist ein Alias für `uv tool run`. Es führt Library Skills in einer temporären, isolierten Umgebung aus, während Library Skills die in Ihrem Projekt installierten Packages scannt.
|
||||
|
||||
///
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
FastAPI hat eine [offizielle Erweiterung für VS Code](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) (und Cursor), die viele Funktionen bereitstellt, darunter einen Pfadoperation-Explorer, eine Pfadoperation-Suche, CodeLens-Navigation in Tests (zur Definition aus Tests springen) sowie FastAPI-Cloud-Deployment und Logs – alles direkt aus Ihrem Editor.
|
||||
|
||||
///
|
||||
Der Skill ist kompatibel mit Codex, Claude Code, Cursor, GitHub Copilot, Gemini CLI, Pi, OpenCode und den meisten anderen Coding-Agenten. Wählen Sie bei Claude Code `.claude/skills`, wenn Sie gefragt werden, wo der Skill installiert werden soll.
|
||||
|
||||
## Handbuch für fortgeschrittene Benutzer { #advanced-user-guide }
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ Sie können die folgenden Felder festlegen, die in der OpenAPI-Spezifikation und
|
||||
| `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> |
|
||||
| `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. |
|
||||
| `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> |
|
||||
@@ -74,7 +74,7 @@ Verwenden Sie den Parameter `tags` mit Ihren *Pfadoperationen* (und `APIRouter`n
|
||||
|
||||
{* ../../docs_src/metadata/tutorial004_py310.py hl[21,26] *}
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Lesen Sie mehr zu Tags unter [Pfadoperation-Konfiguration](path-operation-configuration.md#tags).
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@ Sie können Middleware zu **FastAPI**-Anwendungen hinzufügen.
|
||||
Eine „Middleware“ ist eine Funktion, die mit jedem **<abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr>** arbeitet, bevor er von einer bestimmten *Pfadoperation* verarbeitet wird. Und auch mit jeder **<abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>**, bevor sie zurückgegeben wird.
|
||||
|
||||
* Sie nimmt jeden **Request** entgegen, der an Ihre Anwendung gesendet wird.
|
||||
* Sie kann dann etwas mit diesem **Request** tun oder beliebigen Code ausführen.
|
||||
* Sie kann dann etwas mit diesem **Request** tun oder jeden notwendigen Code ausführen.
|
||||
* Dann gibt sie den **Request** zur Verarbeitung durch den Rest der Anwendung weiter (durch eine bestimmte *Pfadoperation*).
|
||||
* Sie nimmt dann die **Response** entgegen, die von der Anwendung generiert wurde (durch eine bestimmte *Pfadoperation*).
|
||||
* Sie kann etwas mit dieser **Response** tun oder beliebigen Code ausführen.
|
||||
* Sie kann etwas mit dieser **Response** tun oder jeden notwendigen Code ausführen.
|
||||
* Dann gibt sie die **Response** zurück.
|
||||
|
||||
/// note | Technische Details
|
||||
@@ -28,8 +28,8 @@ Die Middleware-Funktion erhält:
|
||||
* Den `request`.
|
||||
* Eine Funktion `call_next`, die den `request` als Parameter erhält.
|
||||
* Diese Funktion gibt den `request` an die entsprechende *Pfadoperation* weiter.
|
||||
* Dann gibt es die von der entsprechenden *Pfadoperation* generierte `response` zurück.
|
||||
* Sie können die `response` dann weiter modifizieren, bevor Sie sie zurückgeben.
|
||||
* Dann gibt sie die von der entsprechenden *Pfadoperation* generierte `response` zurück.
|
||||
* Sie können die `response` dann weiter ändern, bevor Sie sie zurückgeben.
|
||||
|
||||
{* ../../docs_src/middleware/tutorial001_py310.py hl[8:9,11,14] *}
|
||||
|
||||
@@ -37,7 +37,7 @@ Die Middleware-Funktion erhält:
|
||||
|
||||
Beachten Sie, dass benutzerdefinierte proprietäre Header hinzugefügt werden können [unter Verwendung des `X-`-Präfixes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers).
|
||||
|
||||
Wenn Sie jedoch benutzerdefinierte Header haben, die ein Client in einem Browser sehen soll, müssen Sie sie zu Ihrer CORS-Konfiguration ([CORS (Cross-Origin Resource Sharing)](cors.md)) hinzufügen, indem Sie den Parameter `expose_headers` verwenden, der in [Starlettes CORS-Dokumentation](https://www.starlette.dev/middleware/#corsmiddleware) dokumentiert ist.
|
||||
Wenn Sie jedoch benutzerdefinierte Header haben, die ein Client in einem Browser sehen soll, müssen Sie sie zu Ihren CORS-Konfigurationen ([CORS (Cross-Origin Resource Sharing)](cors.md)) hinzufügen, indem Sie den Parameter `expose_headers` verwenden, der in [Starlettes CORS-Dokumentation](https://starlette.dev/middleware/#corsmiddleware) dokumentiert ist.
|
||||
|
||||
///
|
||||
|
||||
@@ -67,7 +67,7 @@ Hier verwenden wir [`time.perf_counter()`](https://docs.python.org/3/library/tim
|
||||
|
||||
## Ausführungsreihenfolge bei mehreren Middlewares { #multiple-middleware-execution-order }
|
||||
|
||||
Wenn Sie mehrere Middlewares hinzufügen, entweder mit dem `@app.middleware()` Dekorator oder der Methode `app.add_middleware()`, umschließt jede neue Middleware die Anwendung und bildet einen Stapel. Die zuletzt hinzugefügte Middleware ist die *äußerste*, und die erste ist die *innerste*.
|
||||
Wenn Sie mehrere Middlewares hinzufügen, entweder mit dem `@app.middleware()`-Dekorator oder der Methode `app.add_middleware()`, wrappt jede neue Middleware die Anwendung und bildet einen Stapel. Die zuletzt hinzugefügte Middleware ist die *äußerste*, und die erste ist die *innerste*.
|
||||
|
||||
Auf dem Requestpfad läuft die *äußerste* Middleware zuerst.
|
||||
|
||||
@@ -92,4 +92,4 @@ Dieses Stapelverhalten stellt sicher, dass Middlewares in einer vorhersehbaren u
|
||||
|
||||
Sie können später mehr über andere Middlewares im [Handbuch für fortgeschrittene Benutzer: Fortgeschrittene Middleware](../advanced/middleware.md) lesen.
|
||||
|
||||
In der nächsten Sektion erfahren Sie, wie Sie <abbr title="Cross-Origin Resource Sharing – Ressourcenfreigabe zwischen Ursprüngen">CORS</abbr> mit einer Middleware behandeln können.
|
||||
In der nächsten Sektion erfahren Sie, wie Sie <abbr title="Cross-Origin Resource Sharing - Ressourcenfreigabe zwischen Ursprüngen">CORS</abbr> mit einer Middleware behandeln können.
|
||||
|
||||
@@ -38,11 +38,11 @@ Diese werden zum OpenAPI-Schema hinzugefügt und von den automatischen Dokumenta
|
||||
|
||||
<img src="/img/tutorial/path-operation-configuration/image01.png">
|
||||
|
||||
### Tags mittels Enumeration { #tags-with-enums }
|
||||
### Tags mit Enums { #tags-with-enums }
|
||||
|
||||
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:
|
||||
|
||||
@@ -72,13 +72,13 @@ Sie können die Response mit dem Parameter `response_description` beschreiben:
|
||||
|
||||
{* ../../docs_src/path_operation_configuration/tutorial005_py310.py hl[18] *}
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Beachten Sie, dass sich `response_description` speziell auf die Response bezieht, während `description` sich generell auf die *Pfadoperation* bezieht.
|
||||
|
||||
///
|
||||
|
||||
/// check | Testen
|
||||
/// tip | Tipp
|
||||
|
||||
OpenAPI verlangt, dass jede *Pfadoperation* über eine Beschreibung der Response verfügt.
|
||||
|
||||
@@ -104,4 +104,4 @@ Vergleichen Sie, wie deprecatete und nicht-deprecatete *Pfadoperationen* aussehe
|
||||
|
||||
## 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.
|
||||
|
||||
@@ -8,7 +8,7 @@ Importieren Sie zuerst `Path` von `fastapi`, und importieren Sie `Annotated`:
|
||||
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py hl[1,3] *}
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
FastAPI hat in Version 0.95.0 Unterstützung für `Annotated` hinzugefügt und es zur Verwendung empfohlen.
|
||||
|
||||
@@ -131,7 +131,7 @@ Und Sie können auch Zahlenvalidierungen deklarieren:
|
||||
* `lt`: `l`ess `t`han (kleiner als)
|
||||
* `le`: `l`ess than or `e`qual (kleiner oder gleich)
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
`Query`, `Path`, und andere Klassen, die Sie später sehen werden, sind Unterklassen einer gemeinsamen `Param`-Klasse.
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ Sie können Pfad-„Parameter“ oder -„Variablen“ mit der gleichen Syntax d
|
||||
|
||||
Der Wert des Pfad-Parameters `item_id` wird Ihrer Funktion als das Argument `item_id` übergeben.
|
||||
|
||||
Wenn Sie dieses Beispiel ausführen und auf [http://127.0.0.1:8000/items/foo](http://127.0.0.1:8000/items/foo) gehen, sehen Sie als <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>:
|
||||
Wenn Sie also dieses Beispiel ausführen und auf [http://127.0.0.1:8000/items/foo](http://127.0.0.1:8000/items/foo) gehen, sehen Sie als <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>:
|
||||
|
||||
```JSON
|
||||
{"item_id":"foo"}
|
||||
@@ -14,13 +14,13 @@ Wenn Sie dieses Beispiel ausführen und auf [http://127.0.0.1:8000/items/foo](ht
|
||||
|
||||
## Pfad-Parameter mit Typen { #path-parameters-with-types }
|
||||
|
||||
Sie können den Typ eines Pfad-Parameters in der Argumentliste der Funktion deklarieren, mit Standard-Python-Typannotationen:
|
||||
Sie können den Typ eines Pfad-Parameters in der Funktion deklarieren, mit Standard-Python-Typannotationen:
|
||||
|
||||
{* ../../docs_src/path_params/tutorial002_py310.py hl[7] *}
|
||||
|
||||
In diesem Fall wird `item_id` als `int` deklariert, also als Ganzzahl.
|
||||
In diesem Fall wird `item_id` als `int` deklariert.
|
||||
|
||||
/// check | Testen
|
||||
/// tip | Tipp
|
||||
|
||||
Dadurch erhalten Sie Editor-Unterstützung innerhalb Ihrer Funktion, mit Fehlerprüfungen, Codevervollständigung, usw.
|
||||
|
||||
@@ -34,11 +34,11 @@ Wenn Sie dieses Beispiel ausführen und Ihren Browser unter [http://127.0.0.1:80
|
||||
{"item_id":3}
|
||||
```
|
||||
|
||||
/// check | Testen
|
||||
/// tip | Tipp
|
||||
|
||||
Beachten Sie, dass der Wert, den Ihre Funktion erhält und zurückgibt, die Zahl `3` ist, also ein `int`. Nicht der String „3“, also ein `str`.
|
||||
Beachten Sie, dass der Wert, den Ihre Funktion erhalten (und zurückgegeben) hat, `3` ist, als Python-`int`, nicht als String `"3"`.
|
||||
|
||||
Sprich, mit dieser Typdeklaration wird **FastAPI** den <dfn title="Den String, der von einem HTTP-Request kommt, in Python-Daten konvertieren">„parsen“</dfn>.
|
||||
Sprich, mit dieser Typdeklaration bietet **FastAPI** Ihnen automatisches Request-<dfn title="Den String, der von einem HTTP-Request kommt, in Python-Daten konvertieren">„Parsing“</dfn>.
|
||||
|
||||
///
|
||||
|
||||
@@ -62,11 +62,11 @@ Wenn Sie aber im Browser [http://127.0.0.1:8000/items/foo](http://127.0.0.1:8000
|
||||
}
|
||||
```
|
||||
|
||||
Der Pfad-Parameter `item_id` hatte den Wert „foo“, was kein `int` ist.
|
||||
denn der Pfad-Parameter `item_id` hatte den Wert `"foo"`, was kein `int` ist.
|
||||
|
||||
Die gleiche Fehlermeldung würde angezeigt werden, wenn Sie ein `float` (also eine Kommazahl) statt eines `int`s übergeben würden, wie etwa in: [http://127.0.0.1:8000/items/4.2](http://127.0.0.1:8000/items/4.2)
|
||||
Die gleiche Fehlermeldung würde angezeigt werden, wenn Sie ein `float` statt eines `int`s übergeben würden, wie etwa in: [http://127.0.0.1:8000/items/4.2](http://127.0.0.1:8000/items/4.2)
|
||||
|
||||
/// check | Testen
|
||||
/// tip | Tipp
|
||||
|
||||
Sprich, mit der gleichen Python-Typdeklaration gibt Ihnen **FastAPI** Datenvalidierung.
|
||||
|
||||
@@ -78,101 +78,101 @@ Das ist unglaublich hilfreich, wenn Sie Code entwickeln und debuggen, welcher mi
|
||||
|
||||
## Dokumentation { #documentation }
|
||||
|
||||
Wenn Sie die Seite [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) in Ihrem Browser öffnen, sehen Sie eine automatische, interaktive API-Dokumentation:
|
||||
Und wenn Sie die Seite [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) in Ihrem Browser öffnen, sehen Sie eine automatische, interaktive API-Dokumentation wie:
|
||||
|
||||
<img src="/img/tutorial/path-params/image01.png">
|
||||
|
||||
/// check | Testen
|
||||
/// tip | Tipp
|
||||
|
||||
Wiederum, mit dieser gleichen Python-Typdeklaration gibt Ihnen **FastAPI** eine automatische, interaktive Dokumentation (verwendet die Swagger-Benutzeroberfläche).
|
||||
Wiederum, nur mit dieser gleichen Python-Typdeklaration gibt Ihnen **FastAPI** eine automatische, interaktive Dokumentation (integriert Swagger UI).
|
||||
|
||||
Beachten Sie, dass der Pfad-Parameter dort als Ganzzahl deklariert ist.
|
||||
|
||||
///
|
||||
|
||||
## Nützliche Standards, alternative Dokumentation { #standards-based-benefits-alternative-documentation }
|
||||
## Standardbasierte Vorteile, alternative Dokumentation { #standards-based-benefits-alternative-documentation }
|
||||
|
||||
Und weil das generierte Schema vom [OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md)-Standard kommt, gibt es viele kompatible Tools.
|
||||
Und weil das generierte Schema vom [OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md)-Standard kommt, gibt es viele kompatible Tools.
|
||||
|
||||
Zum Beispiel bietet **FastAPI** selbst eine alternative API-Dokumentation (verwendet ReDoc), welche Sie unter [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc) einsehen können:
|
||||
Aus diesem Grund bietet **FastAPI** selbst eine alternative API-Dokumentation (verwendet ReDoc), welche Sie unter [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc) einsehen können:
|
||||
|
||||
<img src="/img/tutorial/path-params/image02.png">
|
||||
|
||||
Und viele weitere kompatible Tools. Inklusive Codegenerierung für viele Sprachen.
|
||||
Auf die gleiche Weise gibt es viele kompatible Tools. Inklusive Codegenerierungstools für viele Sprachen.
|
||||
|
||||
## Pydantic { #pydantic }
|
||||
|
||||
Die ganze Datenvalidierung wird hinter den Kulissen von [Pydantic](https://docs.pydantic.dev/) durchgeführt, Sie profitieren also von dessen Vorteilen. Und Sie wissen, dass Sie in guten Händen sind.
|
||||
Die ganze Datenvalidierung wird hinter den Kulissen von [Pydantic](https://pydantic.dev/docs/) durchgeführt, Sie profitieren also von dessen Vorteilen. Und Sie wissen, dass Sie in guten Händen sind.
|
||||
|
||||
Sie können für Typdeklarationen auch `str`, `float`, `bool` und viele andere komplexe Datentypen verwenden.
|
||||
Sie können die gleichen Typdeklarationen auch mit `str`, `float`, `bool` und vielen anderen komplexen Datentypen verwenden.
|
||||
|
||||
Mehrere davon werden wir in den nächsten Kapiteln erkunden.
|
||||
Mehrere davon werden in den nächsten Kapiteln des Tutorials erkundet.
|
||||
|
||||
## Die Reihenfolge ist wichtig { #order-matters }
|
||||
|
||||
Wenn Sie *Pfadoperationen* erstellen, haben Sie manchmal einen fixen Pfad.
|
||||
Wenn Sie *Pfadoperationen* erstellen, haben Sie manchmal Situationen, in denen Sie einen fixen Pfad haben.
|
||||
|
||||
Etwa `/users/me`, um Daten über den aktuellen Benutzer zu erhalten.
|
||||
Etwa `/users/me`, sagen wir, um Daten über den aktuellen Benutzer zu erhalten.
|
||||
|
||||
Und Sie haben auch einen Pfad `/users/{user_id}`, um Daten über einen spezifischen Benutzer zu erhalten, mittels einer Benutzer-ID.
|
||||
Und Sie können auch einen Pfad `/users/{user_id}` haben, um Daten über einen spezifischen Benutzer mittels irgendeiner Benutzer-ID zu erhalten.
|
||||
|
||||
Weil *Pfadoperationen* in ihrer Reihenfolge ausgewertet werden, müssen Sie sicherstellen, dass der Pfad `/users/me` vor `/users/{user_id}` deklariert wurde:
|
||||
Weil *Pfadoperationen* in ihrer Reihenfolge ausgewertet werden, müssen Sie sicherstellen, dass der Pfad für `/users/me` vor dem für `/users/{user_id}` deklariert wurde:
|
||||
|
||||
{* ../../docs_src/path_params/tutorial003_py310.py hl[6,11] *}
|
||||
|
||||
Ansonsten würde der Pfad für `/users/{user_id}` auch `/users/me` auswerten, und annehmen, dass ein Parameter `user_id` mit dem Wert „me“ übergeben wurde.
|
||||
Ansonsten würde der Pfad für `/users/{user_id}` auch auf `/users/me` passen und „denken“, dass er einen Parameter `user_id` mit dem Wert `"me"` erhält.
|
||||
|
||||
Sie können eine Pfadoperation auch nicht erneut definieren:
|
||||
Ebenso können Sie eine Pfadoperation nicht erneut definieren:
|
||||
|
||||
{* ../../docs_src/path_params/tutorial003b_py310.py hl[6,11] *}
|
||||
|
||||
Die erste Definition wird immer verwendet werden, da ihr Pfad zuerst übereinstimmt.
|
||||
|
||||
## Vordefinierte Parameterwerte { #predefined-values }
|
||||
## Vordefinierte Werte { #predefined-values }
|
||||
|
||||
Wenn Sie eine *Pfadoperation* haben, welche einen *Pfad-Parameter* hat, aber Sie wollen, dass dessen gültige Werte vordefiniert sind, können Sie ein Standard-Python <abbr title="Enumeration">`Enum`</abbr> verwenden.
|
||||
Wenn Sie eine *Pfadoperation* haben, welche einen *Pfad-Parameter* erhält, aber Sie wollen, dass die möglichen gültigen *Pfad-Parameter*-Werte vordefiniert sind, können Sie ein Standard-Python-<abbr title="Enumeration">`Enum`</abbr> verwenden.
|
||||
|
||||
### Eine `Enum`-Klasse erstellen { #create-an-enum-class }
|
||||
|
||||
Importieren Sie `Enum` und erstellen Sie eine Unterklasse, die von `str` und `Enum` erbt.
|
||||
|
||||
Indem Sie von `str` erben, weiß die API-Dokumentation, dass die Werte vom Typ `str` sein müssen, und wird in der Lage sein, korrekt zu rendern.
|
||||
Indem Sie von `str` erben, weiß die API-Dokumentation, dass die Werte vom Typ `string` sein müssen, und wird in der Lage sein, korrekt zu rendern.
|
||||
|
||||
Erstellen Sie dann Klassen-Attribute mit festgelegten Werten, welches die erlaubten Werte sein werden:
|
||||
Erstellen Sie dann Klassen-Attribute mit festgelegten Werten, welche die verfügbaren gültigen Werte sein werden:
|
||||
|
||||
{* ../../docs_src/path_params/tutorial005_py310.py hl[1,6:9] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Falls Sie sich fragen, was „AlexNet“, „ResNet“ und „LeNet“ ist, das sind Namen von <dfn title="Genauer gesagt: Deep-Learning-Modellarchitekturen">Modellen</dfn> für maschinelles Lernen.
|
||||
Falls Sie sich fragen: „AlexNet“, „ResNet“ und „LeNet“ sind nur Namen von <dfn title="Genauer gesagt: Deep-Learning-Modellarchitekturen">Modellen</dfn> für maschinelles Lernen.
|
||||
|
||||
///
|
||||
|
||||
### Einen *Pfad-Parameter* deklarieren { #declare-a-path-parameter }
|
||||
|
||||
Dann erstellen Sie einen *Pfad-Parameter*, der als Typ die gerade erstellte Enum-Klasse hat (`ModelName`):
|
||||
Dann erstellen Sie einen *Pfad-Parameter* mit einer Typannotation, welche die von Ihnen erstellte Enum-Klasse (`ModelName`) verwendet:
|
||||
|
||||
{* ../../docs_src/path_params/tutorial005_py310.py hl[16] *}
|
||||
|
||||
### Die API-Dokumentation testen { #check-the-docs }
|
||||
### Die Dokumentation testen { #check-the-docs }
|
||||
|
||||
Weil die erlaubten Werte für den *Pfad-Parameter* nun vordefiniert sind, kann die interaktive Dokumentation sie als Auswahl-Drop-Down anzeigen:
|
||||
Weil die verfügbaren Werte für den *Pfad-Parameter* nun vordefiniert sind, kann die interaktive Dokumentation diese hübsch anzeigen:
|
||||
|
||||
<img src="/img/tutorial/path-params/image03.png">
|
||||
|
||||
### Mit Python-*Enumerationen* arbeiten { #working-with-python-enumerations }
|
||||
|
||||
Der *Pfad-Parameter* wird ein *<abbr title="Member – Mitglied: Einer der möglichen Werte einer Enumeration">Member</abbr> einer Enumeration* sein.
|
||||
Der Wert des *Pfad-Parameters* wird ein *<abbr title="Member – Mitglied: Einer der möglichen Werte einer Enumeration">Member</abbr> einer Enumeration* sein.
|
||||
|
||||
#### *Enumeration-Member* vergleichen { #compare-enumeration-members }
|
||||
|
||||
Sie können ihn mit einem Member Ihrer Enumeration `ModelName` vergleichen:
|
||||
Sie können ihn mit dem *Enumeration-Member* in Ihrem erstellten Enum `ModelName` vergleichen:
|
||||
|
||||
{* ../../docs_src/path_params/tutorial005_py310.py hl[17] *}
|
||||
|
||||
#### *Enumerations-Wert* erhalten { #get-the-enumeration-value }
|
||||
|
||||
Den tatsächlichen Wert (in diesem Fall ein `str`) erhalten Sie via `model_name.value`, oder generell, `your_enum_member.value`:
|
||||
Den tatsächlichen Wert (in diesem Fall ein `str`) erhalten Sie mittels `model_name.value`, oder generell, `your_enum_member.value`:
|
||||
|
||||
{* ../../docs_src/path_params/tutorial005_py310.py hl[20] *}
|
||||
|
||||
@@ -184,13 +184,13 @@ Sie können den Wert `"lenet"` außerdem mittels `ModelName.lenet.value` abrufen
|
||||
|
||||
#### *Enumeration-Member* zurückgeben { #return-enumeration-members }
|
||||
|
||||
Sie können *Enum-Member* in ihrer *Pfadoperation* zurückgeben, sogar verschachtelt in einem JSON-Body (z. B. als `dict`).
|
||||
Sie können *Enum-Member* von Ihrer *Pfadoperation* zurückgeben, sogar verschachtelt in einem JSON-Body (z. B. als `dict`).
|
||||
|
||||
Diese werden zu ihren entsprechenden Werten konvertiert (in diesem Fall Strings), bevor sie zum Client übertragen werden:
|
||||
Diese werden zu ihren entsprechenden Werten konvertiert (in diesem Fall Strings), bevor sie an den Client zurückgegeben werden:
|
||||
|
||||
{* ../../docs_src/path_params/tutorial005_py310.py hl[18,21,23] *}
|
||||
|
||||
In Ihrem Client erhalten Sie eine JSON-Response, wie etwa:
|
||||
In Ihrem Client erhalten Sie eine JSON-Response wie:
|
||||
|
||||
```JSON
|
||||
{
|
||||
@@ -209,21 +209,21 @@ Sprich, die URL für diese Datei wäre etwas wie: `/files/home/johndoe/myfile.tx
|
||||
|
||||
### OpenAPI-Unterstützung { #openapi-support }
|
||||
|
||||
OpenAPI bietet nicht die Möglichkeit, dass ein *Pfad-Parameter* seinerseits einen *Pfad* enthalten kann, das würde zu Szenarios führen, die schwierig zu testen und zu definieren sind.
|
||||
OpenAPI bietet nicht die Möglichkeit, zu deklarieren, dass ein *Pfad-Parameter* in sich einen *Pfad* enthalten kann, da das zu Szenarios führen könnte, die schwierig zu testen und zu definieren sind.
|
||||
|
||||
Trotzdem können Sie das in **FastAPI** tun, indem Sie eines der internen Tools von Starlette verwenden.
|
||||
|
||||
Die Dokumentation würde weiterhin funktionieren, allerdings wird nicht dokumentiert werden, dass der Parameter ein Pfad sein sollte.
|
||||
Die Dokumentation würde weiterhin funktionieren, allerdings ohne irgendeine Dokumentation hinzuzufügen, die besagt, dass der Parameter einen Pfad enthalten sollte.
|
||||
|
||||
### Pfad-Konverter { #path-convertor }
|
||||
|
||||
Mittels einer Option direkt von Starlette können Sie einen *Pfad-Parameter* deklarieren, der einen Pfad enthalten soll, indem Sie eine URL wie folgt definieren:
|
||||
Mittels einer Option direkt von Starlette können Sie einen *Pfad-Parameter* deklarieren, der einen *Pfad* enthält, indem Sie eine URL wie folgt definieren:
|
||||
|
||||
```
|
||||
/files/{file_path:path}
|
||||
```
|
||||
|
||||
In diesem Fall ist der Name des Parameters `file_path`. Der letzte Teil, `:path`, sagt aus, dass der Parameter ein *Pfad* sein soll.
|
||||
In diesem Fall ist der Name des Parameters `file_path`, und der letzte Teil, `:path`, sagt ihm, dass der Parameter mit jedem *Pfad* übereinstimmen sollte.
|
||||
|
||||
Sie verwenden das also wie folgt:
|
||||
|
||||
@@ -231,7 +231,7 @@ Sie verwenden das also wie folgt:
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Der Parameter könnte einen führenden Schrägstrich (`/`) haben, wie etwa in `/home/johndoe/myfile.txt`.
|
||||
Der Parameter könnte `/home/johndoe/myfile.txt` enthalten müssen, mit einem führenden Schrägstrich (`/`).
|
||||
|
||||
In dem Fall wäre die URL: `/files//home/johndoe/myfile.txt`, mit einem doppelten Schrägstrich (`//`) zwischen `files` und `home`.
|
||||
|
||||
@@ -239,13 +239,13 @@ In dem Fall wäre die URL: `/files//home/johndoe/myfile.txt`, mit einem doppelte
|
||||
|
||||
## Zusammenfassung { #recap }
|
||||
|
||||
In **FastAPI** erhalten Sie mittels kurzer, intuitiver Typdeklarationen:
|
||||
Mit **FastAPI** erhalten Sie mittels kurzer, intuitiver und Standard-Python-Typdeklarationen:
|
||||
|
||||
* Editor-Unterstützung: Fehlerprüfungen, Codevervollständigung, usw.
|
||||
* Daten „<dfn title="Den String, der von einem HTTP-Request kommt, in Python-Daten konvertieren">parsen</dfn>“
|
||||
* Datenvalidierung
|
||||
* API-Annotationen und automatische Dokumentation
|
||||
* API-Annotation und automatische Dokumentation
|
||||
|
||||
Und Sie müssen sie nur einmal deklarieren.
|
||||
|
||||
Das ist wahrscheinlich der sichtbarste Unterschied zwischen **FastAPI** und alternativen Frameworks (abgesehen von der reinen Performanz).
|
||||
Das ist wahrscheinlich der wichtigste sichtbare Vorteil von **FastAPI** im Vergleich zu alternativen Frameworks (abgesehen von der rohen Performanz).
|
||||
|
||||
@@ -29,7 +29,7 @@ Um dies zu erreichen, importieren Sie zuerst:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[1,3] *}
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
FastAPI hat Unterstützung für `Annotated` hinzugefügt (und begonnen, es zu empfehlen) in der Version 0.95.0.
|
||||
|
||||
@@ -81,7 +81,7 @@ FastAPI wird nun:
|
||||
|
||||
* 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
|
||||
* 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 }
|
||||
|
||||
@@ -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.
|
||||
|
||||
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 }
|
||||
|
||||
@@ -276,7 +276,7 @@ Wenn Sie zu:
|
||||
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
|
||||
{
|
||||
@@ -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.
|
||||
|
||||
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.
|
||||
|
||||
///
|
||||
|
||||
@@ -335,7 +335,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
|
||||
|
||||
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 ...
|
||||
|
||||
@@ -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.
|
||||
|
||||
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 <dfn title="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 <dfn title="obsolet, es wird empfohlen, es nicht zu verwenden">deprecatet</dfn> anzeigt.
|
||||
|
||||
Dann übergeben Sie den Parameter `deprecated=True` an `Query`:
|
||||
|
||||
@@ -369,11 +369,11 @@ Es kann Fälle geben, in denen Sie eine **benutzerdefinierte Validierung** durch
|
||||
|
||||
In diesen Fällen können Sie eine **benutzerdefinierte Validierungsfunktion** verwenden, die nach der normalen Validierung angewendet wird (z. B. nach der Validierung, dass der Wert ein `str` ist).
|
||||
|
||||
Sie können dies mit [Pydantics `AfterValidator`](https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator) innerhalb von `Annotated` erreichen.
|
||||
Sie können dies mit [Pydantics `AfterValidator`](https://pydantic.dev/docs/validation/latest/concepts/validators/#field-after-validator) innerhalb von `Annotated` erreichen.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Pydantic unterstützt auch [`BeforeValidator`](https://docs.pydantic.dev/latest/concepts/validators/#field-before-validator) und andere. 🤓
|
||||
Pydantic unterstützt auch [`BeforeValidator`](https://pydantic.dev/docs/validation/latest/concepts/validators/#field-before-validator) und andere. 🤓
|
||||
|
||||
///
|
||||
|
||||
@@ -381,7 +381,7 @@ Zum Beispiel überprüft dieser benutzerdefinierte Validator, ob die Artikel-ID
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Dies ist verfügbar seit Pydantic Version 2 oder höher. 😎
|
||||
|
||||
@@ -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. 🤸
|
||||
|
||||
@@ -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.
|
||||
|
||||
#### 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:
|
||||
|
||||
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[16:19] hl[17] *}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
* Editor Unterstützung (natürlich)
|
||||
* Editor-Unterstützung (natürlich)
|
||||
* Daten-<dfn title="Konvertieren des Strings, der von einem HTTP-Request kommt, in Python-Daten">„Parsen“</dfn>
|
||||
* Datenvalidierung
|
||||
* Automatische Dokumentation
|
||||
@@ -65,19 +65,19 @@ Auf die gleiche Weise können Sie optionale Query-Parameter deklarieren, indem S
|
||||
|
||||
In diesem Fall wird der Funktionsparameter `q` optional und standardmäßig `None` sein.
|
||||
|
||||
/// check | Testen
|
||||
/// 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.
|
||||
|
||||
///
|
||||
|
||||
## Query-Parameter Typkonvertierung { #query-parameter-type-conversion }
|
||||
## Typkonvertierung von Query-Parametern { #query-parameter-type-conversion }
|
||||
|
||||
Sie können auch `bool`-Typen deklarieren, und sie werden konvertiert:
|
||||
|
||||
{* ../../docs_src/query_params/tutorial003_py310.py hl[7] *}
|
||||
|
||||
Wenn Sie nun zu:
|
||||
Wenn Sie in diesem Fall zu:
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/foo?short=1
|
||||
@@ -109,6 +109,7 @@ http://127.0.0.1:8000/items/foo?short=yes
|
||||
|
||||
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 }
|
||||
|
||||
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:
|
||||
|
||||
## Erforderliche Query-Parameter { #required-query-parameters }
|
||||
|
||||
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`.
|
||||
|
||||
@@ -129,7 +130,7 @@ Aber wenn Sie wollen, dass ein Query-Parameter erforderlich ist, vergeben Sie ei
|
||||
|
||||
{* ../../docs_src/query_params/tutorial005_py310.py hl[6:7] *}
|
||||
|
||||
Hier ist `needy` ein erforderlicher Query-Parameter vom Typ `str`.
|
||||
Hier ist der Query-Parameter `needy` ein erforderlicher Query-Parameter vom Typ `str`.
|
||||
|
||||
Wenn Sie in Ihrem Browser eine URL wie:
|
||||
|
||||
@@ -137,7 +138,7 @@ Wenn Sie in Ihrem Browser eine URL wie:
|
||||
http://127.0.0.1:8000/items/foo-item
|
||||
```
|
||||
|
||||
... öffnen, ohne den benötigten Parameter `needy`, dann erhalten Sie einen Fehler wie den folgenden:
|
||||
... öffnen, ohne den erforderlichen Parameter `needy` hinzuzufügen, dann erhalten Sie einen Fehler wie den folgenden:
|
||||
|
||||
```JSON
|
||||
{
|
||||
@@ -161,7 +162,7 @@ Da `needy` ein erforderlicher Parameter ist, müssen Sie ihn in der URL setzen:
|
||||
http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
|
||||
```
|
||||
|
||||
... Das funktioniert:
|
||||
... das funktioniert:
|
||||
|
||||
```JSON
|
||||
{
|
||||
@@ -174,7 +175,7 @@ Und natürlich können Sie einige Parameter als erforderlich, einige mit Default
|
||||
|
||||
{* ../../docs_src/query_params/tutorial006_py310.py hl[8] *}
|
||||
|
||||
In diesem Fall gibt es drei Query-Parameter:
|
||||
In diesem Fall gibt es 3 Query-Parameter:
|
||||
|
||||
* `needy`, ein erforderlicher `str`.
|
||||
* `skip`, ein `int` mit einem Defaultwert `0`.
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
|
||||
Sie können Dateien, die vom Client hochgeladen werden, mithilfe von `File` definieren.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Um hochgeladene Dateien zu empfangen, installieren Sie zuerst [`python-multipart`](https://github.com/Kludex/python-multipart).
|
||||
|
||||
Stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../virtual-environments.md) erstellen, sie aktivieren und dann das Paket installieren, zum Beispiel:
|
||||
Fügen Sie es Ihrem Projekt hinzu:
|
||||
|
||||
```console
|
||||
$ pip install python-multipart
|
||||
$ uv add python-multipart
|
||||
```
|
||||
|
||||
Das liegt daran, dass hochgeladene Dateien als „Formulardaten“ gesendet werden.
|
||||
@@ -24,11 +24,11 @@ Importieren Sie `File` und `UploadFile` von `fastapi`:
|
||||
|
||||
## `File`-Parameter definieren { #define-file-parameters }
|
||||
|
||||
Erstellen Sie Datei-Parameter, so wie Sie es auch mit `Body` und `Form` machen würden:
|
||||
Erstellen Sie Datei-Parameter, so wie Sie es auch mit `Body` oder `Form` machen würden:
|
||||
|
||||
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[9] *}
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
`File` ist eine Klasse, die direkt von `Form` erbt.
|
||||
|
||||
@@ -44,7 +44,7 @@ Um Dateibodys zu deklarieren, müssen Sie `File` verwenden, da diese Parameter s
|
||||
|
||||
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.
|
||||
|
||||
@@ -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.
|
||||
* 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.
|
||||
* 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.
|
||||
|
||||
### `UploadFile` { #uploadfile }
|
||||
|
||||
`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`).
|
||||
* `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.
|
||||
* `read(anzahl)`: Liest `anzahl` (`int`) bytes/Zeichen aus der Datei.
|
||||
* `seek(versatz)`: Geht zur Position `versatz` (`int`) in der Datei.
|
||||
* `write(data)`: Schreibt `data` (`str` oder `bytes`) in die Datei.
|
||||
* `read(size)`: Liest `size` (`int`) Bytes/Zeichen aus 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.
|
||||
* 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.
|
||||
|
||||
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:
|
||||
|
||||
@@ -105,7 +105,7 @@ Wenn Sie die `async`-Methoden verwenden, führt **FastAPI** die Datei-Methoden i
|
||||
|
||||
/// 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.
|
||||
|
||||
**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
|
||||
|
||||
Daten aus Formularen werden, wenn es keine Dateien sind, normalerweise mit dem <abbr title='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 <abbr title='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.
|
||||
|
||||
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).
|
||||
|
||||
///
|
||||
|
||||
@@ -147,9 +147,9 @@ Sie können auch `File()` mit `UploadFile` verwenden, um zum Beispiel zusätzlic
|
||||
|
||||
## Mehrere Datei-Uploads { #multiple-file-uploads }
|
||||
|
||||
Es ist auch möglich, mehrere Dateien gleichzeitig hochzuladen.
|
||||
Es ist 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:
|
||||
|
||||
@@ -159,7 +159,7 @@ Sie erhalten, wie deklariert, eine `list` von `bytes` oder `UploadFile`s.
|
||||
|
||||
/// note | Technische Details
|
||||
|
||||
Sie können auch `from starlette.responses import HTMLResponse` verwenden.
|
||||
Sie könnten auch `from starlette.responses import HTMLResponse` verwenden.
|
||||
|
||||
**FastAPI** bietet dieselben `starlette.responses` auch via `fastapi.responses` an, als Annehmlichkeit für Sie, den Entwickler. Die meisten verfügbaren <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Responses</abbr> kommen aber direkt von Starlette.
|
||||
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
|
||||
Sie können **Pydantic-Modelle** verwenden, um **Formularfelder** in FastAPI zu deklarieren.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Um Formulare zu verwenden, installieren Sie zuerst [`python-multipart`](https://github.com/Kludex/python-multipart).
|
||||
|
||||
Stellen Sie sicher, dass Sie eine [Virtuelle Umgebung](../virtual-environments.md) erstellen, sie aktivieren und es dann installieren, zum Beispiel:
|
||||
Fügen Sie es zu Ihrem Projekt hinzu:
|
||||
|
||||
```console
|
||||
$ pip install python-multipart
|
||||
$ uv add python-multipart
|
||||
```
|
||||
|
||||
///
|
||||
@@ -38,7 +38,7 @@ Sie können dies in der Dokumentations-UI unter `/docs` testen:
|
||||
|
||||
## Zusätzliche Formularfelder verbieten { #forbid-extra-form-fields }
|
||||
|
||||
In einigen speziellen Anwendungsfällen (wahrscheinlich nicht sehr häufig) möchten Sie möglicherweise die Formularfelder auf nur diejenigen beschränken, die im Pydantic-Modell deklariert sind, und jegliche **zusätzlichen** Felder **verbieten**.
|
||||
In einigen speziellen Anwendungsfällen (wahrscheinlich nicht sehr häufig) möchten Sie möglicherweise die Formularfelder auf nur diejenigen **beschränken**, die im Pydantic-Modell deklariert sind. Und jegliche **zusätzlichen** Felder **verbieten**.
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
@@ -46,11 +46,11 @@ Dies wird seit FastAPI Version `0.114.0` unterstützt. 🤓
|
||||
|
||||
///
|
||||
|
||||
Sie können die Modellkonfiguration von Pydantic verwenden, um jegliche `extra` Felder zu `verbieten`:
|
||||
Sie können Pydantics Modellkonfiguration verwenden, um jegliche `extra`-Felder auf `forbid` zu setzen:
|
||||
|
||||
{* ../../docs_src/request_form_models/tutorial002_an_py310.py hl[12] *}
|
||||
|
||||
Wenn ein Client versucht, einige zusätzliche Daten zu senden, erhält er eine **Error-<abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>**.
|
||||
Wenn ein Client versucht, einige zusätzliche Daten zu senden, erhält er eine **Error**-<abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>.
|
||||
|
||||
Zum Beispiel, wenn der Client versucht, folgende Formularfelder zu senden:
|
||||
|
||||
@@ -58,7 +58,7 @@ Zum Beispiel, wenn der Client versucht, folgende Formularfelder zu senden:
|
||||
* `password`: `Portal Gun`
|
||||
* `extra`: `Mr. Poopybutthole`
|
||||
|
||||
erhält er eine Error-Response, die ihm mitteilt, dass das Feld `extra` nicht erlaubt ist:
|
||||
Er erhält eine Error-Response, die ihm mitteilt, dass das Feld `extra` nicht erlaubt ist:
|
||||
|
||||
```json
|
||||
{
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
# Formulardaten und Dateien im Request { #request-forms-and-files }
|
||||
|
||||
Sie können gleichzeitig Dateien und Formulardaten mit `File` und `Form` definieren.
|
||||
Sie können gleichzeitig Dateien und Formularfelder mit `File` und `Form` definieren.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Um hochgeladene Dateien und/oder Formulardaten zu empfangen, installieren Sie zuerst [`python-multipart`](https://github.com/Kludex/python-multipart).
|
||||
|
||||
Stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../virtual-environments.md) erstellen, diese aktivieren und es dann installieren, z. B.:
|
||||
Fügen Sie es Ihrem Projekt hinzu:
|
||||
|
||||
```console
|
||||
$ pip install python-multipart
|
||||
$ uv add python-multipart
|
||||
```
|
||||
|
||||
///
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
# Formulardaten { #form-data }
|
||||
|
||||
|
||||
Wenn Sie Felder aus Formularen statt JSON empfangen müssen, können Sie `Form` verwenden.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Um Formulare zu verwenden, installieren Sie zuerst [`python-multipart`](https://github.com/Kludex/python-multipart).
|
||||
|
||||
Erstellen Sie unbedingt eine [virtuelle Umgebung](../virtual-environments.md), aktivieren Sie diese und installieren Sie dann das Paket, zum Beispiel:
|
||||
Fügen Sie es Ihrem Projekt hinzu:
|
||||
|
||||
```console
|
||||
$ pip install python-multipart
|
||||
$ uv add python-multipart
|
||||
```
|
||||
|
||||
///
|
||||
@@ -22,7 +23,7 @@ Importieren Sie `Form` von `fastapi`:
|
||||
|
||||
## `Form`-Parameter definieren { #define-form-parameters }
|
||||
|
||||
Erstellen Sie Formular-Parameter, so wie Sie es auch mit `Body` und `Query` machen würden:
|
||||
Erstellen Sie Formular-Parameter, so wie Sie es auch mit `Body` oder `Query` machen würden:
|
||||
|
||||
{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[9] *}
|
||||
|
||||
@@ -32,7 +33,7 @@ Die <dfn title="Spezifikation">Spezifikation</dfn> erfordert, dass die Felder ex
|
||||
|
||||
Mit `Form` haben Sie die gleichen Konfigurationsmöglichkeiten wie mit `Body` (und `Query`, `Path`, `Cookie`), inklusive Validierung, Beispielen, einem Alias (z. B. `user-name` statt `username`), usw.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
`Form` ist eine Klasse, die direkt von `Body` erbt.
|
||||
|
||||
@@ -56,7 +57,7 @@ Daten aus Formularen werden normalerweise mit dem <abbr title="Medientyp">„med
|
||||
|
||||
Wenn das Formular stattdessen Dateien enthält, werden diese mit `multipart/form-data` kodiert. Im nächsten Kapitel erfahren Sie mehr über die Handhabung von Dateien.
|
||||
|
||||
Wenn Sie mehr über Formularfelder und ihre Kodierungen 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 Formularfelder und ihre Kodierungen 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).
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Responsemodell – Rückgabetyp { #response-model-return-type }
|
||||
|
||||
Sie können den Typ der <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr> deklarieren, indem Sie den **Rückgabetyp** der *Pfadoperation* annotieren.
|
||||
Sie können den Typ der <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr> deklarieren, indem Sie den **Rückgabetyp** der *Pfadoperation-Funktion* annotieren.
|
||||
|
||||
Hierbei können Sie **Typannotationen** genauso verwenden, wie Sie es bei Werten von Funktions-**Parametern** machen; verwenden Sie Pydantic-Modelle, Listen, Dicts und skalare Werte wie Nummern, Booleans, usw.
|
||||
Hierbei können Sie **Typannotationen** genauso verwenden, wie Sie es bei Eingabedaten in Funktions-**Parametern** machen; verwenden Sie Pydantic-Modelle, Listen, Dictionaries und skalare Werte wie Integer, Booleans, usw.
|
||||
|
||||
{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *}
|
||||
|
||||
@@ -24,9 +24,9 @@ Aber am wichtigsten:
|
||||
|
||||
Es gibt Fälle, da möchten oder müssen Sie Daten zurückgeben, die nicht genau dem entsprechen, was der Typ deklariert.
|
||||
|
||||
Zum Beispiel könnten Sie **ein Dictionary zurückgeben** wollen, oder ein Datenbank-Objekt, aber **es als Pydantic-Modell deklarieren**. Auf diese Weise übernimmt das Pydantic-Modell alle Datendokumentation, -validierung, usw. für das Objekt, welches Sie zurückgeben (z. B. ein Dictionary oder ein Datenbank-Objekt).
|
||||
Zum Beispiel könnten Sie **ein Dictionary zurückgeben** wollen, oder ein Datenbankobjekt, aber **es als Pydantic-Modell deklarieren**. Auf diese Weise übernimmt das Pydantic-Modell alle Datendokumentation, -validierung, usw. für das Objekt, welches Sie zurückgeben (z. B. ein Dictionary oder ein Datenbankobjekt).
|
||||
|
||||
Würden Sie eine hierfür eine Rückgabetyp-Annotation verwenden, dann würden Tools und Editoren (korrekterweise) Fehler ausgeben, die Ihnen sagen, dass Ihre Funktion einen Typ zurückgibt (z. B. ein Dict), der sich unterscheidet von dem, was Sie deklariert haben (z. B. ein Pydantic-Modell).
|
||||
Würden Sie eine Rückgabetyp-Annotation hinzufügen, dann würden Tools und Editoren (korrekterweise) Fehler ausgeben, die Ihnen sagen, dass Ihre Funktion einen Typ zurückgibt (z. B. ein Dict), der sich unterscheidet von dem, was Sie deklariert haben (z. B. ein Pydantic-Modell).
|
||||
|
||||
In solchen Fällen können Sie statt des Rückgabetyps den **Pfadoperation-Dekorator**-Parameter `response_model` verwenden.
|
||||
|
||||
@@ -42,17 +42,17 @@ Sie können `response_model` in jeder möglichen *Pfadoperation* verwenden:
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
Beachten Sie, dass `response_model` ein Parameter der „Dekorator“-Methode ist (`get`, `post`, usw.). Nicht der *Pfadoperation-Funktion*, so wie die anderen Parameter und der Body.
|
||||
Beachten Sie, dass `response_model` ein Parameter der „Dekorator“-Methode ist (`get`, `post`, usw.). Nicht Ihrer *Pfadoperation-Funktion*, so wie alle Parameter und der Body.
|
||||
|
||||
///
|
||||
|
||||
`response_model` nimmt denselben Typ entgegen, den Sie auch für ein Pydantic-Modellfeld deklarieren würden, also etwa ein Pydantic-Modell, aber es kann auch z. B. eine `list`e von Pydantic-Modellen sein, wie etwa `List[Item]`.
|
||||
`response_model` nimmt denselben Typ entgegen, den Sie auch für ein Pydantic-Modellfeld deklarieren würden, also etwa ein Pydantic-Modell, aber es kann auch z. B. eine `list` von Pydantic-Modellen sein, wie etwa `List[Item]`.
|
||||
|
||||
FastAPI wird dieses `response_model` nehmen, um die Daten zu dokumentieren, validieren, usw. und auch, um **die Ausgabedaten** entsprechend der Typdeklaration **zu konvertieren und filtern**.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Wenn Sie in Ihrem Editor strikte Typchecks haben, mypy, usw., können Sie den Funktions-Rückgabetyp als <abbr title="„Irgend etwas“">`Any`</abbr> deklarieren.
|
||||
Wenn Sie in Ihrem Editor strikte Typchecks haben, mypy, usw., können Sie den Funktions-Rückgabetyp als `Any` deklarieren.
|
||||
|
||||
So sagen Sie dem Editor, dass Sie absichtlich *irgendetwas* zurückgeben. Aber FastAPI wird trotzdem die Dokumentation, Validierung, Filterung, usw. der Daten übernehmen, via `response_model`.
|
||||
|
||||
@@ -60,11 +60,11 @@ So sagen Sie dem Editor, dass Sie absichtlich *irgendetwas* zurückgeben. Aber F
|
||||
|
||||
### `response_model`-Priorität { #response-model-priority }
|
||||
|
||||
Wenn sowohl Rückgabetyp als auch `response_model` deklariert sind, hat `response_model` die Priorität und wird von FastAPI bevorzugt verwendet.
|
||||
Wenn sowohl Rückgabetyp als auch `response_model` deklariert sind, hat `response_model` die Priorität und wird von FastAPI verwendet.
|
||||
|
||||
So können Sie korrekte Typannotationen zu Ihrer Funktion hinzufügen, die von Ihrem Editor und Tools wie mypy verwendet werden. Und dennoch übernimmt FastAPI die Validierung und Dokumentation, usw., der Daten anhand von `response_model`.
|
||||
So können Sie korrekte Typannotationen zu Ihren Funktionen hinzufügen, selbst wenn Sie einen anderen Typ als das Responsemodell zurückgeben, die von Ihrem Editor und Tools wie mypy verwendet werden. Und dennoch übernimmt FastAPI die Validierung und Dokumentation, usw., der Daten anhand von `response_model`.
|
||||
|
||||
Sie können auch `response_model=None` verwenden, um das Erstellen eines Responsemodells für diese *Pfadoperation* zu unterbinden. Sie könnten das tun wollen, wenn Sie Dinge annotieren, die nicht gültige Pydantic-Felder sind. Ein Beispiel dazu werden Sie in einer der Abschnitte unten sehen.
|
||||
Sie können auch `response_model=None` verwenden, um das Erstellen eines Responsemodells für diese *Pfadoperation* zu unterbinden. Sie könnten das tun müssen, wenn Sie Typannotationen für Dinge hinzufügen, die keine gültigen Pydantic-Felder sind. Ein Beispiel dazu werden Sie in einem der Abschnitte unten sehen.
|
||||
|
||||
## Dieselben Eingabedaten zurückgeben { #return-the-same-input-data }
|
||||
|
||||
@@ -72,20 +72,20 @@ Im Folgenden deklarieren wir ein `UserIn`-Modell; es enthält ein Klartext-Passw
|
||||
|
||||
{* ../../docs_src/response_model/tutorial002_py310.py hl[7,9] *}
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Um `EmailStr` zu verwenden, installieren Sie zuerst [`email-validator`](https://github.com/JoshData/python-email-validator).
|
||||
|
||||
Stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../virtual-environments.md) erstellen, sie aktivieren und es dann installieren, zum Beispiel:
|
||||
Fügen Sie es Ihrem Projekt hinzu:
|
||||
|
||||
```console
|
||||
$ pip install email-validator
|
||||
$ uv add email-validator
|
||||
```
|
||||
|
||||
oder mit:
|
||||
|
||||
```console
|
||||
$ pip install "pydantic[email]"
|
||||
$ uv add "pydantic[email]"
|
||||
```
|
||||
|
||||
///
|
||||
@@ -98,11 +98,11 @@ Immer wenn jetzt ein Browser einen Benutzer mit Passwort erzeugt, gibt die API d
|
||||
|
||||
Hier ist das möglicherweise kein Problem, da es derselbe Benutzer ist, der das Passwort sendet.
|
||||
|
||||
Aber wenn wir dasselbe Modell für eine andere *Pfadoperation* verwenden, könnten wir das Passwort dieses Benutzers zu jedem Client schicken.
|
||||
Aber wenn wir dasselbe Modell für eine andere *Pfadoperation* verwenden, könnten wir die Passwörter unserer Benutzer an jeden Client senden.
|
||||
|
||||
/// danger | Gefahr
|
||||
|
||||
Speichern Sie niemals das Klartext-Passwort eines Benutzers, oder versenden Sie es in einer Response wie dieser, wenn Sie sich nicht der resultierenden Gefahren bewusst sind und nicht wissen, was Sie tun.
|
||||
Speichern Sie niemals das Klartext-Passwort eines Benutzers, oder versenden Sie es in einer Response wie dieser, es sei denn, Sie kennen alle Einschränkungen und wissen, was Sie tun.
|
||||
|
||||
///
|
||||
|
||||
@@ -116,31 +116,31 @@ Obwohl unsere *Pfadoperation-Funktion* hier denselben `user` von der Eingabe zur
|
||||
|
||||
{* ../../docs_src/response_model/tutorial003_py310.py hl[24] *}
|
||||
|
||||
... haben wir deklariert, dass `response_model` das Modell `UserOut` ist, welches das Passwort nicht enthält:
|
||||
... haben wir deklariert, dass `response_model` unser Modell `UserOut` ist, welches das Passwort nicht enthält:
|
||||
|
||||
{* ../../docs_src/response_model/tutorial003_py310.py hl[22] *}
|
||||
|
||||
Darum wird **FastAPI** sich darum kümmern, dass alle Daten, die nicht im Ausgabemodell deklariert sind, herausgefiltert werden (mittels Pydantic).
|
||||
|
||||
### `response_model` oder Rückgabewert { #response-model-or-return-type }
|
||||
### `response_model` oder Rückgabetyp { #response-model-or-return-type }
|
||||
|
||||
Da unsere zwei Modelle in diesem Fall unterschiedlich sind, würde, wenn wir den Rückgabewert der Funktion als `UserOut` deklarieren, der Editor sich beschweren, dass wir einen ungültigen Typ zurückgeben, weil das unterschiedliche Klassen sind.
|
||||
Da unsere zwei Modelle in diesem Fall unterschiedlich sind, würde, wenn wir den Funktions-Rückgabetyp als `UserOut` deklarieren, der Editor sich beschweren, dass wir einen ungültigen Typ zurückgeben, weil das unterschiedliche Klassen sind.
|
||||
|
||||
Darum müssen wir es in diesem Fall im `response_model`-Parameter deklarieren.
|
||||
Darum müssen wir es in diesem Beispiel im `response_model`-Parameter deklarieren.
|
||||
|
||||
... aber lesen Sie weiter, um zu sehen, wie man das anders lösen kann.
|
||||
|
||||
## Rückgabewert und Datenfilterung { #return-type-and-data-filtering }
|
||||
## Rückgabetyp und Datenfilterung { #return-type-and-data-filtering }
|
||||
|
||||
Führen wir unser vorheriges Beispiel fort. Wir wollten **die Funktion mit einem Typ annotieren**, aber wir wollten in der Funktion tatsächlich etwas zurückgeben, das **mehr Daten** enthält.
|
||||
|
||||
Wir möchten, dass FastAPI die Daten weiterhin mithilfe des Responsemodells **filtert**. Selbst wenn die Funktion mehr Daten zurückgibt, soll die Response nur die Felder enthalten, die im Responsemodell deklariert sind.
|
||||
|
||||
Im vorherigen Beispiel mussten wir den `response_model`-Parameter verwenden, weil die Klassen unterschiedlich waren. Das bedeutet aber auch, wir bekommen keine Unterstützung vom Editor und anderen Tools, die den Funktions-Rückgabewert überprüfen.
|
||||
Im vorherigen Beispiel mussten wir den `response_model`-Parameter verwenden, weil die Klassen unterschiedlich waren. Das bedeutet aber auch, wir bekommen keine Unterstützung vom Editor und anderen Tools, die den Funktions-Rückgabetyp überprüfen.
|
||||
|
||||
Aber in den meisten Fällen, wenn wir so etwas machen, wollen wir nur, dass das Modell einige der Daten **filtert/entfernt**, so wie in diesem Beispiel.
|
||||
|
||||
Und in solchen Fällen können wir Klassen und Vererbung verwenden, um Vorteil aus den Typannotationen in der Funktion zu ziehen, was vom Editor und von Tools besser unterstützt wird, während wir gleichzeitig FastAPIs **Datenfilterung** behalten.
|
||||
Und in solchen Fällen können wir Klassen und Vererbung verwenden, um Vorteil aus den **Typannotationen** in der Funktion zu ziehen, was vom Editor und von Tools besser unterstützt wird, während wir gleichzeitig FastAPIs **Datenfilterung** behalten.
|
||||
|
||||
{* ../../docs_src/response_model/tutorial003_01_py310.py hl[7:10,13:14,18] *}
|
||||
|
||||
@@ -156,7 +156,7 @@ Sehen wir uns zunächst an, wie Editor, mypy und andere Tools dies sehen würden
|
||||
|
||||
Wir annotieren den Funktionsrückgabetyp als `BaseUser`, geben aber tatsächlich eine `UserIn`-Instanz zurück.
|
||||
|
||||
Für den Editor, mypy und andere Tools ist das kein Problem, da `UserIn` eine Unterklasse von `BaseUser` ist (Salopp: `UserIn` ist ein `BaseUser`). Es handelt sich um einen *gültigen* Typ, solange irgendetwas überreicht wird, das ein `BaseUser` ist.
|
||||
Der Editor, mypy und andere Tools werden sich darüber nicht beschweren, weil `UserIn` im Sinne des Typings eine Unterklasse von `BaseUser` ist. Das bedeutet, es ist ein *gültiger* Typ, wenn etwas erwartet wird, das ein `BaseUser` ist.
|
||||
|
||||
### FastAPI Datenfilterung { #fastapi-data-filtering }
|
||||
|
||||
@@ -182,7 +182,7 @@ Es kann Fälle geben, bei denen Sie etwas zurückgeben, das kein gültiges Pydan
|
||||
|
||||
### Eine Response direkt zurückgeben { #return-a-response-directly }
|
||||
|
||||
Der häufigste Anwendungsfall ist, wenn Sie [eine Response direkt zurückgeben, wie es später im Handbuch für fortgeschrittene Benutzer erläutert wird](../advanced/response-directly.md).
|
||||
Der häufigste Anwendungsfall ist, wenn Sie [eine Response direkt zurückgeben, wie es später in der Dokumentation für fortgeschrittene Benutzer erläutert wird](../advanced/response-directly.md).
|
||||
|
||||
{* ../../docs_src/response_model/tutorial003_02_py310.py hl[8,10:11] *}
|
||||
|
||||
@@ -192,7 +192,7 @@ Und Tools werden auch glücklich sein, weil sowohl `RedirectResponse` als auch `
|
||||
|
||||
### Eine Unterklasse von Response annotieren { #annotate-a-response-subclass }
|
||||
|
||||
Sie können auch eine Unterklasse von `Response` in der Typannotation verwenden.
|
||||
Sie können auch eine Unterklasse von `Response` in der Typannotation verwenden:
|
||||
|
||||
{* ../../docs_src/response_model/tutorial003_03_py310.py hl[8:9] *}
|
||||
|
||||
@@ -200,9 +200,9 @@ Das wird ebenfalls funktionieren, weil `RedirectResponse` eine Unterklasse von `
|
||||
|
||||
### Ungültige Rückgabetyp-Annotationen { #invalid-return-type-annotations }
|
||||
|
||||
Aber wenn Sie ein beliebiges anderes Objekt zurückgeben, das kein gültiger Pydantic-Typ ist (z. B. ein Datenbank-Objekt), und Sie annotieren es so in der Funktion, wird FastAPI versuchen, ein Pydantic-Responsemodell von dieser Typannotation zu erstellen, und scheitern.
|
||||
Aber wenn Sie ein beliebiges anderes Objekt zurückgeben, das kein gültiger Pydantic-Typ ist (z. B. ein Datenbankobjekt), und Sie annotieren es so in der Funktion, wird FastAPI versuchen, ein Pydantic-Responsemodell von dieser Typannotation zu erstellen, und scheitern.
|
||||
|
||||
Das gleiche wird passieren, wenn Sie eine <dfn title="Eine Union mehrerer Typen bedeutet: „Irgendeiner dieser Typen“">Union</dfn> mehrerer Typen haben, und einer oder mehrere sind nicht gültige Pydantic-Typen. Zum Beispiel funktioniert folgendes nicht 💥:
|
||||
Das gleiche wird passieren, wenn Sie eine <dfn title="Eine Union zwischen mehreren Typen bedeutet: „irgendeiner dieser Typen“.">Union</dfn> mehrerer Typen haben, und einer oder mehrere sind nicht gültige Pydantic-Typen. Zum Beispiel funktioniert folgendes nicht 💥:
|
||||
|
||||
{* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}
|
||||
|
||||
@@ -230,7 +230,7 @@ Ihr Responsemodell könnte Defaultwerte haben, wie:
|
||||
* `tax: float = 10.5` hat einen Defaultwert `10.5`.
|
||||
* `tags: List[str] = []` hat eine leere Liste als Defaultwert: `[]`.
|
||||
|
||||
Aber Sie möchten diese vielleicht vom Resultat ausschließen, wenn Sie gar nicht gesetzt wurden.
|
||||
Aber Sie möchten diese vielleicht vom Resultat ausschließen, wenn sie tatsächlich nicht gespeichert wurden.
|
||||
|
||||
Wenn Sie zum Beispiel Modelle mit vielen optionalen Attributen in einer NoSQL-Datenbank haben, und Sie möchten nicht ellenlange JSON-Responses voller Defaultwerte senden.
|
||||
|
||||
@@ -242,7 +242,7 @@ Sie können den *Pfadoperation-Dekorator*-Parameter `response_model_exclude_unse
|
||||
|
||||
Die Defaultwerte werden dann nicht in der Response enthalten sein, sondern nur die tatsächlich gesetzten Werte.
|
||||
|
||||
Wenn Sie also den Artikel mit der ID `foo` bei der *Pfadoperation* anfragen, wird (ohne die Defaultwerte) die Response sein:
|
||||
Wenn Sie also einen Request an diese *Pfadoperation* für den Artikel mit der ID `foo` senden, wird (ohne die Defaultwerte) die Response sein:
|
||||
|
||||
```JSON
|
||||
{
|
||||
@@ -251,20 +251,20 @@ Wenn Sie also den Artikel mit der ID `foo` bei der *Pfadoperation* anfragen, wir
|
||||
}
|
||||
```
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Sie können auch:
|
||||
|
||||
* `response_model_exclude_defaults=True`
|
||||
* `response_model_exclude_none=True`
|
||||
|
||||
verwenden, wie in der [Pydantic-Dokumentation](https://docs.pydantic.dev/1.10/usage/exporting_models/#modeldict) für `exclude_defaults` und `exclude_none` beschrieben.
|
||||
verwenden, wie in der [Pydantic-Dokumentation](https://pydantic.dev/docs/validation/latest/concepts/serialization/#excluding-and-including-fields-based-on-their-value) für `exclude_defaults` und `exclude_none` beschrieben.
|
||||
|
||||
///
|
||||
|
||||
#### Daten mit Werten für Felder mit Defaultwerten { #data-with-values-for-fields-with-defaults }
|
||||
|
||||
Aber wenn Ihre Daten Werte für Modellfelder mit Defaultwerten haben, wie etwa der Artikel mit der ID `bar`:
|
||||
Aber wenn Ihre Daten Werte für die Felder des Modells mit Defaultwerten haben, wie etwa der Artikel mit der ID `bar`:
|
||||
|
||||
```Python hl_lines="3 5"
|
||||
{
|
||||
@@ -331,14 +331,14 @@ Die Syntax `{"name", "description"}` erzeugt ein `set` mit diesen zwei Werten.
|
||||
|
||||
///
|
||||
|
||||
#### `list`en statt `set`s verwenden { #using-lists-instead-of-sets }
|
||||
#### `list`s statt `set`s verwenden { #using-lists-instead-of-sets }
|
||||
|
||||
Wenn Sie vergessen, ein `set` zu verwenden, und stattdessen eine `list`e oder ein `tuple` übergeben, wird FastAPI die dennoch in ein `set` konvertieren, und es wird korrekt funktionieren:
|
||||
Wenn Sie vergessen, ein `set` zu verwenden, und stattdessen eine `list` oder ein `tuple` übergeben, wird FastAPI die dennoch in ein `set` konvertieren, und es wird korrekt funktionieren:
|
||||
|
||||
{* ../../docs_src/response_model/tutorial006_py310.py hl[29,35] *}
|
||||
|
||||
## Zusammenfassung { #recap }
|
||||
|
||||
Verwenden Sie den Parameter `response_model` im *Pfadoperation-Dekorator*, um Responsemodelle zu definieren, und besonders, um private Daten herauszufiltern.
|
||||
Verwenden Sie den Parameter `response_model` im *Pfadoperation-Dekorator*, um Responsemodelle zu definieren, und besonders, um sicherzustellen, dass private Daten herausgefiltert werden.
|
||||
|
||||
Verwenden Sie `response_model_exclude_unset`, um nur explizit gesetzte Werte zurückzugeben.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Response-Statuscode { #response-status-code }
|
||||
|
||||
|
||||
Genauso wie Sie ein Responsemodell angeben können, können Sie auch den HTTP-Statuscode für die <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr> mit dem Parameter `status_code` in jeder der *Pfadoperationen* deklarieren:
|
||||
|
||||
* `@app.get()`
|
||||
@@ -18,7 +19,7 @@ Beachten Sie, dass `status_code` ein Parameter der „Dekorator“-Methode ist (
|
||||
|
||||
Dem `status_code`-Parameter wird eine Zahl mit dem HTTP-Statuscode übergeben.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Alternativ kann `status_code` auch ein `IntEnum` erhalten, wie etwa Pythons [`http.HTTPStatus`](https://docs.python.org/3/library/http.html#http.HTTPStatus).
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@ Sie können `examples` („Beispiele“) für ein Pydantic-Modell deklarieren, w
|
||||
|
||||
Diese zusätzlichen Informationen werden unverändert zum für dieses Modell ausgegebenen **JSON-Schema** hinzugefügt und in der API-Dokumentation verwendet.
|
||||
|
||||
Sie können das Attribut `model_config` verwenden, das ein <abbr title="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 <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> akzeptiert, wie beschrieben in [Pydantic-Dokumentation: Configuration](https://pydantic.dev/docs/validation/latest/api/pydantic/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
|
||||
|
||||
@@ -24,7 +24,7 @@ Sie könnten das beispielsweise verwenden, um Metadaten für eine Frontend-Benut
|
||||
|
||||
///
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
OpenAPI 3.1.0 (verwendet seit FastAPI 0.99.0) hat Unterstützung für `examples` hinzugefügt, was Teil des **JSON Schema** Standards ist.
|
||||
|
||||
@@ -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*.
|
||||
|
||||
### 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:
|
||||
|
||||
@@ -155,7 +155,7 @@ OpenAPI fügte auch die Felder `example` und `examples` zu anderen Teilen der Sp
|
||||
* `File()`
|
||||
* `Form()`
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Dieser alte, OpenAPI-spezifische `examples`-Parameter heißt seit FastAPI `0.103.0` jetzt `openapi_examples`.
|
||||
|
||||
@@ -171,7 +171,7 @@ Und jetzt hat dieses neue `examples`-Feld Vorrang vor dem alten (und benutzerdef
|
||||
|
||||
Dieses neue `examples`-Feld in JSON Schema ist **nur eine `list`** von Beispielen, kein Dict mit zusätzlichen Metadaten wie an den anderen Stellen in OpenAPI (oben beschrieben).
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Selbst, nachdem OpenAPI 3.1.0 veröffentlicht wurde, mit dieser neuen, einfacheren Integration mit JSON Schema, unterstützte Swagger UI, das Tool, das die automatische Dokumentation bereitstellt, eine Zeit lang OpenAPI 3.1.0 nicht (das tut es seit Version 5.0.0 🎉).
|
||||
|
||||
@@ -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.
|
||||
|
||||
### 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. 🤓
|
||||
|
||||
|
||||
@@ -24,20 +24,18 @@ Kopieren Sie das Beispiel in eine Datei `main.py`:
|
||||
|
||||
## Ausführen { #run-it }
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Das Paket [`python-multipart`](https://github.com/Kludex/python-multipart) wird automatisch mit **FastAPI** installiert, wenn Sie den Befehl `pip install "fastapi[standard]"` ausführen.
|
||||
Das Paket [`python-multipart`](https://github.com/Kludex/python-multipart) wird automatisch mit **FastAPI** installiert, wenn Sie den Befehl `uv add "fastapi[standard]"` ausführen.
|
||||
|
||||
Wenn Sie jedoch den Befehl `pip install fastapi` verwenden, ist das Paket `python-multipart` nicht standardmäßig enthalten.
|
||||
Wenn Sie jedoch den Befehl `uv add fastapi` verwenden, ist das Paket `python-multipart` nicht standardmäßig enthalten.
|
||||
|
||||
Um es manuell zu installieren, stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../../virtual-environments.md) erstellen, sie aktivieren und es dann mit:
|
||||
Um es manuell zu installieren, fügen Sie es Ihrem Projekt hinzu mit:
|
||||
|
||||
```console
|
||||
$ pip install python-multipart
|
||||
$ uv add python-multipart
|
||||
```
|
||||
|
||||
installieren.
|
||||
|
||||
Das liegt daran, dass **OAuth2** „Formulardaten“ zum Senden von `username` und `password` verwendet.
|
||||
|
||||
///
|
||||
@@ -47,7 +45,7 @@ Führen Sie das Beispiel aus mit:
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev
|
||||
$ uv run fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
@@ -62,7 +60,7 @@ Sie werden etwa Folgendes sehen:
|
||||
|
||||
<img src="/img/tutorial/security/image01.png">
|
||||
|
||||
/// check | Authorize-Button!
|
||||
/// tip | Authorize-Button!
|
||||
|
||||
Sie haben bereits einen glänzenden, neuen „Authorize“-Button.
|
||||
|
||||
@@ -120,7 +118,7 @@ Betrachten wir es also aus dieser vereinfachten Sicht:
|
||||
|
||||
In diesem Beispiel verwenden wir **OAuth2** mit dem **Password**-Flow und einem **Bearer**-Token. Wir machen das mit der Klasse `OAuth2PasswordBearer`.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Ein „Bearer“-Token ist nicht die einzige Option.
|
||||
|
||||
@@ -150,7 +148,7 @@ Dieser Parameter erstellt nicht diesen Endpunkt / diese *Pfadoperation*, sondern
|
||||
|
||||
Wir werden demnächst auch die eigentliche Pfadoperation erstellen.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Wenn Sie ein sehr strenger „Pythonista“ sind, missfällt Ihnen möglicherweise die Schreibweise des Parameternamens `tokenUrl` anstelle von `token_url`.
|
||||
|
||||
@@ -178,7 +176,7 @@ Diese Abhängigkeit stellt einen `str` bereit, der dem Parameter `token` der *Pf
|
||||
|
||||
**FastAPI** weiß, dass es diese Abhängigkeit verwenden kann, um ein „Sicherheitsschema“ im OpenAPI-Schema (und der automatischen API-Dokumentation) zu definieren.
|
||||
|
||||
/// info | Technische Details
|
||||
/// note | Technische Details
|
||||
|
||||
**FastAPI** weiß, dass es die Klasse `OAuth2PasswordBearer` (deklariert in einer Abhängigkeit) verwenden kann, um das Sicherheitsschema in OpenAPI zu definieren, da es von `fastapi.security.oauth2.OAuth2` erbt, das wiederum von `fastapi.security.base.SecurityBase` erbt.
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ Erstellen wir zunächst ein Pydantic-Benutzermodell.
|
||||
|
||||
So wie wir Pydantic zum Deklarieren von Bodys verwenden, können wir es auch überall sonst verwenden:
|
||||
|
||||
{* ../../docs_src/security/tutorial002_an_py310.py hl[5,12:6] *}
|
||||
{* ../../docs_src/security/tutorial002_an_py310.py hl[5,12:16] *}
|
||||
|
||||
## Eine `get_current_user`-Abhängigkeit erstellen { #create-a-get-current-user-dependency }
|
||||
|
||||
@@ -52,7 +52,7 @@ Weil Sie `Depends` verwenden, wird **FastAPI** hier aber nicht verwirrt.
|
||||
|
||||
///
|
||||
|
||||
/// check | Testen
|
||||
/// tip | Tipp
|
||||
|
||||
Die Art und Weise, wie dieses System von Abhängigkeiten konzipiert ist, ermöglicht es uns, verschiedene Abhängigkeiten (verschiedene „Dependables“) zu haben, die alle ein `User`-Modell zurückgeben.
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Da wir nun über den gesamten Sicherheitsablauf verfügen, machen wir die Anwend
|
||||
|
||||
Diesen Code können Sie tatsächlich in Ihrer Anwendung verwenden, die Passwort-Hashes in Ihrer Datenbank speichern, usw.
|
||||
|
||||
Wir bauen auf dem vorherigen Kapitel auf.
|
||||
Wir bauen auf dem vorherigen Kapitel auf und erweitern es.
|
||||
|
||||
## Über JWT { #about-jwt }
|
||||
|
||||
@@ -30,21 +30,21 @@ Wenn Sie mit JWT-Tokens spielen und sehen möchten, wie sie funktionieren, schau
|
||||
|
||||
Wir müssen `PyJWT` installieren, um die JWT-Tokens in Python zu generieren und zu verifizieren.
|
||||
|
||||
Stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../../virtual-environments.md) erstellen, sie aktivieren und dann `pyjwt` installieren:
|
||||
Fügen Sie `pyjwt` zu Ihrem Projekt hinzu:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install pyjwt
|
||||
$ uv add pyjwt
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Wenn Sie planen, digitale Signaturalgorithmen wie RSA oder ECDSA zu verwenden, sollten Sie die Kryptografie-Abhängigkeit `pyjwt[crypto]` installieren.
|
||||
Wenn Sie planen, digitale Signaturalgorithmen wie RSA oder ECDSA zu verwenden, sollten Sie die Kryptografie-Bibliotheksabhängigkeit `pyjwt[crypto]` installieren.
|
||||
|
||||
Weitere Informationen finden Sie in der [PyJWT-Installationsdokumentation](https://pyjwt.readthedocs.io/en/latest/installation.html).
|
||||
|
||||
@@ -72,12 +72,12 @@ Es unterstützt viele sichere Hashing-Algorithmen und Werkzeuge, um mit diesen z
|
||||
|
||||
Der empfohlene Algorithmus ist „Argon2“.
|
||||
|
||||
Stellen Sie sicher, dass Sie eine [virtuelle Umgebung](../../virtual-environments.md) erstellen, sie aktivieren, und installieren Sie dann pwdlib mit Argon2:
|
||||
Fügen Sie `pwdlib` mit Argon2 zu Ihrem Projekt hinzu:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "pwdlib[argon2]"
|
||||
$ uv add "pwdlib[argon2]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
@@ -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.
|
||||
|
||||
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
|
||||
|
||||
@@ -168,7 +168,7 @@ Wenn der Token ungültig ist, geben Sie sofort einen HTTP-Fehler zurück.
|
||||
|
||||
{* ../../docs_src/security/tutorial004_an_py310.py hl[93:110] *}
|
||||
|
||||
## Die *Pfadoperation* `/token` aktualisieren { #update-the-token-path-operation }
|
||||
## Die `/token`-*Pfadoperation* aktualisieren { #update-the-token-path-operation }
|
||||
|
||||
Erstellen Sie ein <abbr title="Zeitdifferenz">`timedelta`</abbr> mit der Ablaufzeit des Tokens.
|
||||
|
||||
@@ -206,14 +206,14 @@ Die Benutzeroberfläche sieht wie folgt aus:
|
||||
|
||||
<img src="/img/tutorial/security/image07.png">
|
||||
|
||||
Melden Sie sich bei der Anwendung auf die gleiche Weise wie zuvor an.
|
||||
Autorisieren Sie die Anwendung auf die gleiche Weise wie zuvor.
|
||||
|
||||
Verwenden Sie die Anmeldeinformationen:
|
||||
|
||||
Benutzername: `johndoe`
|
||||
Passwort: `secret`
|
||||
|
||||
/// check | Testen
|
||||
/// tip | Tipp
|
||||
|
||||
Beachten Sie, dass im Code nirgendwo das Klartext-Passwort „`secret`“ steht, wir haben nur die gehashte Version.
|
||||
|
||||
@@ -260,7 +260,7 @@ Mit dem, was Sie bis hier gesehen haben, können Sie eine sichere **FastAPI**-An
|
||||
|
||||
In fast jedem Framework wird die Handhabung der Sicherheit recht schnell zu einem ziemlich komplexen Thema.
|
||||
|
||||
Viele Packages, die es stark vereinfachen, müssen viele Kompromisse beim Datenmodell, der Datenbank und den verfügbaren Funktionen eingehen. Und einige dieser Pakete, die die Dinge zu sehr vereinfachen, weisen tatsächlich Sicherheitslücken auf.
|
||||
Viele Packages, die es stark vereinfachen, müssen viele Kompromisse beim Datenmodell, der Datenbank und den verfügbaren Funktionen eingehen. Und einige dieser Packages, die die Dinge zu sehr vereinfachen, weisen tatsächlich Sicherheitslücken auf.
|
||||
|
||||
---
|
||||
|
||||
@@ -268,7 +268,7 @@ Viele Packages, die es stark vereinfachen, müssen viele Kompromisse beim Datenm
|
||||
|
||||
Es gibt Ihnen die volle Flexibilität, diejenigen auszuwählen, die am besten zu Ihrem Projekt passen.
|
||||
|
||||
Und Sie können viele gut gepflegte und weit verbreitete Packages wie `pwdlib` und `PyJWT` direkt verwenden, da **FastAPI** keine komplexen Mechanismen zur Integration externer Pakete erfordert.
|
||||
Und Sie können viele gut gepflegte und weit verbreitete Packages wie `pwdlib` und `PyJWT` direkt verwenden, da **FastAPI** keine komplexen Mechanismen zur Integration externer Packages erfordert.
|
||||
|
||||
Aber es bietet Ihnen die Werkzeuge, um den Prozess so weit wie möglich zu vereinfachen, ohne Kompromisse bei Flexibilität, Robustheit oder Sicherheit einzugehen.
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Die Spezifikation besagt auch, dass `username` und `password` als Formulardaten
|
||||
|
||||
### `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“.
|
||||
|
||||
@@ -32,7 +32,7 @@ Diese werden normalerweise verwendet, um bestimmte Sicherheitsberechtigungen zu
|
||||
* `instagram_basic` wird von Facebook / Instagram verwendet.
|
||||
* `https://www.googleapis.com/auth/drive` wird von Google verwendet.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
In OAuth2 ist ein „Scope“ nur ein String, der eine bestimmte erforderliche Berechtigung deklariert.
|
||||
|
||||
@@ -72,7 +72,7 @@ Wenn Sie es erzwingen müssen, verwenden Sie `OAuth2PasswordRequestFormStrict` a
|
||||
* Eine optionale `client_id` (benötigen wir für unser Beispiel nicht).
|
||||
* Ein optionales `client_secret` (benötigen wir für unser Beispiel nicht).
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
`OAuth2PasswordRequestForm` ist keine spezielle Klasse für **FastAPI**, so wie `OAuth2PasswordBearer`.
|
||||
|
||||
@@ -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.
|
||||
|
||||
##### Warum Passwort-Hashing verwenden? { #why-use-password-hashing }
|
||||
##### Warum Passwort-Hashing verwenden { #why-use-password-hashing }
|
||||
|
||||
Wenn Ihre Datenbank gestohlen wird, hat der Dieb nicht die Klartext-Passwörter Ihrer Benutzer, sondern nur die Hashes.
|
||||
|
||||
@@ -144,9 +144,9 @@ UserInDB(
|
||||
)
|
||||
```
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Eine ausführlichere Erklärung von `**user_dict` finden Sie in [der Dokumentation für **Extra Modelle**](../extra-models.md#about-user-in-dict).
|
||||
Eine ausführlichere Erklärung von `**user_dict` finden Sie in [der Dokumentation für **Extra Modelle**](../extra-models.md#about-user-in-model-dump).
|
||||
|
||||
///
|
||||
|
||||
@@ -196,7 +196,7 @@ In unserem Endpunkt erhalten wir also nur dann einen Benutzer, wenn der Benutzer
|
||||
|
||||
{* ../../docs_src/security/tutorial003_an_py310.py hl[58:66,69:74,94] *}
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Der zusätzliche Header `WWW-Authenticate` mit dem Wert `Bearer`, den wir hier zurückgeben, ist ebenfalls Teil der Spezifikation.
|
||||
|
||||
@@ -226,7 +226,7 @@ Verwenden Sie die Anmeldedaten:
|
||||
|
||||
Benutzer: `johndoe`
|
||||
|
||||
Passwort: `secret`.
|
||||
Passwort: `secret`
|
||||
|
||||
<img src="/img/tutorial/security/image04.png">
|
||||
|
||||
@@ -264,9 +264,9 @@ Wenn Sie auf das Schlosssymbol klicken und sich abmelden und dann den gleichen V
|
||||
|
||||
Versuchen Sie es nun mit einem inaktiven Benutzer und authentisieren Sie sich mit:
|
||||
|
||||
Benutzer: `alice`.
|
||||
Benutzer: `alice`
|
||||
|
||||
Passwort: `secret2`.
|
||||
Passwort: `secret2`
|
||||
|
||||
Und versuchen Sie, die Operation `GET` mit dem Pfad `/users/me` zu verwenden.
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
Sie können Daten mithilfe von **Server-Sent Events** (SSE) an den Client streamen.
|
||||
|
||||
Das ist ähnlich wie [JSON Lines streamen](stream-json-lines.md), verwendet aber das Format `text/event-stream`, das von Browsern nativ mit der [die `EventSource`-API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) unterstützt wird.
|
||||
Das ist ähnlich wie [JSON Lines streamen](stream-json-lines.md), verwendet aber das Format `text/event-stream`, das von Browsern nativ mit der [`EventSource`-API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) unterstützt wird.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Hinzugefügt in FastAPI 0.135.0.
|
||||
|
||||
@@ -29,7 +29,7 @@ SSE wird häufig für KI-Chat-Streaming, Live-Benachrichtigungen, Logs und Obser
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Wenn Sie Binärdaten streamen wollen, z. B. Video oder Audio, sehen Sie im fortgeschrittenen Handbuch nach: [Daten streamen](../advanced/stream-data.md).
|
||||
Wenn Sie Binärdaten streamen wollen, z. B. Video oder Audio, sehen Sie im Handbuch für fortgeschrittene Benutzer nach: [Daten streamen](../advanced/stream-data.md).
|
||||
|
||||
///
|
||||
|
||||
@@ -103,7 +103,7 @@ Sie können ihn als Header-Parameter einlesen und verwenden, um den Stream dort
|
||||
|
||||
## SSE mit POST { #sse-with-post }
|
||||
|
||||
SSE funktioniert mit **jedem HTTP-Method**, nicht nur mit `GET`.
|
||||
SSE funktioniert mit **jeder HTTP-Methode**, nicht nur mit `GET`.
|
||||
|
||||
Das ist nützlich für Protokolle wie [MCP](https://modelcontextprotocol.io), die SSE über `POST` streamen:
|
||||
|
||||
@@ -113,7 +113,7 @@ Das ist nützlich für Protokolle wie [MCP](https://modelcontextprotocol.io), di
|
||||
|
||||
FastAPI implementiert einige bewährte SSE-Praktiken direkt out of the box.
|
||||
|
||||
- Alle 15 Sekunden, wenn keine Nachricht gesendet wurde, einen **„keep alive“-`ping`-Kommentar** senden, um zu verhindern, dass einige Proxys die Verbindung schließen, wie in der [HTML-Spezifikation: Server-Sent Events](https://html.spec.whatwg.org/multipage/server-sent-events.html#authoring-notes) vorgeschlagen.
|
||||
- Einen **„keep alive“-`ping`-Kommentar** alle 15 Sekunden senden, wenn keine Nachricht gesendet wurde, um zu verhindern, dass einige Proxys die Verbindung schließen, wie in der [HTML-Spezifikation: Server-Sent Events](https://html.spec.whatwg.org/multipage/server-sent-events.html#authoring-notes) vorgeschlagen.
|
||||
- Den Header `Cache-Control: no-cache` setzen, um **Caching** des Streams zu verhindern.
|
||||
- Einen speziellen Header `X-Accel-Buffering: no` setzen, um **Buffering** in einigen Proxys wie Nginx zu verhindern.
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ Hier werden wir ein Beispiel mit [SQLModel](https://sqlmodel.tiangolo.com/) sehe
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Sie könnten jede andere SQL- oder NoSQL-Datenbankbibliothek verwenden, die Sie möchten (in einigen Fällen als <abbr title="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 <abbr title="Objektrelationaler Mapper: Ein Fachbegriff für eine Bibliothek, in der einige Klassen repräsentieren SQL-Tabellen und Instanzen repräsentieren Zeilen in diesen Tabellen">„ORMs“</abbr> bezeichnet), FastAPI zwingt Sie nicht, irgendetwas zu verwenden. 😎
|
||||
|
||||
///
|
||||
|
||||
@@ -34,12 +34,12 @@ Dies ist ein sehr einfaches und kurzes Tutorial. Wenn Sie mehr über Datenbanken
|
||||
|
||||
## `SQLModel` installieren { #install-sqlmodel }
|
||||
|
||||
Stellen Sie zunächst sicher, dass Sie Ihre [virtuelle Umgebung](../virtual-environments.md) erstellen, sie aktivieren und dann `sqlmodel` installieren:
|
||||
Fügen Sie `sqlmodel` Ihrem Projekt hinzu:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install sqlmodel
|
||||
$ uv add sqlmodel
|
||||
---> 100%
|
||||
```
|
||||
|
||||
@@ -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.
|
||||
|
||||
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.
|
||||
|
||||
{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[40:45] hl[40:45] *}
|
||||
|
||||
@@ -152,7 +152,7 @@ Sie können die App ausführen:
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev
|
||||
$ uv run fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
@@ -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.
|
||||
|
||||
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. 🤷
|
||||
|
||||
@@ -337,7 +337,7 @@ Sie können die App erneut ausführen:
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi dev
|
||||
$ uv run fastapi dev
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
|
||||
Mit `StaticFiles` können Sie statische Dateien aus einem Verzeichnis automatisch bereitstellen.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Wenn Sie ein Frontend hosten müssen, verwenden Sie stattdessen `app.frontend()`; lesen Sie mehr dazu unter [Frontend](frontend.md).
|
||||
|
||||
`app.frontend()` verwendet darunter `StaticFiles`, mit mehreren zusätzlichen Vorteilen für Frontends, wie der Handhabung von clientseitigem Routing.
|
||||
|
||||
///
|
||||
|
||||
## `StaticFiles` verwenden { #use-staticfiles }
|
||||
|
||||
* Importieren Sie `StaticFiles`.
|
||||
@@ -13,7 +21,7 @@ Mit `StaticFiles` können Sie statische Dateien aus einem Verzeichnis automatisc
|
||||
|
||||
Sie könnten auch `from starlette.staticfiles import StaticFiles` verwenden.
|
||||
|
||||
**FastAPI** stellt dasselbe `starlette.staticfiles` auch via `fastapi.staticfiles` bereit, als Annehmlichkeit für Sie, den Entwickler. Es kommt aber tatsächlich direkt von Starlette.
|
||||
**FastAPI** stellt dasselbe `starlette.staticfiles` auch als `fastapi.staticfiles` bereit, nur als Annehmlichkeit für Sie, den Entwickler. Es kommt aber tatsächlich direkt von Starlette.
|
||||
|
||||
///
|
||||
|
||||
@@ -37,4 +45,4 @@ Alle diese Parameter können anders als „`static`“ lauten, passen Sie sie an
|
||||
|
||||
## Weitere Informationen { #more-info }
|
||||
|
||||
Weitere Details und Optionen finden Sie in [Starlettes Dokumentation zu statischen Dateien](https://www.starlette.dev/staticfiles/).
|
||||
Weitere Details und Optionen finden Sie in [Starlettes Dokumentation zu statischen Dateien](https://starlette.dev/staticfiles/).
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Sie könnten eine Folge von Daten haben, die Sie in einem „Stream“ senden möchten, das können Sie mit **JSON Lines** tun.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Hinzugefügt in FastAPI 0.134.0.
|
||||
|
||||
@@ -48,7 +48,7 @@ Eine Response hätte einen Content-Type von `application/jsonl` (anstelle von `a
|
||||
|
||||
Es ist einem JSON-Array (entspricht einer Python-Liste) sehr ähnlich, aber anstatt in `[]` eingeschlossen zu sein und `,` zwischen den Elementen zu haben, gibt es hier **ein JSON-Objekt pro Zeile**, sie sind durch ein Zeilenumbruchzeichen getrennt.
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Der wichtige Punkt ist, dass Ihre App in der Lage ist, jede Zeile der Reihe nach zu erzeugen, während der Client die vorherigen Zeilen konsumiert.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Testen { #testing }
|
||||
|
||||
Dank [Starlette](https://www.starlette.dev/testclient/) ist das Testen von **FastAPI**-Anwendungen einfach und macht Spaß.
|
||||
Dank [Starlette](https://starlette.dev/testclient/) ist das Testen von **FastAPI**-Anwendungen einfach und macht Spaß.
|
||||
|
||||
Es basiert auf [HTTPX](https://www.python-httpx.org), welches wiederum auf der Grundlage von Requests konzipiert wurde, es ist also sehr vertraut und intuitiv.
|
||||
|
||||
@@ -8,14 +8,14 @@ Damit können Sie [pytest](https://docs.pytest.org/) direkt mit **FastAPI** verw
|
||||
|
||||
## `TestClient` verwenden { #using-testclient }
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Um `TestClient` zu verwenden, installieren Sie zunächst [`httpx`](https://www.python-httpx.org).
|
||||
|
||||
Erstellen Sie eine [virtuelle Umgebung](../virtual-environments.md), aktivieren Sie sie und installieren Sie es dann, z. B.:
|
||||
Fügen Sie es zu Ihrem Projekt hinzu:
|
||||
|
||||
```console
|
||||
$ pip install httpx
|
||||
$ uv add httpx
|
||||
```
|
||||
|
||||
///
|
||||
@@ -24,7 +24,7 @@ Importieren Sie `TestClient`.
|
||||
|
||||
Erstellen Sie einen `TestClient`, indem Sie ihm Ihre **FastAPI**-Anwendung übergeben.
|
||||
|
||||
Erstellen Sie Funktionen mit einem Namen, der mit `test_` beginnt (das sind `pytest`-Konventionen).
|
||||
Erstellen Sie Funktionen mit einem Namen, der mit `test_` beginnt (das ist eine Standard-`pytest`-Konvention).
|
||||
|
||||
Verwenden Sie das `TestClient`-Objekt auf die gleiche Weise wie `httpx`.
|
||||
|
||||
@@ -36,7 +36,7 @@ Schreiben Sie einfache `assert`-Anweisungen mit den Standard-Python-Ausdrücken,
|
||||
|
||||
Beachten Sie, dass die Testfunktionen normal `def` und nicht `async def` sind.
|
||||
|
||||
Und die Anrufe an den Client sind ebenfalls normale Anrufe, die nicht `await` verwenden.
|
||||
Und die Aufrufe an den Client sind ebenfalls normale Aufrufe, die nicht `await` verwenden.
|
||||
|
||||
Dadurch können Sie `pytest` ohne Komplikationen direkt nutzen.
|
||||
|
||||
@@ -52,7 +52,7 @@ Sie könnten auch `from starlette.testclient import TestClient` verwenden.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Wenn Sie in Ihren Tests neben dem Senden von <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> an Ihre FastAPI-Anwendung auch `async`-Funktionen aufrufen möchten (z. B. asynchrone Datenbankfunktionen), werfen Sie einen Blick auf die [Async-Tests](../advanced/async-tests.md) im Handbuch für fortgeschrittene Benutzer.
|
||||
Wenn Sie in Ihren Tests neben dem Senden von <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> an Ihre FastAPI-Anwendung auch `async`-Funktionen aufrufen möchten (z. B. asynchrone Datenbankfunktionen), werfen Sie einen Blick auf die [Async-Tests](../advanced/async-tests.md) im Tutorial für fortgeschrittene Benutzer.
|
||||
|
||||
///
|
||||
|
||||
@@ -62,7 +62,7 @@ In einer echten Anwendung würden Sie Ihre Tests wahrscheinlich in einer anderen
|
||||
|
||||
Und Ihre **FastAPI**-Anwendung könnte auch aus mehreren Dateien/Modulen, usw. bestehen.
|
||||
|
||||
### **FastAPI** Anwendungsdatei { #fastapi-app-file }
|
||||
### **FastAPI**-Anwendungsdatei { #fastapi-app-file }
|
||||
|
||||
Nehmen wir an, Sie haben eine Dateistruktur wie in [Größere Anwendungen](bigger-applications.md) beschrieben:
|
||||
|
||||
@@ -131,7 +131,7 @@ Anschließend könnten Sie `test_main.py` mit den erweiterten Tests aktualisiere
|
||||
{* ../../docs_src/app_testing/app_b_an_py310/test_main.py *}
|
||||
|
||||
|
||||
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.
|
||||
|
||||
@@ -145,7 +145,7 @@ Z. B.:
|
||||
|
||||
Weitere Informationen zum Übergeben von Daten an das Backend (mithilfe von `httpx` oder dem `TestClient`) finden Sie in der [HTTPX-Dokumentation](https://www.python-httpx.org).
|
||||
|
||||
/// info | Info
|
||||
/// note | Hinweis
|
||||
|
||||
Beachten Sie, dass der `TestClient` Daten empfängt, die nach JSON konvertiert werden können, keine Pydantic-Modelle.
|
||||
|
||||
@@ -153,16 +153,16 @@ Wenn Sie ein Pydantic-Modell in Ihrem Test haben und dessen Daten während des T
|
||||
|
||||
///
|
||||
|
||||
## Tests ausführen { #run-it }
|
||||
## Ausführen { #run-it }
|
||||
|
||||
Danach müssen Sie nur noch `pytest` installieren.
|
||||
|
||||
Erstellen Sie eine [virtuelle Umgebung](../virtual-environments.md), aktivieren Sie sie und installieren Sie es dann, z. B.:
|
||||
Fügen Sie es zu Ihrem Projekt hinzu:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install pytest
|
||||
$ uv add pytest
|
||||
|
||||
---> 100%
|
||||
```
|
||||
@@ -176,7 +176,7 @@ Führen Sie die Tests aus, mit:
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pytest
|
||||
$ uv run pytest
|
||||
|
||||
================ test session starts ================
|
||||
platform linux -- Python 3.6.9, pytest-5.3.5, py-1.8.1, pluggy-0.13.1
|
||||
|
||||
@@ -1,862 +1,35 @@
|
||||
# Virtuelle Umgebungen { #virtual-environments }
|
||||
|
||||
Wenn Sie an Python-Projekten arbeiten, sollten Sie wahrscheinlich eine **virtuelle Umgebung** (oder einen ähnlichen Mechanismus) verwenden, um die <abbr title="Python Installationspakete">Packages</abbr>, die Sie für jedes Projekt installieren, zu isolieren.
|
||||
Wenn Sie mit Python-Projekten arbeiten, sollten Sie eine **virtuelle Umgebung** verwenden, um die für jedes Projekt installierten Packages zu isolieren.
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
Wenn Sie bereits über virtuelle Umgebungen Bescheid wissen, wie man sie erstellt und verwendet, möchten Sie diesen Abschnitt vielleicht überspringen. 🤓
|
||||
|
||||
///
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Eine **virtuelle Umgebung** unterscheidet sich von einer **Umgebungsvariable**.
|
||||
|
||||
Eine **Umgebungsvariable** ist eine Variable im System, die von Programmen verwendet werden kann.
|
||||
|
||||
Eine **virtuelle Umgebung** ist ein Verzeichnis mit einigen Dateien darin.
|
||||
|
||||
///
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
Diese Seite wird Ihnen beibringen, wie Sie **virtuelle Umgebungen** verwenden und wie sie funktionieren.
|
||||
|
||||
Wenn Sie bereit sind, ein **Tool zu verwenden, das alles für Sie verwaltet** (einschließlich der Installation von Python), probieren Sie [uv](https://github.com/astral-sh/uv).
|
||||
|
||||
///
|
||||
Für FastAPI-Projekte empfehle ich die Verwendung von [uv](https://docs.astral.sh/uv/), um das Projekt, seine Abhängigkeiten und seine virtuelle Umgebung zu verwalten.
|
||||
|
||||
## Ein Projekt erstellen { #create-a-project }
|
||||
|
||||
Erstellen Sie zuerst ein Verzeichnis für Ihr Projekt.
|
||||
|
||||
Was ich normalerweise mache, ist, dass ich ein Verzeichnis namens `code` in meinem Home/Benutzerverzeichnis erstelle.
|
||||
|
||||
Und darin erstelle ich ein Verzeichnis pro Projekt.
|
||||
Installieren Sie `uv` mithilfe der [offiziellen Installationsanleitung](https://docs.astral.sh/uv/getting-started/installation/) und erstellen Sie dann ein Projekt:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Gehe zum Home-Verzeichnis
|
||||
$ cd
|
||||
// Erstelle ein Verzeichnis für alle Ihre Code-Projekte
|
||||
$ mkdir code
|
||||
// Gehe in dieses Code-Verzeichnis
|
||||
$ cd code
|
||||
// Erstelle ein Verzeichnis für dieses Projekt
|
||||
$ mkdir awesome-project
|
||||
// Gehe in dieses Projektverzeichnis
|
||||
$ uv init awesome-project --bare
|
||||
$ cd awesome-project
|
||||
$ uv add "fastapi[standard]"
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## Eine virtuelle Umgebung erstellen { #create-a-virtual-environment }
|
||||
`uv` erstellt automatisch eine virtuelle Umgebung für das Projekt. Sie müssen selbst keine erstellen oder aktivieren.
|
||||
|
||||
Wenn Sie zum **ersten Mal** an einem Python-Projekt arbeiten, erstellen Sie eine virtuelle Umgebung **<dfn title="es gibt andere Optionen, dies ist eine einfache Richtlinie">innerhalb Ihres Projekts</dfn>**.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Sie müssen dies nur **einmal pro Projekt** tun, nicht jedes Mal, wenn Sie daran arbeiten.
|
||||
|
||||
///
|
||||
|
||||
//// tab | `venv`
|
||||
|
||||
Um eine virtuelle Umgebung zu erstellen, können Sie das `venv`-Modul verwenden, das mit Python geliefert wird.
|
||||
Führen Sie Befehle innerhalb der Projektumgebung mit `uv run` aus, zum Beispiel:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python -m venv .venv
|
||||
$ uv run fastapi dev
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// details | Was dieser Befehl bedeutet
|
||||
## Mehr erfahren { #learn-more }
|
||||
|
||||
* `python`: das Programm namens `python` verwenden
|
||||
* `-m`: ein Modul als Skript aufrufen, wir geben als nächstes an, welches Modul
|
||||
* `venv`: das Modul namens `venv` verwenden, das normalerweise mit Python installiert wird
|
||||
* `.venv`: die virtuelle Umgebung im neuen Verzeichnis `.venv` erstellen
|
||||
|
||||
///
|
||||
|
||||
////
|
||||
|
||||
//// tab | `uv`
|
||||
|
||||
Wenn Sie [`uv`](https://github.com/astral-sh/uv) installiert haben, können Sie es verwenden, um eine virtuelle Umgebung zu erstellen.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uv venv
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Standardmäßig erstellt `uv` eine virtuelle Umgebung in einem Verzeichnis namens `.venv`.
|
||||
|
||||
Aber Sie könnten es anpassen, indem Sie ein zusätzliches Argument mit dem Verzeichnisnamen übergeben.
|
||||
|
||||
///
|
||||
|
||||
////
|
||||
|
||||
Dieser Befehl erstellt eine neue virtuelle Umgebung in einem Verzeichnis namens `.venv`.
|
||||
|
||||
/// details | `.venv` oder ein anderer Name
|
||||
|
||||
Sie könnten die virtuelle Umgebung in einem anderen Verzeichnis erstellen, aber es ist eine Konvention, sie `.venv` zu nennen.
|
||||
|
||||
///
|
||||
|
||||
## Die virtuelle Umgebung aktivieren { #activate-the-virtual-environment }
|
||||
|
||||
Aktivieren Sie die neue virtuelle Umgebung, damit jeder Python-Befehl, den Sie ausführen oder jedes Paket, das Sie installieren, diese Umgebung verwendet.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Tun Sie dies **jedes Mal**, wenn Sie eine **neue Terminalsitzung** starten, um an dem Projekt zu arbeiten.
|
||||
|
||||
///
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ source .venv/bin/activate
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ .venv\Scripts\Activate.ps1
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows Bash
|
||||
|
||||
Oder wenn Sie Bash für Windows verwenden (z. B. [Git Bash](https://gitforwindows.org/)):
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ source .venv/Scripts/activate
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Jedes Mal, wenn Sie ein **neues Paket** in dieser Umgebung installieren, aktivieren Sie die Umgebung erneut.
|
||||
|
||||
So stellen Sie sicher, dass, wenn Sie ein **Terminalprogramm (<abbr title="command line interface - Kommandozeileninterface">CLI</abbr>)** verwenden, das durch dieses Paket installiert wurde, Sie das aus Ihrer virtuellen Umgebung verwenden und nicht eines, das global installiert ist, wahrscheinlich mit einer anderen Version als der, die Sie benötigen.
|
||||
|
||||
///
|
||||
|
||||
## Testen, ob die virtuelle Umgebung aktiv ist { #check-the-virtual-environment-is-active }
|
||||
|
||||
Testen Sie, dass die virtuelle Umgebung aktiv ist (der vorherige Befehl funktioniert hat).
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Dies ist **optional**, aber es ist eine gute Möglichkeit, **zu überprüfen**, ob alles wie erwartet funktioniert und Sie die beabsichtigte virtuelle Umgebung verwenden.
|
||||
|
||||
///
|
||||
|
||||
//// tab | Linux, macOS, Windows Bash
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ which python
|
||||
|
||||
/home/user/code/awesome-project/.venv/bin/python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Wenn es das `python`-Binary in `.venv/bin/python` anzeigt, innerhalb Ihres Projekts (in diesem Fall `awesome-project`), dann hat es funktioniert. 🎉
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ Get-Command python
|
||||
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts\python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Wenn es das `python`-Binary in `.venv\Scripts\python` anzeigt, innerhalb Ihres Projekts (in diesem Fall `awesome-project`), dann hat es funktioniert. 🎉
|
||||
|
||||
////
|
||||
|
||||
## `pip` aktualisieren { #upgrade-pip }
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Wenn Sie [`uv`](https://github.com/astral-sh/uv) verwenden, würden Sie das verwenden, um Dinge zu installieren anstelle von `pip`, sodass Sie `pip` nicht aktualisieren müssen. 😎
|
||||
|
||||
///
|
||||
|
||||
Wenn Sie `pip` verwenden, um Pakete zu installieren (es wird standardmäßig mit Python geliefert), sollten Sie es auf die neueste Version **aktualisieren**.
|
||||
|
||||
Viele exotische Fehler beim Installieren eines Pakets werden einfach dadurch gelöst, dass zuerst `pip` aktualisiert wird.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Normalerweise würden Sie dies **einmal** tun, unmittelbar nachdem Sie die virtuelle Umgebung erstellt haben.
|
||||
|
||||
///
|
||||
|
||||
Stellen Sie sicher, dass die virtuelle Umgebung aktiv ist (mit dem obigen Befehl) und führen Sie dann aus:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python -m pip install --upgrade pip
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Manchmal kann beim Versuch, `pip` zu aktualisieren, der Fehler **`No module named pip`** auftreten.
|
||||
|
||||
Wenn das passiert, installieren und aktualisieren Sie `pip` mit dem folgenden Befehl:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python -m ensurepip --upgrade
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Dieser Befehl installiert `pip`, falls es noch nicht installiert ist, und stellt außerdem sicher, dass die installierte Version von `pip` mindestens so aktuell ist wie die in `ensurepip` verfügbare.
|
||||
|
||||
///
|
||||
|
||||
## `.gitignore` hinzufügen { #add-gitignore }
|
||||
|
||||
Wenn Sie **Git** verwenden (was Sie sollten), fügen Sie eine `.gitignore`-Datei hinzu, um alles in Ihrem `.venv` von Git auszuschließen.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Wenn Sie [`uv`](https://github.com/astral-sh/uv) verwendet haben, um die virtuelle Umgebung zu erstellen, hat es dies bereits für Sie getan, Sie können diesen Schritt überspringen. 😎
|
||||
|
||||
///
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Tun Sie dies **einmal**, unmittelbar nachdem Sie die virtuelle Umgebung erstellt haben.
|
||||
|
||||
///
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ echo "*" > .venv/.gitignore
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// details | Was dieser Befehl bedeutet
|
||||
|
||||
* `echo "*"`: wird den Text `*` im Terminal „drucken“ (der nächste Teil ändert das ein wenig)
|
||||
* `>`: alles, was durch den Befehl links von `>` im Terminal ausgegeben wird, sollte nicht gedruckt, sondern stattdessen in die Datei geschrieben werden, die rechts von `>` kommt
|
||||
* `.gitignore`: der Name der Datei, in die der Text geschrieben werden soll
|
||||
|
||||
Und `*` bedeutet für Git „alles“. Also wird alles im `.venv`-Verzeichnis ignoriert.
|
||||
|
||||
Dieser Befehl erstellt eine Datei `.gitignore` mit dem Inhalt:
|
||||
|
||||
```gitignore
|
||||
*
|
||||
```
|
||||
|
||||
///
|
||||
|
||||
## Pakete installieren { #install-packages }
|
||||
|
||||
Nachdem Sie die Umgebung aktiviert haben, können Sie Pakete darin installieren.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Tun Sie dies **einmal**, wenn Sie die Pakete installieren oder aktualisieren, die Ihr Projekt benötigt.
|
||||
|
||||
Wenn Sie eine Version aktualisieren oder ein neues Paket hinzufügen müssen, würden Sie **dies erneut tun**.
|
||||
|
||||
///
|
||||
|
||||
### Pakete direkt installieren { #install-packages-directly }
|
||||
|
||||
Wenn Sie es eilig haben und keine Datei verwenden möchten, um die Paketanforderungen Ihres Projekts zu deklarieren, können Sie sie direkt installieren.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Es ist eine (sehr) gute Idee, die Pakete und Versionen, die Ihr Programm benötigt, in einer Datei zu speichern (zum Beispiel `requirements.txt` oder `pyproject.toml`).
|
||||
|
||||
///
|
||||
|
||||
//// tab | `pip`
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "fastapi[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | `uv`
|
||||
|
||||
Wenn Sie [`uv`](https://github.com/astral-sh/uv) haben:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uv pip install "fastapi[standard]"
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
### Installation von `requirements.txt` { #install-from-requirements-txt }
|
||||
|
||||
Wenn Sie eine `requirements.txt` haben, können Sie diese nun verwenden, um deren Pakete zu installieren.
|
||||
|
||||
//// tab | `pip`
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install -r requirements.txt
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | `uv`
|
||||
|
||||
Wenn Sie [`uv`](https://github.com/astral-sh/uv) haben:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uv pip install -r requirements.txt
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
/// details | `requirements.txt`
|
||||
|
||||
Eine `requirements.txt` mit einigen Paketen könnte folgendermaßen aussehen:
|
||||
|
||||
```requirements.txt
|
||||
fastapi[standard]==0.113.0
|
||||
pydantic==2.8.0
|
||||
```
|
||||
|
||||
///
|
||||
|
||||
## Ihr Programm ausführen { #run-your-program }
|
||||
|
||||
Nachdem Sie die virtuelle Umgebung aktiviert haben, können Sie Ihr Programm ausführen, und es wird das Python innerhalb Ihrer virtuellen Umgebung mit den Paketen verwenden, die Sie dort installiert haben.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python main.py
|
||||
|
||||
Hello World
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## Ihren Editor konfigurieren { #configure-your-editor }
|
||||
|
||||
Sie würden wahrscheinlich einen Editor verwenden, stellen Sie sicher, dass Sie ihn so konfigurieren, dass er dieselbe virtuelle Umgebung verwendet, die Sie erstellt haben (er wird sie wahrscheinlich automatisch erkennen), sodass Sie Autovervollständigungen und Inline-Fehler erhalten können.
|
||||
|
||||
Zum Beispiel:
|
||||
|
||||
* [VS Code](https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment)
|
||||
* [PyCharm](https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html)
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Normalerweise müssen Sie dies nur **einmal** tun, wenn Sie die virtuelle Umgebung erstellen.
|
||||
|
||||
///
|
||||
|
||||
## Die virtuelle Umgebung deaktivieren { #deactivate-the-virtual-environment }
|
||||
|
||||
Sobald Sie mit der Arbeit an Ihrem Projekt fertig sind, können Sie die virtuelle Umgebung **deaktivieren**.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ deactivate
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Auf diese Weise, wenn Sie `python` ausführen, wird nicht versucht, es aus dieser virtuellen Umgebung mit den dort installierten Paketen auszuführen.
|
||||
|
||||
## Bereit zu arbeiten { #ready-to-work }
|
||||
|
||||
Jetzt sind Sie bereit, mit Ihrem Projekt zu arbeiten.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Möchten Sie verstehen, was das alles oben bedeutet?
|
||||
|
||||
Lesen Sie weiter. 👇🤓
|
||||
|
||||
///
|
||||
|
||||
## Warum virtuelle Umgebungen { #why-virtual-environments }
|
||||
|
||||
Um mit FastAPI zu arbeiten, müssen Sie [Python](https://www.python.org/) installieren.
|
||||
|
||||
Danach müssen Sie FastAPI und alle anderen Pakete, die Sie verwenden möchten, **installieren**.
|
||||
|
||||
Um Pakete zu installieren, würden Sie normalerweise den `pip`-Befehl verwenden, der mit Python geliefert wird (oder ähnliche Alternativen).
|
||||
|
||||
Wenn Sie jedoch `pip` direkt verwenden, werden die Pakete in Ihrer **globalen Python-Umgebung** (der globalen Installation von Python) installiert.
|
||||
|
||||
### Das Problem { #the-problem }
|
||||
|
||||
Was ist also das Problem beim Installieren von Paketen in der globalen Python-Umgebung?
|
||||
|
||||
Irgendwann werden Sie wahrscheinlich viele verschiedene Programme schreiben, die von **verschiedenen Paketen** abhängen. Und einige dieser Projekte, an denen Sie arbeiten, werden von **verschiedenen Versionen** desselben Pakets abhängen. 😱
|
||||
|
||||
Zum Beispiel könnten Sie ein Projekt namens `philosophers-stone` erstellen, dieses Programm hängt von einem anderen Paket namens **`harry`, Version `1`** ab. Also müssen Sie `harry` installieren.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
stone(philosophers-stone) -->|benötigt| harry-1[harry v1]
|
||||
```
|
||||
|
||||
Dann erstellen Sie zu einem späteren Zeitpunkt ein weiteres Projekt namens `prisoner-of-azkaban`, und dieses Projekt hängt ebenfalls von `harry` ab, aber dieses Projekt benötigt **`harry` Version `3`**.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
azkaban(prisoner-of-azkaban) --> |benötigt| harry-3[harry v3]
|
||||
```
|
||||
|
||||
Aber jetzt ist das Problem, wenn Sie die Pakete global (in der globalen Umgebung) installieren anstatt in einer lokalen **virtuellen Umgebung**, müssen Sie wählen, welche Version von `harry` zu installieren ist.
|
||||
|
||||
Wenn Sie `philosophers-stone` ausführen möchten, müssen Sie zuerst `harry` Version `1` installieren, zum Beispiel mit:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "harry==1"
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Und dann hätten Sie `harry` Version `1` in Ihrer globalen Python-Umgebung installiert.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph global[globale Umgebung]
|
||||
harry-1[harry v1]
|
||||
end
|
||||
subgraph stone-project[philosophers-stone-Projekt]
|
||||
stone(philosophers-stone) -->|benötigt| harry-1
|
||||
end
|
||||
```
|
||||
|
||||
Aber dann, wenn Sie `prisoner-of-azkaban` ausführen möchten, müssen Sie `harry` Version `1` deinstallieren und `harry` Version `3` installieren (oder einfach die Version `3` installieren, was die Version `1` automatisch deinstallieren würde).
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "harry==3"
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Und dann hätten Sie `harry` Version `3` in Ihrer globalen Python-Umgebung installiert.
|
||||
|
||||
Und wenn Sie versuchen, `philosophers-stone` erneut auszuführen, besteht die Möglichkeit, dass es **nicht funktioniert**, weil es `harry` Version `1` benötigt.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph global[globale Umgebung]
|
||||
harry-1[<strike>harry v1</strike>]
|
||||
style harry-1 fill:#ccc,stroke-dasharray: 5 5
|
||||
harry-3[harry v3]
|
||||
end
|
||||
subgraph stone-project[philosophers-stone-Projekt]
|
||||
stone(philosophers-stone) -.-x|⛔️| harry-1
|
||||
end
|
||||
subgraph azkaban-project[prisoner-of-azkaban-Projekt]
|
||||
azkaban(prisoner-of-azkaban) --> |benötigt| harry-3
|
||||
end
|
||||
```
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Es ist sehr üblich in Python-Paketen, alles zu versuchen, **Breaking Changes** in **neuen Versionen** zu vermeiden, aber es ist besser, auf Nummer sicher zu gehen und neue Versionen absichtlich zu installieren und wenn Sie die Tests ausführen können, sicherzustellen, dass alles korrekt funktioniert.
|
||||
|
||||
///
|
||||
|
||||
Stellen Sie sich das jetzt mit **vielen** anderen **Paketen** vor, von denen alle Ihre **Projekte abhängen**. Das ist sehr schwierig zu verwalten. Und Sie würden wahrscheinlich einige Projekte mit einigen **inkompatiblen Versionen** der Pakete ausführen und nicht wissen, warum etwas nicht funktioniert.
|
||||
|
||||
Darüber hinaus könnte es je nach Ihrem Betriebssystem (z. B. Linux, Windows, macOS) bereits mit installiertem Python geliefert worden sein. Und in diesem Fall hatte es wahrscheinlich einige Pakete mit bestimmten Versionen **installiert**, die von Ihrem System benötigt werden. Wenn Sie Pakete in der globalen Python-Umgebung installieren, könnten Sie einige der Programme, die mit Ihrem Betriebssystem geliefert wurden, **kaputtmachen**.
|
||||
|
||||
## Wo werden Pakete installiert { #where-are-packages-installed }
|
||||
|
||||
Wenn Sie Python installieren, werden einige Verzeichnisse mit einigen Dateien auf Ihrem Rechner erstellt.
|
||||
|
||||
Einige dieser Verzeichnisse sind dafür zuständig, alle Pakete, die Sie installieren, aufzunehmen.
|
||||
|
||||
Wenn Sie ausführen:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Führen Sie dies jetzt nicht aus, es ist nur ein Beispiel 🤓
|
||||
$ pip install "fastapi[standard]"
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Das lädt eine komprimierte Datei mit dem FastAPI-Code herunter, normalerweise von [PyPI](https://pypi.org/project/fastapi/).
|
||||
|
||||
Es wird auch Dateien für andere Pakete **herunterladen**, von denen FastAPI abhängt.
|
||||
|
||||
Dann wird es all diese Dateien **extrahieren** und sie in ein Verzeichnis auf Ihrem Rechner legen.
|
||||
|
||||
Standardmäßig werden diese heruntergeladenen und extrahierten Dateien in das Verzeichnis gelegt, das mit Ihrer Python-Installation kommt, das ist die **globale Umgebung**.
|
||||
|
||||
## Was sind virtuelle Umgebungen { #what-are-virtual-environments }
|
||||
|
||||
Die Lösung für die Probleme, alle Pakete in der globalen Umgebung zu haben, besteht darin, eine **virtuelle Umgebung für jedes Projekt** zu verwenden, an dem Sie arbeiten.
|
||||
|
||||
Eine virtuelle Umgebung ist ein **Verzeichnis**, sehr ähnlich zu dem globalen, in dem Sie die Pakete für ein Projekt installieren können.
|
||||
|
||||
Auf diese Weise hat jedes Projekt seine eigene virtuelle Umgebung (`.venv`-Verzeichnis) mit seinen eigenen Paketen.
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph stone-project[philosophers-stone-Projekt]
|
||||
stone(philosophers-stone) --->|benötigt| harry-1
|
||||
subgraph venv1[.venv]
|
||||
harry-1[harry v1]
|
||||
end
|
||||
end
|
||||
subgraph azkaban-project[prisoner-of-azkaban-Projekt]
|
||||
azkaban(prisoner-of-azkaban) --->|benötigt| harry-3
|
||||
subgraph venv2[.venv]
|
||||
harry-3[harry v3]
|
||||
end
|
||||
end
|
||||
stone-project ~~~ azkaban-project
|
||||
```
|
||||
|
||||
## Was bedeutet das Aktivieren einer virtuellen Umgebung { #what-does-activating-a-virtual-environment-mean }
|
||||
|
||||
Wenn Sie eine virtuelle Umgebung aktivieren, zum Beispiel mit:
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ source .venv/bin/activate
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ .venv\Scripts\Activate.ps1
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows Bash
|
||||
|
||||
Oder wenn Sie Bash für Windows verwenden (z. B. [Git Bash](https://gitforwindows.org/)):
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ source .venv/Scripts/activate
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
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.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Sie können mehr über die `PATH`-Umgebungsvariable im Abschnitt [Umgebungsvariablen](environment-variables.md#path-environment-variable) erfahren.
|
||||
|
||||
///
|
||||
|
||||
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:
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
```plaintext
|
||||
/usr/bin:/bin:/usr/sbin:/sbin
|
||||
```
|
||||
|
||||
Das bedeutet, dass das System nach Programmen sucht in:
|
||||
|
||||
* `/usr/bin`
|
||||
* `/bin`
|
||||
* `/usr/sbin`
|
||||
* `/sbin`
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows
|
||||
|
||||
```plaintext
|
||||
C:\Windows\System32
|
||||
```
|
||||
|
||||
Das bedeutet, dass das System nach Programmen sucht in:
|
||||
|
||||
* `C:\Windows\System32`
|
||||
|
||||
////
|
||||
|
||||
Nach dem Aktivieren der virtuellen Umgebung würde die `PATH`-Umgebungsvariable folgendermaßen aussehen:
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
```plaintext
|
||||
/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin
|
||||
```
|
||||
|
||||
Das bedeutet, dass das System nun zuerst nach Programmen sucht in:
|
||||
|
||||
```plaintext
|
||||
/home/user/code/awesome-project/.venv/bin
|
||||
```
|
||||
|
||||
bevor es in den anderen Verzeichnissen sucht.
|
||||
|
||||
Wenn Sie also `python` im Terminal eingeben, wird das System das Python-Programm in
|
||||
|
||||
```plaintext
|
||||
/home/user/code/awesome-project/.venv/bin/python
|
||||
```
|
||||
|
||||
finden und dieses verwenden.
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows
|
||||
|
||||
```plaintext
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32
|
||||
```
|
||||
|
||||
Das bedeutet, dass das System nun zuerst nach Programmen sucht in:
|
||||
|
||||
```plaintext
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts
|
||||
```
|
||||
|
||||
bevor es in den anderen Verzeichnissen sucht.
|
||||
|
||||
Wenn Sie also `python` im Terminal eingeben, wird das System das Python-Programm in
|
||||
|
||||
```plaintext
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts\python
|
||||
```
|
||||
|
||||
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).
|
||||
|
||||
Das Aktivieren einer virtuellen Umgebung ändert auch ein paar andere Dinge, aber dies ist eines der wichtigsten Dinge, die es tut.
|
||||
|
||||
## Testen einer virtuellen Umgebung { #checking-a-virtual-environment }
|
||||
|
||||
Wenn Sie testen, ob eine virtuelle Umgebung aktiv ist, zum Beispiel mit:
|
||||
|
||||
//// tab | Linux, macOS, Windows Bash
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ which python
|
||||
|
||||
/home/user/code/awesome-project/.venv/bin/python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ Get-Command python
|
||||
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts\python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
bedeutet das, dass das `python`-Programm, das verwendet wird, das in der **virtuellen Umgebung** ist.
|
||||
|
||||
Sie verwenden `which` auf Linux und macOS und `Get-Command` in Windows PowerShell.
|
||||
|
||||
So funktioniert dieser Befehl: Er wird in der `PATH`-Umgebungsvariable nachsehen und **jeden Pfad in der Reihenfolge durchgehen**, um das Programm namens `python` zu finden. Sobald er es findet, wird er Ihnen **den Pfad** zu diesem Programm anzeigen.
|
||||
|
||||
Der wichtigste Punkt ist, dass, wenn Sie `python` aufrufen, genau dieses „`python`“ ausgeführt wird.
|
||||
|
||||
So können Sie überprüfen, ob Sie sich in der richtigen virtuellen Umgebung befinden.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Es ist einfach, eine virtuelle Umgebung zu aktivieren, ein Python zu bekommen und dann **zu einem anderen Projekt zu wechseln**.
|
||||
|
||||
Und das zweite Projekt **würde nicht funktionieren**, weil Sie das **falsche Python** verwenden, aus einer virtuellen Umgebung für ein anderes Projekt.
|
||||
|
||||
Es ist nützlich, überprüfen zu können, welches `python` verwendet wird. 🤓
|
||||
|
||||
///
|
||||
|
||||
## Warum eine virtuelle Umgebung deaktivieren { #why-deactivate-a-virtual-environment }
|
||||
|
||||
Zum Beispiel könnten Sie an einem Projekt `philosophers-stone` arbeiten, diese virtuelle Umgebung **aktivieren**, Pakete installieren und mit dieser Umgebung arbeiten.
|
||||
|
||||
Und dann möchten Sie an **einem anderen Projekt** `prisoner-of-azkaban` arbeiten.
|
||||
|
||||
Sie gehen zu diesem Projekt:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ cd ~/code/prisoner-of-azkaban
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Wenn Sie die virtuelle Umgebung für `philosophers-stone` nicht deaktivieren, wird beim Ausführen von `python` im Terminal versucht, das Python von `philosophers-stone` zu verwenden.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ cd ~/code/prisoner-of-azkaban
|
||||
|
||||
$ python main.py
|
||||
|
||||
// Fehler beim Importieren von sirius, es ist nicht installiert 😱
|
||||
Traceback (most recent call last):
|
||||
File "main.py", line 1, in <module>
|
||||
import sirius
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Wenn Sie jedoch die virtuelle Umgebung deaktivieren und die neue für `prisoner-of-azkaban` aktivieren, wird beim Ausführen von `python` das Python aus der virtuellen Umgebung in `prisoner-of-azkaban` verwendet.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ cd ~/code/prisoner-of-azkaban
|
||||
|
||||
// Sie müssen nicht im alten Verzeichnis sein, um zu deaktivieren, Sie können dies überall tun, sogar nachdem Sie zum anderen Projekt gewechselt haben 😎
|
||||
$ deactivate
|
||||
|
||||
// Die virtuelle Umgebung in prisoner-of-azkaban/.venv 🚀 aktivieren
|
||||
$ source .venv/bin/activate
|
||||
|
||||
// Jetzt, wenn Sie python ausführen, wird das Paket sirius in dieser virtuellen Umgebung gefunden ✨
|
||||
$ python main.py
|
||||
|
||||
I solemnly swear 🐺
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## Alternativen { #alternatives }
|
||||
|
||||
Dies ist ein einfacher Leitfaden, um Ihnen den Einstieg zu erleichtern und Ihnen beizubringen, wie alles **unter der Haube** funktioniert.
|
||||
|
||||
Es gibt viele **Alternativen** zur Verwaltung von virtuellen Umgebungen, Paketabhängigkeiten (Anforderungen), Projekten.
|
||||
|
||||
Sobald Sie bereit sind und ein Tool verwenden möchten, das **das gesamte Projekt verwaltet**, Paketabhängigkeiten, virtuelle Umgebungen usw., würde ich Ihnen vorschlagen, [uv](https://github.com/astral-sh/uv) auszuprobieren.
|
||||
|
||||
`uv` kann viele Dinge tun, es kann:
|
||||
|
||||
* **Python für Sie installieren**, einschließlich verschiedener Versionen
|
||||
* Die **virtuelle Umgebung** für Ihre Projekte verwalten
|
||||
* **Pakete installieren**
|
||||
* Paket**abhängigkeiten und Versionen** für Ihr Projekt verwalten
|
||||
* Sicherstellen, dass Sie eine **exakte** Menge an Paketen und Versionen zur Installation haben, einschließlich ihrer Abhängigkeiten, damit Sie sicher sein können, dass Sie Ihr Projekt in der Produktionsumgebung genauso ausführen können wie auf Ihrem Rechner während der Entwicklung, dies wird **Locking** genannt
|
||||
* Und viele andere Dinge
|
||||
|
||||
## Fazit { #conclusion }
|
||||
|
||||
Wenn Sie das alles gelesen und verstanden haben, wissen Sie jetzt **viel mehr** über virtuelle Umgebungen als viele Entwickler da draußen. 🤓
|
||||
|
||||
Das Wissen über diese Details wird in Zukunft wahrscheinlich nützlich sein, wenn Sie etwas debuggen, das komplex erscheint, aber Sie werden wissen, **wie alles unter der Haube funktioniert**. 😎
|
||||
Lesen Sie den [Leitfaden zu virtuellen Umgebungen](https://tiangolo.com/guides/virtual-environments/), um zu erfahren, wie virtuelle Umgebungen unter der Haube funktionieren, einschließlich Aktivierung und dem alternativen `python -m venv`- und `pip`-Workflow.
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
tiangolo:
|
||||
login: tiangolo
|
||||
count: 961
|
||||
count: 1005
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
|
||||
url: https://github.com/tiangolo
|
||||
dependabot:
|
||||
login: dependabot
|
||||
count: 201
|
||||
count: 221
|
||||
avatarUrl: https://avatars.githubusercontent.com/in/29110?v=4
|
||||
url: https://github.com/apps/dependabot
|
||||
YuriiMotov:
|
||||
login: YuriiMotov
|
||||
count: 78
|
||||
count: 82
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=bc48be95c429989224786106b027f3c5e40cc354&v=4
|
||||
url: https://github.com/YuriiMotov
|
||||
alejsdev:
|
||||
login: alejsdev
|
||||
count: 56
|
||||
count: 57
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=0facffe3abf87f57a1f05fa773d1119cc5c2f6a5&v=4
|
||||
url: https://github.com/alejsdev
|
||||
pre-commit-ci:
|
||||
|
||||
+119
-149
@@ -11,9 +11,6 @@ sponsors:
|
||||
- login: coderabbitai
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/132028505?v=4
|
||||
url: https://github.com/coderabbitai
|
||||
- login: zuplo
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/85497839?v=4
|
||||
url: https://github.com/zuplo
|
||||
- login: blockbee-io
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/115143449?u=1b8620c2d6567c4df2111a371b85a51f448f9b85&v=4
|
||||
url: https://github.com/blockbee-io
|
||||
@@ -23,12 +20,12 @@ sponsors:
|
||||
- login: railwayapp
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/66716858?v=4
|
||||
url: https://github.com/railwayapp
|
||||
- - login: speakeasy-api
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/91446104?v=4
|
||||
url: https://github.com/speakeasy-api
|
||||
- login: stainless-api
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/88061651?v=4
|
||||
url: https://github.com/stainless-api
|
||||
- - login: dribia
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41189616?v=4
|
||||
url: https://github.com/dribia
|
||||
- login: BairesDev-LLC
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/133211198?u=c1462ade28fe251414bfedc28ce3f10242d44843&v=4
|
||||
url: https://github.com/BairesDev-LLC
|
||||
- login: svix
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/80175132?v=4
|
||||
url: https://github.com/svix
|
||||
@@ -38,19 +35,22 @@ sponsors:
|
||||
- login: databento
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/64141749?v=4
|
||||
url: https://github.com/databento
|
||||
- login: tutorcruncher
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3341959?v=4
|
||||
url: https://github.com/tutorcruncher
|
||||
- - login: LambdaTest-Inc
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/171592363?u=96606606a45fa170427206199014f2a5a2a4920b&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/171592363?u=080d9ba6069d0ff2a0558825ff2f667c45807687&v=4
|
||||
url: https://github.com/LambdaTest-Inc
|
||||
- login: Ponte-Energy-Partners
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/114745848?v=4
|
||||
url: https://github.com/Ponte-Energy-Partners
|
||||
- login: BoostryJP
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/57932412?v=4
|
||||
url: https://github.com/BoostryJP
|
||||
- login: acsone
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7601056?v=4
|
||||
url: https://github.com/acsone
|
||||
- - login: scalar
|
||||
- - login: manulife-ai
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/195145621?v=4
|
||||
url: https://github.com/manulife-ai
|
||||
- login: scalar
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/301879?v=4
|
||||
url: https://github.com/scalar
|
||||
- login: Trivie
|
||||
@@ -62,9 +62,6 @@ sponsors:
|
||||
- login: Doist
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2565372?v=4
|
||||
url: https://github.com/Doist
|
||||
- - login: mainframeindustries
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/55092103?v=4
|
||||
url: https://github.com/mainframeindustries
|
||||
- - login: alixlahuec
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/29543316?u=44357eb2a93bccf30fb9d389b8befe94a3d00985&v=4
|
||||
url: https://github.com/alixlahuec
|
||||
@@ -77,45 +74,45 @@ sponsors:
|
||||
- login: ChargeStorm
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/26000165?v=4
|
||||
url: https://github.com/ChargeStorm
|
||||
- login: ibrahimpelumi6142
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/113442282?v=4
|
||||
url: https://github.com/ibrahimpelumi6142
|
||||
- login: tltaylor1
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/234697691?u=f9bf860a7a6e1109b35f1eb930920bd37e3bf571&v=4
|
||||
url: https://github.com/tltaylor1
|
||||
- login: justoutofcuriosity
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/57193655?v=4
|
||||
url: https://github.com/justoutofcuriosity
|
||||
- login: nilslindemann
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4
|
||||
url: https://github.com/nilslindemann
|
||||
- - login: samuelcolvin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4039449?u=42eb3b833047c8c4b4f647a031eaef148c16d93f&v=4
|
||||
url: https://github.com/samuelcolvin
|
||||
- login: otosky
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/42260747?u=69d089387c743d89427aa4ad8740cfb34045a9e0&v=4
|
||||
url: https://github.com/otosky
|
||||
- login: ramonalmeidam
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/45269580?u=3358750b3a5854d7c3ed77aaca7dd20a0f529d32&v=4
|
||||
url: https://github.com/ramonalmeidam
|
||||
- login: roboflow
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/53104118?v=4
|
||||
url: https://github.com/roboflow
|
||||
- login: dudikbender
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/53487583?u=3a57542938ebfd57579a0111db2b297e606d9681&v=4
|
||||
url: https://github.com/dudikbender
|
||||
- login: ehaca
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25950317?u=cec1a3e0643b785288ae8260cc295a85ab344995&v=4
|
||||
url: https://github.com/ehaca
|
||||
- login: raphaellaude
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/28026311?u=91e1c00d9ac4f8045527e13de8050d504531cbc0&v=4
|
||||
url: https://github.com/raphaellaude
|
||||
- login: timlrx
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/28362229?u=9a745ca31372ee324af682715ae88ce8522f9094&v=4
|
||||
url: https://github.com/timlrx
|
||||
- login: otosky
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/42260747?u=69d089387c743d89427aa4ad8740cfb34045a9e0&v=4
|
||||
url: https://github.com/otosky
|
||||
- login: Leay15
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/32212558?u=c4aa9c1737e515959382a5515381757b1fd86c53&v=4
|
||||
url: https://github.com/Leay15
|
||||
- login: timlrx
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/28362229?u=9a745ca31372ee324af682715ae88ce8522f9094&v=4
|
||||
url: https://github.com/timlrx
|
||||
- login: ehaca
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25950317?u=cec1a3e0643b785288ae8260cc295a85ab344995&v=4
|
||||
url: https://github.com/ehaca
|
||||
- login: RaamEEIL
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/20320552?v=4
|
||||
url: https://github.com/RaamEEIL
|
||||
- login: ashi-agrawal
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/17105294?u=99c7a854035e5398d8e7b674f2d42baae6c957f8&v=4
|
||||
url: https://github.com/ashi-agrawal
|
||||
- login: jugeeem
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/116043716?u=ae590d79c38ac79c91b9c5caa6887d061e865a3d&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/116043716?u=e4df530e99a086a1085f3dc125b94783670fb383&v=4
|
||||
url: https://github.com/jugeeem
|
||||
- login: Karine-Bauch
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/90465103?u=7feb1018abb1a5631cfd9a91fea723d1ceb5f49b&v=4
|
||||
url: https://github.com/Karine-Bauch
|
||||
- login: Charisn
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/100683386?u=5a57e569b443a58cb34a32b6cb6ea12c783e14c1&v=4
|
||||
url: https://github.com/Charisn
|
||||
- login: kaoru0310
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/80977929?u=1b61d10142b490e56af932ddf08a390fae8ee94f&v=4
|
||||
url: https://github.com/kaoru0310
|
||||
@@ -128,20 +125,23 @@ sponsors:
|
||||
- login: anthonycepeda
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=60bdf46240cff8fca482ff0fc07d963fd5e1a27c&v=4
|
||||
url: https://github.com/anthonycepeda
|
||||
- login: AalbatrossGuy
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/68378354?u=0bdeea9356d24f638244131f6d8d1e2d2f3601ca&v=4
|
||||
url: https://github.com/AalbatrossGuy
|
||||
- login: PedroRuizCode
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/69810923?u=26f9b262922b724deacdfa16ccd5785d093ac371&v=4
|
||||
url: https://github.com/PedroRuizCode
|
||||
- login: patsatsia
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/61111267?u=3271b85f7a37b479c8d0ae0a235182e83c166edf&v=4
|
||||
url: https://github.com/patsatsia
|
||||
- login: oliverxchen
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4471774?u=534191f25e32eeaadda22dfab4b0a428733d5489&v=4
|
||||
url: https://github.com/oliverxchen
|
||||
- login: bradsward
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/60303274?u=6b74120e142c8bd4dae22edcf3ac6bb9c3b427bb&v=4
|
||||
url: https://github.com/bradsward
|
||||
- login: dudikbender
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/53487583?u=3a57542938ebfd57579a0111db2b297e606d9681&v=4
|
||||
url: https://github.com/dudikbender
|
||||
- login: jaredtrog
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4381365?v=4
|
||||
url: https://github.com/jaredtrog
|
||||
- login: Ryandaydev
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4292423?u=679ff84cb7b988c5795a5fa583857f574a055763&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4292423?u=87b1afc7f4fff933779959270e2d168339e91402&v=4
|
||||
url: https://github.com/Ryandaydev
|
||||
- login: gorhack
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4141690?u=ec119ebc4bdf00a7bc84657a71aa17834f4f27f3&v=4
|
||||
@@ -149,9 +149,6 @@ sponsors:
|
||||
- login: mj0331
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3890353?u=1c627ac1a024515b4871de5c3ebbfaa1a57f65d4&v=4
|
||||
url: https://github.com/mj0331
|
||||
- login: anomaly
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3654837?v=4
|
||||
url: https://github.com/anomaly
|
||||
- login: aacayaco
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3634801?u=eaadda178c964178fcb64886f6c732172c8f8219&v=4
|
||||
url: https://github.com/aacayaco
|
||||
@@ -170,36 +167,24 @@ sponsors:
|
||||
- login: dodo5522
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1362607?u=9bf1e0e520cccc547c046610c468ce6115bbcf9f&v=4
|
||||
url: https://github.com/dodo5522
|
||||
- login: mintuhouse
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/769950?u=ecfbd79a97d33177e0d093ddb088283cf7fe8444&v=4
|
||||
url: https://github.com/mintuhouse
|
||||
- login: falkben
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=ad9838e089058c9e5a0bab94c0eec7cc181e0cd0&v=4
|
||||
url: https://github.com/falkben
|
||||
- login: netsatan
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/955557?u=cb8fc0ae7f7b06807f0a58e335b1af96c9da0344&v=4
|
||||
url: https://github.com/netsatan
|
||||
- login: koxudaxi
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/630670?u=507d8577b4b3670546b449c4c2ccbc5af40d72f7&v=4
|
||||
url: https://github.com/koxudaxi
|
||||
- login: wshayes
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
|
||||
url: https://github.com/wshayes
|
||||
- login: pamelafox
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/297042?v=4
|
||||
url: https://github.com/pamelafox
|
||||
- login: robintw
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/296686?v=4
|
||||
url: https://github.com/robintw
|
||||
- login: jstanden
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/63288?u=c3658d57d2862c607a0e19c2101c3c51876e36ad&v=4
|
||||
url: https://github.com/jstanden
|
||||
- login: RaamEEIL
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/20320552?v=4
|
||||
url: https://github.com/RaamEEIL
|
||||
- login: ashi-agrawal
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/17105294?u=99c7a854035e5398d8e7b674f2d42baae6c957f8&v=4
|
||||
url: https://github.com/ashi-agrawal
|
||||
- login: mjohnsey
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16784016?u=38fad2e6b411244560b3af99c5f5a4751bc81865&v=4
|
||||
url: https://github.com/mjohnsey
|
||||
- login: cizekmilan
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/15999191?u=df194a9bf279f503bc96af41a35c0027eb94ad4f&v=4
|
||||
url: https://github.com/cizekmilan
|
||||
- login: khadrawy
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/13686061?u=59f25ef42ecf04c22657aac4238ce0e2d3d30304&v=4
|
||||
url: https://github.com/khadrawy
|
||||
@@ -221,63 +206,54 @@ sponsors:
|
||||
- login: FernandoCelmer
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6262214?u=58ba6d5888fa7f355934e52db19f950e20b38162&v=4
|
||||
url: https://github.com/FernandoCelmer
|
||||
- login: geodata-no
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5946299?v=4
|
||||
url: https://github.com/geodata-no
|
||||
- login: eseglem
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5920492?u=208d419cf667b8ac594c82a8db01932c7e50d057&v=4
|
||||
url: https://github.com/eseglem
|
||||
- login: ternaus
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5481618?u=513a26b02a39e7a28d587cd37c6cc877ea368e6e&v=4
|
||||
url: https://github.com/ternaus
|
||||
- - login: Artur-Galstyan
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/63471891?u=e8691f386037e51a737cc0ba866cd8c89e5cf109&v=4
|
||||
url: https://github.com/Artur-Galstyan
|
||||
- login: manoelpqueiroz
|
||||
- - login: jpfyoder
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7548821?u=1683290ed65dae6987d673da044067577ee71521&v=4
|
||||
url: https://github.com/jpfyoder
|
||||
- - login: manoelpqueiroz
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/23669137?u=b12e84b28a84369ab5b30bd5a79e5788df5a0756&v=4
|
||||
url: https://github.com/manoelpqueiroz
|
||||
- login: Artur-Galstyan
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/63471891?u=e8691f386037e51a737cc0ba866cd8c89e5cf109&v=4
|
||||
url: https://github.com/Artur-Galstyan
|
||||
- - login: pawamoy
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4
|
||||
url: https://github.com/pawamoy
|
||||
- login: siavashyj
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43583410?u=562005ddc7901cd27a1219a118a2363817b14977&v=4
|
||||
url: https://github.com/siavashyj
|
||||
- login: mobyw
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/44370805?v=4
|
||||
url: https://github.com/mobyw
|
||||
- login: ArtyomVancyan
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/44609997?v=4
|
||||
url: https://github.com/ArtyomVancyan
|
||||
- login: caviri
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/45425937?u=5f3d66ea5edea94c028c51ebf1c0f3b37e6c3db5&v=4
|
||||
url: https://github.com/caviri
|
||||
- login: hgalytoby
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/50397689?u=6cc9028f3db63f8f60ad21c17b1ce4b88c4e2e60&v=4
|
||||
url: https://github.com/hgalytoby
|
||||
- login: johnl28
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/54412955?u=47dd06082d1c39caa90c752eb55566e4f3813957&v=4
|
||||
url: https://github.com/johnl28
|
||||
- login: danielunderwood
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4472301?v=4
|
||||
url: https://github.com/danielunderwood
|
||||
- login: hoenie-ams
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25708487?u=cda07434f0509ac728d9edf5e681117c0f6b818b&v=4
|
||||
url: https://github.com/hoenie-ams
|
||||
- login: mobyw
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/44370805?v=4
|
||||
url: https://github.com/mobyw
|
||||
- login: siavashyj
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43583410?u=562005ddc7901cd27a1219a118a2363817b14977&v=4
|
||||
url: https://github.com/siavashyj
|
||||
- login: bnkc
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/34930566?u=888af82706afa36727feebce0e62225905926131&v=4
|
||||
url: https://github.com/bnkc
|
||||
- login: joerambo
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/26282974?v=4
|
||||
url: https://github.com/joerambo
|
||||
- login: engineerjoe440
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/33275230?u=eb223cad27017bb1e936ee9b429b450d092d0236&v=4
|
||||
url: https://github.com/engineerjoe440
|
||||
- login: bnkc
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/34930566?u=4771ac4e64066f0847d40e5b29910adabd9b2372&v=4
|
||||
url: https://github.com/bnkc
|
||||
- login: petercool
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/37613029?u=75aa8c6729e6e8f85a300561c4dbeef9d65c8797&v=4
|
||||
url: https://github.com/petercool
|
||||
- login: PelicanQ
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/77930606?v=4
|
||||
url: https://github.com/PelicanQ
|
||||
- login: PunRabbit
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/70463212?u=1a835cfbc99295a60c8282f6aa6199d1b42241a5&v=4
|
||||
url: https://github.com/PunRabbit
|
||||
- login: hoenie-ams
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25708487?u=cda07434f0509ac728d9edf5e681117c0f6b818b&v=4
|
||||
url: https://github.com/hoenie-ams
|
||||
- login: nisutec
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25281462?u=e562484c451fdfc59053163f64405f8eb262b8b0&v=4
|
||||
url: https://github.com/nisutec
|
||||
- login: joshuatz
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/17817563?u=f1bf05b690d1fc164218f0b420cdd3acb7913e21&v=4
|
||||
url: https://github.com/joshuatz
|
||||
- login: danielunderwood
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4472301?v=4
|
||||
url: https://github.com/danielunderwood
|
||||
- login: my3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1825270?v=4
|
||||
url: https://github.com/my3
|
||||
@@ -290,6 +266,9 @@ sponsors:
|
||||
- login: tochikuji
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/851759?v=4
|
||||
url: https://github.com/tochikuji
|
||||
- login: falkben
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=ad9838e089058c9e5a0bab94c0eec7cc181e0cd0&v=4
|
||||
url: https://github.com/falkben
|
||||
- login: ceb10n
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
|
||||
url: https://github.com/ceb10n
|
||||
@@ -302,39 +281,21 @@ sponsors:
|
||||
- login: ddanier
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/113563?u=ed1dc79de72f93bd78581f88ebc6952b62f472da&v=4
|
||||
url: https://github.com/ddanier
|
||||
- login: nisutec
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25281462?u=e562484c451fdfc59053163f64405f8eb262b8b0&v=4
|
||||
url: https://github.com/nisutec
|
||||
- login: joshuatz
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/17817563?u=f1bf05b690d1fc164218f0b420cdd3acb7913e21&v=4
|
||||
url: https://github.com/joshuatz
|
||||
- login: TheR1D
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16740832?u=b0dfdbdb27b79729430c71c6128962f77b7b53f7&v=4
|
||||
url: https://github.com/TheR1D
|
||||
- login: Zuzah
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10934846?u=1ef43e075ddc87bd1178372bf4d95ee6175cae27&v=4
|
||||
url: https://github.com/Zuzah
|
||||
- login: mntolia
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10390224?v=4
|
||||
url: https://github.com/mntolia
|
||||
- login: hard-coders
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=78d12d1acdf853c817700145e73de7fd9e5d068b&v=4
|
||||
url: https://github.com/hard-coders
|
||||
- login: DMantis
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9536869?u=652dd0d49717803c0cbcbf44f7740e53cf2d4892&v=4
|
||||
url: https://github.com/DMantis
|
||||
- login: xncbf
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=a80a7bb349555b277645632ed66639ff43400614&v=4
|
||||
url: https://github.com/xncbf
|
||||
- login: moonape1226
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8532038?u=d9f8b855a429fff9397c3833c2ff83849ebf989d&v=4
|
||||
url: https://github.com/moonape1226
|
||||
- login: harsh183
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7780198?v=4
|
||||
url: https://github.com/harsh183
|
||||
- login: katnoria
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7674948?u=09767eb13e07e09496c5fee4e5ce21d9eac34a56&v=4
|
||||
url: https://github.com/katnoria
|
||||
- login: KentShikama
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6329898?u=8b236810db9b96333230430837e1f021f9246da1&v=4
|
||||
url: https://github.com/KentShikama
|
||||
@@ -347,33 +308,33 @@ sponsors:
|
||||
- login: rangulvers
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5235430?u=e254d4af4ace5a05fa58372ae677c7d26f0d5a53&v=4
|
||||
url: https://github.com/rangulvers
|
||||
- - login: KOZ39
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/38822500?u=9dfc0a697df1c9628f08e20dc3fb17b1afc4e5a7&v=4
|
||||
url: https://github.com/KOZ39
|
||||
- login: rwxd
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/40308458?u=cd04a39e3655923be4f25c2ba8a5a07b3da3230a&v=4
|
||||
url: https://github.com/rwxd
|
||||
- - login: mohammadi-hadi
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/50410241?u=1137b5ff9ea8585c0192fe9ddb4ae5e21bc3d2e8&v=4
|
||||
url: https://github.com/mohammadi-hadi
|
||||
- login: morzan1001
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/47593005?u=c30ab7230f82a12a9b938dcb54f84a996931409a&v=4
|
||||
url: https://github.com/morzan1001
|
||||
- login: Olegt0rr
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25399456?u=3e87b5239a2f4600975ba13be73054f8567c6060&v=4
|
||||
url: https://github.com/Olegt0rr
|
||||
- login: larsyngvelundin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/34173819?u=74958599695bf83ac9f1addd935a51548a10c6b0&v=4
|
||||
url: https://github.com/larsyngvelundin
|
||||
- login: ArtyomVancyan
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/44609997?v=4
|
||||
url: https://github.com/ArtyomVancyan
|
||||
- login: rwxd
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/40308458?u=cd04a39e3655923be4f25c2ba8a5a07b3da3230a&v=4
|
||||
url: https://github.com/rwxd
|
||||
- login: KOZ39
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/38822500?u=9dfc0a697df1c9628f08e20dc3fb17b1afc4e5a7&v=4
|
||||
url: https://github.com/KOZ39
|
||||
- login: andrecorumba
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/37807517?u=9b9be3b41da9bda60957da9ef37b50dbf65baa61&v=4
|
||||
url: https://github.com/andrecorumba
|
||||
- login: CoderDeltaLAN
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/152043745?u=4ff541efffb7d134e60c5fcf2dd1e343f90bb782&v=4
|
||||
url: https://github.com/CoderDeltaLAN
|
||||
- login: hippoley
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/135493401?u=1164ef48a645a7c12664fabc1638fbb7e1c459b0&v=4
|
||||
url: https://github.com/hippoley
|
||||
- login: nayasinghania
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/74111380?u=752e99a5e139389fdc0a0677122adc08438eb076&v=4
|
||||
url: https://github.com/nayasinghania
|
||||
- login: Olegt0rr
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25399456?u=3e87b5239a2f4600975ba13be73054f8567c6060&v=4
|
||||
url: https://github.com/Olegt0rr
|
||||
- login: diogotoporcov
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/207575398?u=1fa7cf41b4181faa4d27f38bc37a374c17b5163b&v=4
|
||||
url: https://github.com/diogotoporcov
|
||||
- login: anandakrishnone
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/100110721?u=5d30e6fea1524bf3c8be3547027dbce59cc699af&v=4
|
||||
url: https://github.com/anandakrishnone
|
||||
- login: onestn
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/62360849?u=746dd21c34e7e06eefb11b03e8bb01aaae3c2a4f&v=4
|
||||
url: https://github.com/onestn
|
||||
@@ -383,6 +344,15 @@ sponsors:
|
||||
- login: andreagrandi
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/636391?u=13d90cb8ec313593a5b71fbd4e33b78d6da736f5&v=4
|
||||
url: https://github.com/andreagrandi
|
||||
- login: 0xsummerday
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/13888940?u=d0d45d5e2d7efd880a32d030fb222a51406c986f&v=4
|
||||
url: https://github.com/0xsummerday
|
||||
- login: xncbf
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=a80a7bb349555b277645632ed66639ff43400614&v=4
|
||||
url: https://github.com/xncbf
|
||||
- login: DaxServer
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7479937?u=cf2f97f958e47b209679d6aa2ad8723ef0d1cd0f&v=4
|
||||
url: https://github.com/DaxServer
|
||||
- login: msserpa
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6334934?u=82c4489eb1559d88d2990d60001901b14f722bbb&v=4
|
||||
url: https://github.com/msserpa
|
||||
|
||||
@@ -2,21 +2,21 @@ members:
|
||||
- login: tiangolo
|
||||
avatar_url: https://avatars.githubusercontent.com/u/1326112
|
||||
url: https://github.com/tiangolo
|
||||
- login: Kludex
|
||||
avatar_url: https://avatars.githubusercontent.com/u/7353520
|
||||
url: https://github.com/Kludex
|
||||
- login: alejsdev
|
||||
avatar_url: https://avatars.githubusercontent.com/u/90076947
|
||||
url: https://github.com/alejsdev
|
||||
- login: svlandeg
|
||||
avatar_url: https://avatars.githubusercontent.com/u/8796347
|
||||
url: https://github.com/svlandeg
|
||||
- login: YuriiMotov
|
||||
avatar_url: https://avatars.githubusercontent.com/u/109919500
|
||||
url: https://github.com/YuriiMotov
|
||||
- login: svlandeg
|
||||
avatar_url: https://avatars.githubusercontent.com/u/8796347
|
||||
url: https://github.com/svlandeg
|
||||
- login: alejsdev
|
||||
avatar_url: https://avatars.githubusercontent.com/u/90076947
|
||||
url: https://github.com/alejsdev
|
||||
- login: patrick91
|
||||
avatar_url: https://avatars.githubusercontent.com/u/667029
|
||||
url: https://github.com/patrick91
|
||||
- login: luzzodev
|
||||
avatar_url: https://avatars.githubusercontent.com/u/27291415
|
||||
url: https://github.com/luzzodev
|
||||
- login: Kludex
|
||||
avatar_url: https://avatars.githubusercontent.com/u/7353520
|
||||
url: https://github.com/Kludex
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user