Compare commits

..

2 Commits

Author SHA1 Message Date
github-actions[bot]
fd84e7418f 🎨 Auto format 2026-02-13 12:29:14 +00:00
Yurii Motov
dcc38d3f24 Update all 2026-02-13 13:26:04 +01:00
138 changed files with 1499 additions and 1303 deletions

View File

@@ -1,12 +1,12 @@
# 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 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.

View File

@@ -26,7 +26,7 @@ Jedes dieser Response-`dict`s kann einen Schlüssel `model` haben, welcher ein P
Um beispielsweise eine weitere Response mit dem Statuscode `404` und einem Pydantic-Modell `Message` zu deklarieren, können Sie schreiben:
{* ../../docs_src/additional_responses/tutorial001_py310.py hl[18,22] *}
{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *}
/// note | Hinweis
@@ -203,7 +203,7 @@ Sie können beispielsweise eine Response mit dem Statuscode `404` deklarieren, d
Und eine Response mit dem Statuscode `200`, die Ihr `response_model` verwendet, aber ein benutzerdefiniertes Beispiel (`example`) enthält:
{* ../../docs_src/additional_responses/tutorial003_py310.py hl[20:31] *}
{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *}
Es wird alles kombiniert und in Ihre OpenAPI eingebunden und in der API-Dokumentation angezeigt:

View File

@@ -18,7 +18,7 @@ Nicht die Klasse selbst (die bereits aufrufbar ist), sondern eine Instanz dieser
Dazu deklarieren wir eine Methode `__call__`:
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[12] *}
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[12] *}
In diesem Fall ist dieses `__call__` das, was **FastAPI** verwendet, um nach zusätzlichen Parametern und Unterabhängigkeiten zu suchen, und das ist es auch, was später aufgerufen wird, um einen Wert an den Parameter in Ihrer *Pfadoperation-Funktion* zu übergeben.
@@ -26,7 +26,7 @@ In diesem Fall ist dieses `__call__` das, was **FastAPI** verwendet, um nach zus
Und jetzt können wir `__init__` verwenden, um die Parameter der Instanz zu deklarieren, die wir zum „Parametrisieren“ der Abhängigkeit verwenden können:
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[9] *}
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[9] *}
In diesem Fall wird **FastAPI** `__init__` nie berühren oder sich darum kümmern, wir werden es direkt in unserem Code verwenden.
@@ -34,7 +34,7 @@ In diesem Fall wird **FastAPI** `__init__` nie berühren oder sich darum kümmer
Wir könnten eine Instanz dieser Klasse erstellen mit:
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[18] *}
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[18] *}
Und auf diese Weise können wir unsere Abhängigkeit „parametrisieren“, die jetzt `"bar"` enthält, als das Attribut `checker.fixed_content`.
@@ -50,7 +50,7 @@ checker(q="somequery")
... und übergibt, was immer das als Wert dieser Abhängigkeit in unserer *Pfadoperation-Funktion* zurückgibt, als den Parameter `fixed_content_included`:
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[22] *}
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[22] *}
/// tip | Tipp

View File

@@ -1,61 +0,0 @@
# Fortgeschrittene Python-Typen { #advanced-python-types }
Hier sind einige zusätzliche Ideen, die beim Arbeiten mit Python-Typen nützlich sein könnten.
## `Union` oder `Optional` verwenden { #using-union-or-optional }
Wenn Ihr Code aus irgendeinem Grund nicht `|` verwenden kann, z. B. wenn es nicht in einer Typannotation ist, sondern in etwas wie `response_model=`, können Sie anstelle des senkrechten Strichs (`|`) `Union` aus `typing` verwenden.
Zum Beispiel könnten Sie deklarieren, dass etwas ein `str` oder `None` sein könnte:
```python
from typing import Union
def say_hi(name: Union[str, None]):
print(f"Hi {name}!")
```
`typing` hat außerdem eine Abkürzung, um zu deklarieren, dass etwas `None` sein könnte, mit `Optional`.
Hier ist ein Tipp aus meiner sehr **subjektiven** Perspektive:
* 🚨 Vermeiden Sie die Verwendung von `Optional[SomeType]`
* Verwenden Sie stattdessen ✨ **`Union[SomeType, None]`** ✨.
Beides ist äquivalent und unter der Haube identisch, aber ich würde `Union` statt `Optional` empfehlen, weil das Wort „**optional**“ implizieren könnte, dass der Wert optional ist; tatsächlich bedeutet es jedoch „es kann `None` sein“, selbst wenn es nicht optional ist und weiterhin erforderlich bleibt.
Ich finde, `Union[SomeType, None]` ist expliziter in dem, was es bedeutet.
Es geht nur um Wörter und Namen. Aber diese Wörter können beeinflussen, wie Sie und Ihr Team über den Code denken.
Als Beispiel nehmen wir diese Funktion:
```python
from typing import Optional
def say_hi(name: Optional[str]):
print(f"Hey {name}!")
```
Der Parameter `name` ist als `Optional[str]` definiert, aber er ist **nicht optional**, Sie können die Funktion nicht ohne den Parameter aufrufen:
```Python
say_hi() # Oh nein, das löst einen Fehler aus! 😱
```
Der Parameter `name` ist **weiterhin erforderlich** (nicht *optional*), weil er keinen Defaultwert hat. Dennoch akzeptiert `name` den Wert `None`:
```Python
say_hi(name=None) # Das funktioniert, None ist gültig 🎉
```
Die gute Nachricht ist: In den meisten Fällen können Sie einfach `|` verwenden, um Unions von Typen zu definieren:
```python
def say_hi(name: str | None):
print(f"Hey {name}!")
```
Sie müssen sich also normalerweise keine Gedanken über Namen wie `Optional` und `Union` machen. 😎

View File

@@ -32,11 +32,11 @@ Betrachten wir als einfaches Beispiel eine Dateistruktur ähnlich der in [Größ
Die Datei `main.py` hätte als Inhalt:
{* ../../docs_src/async_tests/app_a_py310/main.py *}
{* ../../docs_src/async_tests/app_a_py39/main.py *}
Die Datei `test_main.py` hätte die Tests für `main.py`, das könnte jetzt so aussehen:
{* ../../docs_src/async_tests/app_a_py310/test_main.py *}
{* ../../docs_src/async_tests/app_a_py39/test_main.py *}
## Es ausführen { #run-it }
@@ -56,7 +56,7 @@ $ pytest
Der Marker `@pytest.mark.anyio` teilt pytest mit, dass diese Testfunktion asynchron aufgerufen werden soll:
{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[7] *}
{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[7] *}
/// tip | Tipp
@@ -66,7 +66,7 @@ Beachten Sie, dass die Testfunktion jetzt `async def` ist und nicht nur `def` wi
Dann können wir einen `AsyncClient` mit der App erstellen und mit `await` asynchrone Requests an ihn senden.
{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[9:12] *}
{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[9:12] *}
Das ist das Äquivalent zu:

View File

@@ -44,7 +44,7 @@ $ fastapi run --forwarded-allow-ips="*"
Angenommen, Sie definieren eine *Pfadoperation* `/items/`:
{* ../../docs_src/behind_a_proxy/tutorial001_01_py310.py hl[6] *}
{* ../../docs_src/behind_a_proxy/tutorial001_01_py39.py hl[6] *}
Wenn der Client versucht, zu `/items` zu gehen, würde er standardmäßig zu `/items/` umgeleitet.
@@ -115,7 +115,7 @@ In diesem Fall würde der ursprüngliche Pfad `/app` tatsächlich unter `/api/v1
Auch wenn Ihr gesamter Code unter der Annahme geschrieben ist, dass es nur `/app` gibt.
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[6] *}
{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[6] *}
Und der Proxy würde das **Pfadpräfix** on-the-fly **„entfernen“**, bevor er den <abbr title="Request Anfrage: Daten, die der Client zum Server sendet">Request</abbr> an den Anwendungsserver (wahrscheinlich Uvicorn via FastAPI CLI) übermittelt, dafür sorgend, dass Ihre Anwendung davon überzeugt ist, dass sie unter `/app` bereitgestellt wird, sodass Sie nicht Ihren gesamten Code dahingehend aktualisieren müssen, das Präfix `/api/v1` zu verwenden.
@@ -193,7 +193,7 @@ Sie können den aktuellen `root_path` abrufen, der von Ihrer Anwendung für jede
Hier fügen wir ihn, nur zu Demonstrationszwecken, in die Nachricht ein.
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[8] *}
{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[8] *}
Wenn Sie Uvicorn dann starten mit:
@@ -220,7 +220,7 @@ wäre die <abbr title="Response Antwort: Daten, die der Server zum anfragend
Falls Sie keine Möglichkeit haben, eine Kommandozeilenoption wie `--root-path` oder ähnlich zu übergeben, können Sie, alternativ dazu, beim Erstellen Ihrer FastAPI-Anwendung den Parameter `root_path` setzen:
{* ../../docs_src/behind_a_proxy/tutorial002_py310.py hl[3] *}
{* ../../docs_src/behind_a_proxy/tutorial002_py39.py hl[3] *}
Die Übergabe des `root_path` an `FastAPI` wäre das Äquivalent zur Übergabe der `--root-path`-Kommandozeilenoption an Uvicorn oder Hypercorn.
@@ -400,7 +400,7 @@ Wenn Sie eine benutzerdefinierte Liste von Servern (`servers`) übergeben und es
Zum Beispiel:
{* ../../docs_src/behind_a_proxy/tutorial003_py310.py hl[4:7] *}
{* ../../docs_src/behind_a_proxy/tutorial003_py39.py hl[4:7] *}
Erzeugt ein OpenAPI-Schema, wie:
@@ -455,7 +455,7 @@ Wenn Sie den Parameter `servers` nicht angeben und `root_path` den Wert `/` hat,
Wenn Sie nicht möchten, dass **FastAPI** einen automatischen Server inkludiert, welcher `root_path` verwendet, können Sie den Parameter `root_path_in_servers=False` verwenden:
{* ../../docs_src/behind_a_proxy/tutorial004_py310.py hl[9] *}
{* ../../docs_src/behind_a_proxy/tutorial004_py39.py hl[9] *}
Dann wird er nicht in das OpenAPI-Schema aufgenommen.

View File

@@ -30,7 +30,7 @@ Das liegt daran, dass FastAPI standardmäßig jedes enthaltene Element überprü
Wenn Sie jedoch sicher sind, dass der von Ihnen zurückgegebene Inhalt **mit JSON serialisierbar** ist, können Sie ihn direkt an die Response-Klasse übergeben und die zusätzliche Arbeit vermeiden, die FastAPI hätte, indem es Ihren zurückgegebenen Inhalt durch den `jsonable_encoder` leitet, bevor es ihn an die Response-Klasse übergibt.
{* ../../docs_src/custom_response/tutorial001b_py310.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *}
/// info | Info
@@ -55,7 +55,7 @@ Um eine Response mit HTML direkt von **FastAPI** zurückzugeben, verwenden Sie `
* Importieren Sie `HTMLResponse`.
* Übergeben Sie `HTMLResponse` als den Parameter `response_class` Ihres *Pfadoperation-Dekorators*.
{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *}
/// info | Info
@@ -73,7 +73,7 @@ Wie in [Eine Response direkt zurückgeben](response-directly.md){.internal-link
Das gleiche Beispiel von oben, das eine `HTMLResponse` zurückgibt, könnte so aussehen:
{* ../../docs_src/custom_response/tutorial003_py310.py hl[2,7,19] *}
{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *}
/// warning | Achtung
@@ -97,7 +97,7 @@ Die `response_class` wird dann nur zur Dokumentation der OpenAPI-*Pfadoperation*
Es könnte zum Beispiel so etwas sein:
{* ../../docs_src/custom_response/tutorial004_py310.py hl[7,21,23] *}
{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *}
In diesem Beispiel generiert die Funktion `generate_html_response()` bereits eine `Response` und gibt sie zurück, anstatt das HTML in einem `str` zurückzugeben.
@@ -136,7 +136,7 @@ Sie akzeptiert die folgenden Parameter:
FastAPI (eigentlich Starlette) fügt automatisch einen Content-Length-Header ein. Außerdem wird es einen Content-Type-Header einfügen, der auf dem media_type basiert, und für Texttypen einen Zeichensatz (charset) anfügen.
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
### `HTMLResponse` { #htmlresponse }
@@ -146,7 +146,7 @@ Nimmt Text oder Bytes entgegen und gibt eine HTML-Response zurück, wie Sie oben
Nimmt Text oder Bytes entgegen und gibt eine Plain-Text-Response zurück.
{* ../../docs_src/custom_response/tutorial005_py310.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *}
### `JSONResponse` { #jsonresponse }
@@ -180,7 +180,7 @@ Dazu muss `ujson` installiert werden, z. B. mit `pip install ujson`.
///
{* ../../docs_src/custom_response/tutorial001_py310.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *}
/// tip | Tipp
@@ -194,13 +194,13 @@ Gibt eine HTTP-Weiterleitung (HTTP-Redirect) zurück. Verwendet standardmäßig
Sie können eine `RedirectResponse` direkt zurückgeben:
{* ../../docs_src/custom_response/tutorial006_py310.py hl[2,9] *}
{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
---
Oder Sie können sie im Parameter `response_class` verwenden:
{* ../../docs_src/custom_response/tutorial006b_py310.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}
Wenn Sie das tun, können Sie die URL direkt von Ihrer *Pfadoperation*-Funktion zurückgeben.
@@ -210,13 +210,13 @@ In diesem Fall ist der verwendete `status_code` der Standardcode für die `Redir
Sie können den Parameter `status_code` auch in Kombination mit dem Parameter `response_class` verwenden:
{* ../../docs_src/custom_response/tutorial006c_py310.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}
### `StreamingResponse` { #streamingresponse }
Nimmt einen asynchronen Generator oder einen normalen Generator/Iterator und streamt den Responsebody.
{* ../../docs_src/custom_response/tutorial007_py310.py hl[2,14] *}
{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *}
#### Verwendung von `StreamingResponse` mit dateiartigen Objekten { #using-streamingresponse-with-file-like-objects }
@@ -226,7 +226,7 @@ Auf diese Weise müssen Sie nicht alles zuerst in den Arbeitsspeicher lesen und
Das umfasst viele Bibliotheken zur Interaktion mit Cloud-Speicher, Videoverarbeitung und anderen.
{* ../../docs_src/custom_response/tutorial008_py310.py hl[2,10:12,14] *}
{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *}
1. Das ist die Generatorfunktion. Es handelt sich um eine „Generatorfunktion“, da sie `yield`-Anweisungen enthält.
2. Durch die Verwendung eines `with`-Blocks stellen wir sicher, dass das dateiartige Objekt geschlossen wird, nachdem die Generatorfunktion fertig ist. Also, nachdem sie mit dem Senden der Response fertig ist.
@@ -255,11 +255,11 @@ Nimmt zur Instanziierung einen anderen Satz von Argumenten entgegen als die ande
Datei-Responses enthalten die entsprechenden `Content-Length`-, `Last-Modified`- und `ETag`-Header.
{* ../../docs_src/custom_response/tutorial009_py310.py hl[2,10] *}
{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
Sie können auch den Parameter `response_class` verwenden:
{* ../../docs_src/custom_response/tutorial009b_py310.py hl[2,8,10] *}
{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}
In diesem Fall können Sie den Dateipfad direkt von Ihrer *Pfadoperation*-Funktion zurückgeben.
@@ -273,7 +273,7 @@ Sie möchten etwa, dass Ihre Response eingerücktes und formatiertes JSON zurüc
Sie könnten eine `CustomORJSONResponse` erstellen. Das Wichtigste, was Sie tun müssen, ist, eine `Response.render(content)`-Methode zu erstellen, die den Inhalt als `bytes` zurückgibt:
{* ../../docs_src/custom_response/tutorial009c_py310.py hl[9:14,17] *}
{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *}
Statt:
@@ -299,7 +299,7 @@ Der Parameter, der das definiert, ist `default_response_class`.
Im folgenden Beispiel verwendet **FastAPI** standardmäßig `ORJSONResponse` in allen *Pfadoperationen*, anstelle von `JSONResponse`.
{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}
{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
/// tip | Tipp

View File

@@ -1,4 +1,4 @@
# Datenklassen verwenden { #using-dataclasses }
# Verwendung von Datenklassen { #using-dataclasses }
FastAPI basiert auf **Pydantic**, und ich habe Ihnen gezeigt, wie Sie Pydantic-Modelle verwenden können, um <abbr title="Request Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> und <abbr title="Response Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Responses</abbr> zu deklarieren.
@@ -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 <abbr title="Konvertieren der Daten in ein übertragbares Format">serialisieren</abbr>.
7. Hier verwendet das `response_model` als Typannotation eine Liste von `Author`-Datenklassen.

View File

@@ -30,7 +30,7 @@ Beginnen wir mit einem Beispiel und sehen es uns dann im Detail an.
Wir erstellen eine asynchrone Funktion `lifespan()` mit `yield` wie folgt:
{* ../../docs_src/events/tutorial003_py310.py hl[16,19] *}
{* ../../docs_src/events/tutorial003_py39.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*.
@@ -48,7 +48,7 @@ Möglicherweise müssen Sie eine neue Version starten, oder Sie haben es einfach
Das Erste, was auffällt, ist, dass wir eine asynchrone Funktion mit `yield` definieren. Das ist sehr ähnlich zu Abhängigkeiten mit `yield`.
{* ../../docs_src/events/tutorial003_py310.py hl[14:19] *}
{* ../../docs_src/events/tutorial003_py39.py hl[14:19] *}
Der erste Teil der Funktion, vor dem `yield`, wird ausgeführt **bevor** die Anwendung startet.
@@ -60,7 +60,7 @@ Wie Sie sehen, ist die Funktion mit einem `@asynccontextmanager` versehen.
Dadurch wird die Funktion in einen sogenannten „**asynchronen Kontextmanager**“ umgewandelt.
{* ../../docs_src/events/tutorial003_py310.py hl[1,13] *}
{* ../../docs_src/events/tutorial003_py39.py hl[1,13] *}
Ein **Kontextmanager** in Python ist etwas, das Sie in einer `with`-Anweisung verwenden können, zum Beispiel kann `open()` als Kontextmanager verwendet werden:
@@ -82,7 +82,7 @@ In unserem obigen Codebeispiel verwenden wir ihn nicht direkt, sondern übergebe
Der Parameter `lifespan` der `FastAPI`-App benötigt einen **asynchronen Kontextmanager**, wir können ihm also unseren neuen asynchronen Kontextmanager `lifespan` übergeben.
{* ../../docs_src/events/tutorial003_py310.py hl[22] *}
{* ../../docs_src/events/tutorial003_py39.py hl[22] *}
## Alternative Events (<abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr>) { #alternative-events-deprecated }
@@ -104,7 +104,7 @@ Diese Funktionen können mit `async def` oder normalem `def` deklariert werden.
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] *}
{* ../../docs_src/events/tutorial001_py39.py hl[8] *}
In diesem Fall initialisiert die Eventhandler-Funktion `startup` die „Datenbank“ der Items (nur ein `dict`) mit einigen Werten.
@@ -116,7 +116,7 @@ Und Ihre Anwendung empfängt erst dann Requests, wenn alle `startup`-Eventhandle
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] *}
{* ../../docs_src/events/tutorial002_py39.py hl[6] *}
Hier schreibt die `shutdown`-Eventhandler-Funktion eine Textzeile `"Application shutdown"` in eine Datei `log.txt`.

View File

@@ -2,7 +2,7 @@
Da **FastAPI** auf der **OpenAPI**-Spezifikation basiert, können dessen APIs in einem standardisierten Format beschrieben werden, das viele Tools verstehen.
Dies vereinfacht es, aktuelle **Dokumentation** und Client-Bibliotheken (<abbr title="Software Development Kits - Software-Entwicklungspakete">**SDKs**</abbr>) in verschiedenen Sprachen zu generieren sowie **Test-** oder **Automatisierungs-Workflows**, die mit Ihrem Code synchron bleiben.
Dies vereinfacht es, aktuelle **Dokumentation** und Client-Bibliotheken (<abbr title="Software Development Kit Software-Entwicklungspaket">**SDKs**</abbr>) in verschiedenen Sprachen zu generieren sowie **Test-** oder **Automatisierungs-Workflows**, die mit Ihrem Code synchron bleiben.
In diesem Leitfaden erfahren Sie, wie Sie ein **TypeScript-SDK** für Ihr FastAPI-Backend generieren.
@@ -40,7 +40,7 @@ Einige dieser Lösungen sind möglicherweise auch Open Source oder bieten kosten
Beginnen wir mit einer einfachen FastAPI-Anwendung:
{* ../../docs_src/generate_clients/tutorial001_py310.py hl[7:9,12:13,16:17,21] *}
{* ../../docs_src/generate_clients/tutorial001_py39.py hl[7:9,12:13,16:17,21] *}
Beachten Sie, dass die *Pfadoperationen* die Modelle definieren, die sie für die <abbr title="Request Anfrage: Daten, die der Client zum Server sendet">Request</abbr>- und <abbr title="Response Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>-<abbr title="Die eigentlichen Nutzdaten, abzüglich der Metadaten">Payload</abbr> verwenden, indem sie die Modelle `Item` und `ResponseMessage` verwenden.
@@ -98,7 +98,7 @@ In vielen Fällen wird Ihre FastAPI-App größer sein und Sie werden wahrscheinl
Zum Beispiel könnten Sie einen Abschnitt für **Items (Artikel)** und einen weiteren Abschnitt für **Users (Benutzer)** haben, und diese könnten durch Tags getrennt sein:
{* ../../docs_src/generate_clients/tutorial002_py310.py hl[21,26,34] *}
{* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *}
### Einen TypeScript-Client mit Tags generieren { #generate-a-typescript-client-with-tags }
@@ -145,7 +145,7 @@ Hier verwendet sie beispielsweise den ersten Tag (Sie werden wahrscheinlich nur
Anschließend können Sie diese benutzerdefinierte Funktion als `generate_unique_id_function`-Parameter an **FastAPI** übergeben:
{* ../../docs_src/generate_clients/tutorial003_py310.py hl[6:7,10] *}
{* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *}
### Einen TypeScript-Client mit benutzerdefinierten Operation-IDs generieren { #generate-a-typescript-client-with-custom-operation-ids }
@@ -167,7 +167,7 @@ Aber für den generierten Client könnten wir die OpenAPI-Operation-IDs direkt v
Wir könnten das OpenAPI-JSON in eine Datei `openapi.json` herunterladen und dann mit einem Skript wie dem folgenden **den präfixierten Tag entfernen**:
{* ../../docs_src/generate_clients/tutorial004_py310.py *}
{* ../../docs_src/generate_clients/tutorial004_py39.py *}
//// tab | Node.js
@@ -179,7 +179,7 @@ Wir könnten das OpenAPI-JSON in eine Datei `openapi.json` herunterladen und dan
Damit würden die Operation-IDs von Dingen wie `items-get_items` in `get_items` umbenannt, sodass der Client-Generator einfachere Methodennamen generieren kann.
### Einen TypeScript-Client mit der vorverarbeiteten OpenAPI generieren { #generate-a-typescript-client-with-the-preprocessed-openapi }
### Einen TypeScript-Client mit der modifizierten OpenAPI generieren { #generate-a-typescript-client-with-the-preprocessed-openapi }
Da das Endergebnis nun in einer `openapi.json`-Datei vorliegt, müssen Sie Ihren Eingabeort aktualisieren:

View File

@@ -57,13 +57,13 @@ Erzwingt, dass alle eingehenden <abbr title="Request Anfrage: Daten, die der
Alle eingehenden Requests an `http` oder `ws` werden stattdessen an das sichere Schema umgeleitet.
{* ../../docs_src/advanced_middleware/tutorial001_py310.py hl[2,6] *}
{* ../../docs_src/advanced_middleware/tutorial001_py39.py hl[2,6] *}
## `TrustedHostMiddleware` { #trustedhostmiddleware }
Erzwingt, dass alle eingehenden Requests einen korrekt gesetzten `Host`-Header haben, um sich vor HTTP-Host-Header-Angriffen zu schützen.
{* ../../docs_src/advanced_middleware/tutorial002_py310.py hl[2,6:8] *}
{* ../../docs_src/advanced_middleware/tutorial002_py39.py hl[2,6:8] *}
Die folgenden Argumente werden unterstützt:
@@ -74,11 +74,11 @@ 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.
{* ../../docs_src/advanced_middleware/tutorial003_py310.py hl[2,6] *}
{* ../../docs_src/advanced_middleware/tutorial003_py39.py hl[2,6] *}
Die folgenden Argumente werden unterstützt:

View File

@@ -8,7 +8,7 @@ Das wird normalerweise als **Web<abbr title="Haken, Einhängepunkt">hook</abbr>*
## Webhooks-Schritte { #webhooks-steps }
Der Prozess besteht normalerweise darin, dass **Sie in Ihrem Code definieren**, welche Nachricht Sie senden möchten, den **Requestbody**.
Der Prozess besteht normalerweise darin, dass **Sie in Ihrem Code definieren**, welche Nachricht Sie senden möchten, den **Body des Requests**.
Sie definieren auch auf irgendeine Weise, in welchen **Momenten** Ihre App diese Requests oder Events senden wird.
@@ -18,7 +18,7 @@ Die gesamte **Logik** zur Registrierung der URLs für Webhooks und der Code zum
## Webhooks mit **FastAPI** und OpenAPI dokumentieren { #documenting-webhooks-with-fastapi-and-openapi }
Mit **FastAPI**, mithilfe von OpenAPI, können Sie die Namen dieser Webhooks, die Arten von HTTP-Operationen, die Ihre App senden kann (z. B. `POST`, `PUT`, usw.) und die **Requestbodys** definieren, die Ihre App senden würde.
Mit **FastAPI**, mithilfe von OpenAPI, können Sie die Namen dieser Webhooks, die Arten von HTTP-Operationen, die Ihre App senden kann (z. B. `POST`, `PUT`, usw.) und die Request**bodys** definieren, die Ihre App senden würde.
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.
@@ -32,7 +32,7 @@ Webhooks sind in OpenAPI 3.1.0 und höher verfügbar und werden von FastAPI `0.9
Wenn Sie eine **FastAPI**-Anwendung erstellen, gibt es ein `webhooks`-Attribut, das Sie verwenden können, um *Webhooks* zu definieren, genauso wie Sie *Pfadoperationen* definieren würden, zum Beispiel mit `@app.webhooks.post()`.
{* ../../docs_src/openapi_webhooks/tutorial001_py310.py hl[9:12,15:20] *}
{* ../../docs_src/openapi_webhooks/tutorial001_py39.py hl[9:13,36:53] *}
Die von Ihnen definierten Webhooks landen im **OpenAPI**-Schema und der automatischen **Dokumentations-Oberfläche**.

View File

@@ -12,7 +12,7 @@ Mit dem Parameter `operation_id` können Sie die OpenAPI `operationId` festlegen
Sie müssten sicherstellen, dass sie für jede Operation eindeutig ist.
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py310.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
### Verwendung des Namens der *Pfadoperation-Funktion* als operationId { #using-the-path-operation-function-name-as-the-operationid }
@@ -20,7 +20,7 @@ Wenn Sie die Funktionsnamen Ihrer API als `operationId`s verwenden möchten, kö
Sie sollten dies tun, nachdem Sie alle Ihre *Pfadoperationen* hinzugefügt haben.
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2, 12:21, 24] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
/// tip | Tipp
@@ -40,7 +40,7 @@ Auch wenn diese sich in unterschiedlichen Modulen (Python-Dateien) befinden.
Um eine *Pfadoperation* aus dem generierten OpenAPI-Schema (und damit aus den automatischen Dokumentationssystemen) auszuschließen, verwenden Sie den Parameter `include_in_schema` und setzen Sie ihn auf `False`:
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py310.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
## Fortgeschrittene Beschreibung mittels Docstring { #advanced-description-from-docstring }
@@ -92,7 +92,7 @@ Sie können das OpenAPI-Schema für eine *Pfadoperation* erweitern, indem Sie de
Dieses `openapi_extra` kann beispielsweise hilfreich sein, um [OpenAPI-Erweiterungen](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions) zu deklarieren:
{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py310.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *}
Wenn Sie die automatische API-Dokumentation öffnen, wird Ihre Erweiterung am Ende der spezifischen *Pfadoperation* angezeigt.
@@ -135,13 +135,13 @@ Das <abbr title="Dictionary Zuordnungstabelle: In anderen Sprachen auch Hash
Sie können dem automatisch generierten Schema also zusätzliche Daten hinzufügen.
Sie könnten sich beispielsweise dafür entscheiden, den <abbr title="Request Anfrage: Daten, die der Client zum Server sendet">Request</abbr> mit Ihrem eigenen Code zu lesen und zu validieren, ohne FastAPIs automatische Funktionen mit Pydantic zu verwenden, aber Sie könnten den Request trotzdem im OpenAPI-Schema definieren wollen.
Sie könnten sich beispielsweise dafür entscheiden, den <abbr title="Request Anfrage: Daten, die der Client zum Server sendet">Request</abbr> mit Ihrem eigenen Code zu lesen und zu validieren, ohne die automatischen Funktionen von FastAPI mit Pydantic zu verwenden, aber Sie könnten den Request trotzdem im OpenAPI-Schema definieren wollen.
Das könnte man mit `openapi_extra` machen:
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py310.py hl[19:36, 39:40] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
In diesem Beispiel haben wir kein Pydantic-Modell deklariert. Tatsächlich wird der Requestbody nicht einmal als JSON <dfn title="von einem einfachen Format, wie Bytes, in Python-Objekte konvertiert">geparst</dfn>, sondern direkt als `bytes` gelesen und die Funktion `magic_data_reader()` wäre dafür verantwortlich, ihn in irgendeiner Weise zu parsen.
In diesem Beispiel haben wir kein Pydantic-Modell deklariert. Tatsächlich wird der Requestbody nicht einmal als JSON <abbr title="von einem einfachen Format, wie Bytes, in Python-Objekte konvertieren">geparst</abbr>, sondern direkt als `bytes` gelesen und die Funktion `magic_data_reader()` wäre dafür verantwortlich, ihn in irgendeiner Weise zu parsen.
Dennoch können wir das zu erwartende Schema für den Requestbody deklarieren.
@@ -151,9 +151,9 @@ Mit demselben Trick könnten Sie ein Pydantic-Modell verwenden, um das JSON-Sche
Und Sie könnten dies auch tun, wenn der Datentyp im Request nicht JSON ist.
In der folgenden Anwendung verwenden wir beispielsweise weder FastAPIs integrierte Funktionalität zum Extrahieren des JSON-Schemas aus Pydantic-Modellen noch die automatische Validierung für JSON. Tatsächlich deklarieren wir den Request-Content-Type als YAML und nicht als JSON:
In der folgenden Anwendung verwenden wir beispielsweise weder die integrierte Funktionalität von FastAPI zum Extrahieren des JSON-Schemas aus Pydantic-Modellen noch die automatische Validierung für JSON. Tatsächlich deklarieren wir den Request-Content-Type als YAML und nicht als JSON:
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[15:20, 22] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
Obwohl wir nicht die standardmäßig integrierte Funktionalität verwenden, verwenden wir dennoch ein Pydantic-Modell, um das JSON-Schema für die Daten, die wir in YAML empfangen möchten, manuell zu generieren.
@@ -161,7 +161,7 @@ Dann verwenden wir den Request direkt und extrahieren den Body als `bytes`. Das
Und dann parsen wir in unserem Code diesen YAML-Inhalt direkt und verwenden dann wieder dasselbe Pydantic-Modell, um den YAML-Inhalt zu validieren:
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[24:31] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
/// tip | Tipp

View File

@@ -20,7 +20,7 @@ Sie können einen Parameter vom Typ `Response` in Ihrer *Pfadoperation-Funktion*
Anschließend können Sie den `status_code` in diesem *vorübergehenden* <abbr title="Response Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>-Objekt festlegen.
{* ../../docs_src/response_change_status_code/tutorial001_py310.py hl[1,9,12] *}
{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *}
Und dann können Sie jedes benötigte Objekt zurückgeben, wie Sie es normalerweise tun würden (ein `dict`, ein Datenbankmodell usw.).

View File

@@ -6,7 +6,7 @@ Sie können einen Parameter vom Typ `Response` in Ihrer *Pfadoperation-Funktion*
Und dann können Sie Cookies in diesem *vorübergehenden* <abbr title="Response Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>-Objekt setzen.
{* ../../docs_src/response_cookies/tutorial002_py310.py hl[1, 8:9] *}
{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *}
Anschließend können Sie wie gewohnt jedes gewünschte Objekt zurückgeben (ein `dict`, ein Datenbankmodell, usw.).
@@ -24,7 +24,7 @@ Dazu können Sie eine Response erstellen, wie unter [Eine Response direkt zurüc
Setzen Sie dann Cookies darin und geben Sie sie dann zurück:
{* ../../docs_src/response_cookies/tutorial001_py310.py hl[10:12] *}
{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *}
/// tip | Tipp

View File

@@ -54,7 +54,7 @@ Nehmen wir an, Sie möchten eine <a href="https://en.wikipedia.org/wiki/XML" cla
Sie könnten Ihren XML-Inhalt als String in eine `Response` einfügen und sie zurückgeben:
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
## Anmerkungen { #notes }

View File

@@ -6,7 +6,7 @@ Sie können einen Parameter vom Typ `Response` in Ihrer *Pfadoperation-Funktion*
Und dann können Sie Header in diesem *vorübergehenden* <abbr title="Response Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>-Objekt festlegen.
{* ../../docs_src/response_headers/tutorial002_py310.py hl[1, 7:8] *}
{* ../../docs_src/response_headers/tutorial002_py39.py hl[1, 7:8] *}
Anschließend können Sie wie gewohnt jedes gewünschte Objekt zurückgeben (ein `dict`, ein Datenbankmodell, usw.).
@@ -22,7 +22,7 @@ Sie können auch Header hinzufügen, wenn Sie eine `Response` direkt zurückgebe
Erstellen Sie eine Response wie in [Eine Response direkt zurückgeben](response-directly.md){.internal-link target=_blank} beschrieben und übergeben Sie die Header als zusätzlichen Parameter:
{* ../../docs_src/response_headers/tutorial001_py310.py hl[10:12] *}
{* ../../docs_src/response_headers/tutorial001_py39.py hl[10:12] *}
/// note | Technische Details

View File

@@ -20,7 +20,7 @@ Wenn Sie dann den Benutzernamen und das Passwort eingeben, sendet der Browser di
* Diese gibt ein Objekt vom Typ `HTTPBasicCredentials` zurück:
* Es enthält den gesendeten `username` und das gesendete `password`.
{* ../../docs_src/security/tutorial006_an_py310.py hl[4,8,12] *}
{* ../../docs_src/security/tutorial006_an_py39.py hl[4,8,12] *}
Wenn Sie versuchen, die URL zum ersten Mal zu öffnen (oder in der Dokumentation auf den Button „Execute“ zu klicken), wird der Browser Sie nach Ihrem Benutzernamen und Passwort fragen:
@@ -40,7 +40,7 @@ Um dies zu lösen, konvertieren wir zunächst den `username` und das `password`
Dann können wir `secrets.compare_digest()` verwenden, um sicherzustellen, dass `credentials.username` `"stanleyjobson"` und `credentials.password` `"swordfish"` ist.
{* ../../docs_src/security/tutorial007_an_py310.py hl[1,12:24] *}
{* ../../docs_src/security/tutorial007_an_py39.py hl[1,12:24] *}
Dies wäre das gleiche wie:
@@ -104,4 +104,4 @@ So ist Ihr Anwendungscode, dank der Verwendung von `secrets.compare_digest()`, v
Nachdem Sie festgestellt haben, dass die Anmeldeinformationen falsch sind, geben Sie eine `HTTPException` mit dem Statuscode 401 zurück (derselbe, der auch zurückgegeben wird, wenn keine Anmeldeinformationen angegeben werden) und fügen den Header `WWW-Authenticate` hinzu, damit der Browser die Anmeldeaufforderung erneut anzeigt:
{* ../../docs_src/security/tutorial007_an_py310.py hl[26:30] *}
{* ../../docs_src/security/tutorial007_an_py39.py hl[26:30] *}

View File

@@ -46,6 +46,12 @@ $ pip install "fastapi[all]"
</div>
/// info | Info
In Pydantic v1 war es im Hauptpackage enthalten. Jetzt wird es als unabhängiges Package verteilt, sodass Sie wählen können, ob Sie es installieren möchten oder nicht, falls Sie die Funktionalität nicht benötigen.
///
### Das `Settings`-Objekt erstellen { #create-the-settings-object }
Importieren Sie `BaseSettings` aus Pydantic und erstellen Sie eine Unterklasse, ganz ähnlich wie bei einem Pydantic-Modell.
@@ -54,7 +60,7 @@ Auf die gleiche Weise wie bei Pydantic-Modellen deklarieren Sie Klassenattribute
Sie können dieselben Validierungs-Funktionen und -Tools verwenden, die Sie für Pydantic-Modelle verwenden, z. B. verschiedene Datentypen und zusätzliche Validierungen mit `Field()`.
{* ../../docs_src/settings/tutorial001_py310.py hl[2,5:8,11] *}
{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
/// tip | Tipp
@@ -70,7 +76,7 @@ Als Nächstes werden die Daten konvertiert und validiert. Wenn Sie also dieses `
Dann können Sie das neue `settings`-Objekt in Ihrer Anwendung verwenden:
{* ../../docs_src/settings/tutorial001_py310.py hl[18:20] *}
{* ../../docs_src/settings/tutorial001_py39.py hl[18:20] *}
### Den Server ausführen { #run-the-server }
@@ -104,11 +110,11 @@ Sie könnten diese Einstellungen in eine andere Moduldatei einfügen, wie Sie in
Sie könnten beispielsweise eine Datei `config.py` haben mit:
{* ../../docs_src/settings/app01_py310/config.py *}
{* ../../docs_src/settings/app01_py39/config.py *}
Und dann verwenden Sie diese in einer Datei `main.py`:
{* ../../docs_src/settings/app01_py310/main.py hl[3,11:13] *}
{* ../../docs_src/settings/app01_py39/main.py hl[3,11:13] *}
/// tip | Tipp
@@ -126,7 +132,7 @@ Dies könnte besonders beim Testen nützlich sein, da es sehr einfach ist, eine
Ausgehend vom vorherigen Beispiel könnte Ihre Datei `config.py` so aussehen:
{* ../../docs_src/settings/app02_an_py310/config.py hl[10] *}
{* ../../docs_src/settings/app02_an_py39/config.py hl[10] *}
Beachten Sie, dass wir jetzt keine Standardinstanz `settings = Settings()` erstellen.
@@ -134,7 +140,7 @@ Beachten Sie, dass wir jetzt keine Standardinstanz `settings = Settings()` erste
Jetzt erstellen wir eine Abhängigkeit, die ein neues `config.Settings()` zurückgibt.
{* ../../docs_src/settings/app02_an_py310/main.py hl[6,12:13] *}
{* ../../docs_src/settings/app02_an_py39/main.py hl[6,12:13] *}
/// tip | Tipp
@@ -146,13 +152,13 @@ Im Moment nehmen Sie an, dass `get_settings()` eine normale Funktion ist.
Und dann können wir das von der *Pfadoperation-Funktion* als Abhängigkeit einfordern und es überall dort verwenden, wo wir es brauchen.
{* ../../docs_src/settings/app02_an_py310/main.py hl[17,19:21] *}
{* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *}
### Einstellungen und Tests { #settings-and-testing }
Dann wäre es sehr einfach, beim Testen ein anderes Einstellungsobjekt bereitzustellen, indem man eine Abhängigkeitsüberschreibung für `get_settings` erstellt:
{* ../../docs_src/settings/app02_an_py310/test_main.py hl[9:10,13,21] *}
{* ../../docs_src/settings/app02_an_py39/test_main.py hl[9:10,13,21] *}
Bei der Abhängigkeitsüberschreibung legen wir einen neuen Wert für `admin_email` fest, wenn wir das neue `Settings`-Objekt erstellen, und geben dann dieses neue Objekt zurück.
@@ -193,7 +199,7 @@ APP_NAME="ChimichangApp"
Und dann aktualisieren Sie Ihre `config.py` mit:
{* ../../docs_src/settings/app03_an_py310/config.py hl[9] *}
{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
/// tip | Tipp
@@ -226,7 +232,7 @@ würden wir dieses Objekt für jeden Request erstellen und die `.env`-Datei für
Da wir jedoch den `@lru_cache`-Dekorator oben verwenden, wird das `Settings`-Objekt nur einmal erstellt, nämlich beim ersten Aufruf. ✔️
{* ../../docs_src/settings/app03_an_py310/main.py hl[1,11] *}
{* ../../docs_src/settings/app03_an_py39/main.py hl[1,11] *}
Dann wird bei allen nachfolgenden Aufrufen von `get_settings()`, in den Abhängigkeiten für darauffolgende Requests, dasselbe Objekt zurückgegeben, das beim ersten Aufruf zurückgegeben wurde, anstatt den Code von `get_settings()` erneut auszuführen und ein neues `Settings`-Objekt zu erstellen.

View File

@@ -10,7 +10,7 @@ Wenn Sie zwei unabhängige FastAPI-Anwendungen mit deren eigenen unabhängigen O
Erstellen Sie zunächst die Hauptanwendung **FastAPI** und deren *Pfadoperationen*:
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[3, 6:8] *}
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[3, 6:8] *}
### Unteranwendung { #sub-application }
@@ -18,7 +18,7 @@ Erstellen Sie dann Ihre Unteranwendung und deren *Pfadoperationen*.
Diese Unteranwendung ist nur eine weitere Standard-FastAPI-Anwendung, aber diese wird „gemountet“:
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 14:16] *}
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 14:16] *}
### Die Unteranwendung mounten { #mount-the-sub-application }
@@ -26,7 +26,7 @@ Mounten Sie in Ihrer Top-Level-Anwendung `app` die Unteranwendung `subapi`.
In diesem Fall wird sie im Pfad `/subapi` gemountet:
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 19] *}
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 19] *}
### Die automatische API-Dokumentation testen { #check-the-automatic-api-docs }

View File

@@ -27,7 +27,7 @@ $ pip install jinja2
* Deklarieren Sie einen `<abbr title="Request Anfrage: Daten, die der Client zum Server sendet">Request</abbr>`-Parameter in der *Pfadoperation*, welcher ein Template zurückgibt.
* Verwenden Sie die von Ihnen erstellten `templates`, um eine `TemplateResponse` zu rendern und zurückzugeben, übergeben Sie den Namen des Templates, das Requestobjekt und ein „Kontext“-<abbr title="Dictionary Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">Dictionary</abbr> mit Schlüssel-Wert-Paaren, die innerhalb des Jinja2-Templates verwendet werden sollen.
{* ../../docs_src/templates/tutorial001_py310.py hl[4,11,15:18] *}
{* ../../docs_src/templates/tutorial001_py39.py hl[4,11,15:18] *}
/// note | Hinweis

View File

@@ -2,11 +2,11 @@
Wenn Sie `lifespan` in Ihren Tests ausführen müssen, können Sie den `TestClient` mit einer `with`-Anweisung verwenden:
{* ../../docs_src/app_testing/tutorial004_py310.py hl[9:15,18,27:28,30:32,41:43] *}
{* ../../docs_src/app_testing/tutorial004_py39.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.
Für die deprecateten Events <abbr title="Hochfahren">`startup`</abbr> und <abbr title="Herunterfahren">`shutdown`</abbr> können Sie den `TestClient` wie folgt verwenden:
{* ../../docs_src/app_testing/tutorial003_py310.py hl[9:12,20:24] *}
{* ../../docs_src/app_testing/tutorial003_py39.py hl[9:12,20:24] *}

View File

@@ -4,7 +4,7 @@ Sie können den schon bekannten `TestClient` zum Testen von WebSockets verwenden
Dazu verwenden Sie den `TestClient` in einer `with`-Anweisung, eine Verbindung zum WebSocket herstellend:
{* ../../docs_src/app_testing/tutorial002_py310.py hl[27:31] *}
{* ../../docs_src/app_testing/tutorial002_py39.py hl[27:31] *}
/// note | Hinweis

View File

@@ -29,7 +29,7 @@ Angenommen, Sie möchten auf die IP-Adresse/den Host des Clients in Ihrer *Pfado
Dazu müssen Sie direkt auf den Request zugreifen.
{* ../../docs_src/using_request_directly/tutorial001_py310.py hl[1,7:8] *}
{* ../../docs_src/using_request_directly/tutorial001_py39.py hl[1,7:8] *}
Durch die Deklaration eines *Pfadoperation-Funktionsparameters*, dessen Typ der `Request` ist, weiß **FastAPI**, dass es den `Request` diesem Parameter übergeben soll.

View File

@@ -38,13 +38,13 @@ In der Produktion hätten Sie eine der oben genannten Optionen.
Aber es ist der einfachste Weg, sich auf die Serverseite von WebSockets zu konzentrieren und ein funktionierendes Beispiel zu haben:
{* ../../docs_src/websockets/tutorial001_py310.py hl[2,6:38,41:43] *}
{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *}
## Einen `websocket` erstellen { #create-a-websocket }
Erstellen Sie in Ihrer **FastAPI**-Anwendung einen `websocket`:
{* ../../docs_src/websockets/tutorial001_py310.py hl[1,46:47] *}
{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *}
/// note | Technische Details
@@ -58,7 +58,7 @@ Sie könnten auch `from starlette.websockets import WebSocket` verwenden.
In Ihrer WebSocket-Route können Sie Nachrichten `await`en und Nachrichten senden.
{* ../../docs_src/websockets/tutorial001_py310.py hl[48:52] *}
{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *}
Sie können Binär-, Text- und JSON-Daten empfangen und senden.
@@ -154,7 +154,7 @@ Damit können Sie den WebSocket verbinden und dann Nachrichten senden und empfan
Wenn eine WebSocket-Verbindung geschlossen wird, löst `await websocket.receive_text()` eine `WebSocketDisconnect`-Exception aus, die Sie dann wie in folgendem Beispiel abfangen und behandeln können.
{* ../../docs_src/websockets/tutorial003_py310.py hl[79:81] *}
{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *}
Zum Ausprobieren:

View File

@@ -18,7 +18,7 @@ Wrappen Sie dann die WSGI-Anwendung (z. B. Flask) mit der Middleware.
Und dann mounten Sie das auf einem Pfad.
{* ../../docs_src/wsgi/tutorial001_py310.py hl[1,3,23] *}
{* ../../docs_src/wsgi/tutorial001_py39.py hl[1,3,23] *}
/// note | Hinweis

View File

@@ -20,7 +20,7 @@ Es ist das beliebteste Python-Framework und genießt großes Vertrauen. Es wird
Es ist relativ eng mit relationalen Datenbanken (wie MySQL oder PostgreSQL) gekoppelt, daher ist es nicht sehr einfach, eine NoSQL-Datenbank (wie Couchbase, MongoDB, Cassandra, usw.) als Hauptspeicherengine zu verwenden.
Es wurde erstellt, um den HTML-Code im Backend zu generieren, nicht um APIs zu erstellen, die von einem modernen Frontend (wie React, Vue.js und Angular) oder von anderen Systemen (wie <abbr title="Internet of Things - Internet der Dinge">IoT</abbr>-Geräten) verwendet werden, um mit ihm zu kommunizieren.
Es wurde erstellt, um den HTML-Code im Backend zu generieren, nicht um APIs zu erstellen, die von einem modernen Frontend (wie React, Vue.js und Angular) oder von anderen Systemen (wie <abbr title="Internet of Things Internet der Dinge">IoT</abbr>-Geräten) verwendet werden, um mit ihm zu kommunizieren.
### <a href="https://www.django-rest-framework.org/" class="external-link" target="_blank">Django REST Framework</a> { #django-rest-framework }
@@ -82,7 +82,7 @@ Aus diesem Grund heißt es auf der offiziellen Website:
> Requests ist eines der am häufigsten heruntergeladenen Python-Packages aller Zeiten
Die Art und Weise, wie Sie es verwenden, ist sehr einfach. Um beispielsweise einen `GET`-<abbr title="Request - Anfrage: Daten, die der Client zum Server sendet">Request</abbr> zu machen, würden Sie schreiben:
Die Art und Weise, wie Sie es verwenden, ist sehr einfach. Um beispielsweise einen `GET`-<abbr title="Request Anfrage: Daten, die der Client zum Server sendet">Request</abbr> zu machen, würden Sie schreiben:
```Python
response = requests.get("http://example.com/some/url")
@@ -137,7 +137,7 @@ Es gibt mehrere Flask REST Frameworks, aber nachdem ich die Zeit und Arbeit inve
### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a> { #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-<abbr title="Auch Marshalling, Konvertierung“ genannt">„Serialisierung“</abbr>, 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.
@@ -145,7 +145,7 @@ Ohne ein Datenvalidierungssystem müssten Sie alle Prüfungen manuell im Code du
Für diese Funktionen wurde Marshmallow entwickelt. Es ist eine großartige Bibliothek und ich habe sie schon oft genutzt.
Aber sie wurde erstellt, bevor Typhinweise in Python existierten. Um also ein <dfn title="die Definition, wie Daten geformt sein sollen">Schema</dfn> zu definieren, müssen Sie bestimmte Werkzeuge und Klassen verwenden, die von Marshmallow bereitgestellt werden.
Aber sie wurde erstellt, bevor Typhinweise in Python existierten. Um also ein <abbr title="die Definition, wie Daten geformt sein sollen">Schema</abbr> zu definieren, müssen Sie bestimmte Werkzeuge und Klassen verwenden, die von Marshmallow bereitgestellt werden.
/// check | Inspirierte **FastAPI**
@@ -155,7 +155,7 @@ Code zu verwenden, um „Schemas“ zu definieren, welche Datentypen und Validie
### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a> { #webargs }
Eine weitere wichtige Funktion, die von APIs benötigt wird, ist das <dfn title="Lesen und Konvertieren nach Python-Daten">Parsen</dfn> von Daten aus eingehenden Requests.
Eine weitere wichtige Funktion, die von APIs benötigt wird, ist das <abbr title="Lesen und Konvertieren nach Python-Daten">Parsen</abbr> von Daten aus eingehenden Requests.
Webargs wurde entwickelt, um dieses für mehrere Frameworks, einschließlich Flask, bereitzustellen.
@@ -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 -Bodys 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.
@@ -419,7 +419,7 @@ Die gesamte Datenvalidierung, Datenserialisierung und automatische Modelldokumen
### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> { #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.
Starlette ist ein leichtgewichtiges <abbr title="Der neue Standard für die Erstellung asynchroner Python-Webanwendungen">ASGI</abbr>-Framework/Toolkit, welches sich ideal für die Erstellung hochperformanter asynchroner Dienste eignet.
Es ist sehr einfach und intuitiv. Es ist so konzipiert, dass es leicht erweiterbar ist und über modulare Komponenten verfügt.

View File

@@ -23,7 +23,7 @@ Die Hierarchie ist wie folgt:
* Sie würden eine Anwendung nicht direkt in Uvicorn schreiben. Das würde bedeuten, dass Ihr Code zumindest mehr oder weniger den gesamten von Starlette (oder **FastAPI**) bereitgestellten Code enthalten müsste. Und wenn Sie das täten, hätte Ihre endgültige Anwendung den gleichen Overhead wie bei der Verwendung eines Frameworks und der Minimierung Ihres Anwendungscodes und der Fehler.
* Wenn Sie Uvicorn vergleichen, vergleichen Sie es mit Anwendungsservern wie Daphne, Hypercorn, uWSGI, usw.
* **Starlette**:
* Wird nach Uvicorn die nächstbeste Performanz erbringen. Tatsächlich verwendet Starlette Uvicorn, um zu laufen. Daher kann es wahrscheinlich nur „langsamer“ als Uvicorn werden, weil mehr Code ausgeführt werden muss.
* Wird nach Uvicorn die nächstbeste Performanz erbringen. Tatsächlich verwendet Starlette intern Uvicorn, um zu laufen. Daher kann es wahrscheinlich nur „langsamer“ als Uvicorn werden, weil mehr Code ausgeführt werden muss.
* Aber es bietet Ihnen die Werkzeuge, um einfache Webanwendungen zu erstellen, mit Routing basierend auf Pfaden, usw.
* Wenn Sie Starlette vergleichen, vergleichen Sie es mit Webframeworks (oder Mikroframeworks) wie Sanic, Flask, Django, usw.
* **FastAPI**:

View File

@@ -1,6 +1,6 @@
# FastAPI bei Cloudanbietern deployen { #deploy-fastapi-on-cloud-providers }
Sie können praktisch **jeden Cloudanbieter** verwenden, um Ihre FastAPI-Anwendung zu deployen.
Sie können praktisch **jeden Cloudanbieter** verwenden, um Ihre FastAPI-Anwendung bereitzustellen.
In den meisten Fällen bieten die großen Cloudanbieter Anleitungen zum Deployment von FastAPI an.

View File

@@ -14,7 +14,7 @@ Sie haben es eilig und kennen sich bereits aus? Springen Sie zum [`Dockerfile` u
<summary>Dockerfile-Vorschau 👀</summary>
```Dockerfile
FROM python:3.14
FROM python:3.9
WORKDIR /code
@@ -166,7 +166,7 @@ Erstellen Sie nun im selben Projektverzeichnis eine Datei `Dockerfile` mit:
```{ .dockerfile .annotate }
# (1)!
FROM python:3.14
FROM python:3.9
# (2)!
WORKDIR /code
@@ -390,7 +390,7 @@ Wenn Ihr FastAPI eine einzelne Datei ist, zum Beispiel `main.py` ohne ein `./app
Dann müssten Sie nur noch die entsprechenden Pfade ändern, um die Datei im `Dockerfile` zu kopieren:
```{ .dockerfile .annotate hl_lines="10 13" }
FROM python:3.14
FROM python:3.9
WORKDIR /code
@@ -454,7 +454,7 @@ Ohne die Verwendung von Containern kann es umständlich und schwierig sein, Anwe
## Replikation Anzahl der Prozesse { #replication-number-of-processes }
Wenn Sie einen <dfn title="Eine Gruppe von Maschinen, die so konfiguriert sind, dass sie verbunden sind und auf irgendeine Weise zusammenarbeiten.">Cluster</dfn> von Maschinen mit **Kubernetes**, Docker Swarm Mode, Nomad verwenden, oder einem anderen, ähnlich komplexen System zur Verwaltung verteilter Container auf mehreren Maschinen, möchten Sie wahrscheinlich die **Replikation auf Cluster-Ebene abwickeln**, anstatt in jedem Container einen **Prozessmanager** (wie Uvicorn mit Workern) zu verwenden.
Wenn Sie einen <abbr title="Eine Gruppe von Maschinen, die so konfiguriert sind, dass sie verbunden sind und auf irgendeine Weise zusammenarbeiten.">Cluster</abbr> von Maschinen mit **Kubernetes**, Docker Swarm Mode, Nomad verwenden, oder einem anderen, ähnlich komplexen System zur Verwaltung verteilter Container auf mehreren Maschinen, möchten Sie wahrscheinlich die **Replikation auf Cluster-Ebene abwickeln**, anstatt in jedem Container einen **Prozessmanager** (wie Uvicorn mit Workern) zu verwenden.
Diese verteilten Containerverwaltungssysteme wie Kubernetes verfügen normalerweise über eine integrierte Möglichkeit, die **Replikation von Containern** zu handhaben und gleichzeitig **Load Balancing** für die eingehenden <abbr title="Request Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> zu unterstützen. Alles auf **Cluster-Ebene**.
@@ -499,7 +499,7 @@ Natürlich gibt es **Sonderfälle**, in denen Sie **einen Container** mit mehrer
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
FROM python:3.9
WORKDIR /code
@@ -570,7 +570,7 @@ Wenn Sie ein einfaches Setup mit einem **einzelnen Container** haben, welcher da
### Docker-Basisimage { #base-docker-image }
Es gab ein offizielles FastAPI-Docker-Image: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>. Dieses ist jedoch jetzt deprecatet. ⛔️
Es gab ein offizielles FastAPI-Docker-Image: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>. Dieses ist jedoch jetzt veraltet. ⛔️
Sie sollten wahrscheinlich **nicht** dieses Basis-Docker-Image (oder ein anderes ähnliches) verwenden.

View File

@@ -65,7 +65,7 @@ Hier ist ein Beispiel, wie eine HTTPS-API aussehen könnte, Schritt für Schritt
Alles beginnt wahrscheinlich damit, dass Sie einen **Domainnamen erwerben**. Anschließend konfigurieren Sie ihn in einem DNS-Server (wahrscheinlich beim selben Cloudanbieter).
Sie würden wahrscheinlich einen Cloud-Server (eine virtuelle Maschine) oder etwas Ähnliches bekommen, und dieser hätte eine <dfn title="Ändert sich im Laufe der Zeit nicht. Nicht dynamisch.">feste</dfn> **öffentliche IP-Adresse**.
Sie würden wahrscheinlich einen Cloud-Server (eine virtuelle Maschine) oder etwas Ähnliches bekommen, und dieser hätte eine <abbr title="Sie ändert sich nicht">feste</abbr> **öffentliche IP-Adresse**.
In dem oder den DNS-Server(n) würden Sie einen Eintrag (einen „`A record`“) konfigurieren, um mit **Ihrer Domain** auf die öffentliche **IP-Adresse Ihres Servers** zu verweisen.

View File

@@ -4,7 +4,7 @@ Das Deployment einer **FastAPI**-Anwendung ist relativ einfach.
## Was bedeutet Deployment { #what-does-deployment-mean }
<abbr title="Bereitstellen der Anwendung">**Deployment**</abbr> bedeutet, die notwendigen Schritte durchzuführen, um die Anwendung **für die Benutzer verfügbar** zu machen.
<abbr title="Bereitstellen der Anwendung">**Deployment**</abbr> bedeutet, die notwendigen Schritte durchzuführen, um die Anwendung **für die Endbenutzer verfügbar** zu machen.
Bei einer **Web-API** bedeutet das normalerweise, diese auf einem **entfernten Rechner** zu platzieren, mit einem **Serverprogramm**, welches gute Leistung, Stabilität, usw. bietet, damit Ihre **Benutzer** auf die Anwendung effizient und ohne Unterbrechungen oder Probleme **zugreifen** können.

View File

@@ -119,7 +119,7 @@ In der Liste der Deployment-Konzepte von oben würde die Verwendung von Workern
* **Sicherheit HTTPS**
* **Beim Hochfahren ausführen**
* ***Neustarts***
* **Neustarts**
* Replikation (die Anzahl der laufenden Prozesse)
* **Arbeitsspeicher**
* **Schritte vor dem Start**

View File

@@ -6,7 +6,7 @@
### Basiert auf offenen Standards { #based-on-open-standards }
* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> 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="Anfragekörper">Requestbodys</abbr>, Sicherheit, usw.
* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> für die Erstellung von APIs, inklusive Deklarationen von <abbr title="auch bekannt als: Endpunkte, Routen">Pfad</abbr>-<abbr title="auch bekannt als HTTP-Methoden, wie POST, GET, PUT, DELETE">Operationen</abbr>, Parametern, <abbr title="Anfragekörper">Requestbodys</abbr>, Sicherheit, usw.
* Automatische Dokumentation der Datenmodelle mit <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> (da OpenAPI selbst auf JSON Schema basiert).
* Um diese Standards herum entworfen, nach sorgfältigem Studium. Statt einer nachträglichen Schicht darüber.
* Dies ermöglicht auch automatische **Client-Code-Generierung** in vielen Sprachen.
@@ -136,7 +136,7 @@ Alles als wiederverwendbare Tools und Komponenten gebaut, die einfach in Ihre Sy
### 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 <abbr title='auch bekannt als Komponenten, Resourcen, Dienste, Dienstanbieter'><strong>Dependency Injection</strong></abbr> 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.
@@ -153,8 +153,8 @@ Jede Integration wurde so entworfen, dass sie so einfach zu nutzen ist (mit Abh
### 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>.
* 100 % <abbr title="Der Prozentsatz an Code, der automatisch getestet wird">Testabdeckung</abbr>.
* 100 % <abbr title="Python-Typannotationen, mit denen Ihr Editor und andere externe Werkzeuge Sie besser unterstützen können">Typen annotiert</abbr>.
* Verwendet in Produktionsanwendungen.
## Starlette Merkmale { #starlette-features }
@@ -179,7 +179,7 @@ Mit **FastAPI** bekommen Sie alles von **Starlette** (da FastAPI nur Starlette a
**FastAPI** ist vollkommen kompatibel (und basiert auf) <a href="https://docs.pydantic.dev/" class="external-link" target="_blank"><strong>Pydantic</strong></a>. Das bedeutet, wenn Sie eigenen Pydantic Quellcode haben, funktioniert der.
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 Abbilder">ORM</abbr>s, <abbr title="Object-Document Mapper Objekt-Dokument-Abbilder">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.
@@ -190,7 +190,7 @@ Mit **FastAPI** bekommen Sie alle Funktionen von **Pydantic** (da FastAPI für d
* **Kein Kopfzerbrechen**:
* Keine neue Schemadefinition-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**:
* Gutes Zusammenspiel mit Ihrer/Ihrem **<abbr title="Integrated Development Environment Integrierte Entwicklungsumgebung: Ähnlich einem Code-Editor">IDE</abbr>/<abbr title="Ein Programm, das Fehler im Quellcode sucht">Linter</abbr>/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.

View File

@@ -58,7 +58,7 @@ Nachdem ich mehrere Alternativen getestet hatte, entschied ich, dass ich <a href
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 <a href="https://www.starlette.dev/" class="external-link" target="_blank">**Starlette**</a> beigetragen, die andere Schlüsselanforderung.
Während der Entwicklung habe ich auch zu <a href="https://www.starlette.dev/" class="external-link" target="_blank">**Starlette**</a> beigetragen, der anderen Schlüsselanforderung.
## Entwicklung { #development }

View File

@@ -8,7 +8,7 @@ Aber falls Ihre Clients aus irgendeinem Grund vom alten Verhalten abhängen, kö
Sie können beispielsweise eine Unterklasse von `HTTPBearer` erstellen, die einen Fehler `403 Forbidden` zurückgibt, statt des Default-`401 Unauthorized`-Fehlers:
{* ../../docs_src/authentication_error_status_code/tutorial001_an_py310.py hl[9:13] *}
{* ../../docs_src/authentication_error_status_code/tutorial001_an_py39.py hl[9:13] *}
/// tip | Tipp

View File

@@ -29,7 +29,7 @@ Sie können problemlos dieselben Pydantic-Einstellungen verwenden, um Ihre gener
Zum Beispiel:
{* ../../docs_src/conditional_openapi/tutorial001_py310.py hl[6,11] *}
{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *}
Hier deklarieren wir die Einstellung `openapi_url` mit dem gleichen Defaultwert `"/openapi.json"`.

View File

@@ -18,7 +18,7 @@ Ohne Änderung der Einstellungen ist die Syntaxhervorhebung standardmäßig akti
Sie können sie jedoch deaktivieren, indem Sie `syntaxHighlight` auf `False` setzen:
{* ../../docs_src/configure_swagger_ui/tutorial001_py310.py hl[3] *}
{* ../../docs_src/configure_swagger_ui/tutorial001_py39.py hl[3] *}
... und dann zeigt die Swagger-Oberfläche die Syntaxhervorhebung nicht mehr an:
@@ -28,7 +28,7 @@ Sie können sie jedoch deaktivieren, indem Sie `syntaxHighlight` auf `False` set
Auf die gleiche Weise könnten Sie das Theme der Syntaxhervorhebung mit dem Schlüssel `"syntaxHighlight.theme"` festlegen (beachten Sie, dass er einen Punkt in der Mitte hat):
{* ../../docs_src/configure_swagger_ui/tutorial002_py310.py hl[3] *}
{* ../../docs_src/configure_swagger_ui/tutorial002_py39.py hl[3] *}
Obige Konfiguration würde das Theme für die Farbe der Syntaxhervorhebung ändern:
@@ -46,7 +46,7 @@ Sie können jede davon überschreiben, indem Sie im Argument `swagger_ui_paramet
Um beispielsweise `deepLinking` zu deaktivieren, könnten Sie folgende Einstellungen an `swagger_ui_parameters` übergeben:
{* ../../docs_src/configure_swagger_ui/tutorial003_py310.py hl[3] *}
{* ../../docs_src/configure_swagger_ui/tutorial003_py39.py hl[3] *}
## Andere Parameter der Swagger-Oberfläche { #other-swagger-ui-parameters }

View File

@@ -18,7 +18,7 @@ Der erste Schritt besteht darin, die automatischen Dokumentationen zu deaktivier
Um diese zu deaktivieren, setzen Sie deren URLs beim Erstellen Ihrer `FastAPI`-App auf `None`:
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[8] *}
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[8] *}
### Die benutzerdefinierten Dokumentationen hinzufügen { #include-the-custom-docs }
@@ -34,7 +34,7 @@ Sie können die internen Funktionen von FastAPI wiederverwenden, um die HTML-Sei
Und ähnlich für ReDoc ...
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[2:6,11:19,22:24,27:33] *}
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[2:6,11:19,22:24,27:33] *}
/// tip | Tipp
@@ -50,7 +50,7 @@ Swagger UI erledigt das hinter den Kulissen für Sie, benötigt aber diesen „U
Um nun testen zu können, ob alles funktioniert, erstellen Sie eine *Pfadoperation*:
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[36:38] *}
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[36:38] *}
### Es testen { #test-it }
@@ -118,7 +118,7 @@ Danach könnte Ihre Dateistruktur wie folgt aussehen:
* Importieren Sie `StaticFiles`.
* „Mounten“ Sie eine `StaticFiles()`-Instanz in einem bestimmten Pfad.
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[7,11] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[7,11] *}
### Die statischen Dateien testen { #test-the-static-files }
@@ -144,7 +144,7 @@ Wie bei der Verwendung eines benutzerdefinierten CDN besteht der erste Schritt d
Um sie zu deaktivieren, setzen Sie deren URLs beim Erstellen Ihrer `FastAPI`-App auf `None`:
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[9] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[9] *}
### Die benutzerdefinierten Dokumentationen für statische Dateien hinzufügen { #include-the-custom-docs-for-static-files }
@@ -160,7 +160,7 @@ Auch hier können Sie die internen Funktionen von FastAPI wiederverwenden, um di
Und ähnlich für ReDoc ...
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[2:6,14:22,25:27,30:36] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[2:6,14:22,25:27,30:36] *}
/// tip | Tipp
@@ -176,7 +176,7 @@ Swagger UI erledigt das hinter den Kulissen für Sie, benötigt aber diesen „U
Um nun testen zu können, ob alles funktioniert, erstellen Sie eine *Pfadoperation*:
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[39:41] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[39:41] *}
### Benutzeroberfläche mit statischen Dateien testen { #test-static-files-ui }

View File

@@ -43,19 +43,19 @@ Fügen wir beispielsweise <a href="https://github.com/Rebilly/ReDoc/blob/master/
Schreiben Sie zunächst wie gewohnt Ihre ganze **FastAPI**-Anwendung:
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[1,4,7:9] *}
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[1,4,7:9] *}
### Das OpenAPI-Schema generieren { #generate-the-openapi-schema }
Verwenden Sie dann dieselbe Hilfsfunktion, um das OpenAPI-Schema innerhalb einer `custom_openapi()`-Funktion zu generieren:
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[2,15:21] *}
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[2,15:21] *}
### Das OpenAPI-Schema ändern { #modify-the-openapi-schema }
Jetzt können Sie die ReDoc-Erweiterung hinzufügen und dem `info`-„Objekt“ im OpenAPI-Schema ein benutzerdefiniertes `x-logo` hinzufügen:
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[22:24] *}
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[22:24] *}
### Zwischenspeichern des OpenAPI-Schemas { #cache-the-openapi-schema }
@@ -65,13 +65,13 @@ Auf diese Weise muss Ihre Anwendung das Schema nicht jedes Mal generieren, wenn
Es wird nur einmal generiert und dann wird dasselbe zwischengespeicherte Schema für die nächsten <abbr title="Request Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> verwendet.
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[13:14,25:26] *}
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[13:14,25:26] *}
### Die Methode überschreiben { #override-the-method }
Jetzt können Sie die Methode `.openapi()` durch Ihre neue Funktion ersetzen.
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[29] *}
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[29] *}
### Es testen { #check-it }

View File

@@ -35,7 +35,7 @@ Abhängig von Ihrem Anwendungsfall könnten Sie eine andere Bibliothek vorziehen
Hier ist eine kleine Vorschau, wie Sie Strawberry mit FastAPI integrieren können:
{* ../../docs_src/graphql_/tutorial001_py310.py hl[3,22,25] *}
{* ../../docs_src/graphql_/tutorial001_py39.py hl[3,22,25] *}
Weitere Informationen zu Strawberry finden Sie in der <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry-Dokumentation</a>.

View File

@@ -40,7 +40,7 @@ Seine Schlüssel-Merkmale sind:
* **Schnell**: Sehr hohe Performanz, auf Augenhöhe mit **NodeJS** und **Go** (dank Starlette und Pydantic). [Eines der schnellsten verfügbaren Python-Frameworks](#performance).
* **Schnell zu entwickeln**: Erhöhen Sie die Geschwindigkeit bei der Entwicklung von Features um etwa 200 % bis 300 %. *
* **Weniger Bugs**: Verringern Sie die von Menschen (Entwicklern) verursachten Fehler um etwa 40 %. *
* **Intuitiv**: Hervorragende Editor-Unterstützung. <dfn title="auch bekannt als Auto-Complete, Autovervollständigung, IntelliSense">Code-Vervollständigung</dfn> überall. Weniger Zeit mit Debuggen verbringen.
* **Intuitiv**: Hervorragende Editor-Unterstützung. <abbr title="auch bekannt als Auto-Complete, Autovervollständigung, IntelliSense">Code-Vervollständigung</abbr> überall. Weniger Zeit mit Debuggen verbringen.
* **Einfach**: So konzipiert, dass es einfach zu benutzen und zu erlernen ist. Weniger Zeit mit dem Lesen von Dokumentation verbringen.
* **Kurz**: Minimieren Sie die Verdoppelung von Code. Mehrere Features aus jeder Parameterdeklaration. Weniger Bugs.
* **Robust**: Erhalten Sie produktionsreifen Code. Mit automatischer, interaktiver Dokumentation.
@@ -363,12 +363,12 @@ item: Item
... und mit dieser einen Deklaration erhalten Sie:
* Editor-Unterstützung, einschließlich:
* Vervollständigung.
* Code-Vervollständigung.
* Typprüfungen.
* Validierung von Daten:
* Automatische und eindeutige Fehler, wenn die Daten ungültig sind.
* Validierung sogar für tief verschachtelte JSON-Objekte.
* <dfn title="auch bekannt als: Serialisierung, Parsen, Marshalling">Konvertierung</dfn> von Eingabedaten: Aus dem Netzwerk kommend, zu Python-Daten und -Typen. Lesen von:
* <abbr title="auch bekannt als: Serialisierung, Parsen, Marshalling">Konvertierung</abbr> von Eingabedaten: Aus dem Netzwerk kommend, zu Python-Daten und -Typen. Lesen von:
* JSON.
* Pfad-Parametern.
* Query-Parametern.
@@ -376,7 +376,7 @@ item: Item
* Headern.
* Formularen.
* Dateien.
* <dfn title="auch bekannt als: Serialisierung, Parsen, Marshalling">Konvertierung</dfn> von Ausgabedaten: Konvertierung von Python-Daten und -Typen zu Netzwerkdaten (als JSON):
* <abbr title="auch bekannt als: Serialisierung, Parsen, Marshalling">Konvertierung</abbr> von Ausgabedaten: Konvertierung von Python-Daten und -Typen zu Netzwerkdaten (als JSON):
* Konvertieren von Python-Typen (`str`, `int`, `float`, `bool`, `list`, usw.).
* `datetime`-Objekte.
* `UUID`-Objekte.
@@ -439,7 +439,7 @@ Für ein vollständigeres Beispiel, mit weiteren Funktionen, siehe das <a href="
* Deklaration von **Parametern** von anderen verschiedenen Stellen wie: **Header**, **Cookies**, **Formularfelder** und **Dateien**.
* Wie man **Validierungs-Constraints** wie `maximum_length` oder `regex` setzt.
* Ein sehr leistungsfähiges und einfach zu bedienendes System für **<dfn title="auch bekannt als Komponenten, Ressourcen, Provider, Services, Injectables">Dependency Injection</dfn>**.
* Ein sehr leistungsfähiges und einfach zu bedienendes System für **<abbr title="auch bekannt als Komponenten, Ressourcen, Provider, Services, Injectables">Dependency Injection</abbr>**.
* Sicherheit und Authentifizierung, einschließlich Unterstützung für **OAuth2** mit **JWT-Tokens** und **HTTP Basic** Authentifizierung.
* Fortgeschrittenere (aber ebenso einfache) Techniken zur Deklaration **tief verschachtelter JSON-Modelle** (dank Pydantic).
* **GraphQL**-Integration mit <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> und anderen Bibliotheken.
@@ -524,7 +524,7 @@ Verwendet von Starlette:
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> erforderlich, wenn Sie den `TestClient` verwenden möchten.
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> erforderlich, wenn Sie die Default-Template-Konfiguration verwenden möchten.
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> erforderlich, wenn Sie Formulare mittels `request.form()` <dfn title="Konvertieren des Strings, der aus einem HTTP-Request stammt, nach Python-Daten">„parsen“</dfn> möchten.
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> erforderlich, wenn Sie Formulare mittels `request.form()` <abbr title="Konvertieren des Strings, der aus einem HTTP-Request stammt, nach Python-Daten">„parsen“</abbr> möchten.
Verwendet von FastAPI:

View File

@@ -20,7 +20,7 @@ GitHub-Repository: <a href="https://github.com/tiangolo/full-stack-fastapi-templ
- 🦇 „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.
- 🔑 JWT (JSON Web Token)-Token-Authentifizierung.
- 📫 E-Mail-basierte Passwortwiederherstellung.
- ✅ Tests mit [Pytest](https://pytest.org).
- 📞 [Traefik](https://traefik.io) als Reverse-Proxy / Load Balancer.

View File

@@ -1,8 +1,8 @@
# Einführung in Python-Typen { #python-types-intro }
Python hat Unterstützung für optionale „Typhinweise“ (auch „Typannotationen“ genannt).
Python hat Unterstützung für optionale <abbr title="englisch: Type hints">„Typhinweise“</abbr> (auch <abbr title="englisch: Type annotations">„Typannotationen“</abbr> genannt).
Diese **„Typhinweise“** oder -Annotationen sind eine spezielle Syntax, die es erlaubt, den <dfn title="zum Beispiel: str, int, float, bool">Typ</dfn> einer Variablen zu deklarieren.
Diese **„Typhinweise“** oder -Annotationen sind eine spezielle Syntax, die es erlaubt, den <abbr title="zum Beispiel: str, int, float, bool">Typ</abbr> einer Variablen zu deklarieren.
Durch das Deklarieren von Typen für Ihre Variablen können Editoren und Tools bessere Unterstützung bieten.
@@ -22,7 +22,7 @@ Wenn Sie ein Python-Experte sind und bereits alles über Typhinweise wissen, üb
Fangen wir mit einem einfachen Beispiel an:
{* ../../docs_src/python_types/tutorial001_py310.py *}
{* ../../docs_src/python_types/tutorial001_py39.py *}
Dieses Programm gibt aus:
@@ -34,9 +34,9 @@ Die Funktion macht Folgendes:
* Nimmt einen `first_name` und `last_name`.
* Schreibt den ersten Buchstaben eines jeden Wortes groß, mithilfe von `title()`.
* <dfn title="Fügt sie zu einer Einheit zusammen. Mit dem Inhalt des einen nach dem anderen.">Verkettet</dfn> sie mit einem Leerzeichen in der Mitte.
* <abbr title="Fügt sie zu einer Einheit zusammen. Mit dem Inhalt des einen nach dem anderen.">Verkettet</abbr> sie mit einem Leerzeichen in der Mitte.
{* ../../docs_src/python_types/tutorial001_py310.py hl[2] *}
{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
### Es bearbeiten { #edit-it }
@@ -78,7 +78,7 @@ Das war's.
Das sind die „Typhinweise“:
{* ../../docs_src/python_types/tutorial002_py310.py hl[1] *}
{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *}
Das ist nicht das gleiche wie das Deklarieren von Defaultwerten, wie es hier der Fall ist:
@@ -106,7 +106,7 @@ Hier können Sie durch die Optionen blättern, bis Sie diejenige finden, bei der
Sehen Sie sich diese Funktion an, sie hat bereits Typhinweise:
{* ../../docs_src/python_types/tutorial003_py310.py hl[1] *}
{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *}
Da der Editor die Typen der Variablen kennt, erhalten Sie nicht nur Code-Vervollständigung, sondern auch eine Fehlerprüfung:
@@ -114,7 +114,7 @@ Da der Editor die Typen der Variablen kennt, erhalten Sie nicht nur Code-Vervoll
Jetzt, da Sie wissen, dass Sie das reparieren müssen, konvertieren Sie `age` mittels `str(age)` in einen String:
{* ../../docs_src/python_types/tutorial004_py310.py hl[2] *}
{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
## Deklarieren von Typen { #declaring-types }
@@ -133,32 +133,29 @@ Zum Beispiel diese:
* `bool`
* `bytes`
{* ../../docs_src/python_types/tutorial005_py310.py hl[1] *}
{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
### `typing`-Modul { #typing-module }
### Generische Typen mit Typ-Parametern { #generic-types-with-type-parameters }
Für einige zusätzliche Anwendungsfälle müssen Sie möglicherweise Dinge aus dem Standardmodul `typing` importieren. Zum Beispiel, wenn Sie deklarieren möchten, dass etwas „jeden Typ“ haben kann, können Sie `Any` aus `typing` verwenden:
Es gibt Datenstrukturen, die andere Werte enthalten können, wie etwa `dict`, `list`, `set` und `tuple`. Die inneren Werte können auch ihren eigenen Typ haben.
```python
from typing import Any
Diese Typen mit inneren Typen werden „**generische**“ Typen genannt. Es ist möglich, sie mit ihren inneren Typen zu deklarieren.
Um diese Typen und die inneren Typen zu deklarieren, können Sie Pythons Standardmodul `typing` verwenden. Es existiert speziell für die Unterstützung dieser Typhinweise.
def some_function(data: Any):
print(data)
```
#### Neuere Python-Versionen { #newer-versions-of-python }
### Generische Typen { #generic-types }
Die Syntax, welche `typing` verwendet, ist **kompatibel** mit allen Versionen, von Python 3.6 aufwärts zu den neuesten, inklusive Python 3.9, Python 3.10, usw.
Einige Typen können „Typ-Parameter“ in eckigen Klammern annehmen, um ihre inneren Typen zu definieren, z. B. eine „Liste von Strings“ würde als `list[str]` deklariert.
Mit der Weiterentwicklung von Python kommen **neuere Versionen** heraus, mit verbesserter Unterstützung für Typannotationen, und in vielen Fällen müssen Sie gar nicht mehr das `typing`-Modul importieren, um Typannotationen zu schreiben.
Diese Typen, die Typ-Parameter annehmen können, werden **generische Typen** oder **Generics** genannt.
Wenn Sie eine neuere Python-Version für Ihr Projekt wählen können, werden Sie aus dieser zusätzlichen Vereinfachung Nutzen ziehen können.
Sie können dieselben eingebauten Typen als Generics verwenden (mit eckigen Klammern und Typen darin):
In der gesamten Dokumentation gibt es Beispiele, welche kompatibel mit unterschiedlichen Python-Versionen sind (wenn es Unterschiede gibt).
* `list`
* `tuple`
* `set`
* `dict`
Zum Beispiel bedeutet „**Python 3.6+**“, dass das Beispiel kompatibel mit Python 3.6 oder höher ist (inklusive 3.7, 3.8, 3.9, 3.10, usw.). Und „**Python 3.9+**“ bedeutet, es ist kompatibel mit Python 3.9 oder höher (inklusive 3.10, usw.).
Wenn Sie über die **neueste Version von Python** verfügen, verwenden Sie die Beispiele für die neueste Version, diese werden die **beste und einfachste Syntax** haben, zum Beispiel, „**Python 3.10+**“.
#### Liste { #list }
@@ -170,7 +167,7 @@ Als Typ nehmen Sie `list`.
Da die Liste ein Typ ist, welcher innere Typen enthält, werden diese von eckigen Klammern umfasst:
{* ../../docs_src/python_types/tutorial006_py310.py hl[1] *}
{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *}
/// info | Info
@@ -196,7 +193,7 @@ Und trotzdem weiß der Editor, dass es sich um ein `str` handelt, und bietet ent
Das Gleiche gilt für die Deklaration eines Tupels `tuple` und einer Menge `set`:
{* ../../docs_src/python_types/tutorial007_py310.py hl[1] *}
{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
Das bedeutet:
@@ -211,7 +208,7 @@ Der erste Typ-Parameter ist für die Schlüssel des `dict`.
Der zweite Typ-Parameter ist für die Werte des `dict`:
{* ../../docs_src/python_types/tutorial008_py310.py hl[1] *}
{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *}
Das bedeutet:
@@ -219,23 +216,47 @@ Das bedeutet:
* Die Schlüssel dieses `dict` sind vom Typ `str` (z. B. die Namen der einzelnen Artikel).
* Die Werte dieses `dict` sind vom Typ `float` (z. B. der Preis jedes Artikels).
#### Union { #union }
#### <abbr title="Union Verbund, Einheit Vereinigung: Eines von Mehreren">Union</abbr> { #union }
Sie können deklarieren, dass eine Variable einer von **verschiedenen Typen** sein kann, zum Beispiel ein `int` oder ein `str`.
Um das zu definieren, verwenden Sie den <dfn title="auch „bitweiser Oder-Operator“ genannt, aber diese Bedeutung ist hier nicht relevant">vertikalen Balken (`|`)</dfn>, um beide Typen zu trennen.
In Python 3.6 und höher (inklusive Python 3.10) können Sie den `Union`-Typ von `typing` verwenden und die möglichen Typen innerhalb der eckigen Klammern auflisten.
Das wird „Union“ genannt, weil die Variable etwas aus der Vereinigung dieser beiden Typmengen sein kann.
In Python 3.10 gibt es zusätzlich eine **neue Syntax**, die es erlaubt, die möglichen Typen getrennt von einem <abbr title='auch „bitweiser Oder-Operator“ genannt, aber diese Bedeutung ist hier nicht relevant'>vertikalen Balken (`|`)</abbr> aufzulisten.
//// tab | Python 3.10+
```Python hl_lines="1"
{!> ../../docs_src/python_types/tutorial008b_py310.py!}
```
Das bedeutet, dass `item` ein `int` oder ein `str` sein könnte.
////
//// tab | Python 3.9+
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial008b_py39.py!}
```
////
In beiden Fällen bedeutet das, dass `item` ein `int` oder ein `str` sein kann.
#### Vielleicht `None` { #possibly-none }
Sie können deklarieren, dass ein Wert einen Typ haben könnte, wie `str`, dass er aber auch `None` sein könnte.
Sie können deklarieren, dass ein Wert ein `str`, aber vielleicht auch `None` sein kann.
In Python 3.6 und darüber (inklusive Python 3.10) können Sie das deklarieren, indem Sie `Optional` vom `typing` Modul importieren und verwenden.
```Python hl_lines="1 4"
{!../../docs_src/python_types/tutorial009_py39.py!}
```
Wenn Sie `Optional[str]` anstelle von nur `str` verwenden, wird Ihr Editor Ihnen dabei helfen, Fehler zu erkennen, bei denen Sie annehmen könnten, dass ein Wert immer eine String (`str`) ist, obwohl er auch `None` sein könnte.
`Optional[Something]` ist tatsächlich eine Abkürzung für `Union[Something, None]`, diese beiden sind äquivalent.
Das bedeutet auch, dass Sie in Python 3.10 `Something | None` verwenden können:
//// tab | Python 3.10+
@@ -245,7 +266,96 @@ Sie können deklarieren, dass ein Wert einen Typ haben könnte, wie `str`, dass
////
Wenn Sie `str | None` anstelle von nur `str` verwenden, wird Ihr Editor Ihnen dabei helfen, Fehler zu erkennen, bei denen Sie annehmen könnten, dass ein Wert immer ein `str` ist, obwohl er auch `None` sein könnte.
//// tab | Python 3.9+
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial009_py39.py!}
```
////
//// tab | Python 3.9+ Alternative
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial009b_py39.py!}
```
////
#### `Union` oder `Optional` verwenden? { #using-union-or-optional }
Wenn Sie eine Python-Version unterhalb 3.10 verwenden, hier ist mein sehr **subjektiver** Standpunkt dazu:
* 🚨 Vermeiden Sie `Optional[SomeType]`
* Stattdessen ✨ **verwenden Sie `Union[SomeType, None]`** ✨.
Beide sind äquivalent und im Hintergrund dasselbe, aber ich empfehle `Union` statt `Optional`, weil das Wort „**optional**“ impliziert, dass dieser Wert, zum Beispiel als Funktionsparameter, optional ist. Tatsächlich bedeutet es aber nur „Der Wert kann `None` sein“, selbst wenn der Wert nicht optional ist und benötigt wird.
Ich denke, `Union[SomeType, None]` ist expliziter bezüglich seiner Bedeutung.
Es geht nur um Worte und Namen. Aber diese Worte können beeinflussen, wie Sie und Ihre Teamkollegen über den Code denken.
Nehmen wir zum Beispiel diese Funktion:
{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *}
Der Parameter `name` ist definiert als `Optional[str]`, aber er ist **nicht optional**, Sie können die Funktion nicht ohne diesen Parameter aufrufen:
```Python
say_hi() # Oh, nein, das löst einen Fehler aus! 😱
```
Der `name` Parameter wird **immer noch benötigt** (nicht *optional*), weil er keinen Default-Wert hat. `name` akzeptiert aber dennoch `None` als Wert:
```Python
say_hi(name=None) # Das funktioniert, None ist gültig 🎉
```
Die gute Nachricht ist, dass Sie sich darüber keine Sorgen mehr machen müssen, wenn Sie Python 3.10 verwenden, da Sie einfach `|` verwenden können, um Vereinigungen von Typen zu definieren:
{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *}
Und dann müssen Sie sich nicht mehr um Namen wie `Optional` und `Union` kümmern. 😎
#### Generische Typen { #generic-types }
Diese Typen, die Typ-Parameter in eckigen Klammern akzeptieren, werden **generische Typen** oder **Generics** genannt.
//// tab | Python 3.10+
Sie können die eingebauten Typen als Generics verwenden (mit eckigen Klammern und Typen darin):
* `list`
* `tuple`
* `set`
* `dict`
Und ebenso wie bei früheren Python-Versionen, aus dem `typing`-Modul:
* `Union`
* `Optional`
* ... und andere.
In Python 3.10 können Sie als Alternative zu den Generics `Union` und `Optional` den <abbr title='auch „bitweiser Oder-Operator“ genannt, aber diese Bedeutung ist hier nicht relevant'>vertikalen Balken (`|`)</abbr> verwenden, um Vereinigungen von Typen zu deklarieren, das ist besser und einfacher.
////
//// tab | Python 3.9+
Sie können die eingebauten Typen als Generics verwenden (mit eckigen Klammern und Typen darin):
* `list`
* `tuple`
* `set`
* `dict`
Und Generics aus dem `typing`-Modul:
* `Union`
* `Optional`
* ... und andere.
////
### Klassen als Typen { #classes-as-types }
@@ -253,11 +363,11 @@ Sie können auch eine Klasse als Typ einer Variablen deklarieren.
Nehmen wir an, Sie haben eine Klasse `Person`, mit einem Namen:
{* ../../docs_src/python_types/tutorial010_py310.py hl[1:3] *}
{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
Dann können Sie eine Variable vom Typ `Person` deklarieren:
{* ../../docs_src/python_types/tutorial010_py310.py hl[6] *}
{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
Und wiederum bekommen Sie die volle Editor-Unterstützung:
@@ -293,13 +403,19 @@ Um mehr über <a href="https://docs.pydantic.dev/" class="external-link" target=
Viel mehr von all dem werden Sie in praktischer Anwendung im [Tutorial Benutzerhandbuch](tutorial/index.md){.internal-link target=_blank} sehen.
/// tip | Tipp
Pydantic verhält sich speziell, wenn Sie `Optional` oder `Union[Something, None]` ohne einen Defaultwert verwenden. Sie können darüber in der Pydantic Dokumentation unter <a href="https://docs.pydantic.dev/2.3/usage/models/#required-fields" class="external-link" target="_blank">Erforderliche optionale Felder</a> mehr erfahren.
///
## Typhinweise mit Metadaten-Annotationen { #type-hints-with-metadata-annotations }
Python bietet auch die Möglichkeit, **zusätzliche <dfn title="Daten über die Daten, in diesem Fall Informationen über den Typ, z. B. eine Beschreibung.">Metadaten</dfn>** in Typhinweisen unterzubringen, mittels `Annotated`.
Python bietet auch die Möglichkeit, **zusätzliche <abbr title="Daten über die Daten, in diesem Fall Informationen über den Typ, z. B. eine Beschreibung.">Metadaten</abbr>** in Typhinweisen unterzubringen, mittels `Annotated`.
Sie können `Annotated` von `typing` importieren.
Seit Python 3.9 ist `Annotated` ein Teil der Standardbibliothek, Sie können es von `typing` importieren.
{* ../../docs_src/python_types/tutorial013_py310.py hl[1,4] *}
{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *}
Python selbst macht nichts mit `Annotated`. Für Editoren und andere Tools ist der Typ immer noch `str`.

View File

@@ -1,11 +0,0 @@
/// details | 🌐 Übersetzung durch KI und Menschen
Diese Übersetzung wurde von KI erstellt, angeleitet von Menschen. 🤝
Sie könnte Fehler enthalten, etwa Missverständnisse des ursprünglichen Sinns oder unnatürliche Formulierungen, usw. 🤖
Sie können diese Übersetzung verbessern, indem Sie [uns helfen, die KI-LLM besser anzuleiten](https://fastapi.tiangolo.com/de/contributing/#translations).
[Englische Version](ENGLISH_VERSION_URL)
///

View File

@@ -15,7 +15,7 @@ Hierzu zählen beispielsweise:
Importieren Sie zunächst `BackgroundTasks` und definieren Sie einen Parameter in Ihrer *Pfadoperation-Funktion* mit der Typdeklaration `BackgroundTasks`:
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[1,13] *}
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *}
**FastAPI** erstellt für Sie das Objekt vom Typ `BackgroundTasks` und übergibt es als diesen Parameter.
@@ -31,13 +31,13 @@ In diesem Fall schreibt die Taskfunktion in eine Datei (den Versand einer E-Mail
Und da der Schreibvorgang nicht `async` und `await` verwendet, definieren wir die Funktion mit normalem `def`:
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[6:9] *}
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *}
## Den Hintergrundtask hinzufügen { #add-the-background-task }
Übergeben Sie innerhalb Ihrer *Pfadoperation-Funktion* Ihre Taskfunktion mit der Methode `.add_task()` an das *Hintergrundtasks*-Objekt:
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[14] *}
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *}
`.add_task()` erhält als Argumente:

View File

@@ -85,7 +85,7 @@ Sie können die *Pfadoperationen* für dieses Modul mit `APIRouter` erstellen.
Sie importieren ihn und erstellen eine „Instanz“ auf die gleiche Weise wie mit der Klasse `FastAPI`:
{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[1,3] title["app/routers/users.py"] *}
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *}
### *Pfadoperationen* mit `APIRouter` { #path-operations-with-apirouter }
@@ -93,7 +93,7 @@ Und dann verwenden Sie ihn, um Ihre *Pfadoperationen* zu deklarieren.
Verwenden Sie ihn auf die gleiche Weise wie die Klasse `FastAPI`:
{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
Sie können sich `APIRouter` als eine „Mini-`FastAPI`“-Klasse vorstellen.
@@ -117,7 +117,7 @@ Also fügen wir sie in ihr eigenes `dependencies`-Modul (`app/dependencies.py`)
Wir werden nun eine einfache Abhängigkeit verwenden, um einen benutzerdefinierten `X-Token`-Header zu lesen:
{* ../../docs_src/bigger_applications/app_an_py310/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
{* ../../docs_src/bigger_applications/app_an_py39/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
/// tip | Tipp
@@ -149,7 +149,7 @@ Wir wissen, dass alle *Pfadoperationen* in diesem Modul folgendes haben:
Anstatt also alles zu jeder *Pfadoperation* hinzuzufügen, können wir es dem `APIRouter` hinzufügen.
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
Da der Pfad jeder *Pfadoperation* mit `/` beginnen muss, wie in:
@@ -208,7 +208,7 @@ Und wir müssen die Abhängigkeitsfunktion aus dem Modul `app.dependencies` impo
Daher verwenden wir einen relativen Import mit `..` für die Abhängigkeiten:
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[3] title["app/routers/items.py"] *}
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[3] title["app/routers/items.py"] *}
#### Wie relative Importe funktionieren { #how-relative-imports-work }
@@ -279,7 +279,7 @@ Wir fügen weder das Präfix `/items` noch `tags=["items"]` zu jeder *Pfadoperat
Aber wir können immer noch _mehr_ `tags` hinzufügen, die auf eine bestimmte *Pfadoperation* angewendet werden, sowie einige zusätzliche `responses`, die speziell für diese *Pfadoperation* gelten:
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[30:31] title["app/routers/items.py"] *}
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[30:31] title["app/routers/items.py"] *}
/// tip | Tipp
@@ -305,13 +305,13 @@ Sie importieren und erstellen wie gewohnt eine `FastAPI`-Klasse.
Und wir können sogar [globale Abhängigkeiten](dependencies/global-dependencies.md){.internal-link target=_blank} deklarieren, die mit den Abhängigkeiten für jeden `APIRouter` kombiniert werden:
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[1,3,7] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[1,3,7] title["app/main.py"] *}
### Den `APIRouter` importieren { #import-the-apirouter }
Jetzt importieren wir die anderen Submodule, die `APIRouter` haben:
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[4:5] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[4:5] title["app/main.py"] *}
Da es sich bei den Dateien `app/routers/users.py` und `app/routers/items.py` um Submodule handelt, die Teil desselben Python-Packages `app` sind, können wir einen einzelnen Punkt `.` verwenden, um sie mit „relativen Imports“ zu importieren.
@@ -374,13 +374,13 @@ würde der `router` von `users` den von `items` überschreiben und wir könnten
Um also beide in derselben Datei verwenden zu können, importieren wir die Submodule direkt:
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[5] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *}
### Die `APIRouter` für `users` und `items` inkludieren { #include-the-apirouters-for-users-and-items }
Inkludieren wir nun die `router` aus diesen Submodulen `users` und `items`:
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[10:11] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[10:11] title["app/main.py"] *}
/// info | Info
@@ -420,13 +420,13 @@ Sie enthält einen `APIRouter` mit einigen administrativen *Pfadoperationen*, di
In diesem Beispiel wird es ganz einfach sein. Nehmen wir jedoch an, dass wir, da sie mit anderen Projekten in der Organisation geteilt wird, sie nicht ändern und kein `prefix`, `dependencies`, `tags`, usw. direkt zum `APIRouter` hinzufügen können:
{* ../../docs_src/bigger_applications/app_an_py310/internal/admin.py hl[3] title["app/internal/admin.py"] *}
{* ../../docs_src/bigger_applications/app_an_py39/internal/admin.py hl[3] title["app/internal/admin.py"] *}
Aber wir möchten immer noch ein benutzerdefiniertes `prefix` festlegen, wenn wir den `APIRouter` einbinden, sodass alle seine *Pfadoperationen* mit `/admin` beginnen, wir möchten es mit den `dependencies` sichern, die wir bereits für dieses Projekt haben, und wir möchten `tags` und `responses` hinzufügen.
Wir können das alles deklarieren, ohne den ursprünglichen `APIRouter` ändern zu müssen, indem wir diese Parameter an `app.include_router()` übergeben:
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[14:17] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[14:17] title["app/main.py"] *}
Auf diese Weise bleibt der ursprüngliche `APIRouter` unverändert, sodass wir dieselbe `app/internal/admin.py`-Datei weiterhin mit anderen Projekten in der Organisation teilen können.
@@ -447,7 +447,7 @@ Wir können *Pfadoperationen* auch direkt zur `FastAPI`-App hinzufügen.
Hier machen wir es ... nur um zu zeigen, dass wir es können 🤷:
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[21:23] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[21:23] title["app/main.py"] *}
und es wird korrekt funktionieren, zusammen mit allen anderen *Pfadoperationen*, die mit `app.include_router()` hinzugefügt wurden.

View File

@@ -44,7 +44,7 @@ Beachten Sie, wie jedes Attribut eines Modells mit einem Typ, Defaultwert und `F
Sie können zusätzliche Information in `Field`, `Query`, `Body`, usw. deklarieren. Und es wird im generierten JSON-Schema untergebracht.
Sie werden später in der Dokumentation mehr darüber lernen, wie man zusätzliche Information unterbringt, wenn Sie lernen, Beispiele zu deklarieren.
Sie werden später mehr darüber lernen, wie man zusätzliche Information unterbringt, wenn Sie lernen, Beispiele zu deklarieren.
/// warning | Achtung

View File

@@ -104,6 +104,12 @@ Da einfache Werte standardmäßig als Query-Parameter interpretiert werden, müs
q: str | None = None
```
Oder in Python 3.9:
```Python
q: Union[str, None] = None
```
Zum Beispiel:
{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *}

View File

@@ -163,7 +163,7 @@ images: list[Image]
so wie in:
{* ../../docs_src/body_nested_models/tutorial008_py310.py hl[13] *}
{* ../../docs_src/body_nested_models/tutorial008_py39.py hl[13] *}
## Editor-Unterstützung überall { #editor-support-everywhere }
@@ -193,7 +193,7 @@ Das schauen wir uns mal an.
Im folgenden Beispiel akzeptieren Sie irgendein `dict`, solange es `int`-Schlüssel und `float`-Werte hat:
{* ../../docs_src/body_nested_models/tutorial009_py310.py hl[7] *}
{* ../../docs_src/body_nested_models/tutorial009_py39.py hl[7] *}
/// tip | Tipp

View File

@@ -154,7 +154,7 @@ Die Funktionsparameter werden wie folgt erkannt:
FastAPI weiß, dass der Wert von `q` nicht erforderlich ist, aufgrund des definierten Defaultwertes `= None`.
Das `str | None` wird von FastAPI nicht verwendet, um zu bestimmen, dass der Wert nicht erforderlich ist. FastAPI weiß, dass er nicht erforderlich ist, weil er einen Defaultwert von `= None` hat.
Das `str | None` (Python 3.10+) oder `Union` in `Union[str, None]` (Python 3.9+) wird von FastAPI nicht verwendet, um zu bestimmen, dass der Wert nicht erforderlich ist. FastAPI weiß, dass er nicht erforderlich ist, weil er einen Defaultwert von `= None` hat.
Das Hinzufügen der Typannotationen ermöglicht jedoch Ihrem Editor, Ihnen eine bessere Unterstützung zu bieten und Fehler zu erkennen.

View File

@@ -46,7 +46,7 @@ Aber selbst wenn Sie die **Daten ausfüllen** und auf „Ausführen“ klicken,
In einigen speziellen Anwendungsfällen (wahrscheinlich nicht sehr häufig) möchten Sie möglicherweise die Cookies, die Sie empfangen möchten, **einschränken**.
Ihre API hat jetzt die Macht, ihre eigene <dfn title="Das ist ein Scherz, nur für den Fall. Es hat nichts mit Cookie-Einwilligungen zu tun, aber es ist witzig, dass selbst die API jetzt die armen Cookies ablehnen kann. Haben Sie einen Keks. 🍪">Cookie-Einwilligung</dfn> zu kontrollieren. 🤪🍪
Ihre API hat jetzt die Macht, ihre eigene <abbr title="Das ist ein Scherz, nur für den Fall. Es hat nichts mit Cookie-Einwilligungen zu tun, aber es ist witzig, dass selbst die API jetzt die armen Cookies ablehnen kann. Haben Sie einen Keks. 🍪">Cookie-Einwilligung</abbr> zu kontrollieren. 🤪🍪
Sie können die Modellkonfiguration von Pydantic verwenden, um `extra` Felder zu verbieten (`forbid`):
@@ -54,9 +54,9 @@ Sie können die Modellkonfiguration von Pydantic verwenden, um `extra` Felder zu
Wenn ein Client versucht, einige **zusätzliche Cookies** zu senden, erhält er eine **Error-<abbr title="Response Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>**.
Arme Cookie-Banner, wie sie sich mühen, Ihre Einwilligung zu erhalten, dass die <dfn title="Das ist ein weiterer Scherz. Beachten Sie mich nicht. Trinken Sie einen Kaffee zu Ihrem Keks. ☕">API sie ablehnen darf</dfn>. 🍪
Arme Cookie-Banner, wie sie sich mühen, Ihre Einwilligung zu erhalten, dass die <abbr title="Das ist ein weiterer Scherz. Beachten Sie mich nicht. Trinken Sie einen Kaffee zu Ihrem Keks. ☕">API sie ablehnen darf</abbr>. 🍪
Wenn der Client beispielsweise versucht, ein `santa_tracker`-Cookie mit einem Wert von `good-list-please` zu senden, erhält der Client eine **Error-Response**, die ihm mitteilt, dass das `santa_tracker` <dfn title="Santa missbilligt den Mangel an Cookies. 🎅 Okay, keine Cookie-Witze mehr.">Cookie nicht erlaubt ist</dfn>:
Wenn der Client beispielsweise versucht, ein `santa_tracker`-Cookie mit einem Wert von `good-list-please` zu senden, erhält der Client eine **Error-Response**, die ihm mitteilt, dass das `santa_tracker` <abbr title="Santa beschwert sich über den Mangel an Cookies. 🎅 Okay, keine Cookie-Witze mehr.">Cookie nicht erlaubt ist</abbr>:
```json
{
@@ -73,4 +73,4 @@ Wenn der Client beispielsweise versucht, ein `santa_tracker`-Cookie mit einem We
## Zusammenfassung { #summary }
Sie können **Pydantic-Modelle** verwenden, um <dfn title="Nehmen Sie einen letzten Keks, bevor Sie gehen. 🍪">**Cookies**</dfn> in **FastAPI** zu deklarieren. 😎
Sie können **Pydantic-Modelle** verwenden, um <abbr title="Nehmen Sie einen letzten Keks, bevor Sie gehen. 🍪">**Cookies**</abbr> in **FastAPI** zu deklarieren. 😎

View File

@@ -46,7 +46,7 @@ Sie können auch angeben, ob Ihr Backend erlaubt:
* Bestimmte HTTP-Methoden (`POST`, `PUT`) oder alle mit der Wildcard `"*"`.
* Bestimmte HTTP-Header oder alle mit der Wildcard `"*"`.
{* ../../docs_src/cors/tutorial001_py310.py hl[2,6:11,13:19] *}
{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *}
Die von der `CORSMiddleware`-Implementierung verwendeten Defaultparameter sind standardmäßig restriktiv, daher müssen Sie bestimmte Origins, Methoden oder Header ausdrücklich aktivieren, damit Browser sie in einem Cross-Domain-Kontext verwenden dürfen.

View File

@@ -6,7 +6,7 @@ Sie können den Debugger in Ihrem Editor verbinden, zum Beispiel mit Visual Stud
Importieren und führen Sie `uvicorn` direkt in Ihrer FastAPI-Anwendung aus:
{* ../../docs_src/debugging/tutorial001_py310.py hl[1,15] *}
{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *}
### Über `__name__ == "__main__"` { #about-name-main }

View File

@@ -101,7 +101,7 @@ Jetzt können Sie Ihre Abhängigkeit mithilfe dieser Klasse deklarieren.
Beachten Sie, wie wir `CommonQueryParams` im obigen Code zweimal schreiben:
//// tab | Python 3.10+
//// tab | Python 3.9+
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
////
//// tab | Python 3.10+ nicht annotiert
//// tab | Python 3.9+ nicht annotiert
/// tip | Tipp
@@ -137,7 +137,7 @@ Aus diesem extrahiert FastAPI die deklarierten Parameter, und dieses ist es, was
In diesem Fall hat das erste `CommonQueryParams` in:
//// tab | Python 3.10+
//// tab | Python 3.9+
```Python
commons: Annotated[CommonQueryParams, ...
@@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ...
////
//// tab | Python 3.10+ nicht annotiert
//// tab | Python 3.9+ nicht annotiert
/// tip | Tipp
@@ -163,7 +163,7 @@ commons: CommonQueryParams ...
Sie könnten tatsächlich einfach schreiben:
//// tab | Python 3.10+
//// tab | Python 3.9+
```Python
commons: Annotated[Any, Depends(CommonQueryParams)]
@@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)]
////
//// tab | Python 3.10+ nicht annotiert
//// tab | Python 3.9+ nicht annotiert
/// tip | Tipp
@@ -197,7 +197,7 @@ Es wird jedoch empfohlen, den Typ zu deklarieren, da Ihr Editor so weiß, was al
Aber Sie sehen, dass wir hier etwas Codeduplizierung haben, indem wir `CommonQueryParams` zweimal schreiben:
//// tab | Python 3.10+
//// tab | Python 3.9+
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
////
//// tab | Python 3.10+ nicht annotiert
//// tab | Python 3.9+ nicht annotiert
/// tip | Tipp
@@ -225,7 +225,7 @@ In diesem speziellen Fall können Sie Folgendes tun:
Anstatt zu schreiben:
//// tab | Python 3.10+
//// tab | Python 3.9+
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
////
//// tab | Python 3.10+ nicht annotiert
//// tab | Python 3.9+ nicht annotiert
/// tip | Tipp
@@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
... schreiben Sie:
//// tab | Python 3.10+
//// tab | Python 3.9+
```Python
commons: Annotated[CommonQueryParams, Depends()]
@@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()]
////
//// tab | Python 3.10+ nicht annotiert
//// tab | Python 3.9+ nicht annotiert
/// tip | Tipp

View File

@@ -6,15 +6,15 @@ Oder die Abhängigkeit gibt keinen Wert zurück.
Aber Sie müssen sie trotzdem ausführen/auflösen.
In diesen Fällen können Sie, anstatt einen Parameter der *Pfadoperation-Funktion* mit `Depends` zu deklarieren, eine `list` von `dependencies` zum *Pfadoperation-Dekorator* hinzufügen.
In diesen Fällen können Sie, anstatt einen Parameter der *Pfadoperation-Funktion* mit `Depends` zu deklarieren, eine `list`e von `dependencies` zum *Pfadoperation-Dekorator* hinzufügen.
## `dependencies` zum *Pfadoperation-Dekorator* hinzufügen { #add-dependencies-to-the-path-operation-decorator }
Der *Pfadoperation-Dekorator* erhält ein optionales Argument `dependencies`.
Es sollte eine `list` von `Depends()` sein:
Es sollte eine `list`e von `Depends()` sein:
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[19] *}
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[19] *}
Diese Abhängigkeiten werden auf die gleiche Weise wie normale Abhängigkeiten ausgeführt/aufgelöst. Aber ihr Wert (falls sie einen zurückgeben) wird nicht an Ihre *Pfadoperation-Funktion* übergeben.
@@ -44,13 +44,13 @@ Sie können dieselben Abhängigkeits-*Funktionen* verwenden, die Sie normalerwei
Sie können Anforderungen für einen <abbr title="Request Anfrage: Daten, die der Client zum Server sendet">Request</abbr> (wie Header) oder andere Unterabhängigkeiten deklarieren:
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[8,13] *}
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[8,13] *}
### Exceptions auslösen { #raise-exceptions }
Die Abhängigkeiten können Exceptions `raise`n, genau wie normale Abhängigkeiten:
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[10,15] *}
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[10,15] *}
### Rückgabewerte { #return-values }
@@ -58,7 +58,7 @@ Und sie können Werte zurückgeben oder nicht, die Werte werden nicht verwendet.
Sie können also eine normale Abhängigkeit (die einen Wert zurückgibt), die Sie bereits an anderer Stelle verwenden, wiederverwenden, und auch wenn der Wert nicht verwendet wird, wird die Abhängigkeit ausgeführt:
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[11,16] *}
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[11,16] *}
## Abhängigkeiten für eine Gruppe von *Pfadoperationen* { #dependencies-for-a-group-of-path-operations }

View File

@@ -1,6 +1,6 @@
# Abhängigkeiten mit `yield` { #dependencies-with-yield }
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.
FastAPI unterstützt Abhängigkeiten, die nach Abschluss einige <abbr title="Manchmal auch genannt „Exit Code“, „Cleanup Code“, „Teardown Code“, „Closing Code“, „Kontextmanager Exit Code“, usw.">zusätzliche Schritte ausführen</abbr>.
Verwenden Sie dazu `yield` statt `return` und schreiben Sie die zusätzlichen Schritte / den zusätzlichen Code danach.
@@ -29,15 +29,15 @@ Sie könnten damit beispielsweise eine Datenbanksession erstellen und diese nach
Nur der Code vor und einschließlich der `yield`-Anweisung wird ausgeführt, bevor eine <abbr title="Response Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr> erzeugt wird:
{* ../../docs_src/dependencies/tutorial007_py310.py hl[2:4] *}
{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *}
Der ge`yield`ete Wert ist das, was in *Pfadoperationen* und andere Abhängigkeiten eingefügt wird:
{* ../../docs_src/dependencies/tutorial007_py310.py hl[4] *}
{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *}
Der auf die `yield`-Anweisung folgende Code wird nach der Response ausgeführt:
{* ../../docs_src/dependencies/tutorial007_py310.py hl[5:6] *}
{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *}
/// tip | Tipp
@@ -57,17 +57,17 @@ Sie können also mit `except SomeException` diese bestimmte Exception innerhalb
Auf die gleiche Weise können Sie `finally` verwenden, um sicherzustellen, dass die Exit-Schritte ausgeführt werden, unabhängig davon, ob eine Exception geworfen wurde oder nicht.
{* ../../docs_src/dependencies/tutorial007_py310.py hl[3,5] *}
{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *}
## Unterabhängigkeiten mit `yield` { #sub-dependencies-with-yield }
Sie können Unterabhängigkeiten und „Bäume“ von Unterabhhängigkeiten beliebiger Größe und Form haben, und einige oder alle davon können `yield` verwenden.
Sie können Unterabhängigkeiten und „Bäume“ von Unterabhängigkeiten beliebiger Größe und Form haben, und einige oder alle davon können `yield` verwenden.
**FastAPI** stellt sicher, dass der „Exit-Code“ in jeder Abhängigkeit mit `yield` in der richtigen Reihenfolge ausgeführt wird.
Beispielsweise kann `dependency_c` von `dependency_b` und `dependency_b` von `dependency_a` abhängen:
{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[6,14,22] *}
{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[6,14,22] *}
Und alle können `yield` verwenden.
@@ -75,7 +75,7 @@ In diesem Fall benötigt `dependency_c` zum Ausführen seines Exit-Codes, dass d
Und wiederum benötigt `dependency_b` den Wert von `dependency_a` (hier `dep_a` genannt) für seinen Exit-Code.
{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[18:19,26:27] *}
{* ../../docs_src/dependencies/tutorial008_an_py39.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.
@@ -109,7 +109,7 @@ Aber es ist für Sie da, wenn Sie es brauchen. 🤓
///
{* ../../docs_src/dependencies/tutorial008b_an_py310.py hl[18:22,31] *}
{* ../../docs_src/dependencies/tutorial008b_an_py39.py hl[18:22,31] *}
Wenn Sie Exceptions abfangen und darauf basierend eine benutzerdefinierte Response erstellen möchten, erstellen Sie einen [benutzerdefinierten Exceptionhandler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
@@ -117,7 +117,7 @@ Wenn Sie Exceptions abfangen und darauf basierend eine benutzerdefinierte Respon
Wenn Sie eine Exception mit `except` in einer Abhängigkeit mit `yield` abfangen und sie nicht erneut auslösen (oder eine neue Exception auslösen), kann FastAPI nicht feststellen, dass es eine Exception gab, genau so wie es bei normalem Python der Fall wäre:
{* ../../docs_src/dependencies/tutorial008c_an_py310.py hl[15:16] *}
{* ../../docs_src/dependencies/tutorial008c_an_py39.py hl[15:16] *}
In diesem Fall sieht der Client eine *HTTP 500 Internal Server Error*-Response, wie es sein sollte, da wir keine `HTTPException` oder Ähnliches auslösen, aber der Server hat **keine Logs** oder einen anderen Hinweis darauf, was der Fehler war. 😱
@@ -127,7 +127,7 @@ Wenn Sie eine Exception in einer Abhängigkeit mit `yield` abfangen, sollten Sie
Sie können dieselbe Exception mit `raise` erneut auslösen:
{* ../../docs_src/dependencies/tutorial008d_an_py310.py hl[17] *}
{* ../../docs_src/dependencies/tutorial008d_an_py39.py hl[17] *}
Jetzt erhält der Client dieselbe *HTTP 500 Internal Server Error*-Response, aber der Server enthält unseren benutzerdefinierten `InternalError` in den Logs. 😎
@@ -190,7 +190,7 @@ Normalerweise wird der Exit-Code von Abhängigkeiten mit `yield` ausgeführt **n
Wenn Sie aber wissen, dass Sie die Abhängigkeit nach der Rückkehr aus der *Pfadoperation-Funktion* nicht mehr benötigen, können Sie `Depends(scope="function")` verwenden, um FastAPI mitzuteilen, dass es die Abhängigkeit nach der Rückkehr aus der *Pfadoperation-Funktion* schließen soll, jedoch **bevor** die **Response gesendet wird**.
{* ../../docs_src/dependencies/tutorial008e_an_py310.py hl[12,16] *}
{* ../../docs_src/dependencies/tutorial008e_an_py39.py hl[12,16] *}
`Depends()` erhält einen `scope`-Parameter, der sein kann:
@@ -268,7 +268,7 @@ In Python können Sie Kontextmanager erstellen, indem Sie <a href="https://docs.
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] *}
{* ../../docs_src/dependencies/tutorial010_py39.py hl[1:9,13] *}
/// tip | Tipp

View File

@@ -6,8 +6,7 @@ Bei einigen Anwendungstypen möchten Sie möglicherweise Abhängigkeiten zur ges
In diesem Fall werden sie auf alle *Pfadoperationen* in der Anwendung angewendet:
{* ../../docs_src/dependencies/tutorial012_an_py310.py hl[17] *}
{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[17] *}
Und alle Ideen aus dem Abschnitt über das [Hinzufügen von `dependencies` zu den *Pfadoperation-Dekoratoren*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} gelten weiterhin, aber in diesem Fall für alle *Pfadoperationen* in der App.

View File

@@ -1,6 +1,6 @@
# Abhängigkeiten { #dependencies }
**FastAPI** hat ein sehr mächtiges, aber intuitives **<dfn title="auch bekannt als Komponenten, Ressourcen, Provider, Services, Injectables">Abhängigkeitsinjektion</dfn>** System.
**FastAPI** hat ein sehr mächtiges, aber intuitives **<abbr title="auch bekannt als: Komponenten, Ressourcen, Provider, Services, Injectables">Dependency Injection</abbr>** System.
Es ist so konzipiert, sehr einfach zu verwenden zu sein und es jedem Entwickler sehr leicht zu machen, andere Komponenten mit **FastAPI** zu integrieren.

View File

@@ -58,11 +58,11 @@ query_extractor --> query_or_cookie_extractor --> read_query
Wenn eine Ihrer Abhängigkeiten mehrmals für dieselbe *Pfadoperation* deklariert wird, beispielsweise wenn mehrere Abhängigkeiten eine gemeinsame Unterabhängigkeit haben, wird **FastAPI** diese Unterabhängigkeit nur einmal pro <abbr title="Request Anfrage: Daten, die der Client zum Server sendet">Request</abbr> aufrufen.
Und es speichert den zurückgegebenen Wert in einem <dfn title="Hilfsprogramm/System zum Speichern berechneter/erzeugter Werte, um sie wiederzuverwenden, anstatt sie erneut zu berechnen.">„Cache“</dfn> und übergibt diesen gecachten Wert an alle „Dependanten“, die ihn in diesem spezifischen Request benötigen, anstatt die Abhängigkeit mehrmals für denselben Request aufzurufen.
Und es speichert den zurückgegebenen Wert in einem <abbr title="Mechanismus, der bereits berechnete/generierte Werte zwischenspeichert, um sie später wiederzuverwenden, anstatt sie erneut zu berechnen.">„Cache“</abbr> und übergibt diesen gecachten Wert an alle „Dependanten“, die ihn in diesem spezifischen Request benötigen, anstatt die Abhängigkeit mehrmals für denselben Request aufzurufen.
In einem fortgeschrittenen Szenario, bei dem Sie wissen, dass die Abhängigkeit bei jedem Schritt (möglicherweise mehrmals) in demselben Request aufgerufen werden muss, anstatt den zwischengespeicherten Wert zu verwenden, können Sie den Parameter `use_cache=False` festlegen, wenn Sie `Depends` verwenden:
//// tab | Python 3.10+
//// tab | Python 3.9+
```Python hl_lines="1"
async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
@@ -71,7 +71,7 @@ async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_ca
////
//// tab | Python 3.10+ nicht annotiert
//// tab | Python 3.9+ nicht annotiert
/// tip | Tipp

View File

@@ -190,9 +190,9 @@ Aber wenn wir das in der Zuweisung `response_model=PlaneItem | CarItem` machen,
Auf die gleiche Weise können Sie Responses von Listen von Objekten deklarieren.
Dafür verwenden Sie Pythons Standard-`list`:
Dafür verwenden Sie Pythons Standard-`typing.List` (oder nur `list` in Python 3.9 und höher):
{* ../../docs_src/extra_models/tutorial004_py310.py hl[18] *}
{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
## Response mit beliebigem `dict` { #response-with-arbitrary-dict }
@@ -200,9 +200,9 @@ Sie können auch eine Response deklarieren, die ein beliebiges `dict` zurückgib
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).
In diesem Fall können Sie `dict` verwenden:
In diesem Fall können Sie `typing.Dict` verwenden (oder nur `dict` in Python 3.9 und höher):
{* ../../docs_src/extra_models/tutorial005_py310.py hl[6] *}
{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *}
## Zusammenfassung { #recap }

View File

@@ -2,7 +2,7 @@
Die einfachste FastAPI-Datei könnte wie folgt aussehen:
{* ../../docs_src/first_steps/tutorial001_py310.py *}
{* ../../docs_src/first_steps/tutorial001_py39.py *}
Kopieren Sie das in eine Datei `main.py`.
@@ -183,7 +183,7 @@ Das war's! Jetzt können Sie Ihre App unter dieser URL aufrufen. ✨
### Schritt 1: `FastAPI` importieren { #step-1-import-fastapi }
{* ../../docs_src/first_steps/tutorial001_py310.py hl[1] *}
{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *}
`FastAPI` ist eine Python-Klasse, die die gesamte Funktionalität für Ihre API bereitstellt.
@@ -197,7 +197,7 @@ Sie können alle <a href="https://www.starlette.dev/" class="external-link" targ
### Schritt 2: Erzeugen einer `FastAPI`-„Instanz“ { #step-2-create-a-fastapi-instance }
{* ../../docs_src/first_steps/tutorial001_py310.py hl[3] *}
{* ../../docs_src/first_steps/tutorial001_py39.py hl[3] *}
In diesem Beispiel ist die Variable `app` eine „Instanz“ der Klasse `FastAPI`.
@@ -266,12 +266,12 @@ Wir werden sie auch „**Operationen**“ nennen.
#### Definieren eines *Pfadoperation-Dekorators* { #define-a-path-operation-decorator }
{* ../../docs_src/first_steps/tutorial001_py310.py hl[6] *}
{* ../../docs_src/first_steps/tutorial001_py39.py hl[6] *}
Das `@app.get("/")` sagt **FastAPI**, dass die Funktion direkt darunter für die Bearbeitung von <abbr title="Request Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> zuständig ist, die an:
* den Pfad `/`
* unter der Verwendung der <dfn title="eine HTTP-GET-Methode"><code>get</code>-Operation</dfn> gehen
* unter der Verwendung der <abbr title="eine HTTP-GET-Methode"><code>get</code>-Operation</abbr> gehen
/// info | `@decorator` Info
@@ -320,7 +320,7 @@ Das ist unsere „**Pfadoperation-Funktion**“:
* **Operation**: ist `get`.
* **Funktion**: ist die Funktion direkt unter dem „Dekorator“ (unter `@app.get("/")`).
{* ../../docs_src/first_steps/tutorial001_py310.py hl[7] *}
{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *}
Dies ist eine Python-Funktion.
@@ -332,7 +332,7 @@ In diesem Fall handelt es sich um eine `async`-Funktion.
Sie könnten sie auch als normale Funktion anstelle von `async def` definieren:
{* ../../docs_src/first_steps/tutorial003_py310.py hl[7] *}
{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *}
/// note | Hinweis
@@ -342,7 +342,7 @@ Wenn Sie den Unterschied nicht kennen, lesen Sie [Async: *„In Eile?“*](../as
### Schritt 5: den Inhalt zurückgeben { #step-5-return-the-content }
{* ../../docs_src/first_steps/tutorial001_py310.py hl[8] *}
{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
Sie können ein `dict`, eine `list`, einzelne Werte wie `str`, `int`, usw. zurückgeben.

View File

@@ -25,7 +25,7 @@ Um HTTP-<abbr title="Response Antwort: Daten, die der Server zum anfragenden
### `HTTPException` importieren { #import-httpexception }
{* ../../docs_src/handling_errors/tutorial001_py310.py hl[1] *}
{* ../../docs_src/handling_errors/tutorial001_py39.py hl[1] *}
### Eine `HTTPException` in Ihrem Code auslösen { #raise-an-httpexception-in-your-code }
@@ -39,7 +39,7 @@ Der Vorteil des Auslösens einer Exception gegenüber dem Zurückgeben eines Wer
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:
{* ../../docs_src/handling_errors/tutorial001_py310.py hl[11] *}
{* ../../docs_src/handling_errors/tutorial001_py39.py hl[11] *}
### Die resultierende Response { #the-resulting-response }
@@ -77,11 +77,11 @@ Sie werden es wahrscheinlich nicht direkt in Ihrem Code verwenden müssen.
Aber falls Sie es für ein fortgeschrittenes Szenario benötigen, können Sie benutzerdefinierte Header hinzufügen:
{* ../../docs_src/handling_errors/tutorial002_py310.py hl[14] *}
{* ../../docs_src/handling_errors/tutorial002_py39.py hl[14] *}
## Benutzerdefinierte Exceptionhandler installieren { #install-custom-exception-handlers }
Sie können benutzerdefinierte <a href="https://www.starlette.dev/exceptions/" class="external-link" target="_blank">Exceptionhandler mit den gleichen Exception-Werkzeugen von Starlette</a> hinzufügen.
Sie können benutzerdefinierte <abbr title="Ausnahmebehandler: Funktion, die sich um die Bearbeitung einer Exception kümmert">Exceptionhandler</abbr> mit <a href="https://www.starlette.dev/exceptions/" class="external-link" target="_blank">den gleichen Exception-Werkzeugen von Starlette</a> hinzufügen.
Angenommen, Sie haben eine benutzerdefinierte Exception `UnicornException`, die Sie (oder eine Bibliothek, die Sie verwenden) `raise`n könnten.
@@ -89,7 +89,7 @@ Und Sie möchten diese Exception global mit FastAPI handhaben.
Sie könnten einen benutzerdefinierten Exceptionhandler mit `@app.exception_handler()` hinzufügen:
{* ../../docs_src/handling_errors/tutorial003_py310.py hl[5:7,13:18,24] *}
{* ../../docs_src/handling_errors/tutorial003_py39.py hl[5:7,13:18,24] *}
Hier, wenn Sie `/unicorns/yolo` anfordern, wird die *Pfadoperation* eine `UnicornException` `raise`n.
@@ -127,7 +127,7 @@ Um diesen zu überschreiben, importieren Sie den `RequestValidationError` und ve
Der Exceptionhandler erhält einen `Request` und die Exception.
{* ../../docs_src/handling_errors/tutorial004_py310.py hl[2,14:19] *}
{* ../../docs_src/handling_errors/tutorial004_py39.py hl[2,14:19] *}
Wenn Sie nun zu `/items/foo` gehen, erhalten Sie anstelle des standardmäßigen JSON-Fehlers mit:
@@ -159,7 +159,7 @@ Auf die gleiche Weise können Sie den `HTTPException`-Handler überschreiben.
Zum Beispiel könnten Sie eine Klartext-Response statt JSON für diese Fehler zurückgeben wollen:
{* ../../docs_src/handling_errors/tutorial004_py310.py hl[3:4,9:11,25] *}
{* ../../docs_src/handling_errors/tutorial004_py39.py hl[3:4,9:11,25] *}
/// note | Technische Details
@@ -183,7 +183,7 @@ Der `RequestValidationError` enthält den empfangenen `body` mit den ungültigen
Sie könnten diesen während der Entwicklung Ihrer Anwendung verwenden, um den Body zu loggen und zu debuggen, ihn an den Benutzer zurückzugeben usw.
{* ../../docs_src/handling_errors/tutorial005_py310.py hl[14] *}
{* ../../docs_src/handling_errors/tutorial005_py39.py hl[14] *}
Versuchen Sie nun, einen ungültigen Artikel zu senden:
@@ -239,6 +239,6 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
Wenn Sie die Exception zusammen mit den gleichen Default-Exceptionhandlern von **FastAPI** verwenden möchten, können Sie die Default-Exceptionhandler aus `fastapi.exception_handlers` importieren und wiederverwenden:
{* ../../docs_src/handling_errors/tutorial006_py310.py hl[2:5,15,21] *}
{* ../../docs_src/handling_errors/tutorial006_py39.py hl[2:5,15,21] *}
In diesem Beispiel geben Sie nur den Fehler mit einer sehr ausdrucksstarken Nachricht aus, aber Sie verstehen das Prinzip. Sie können die Exception verwenden und dann einfach die Default-Exceptionhandler wiederverwenden.

View File

@@ -18,7 +18,7 @@ Sie können die folgenden Felder festlegen, die in der OpenAPI-Spezifikation und
Sie können diese wie folgt setzen:
{* ../../docs_src/metadata/tutorial001_py310.py hl[3:16, 19:32] *}
{* ../../docs_src/metadata/tutorial001_py39.py hl[3:16, 19:32] *}
/// tip | Tipp
@@ -36,7 +36,7 @@ Seit OpenAPI 3.1.0 und FastAPI 0.99.0 können Sie die `license_info` auch mit ei
Zum Beispiel:
{* ../../docs_src/metadata/tutorial001_1_py310.py hl[31] *}
{* ../../docs_src/metadata/tutorial001_1_py39.py hl[31] *}
## Metadaten für Tags { #metadata-for-tags }
@@ -58,7 +58,7 @@ Versuchen wir es mit einem Beispiel mit Tags für `users` und `items`.
Erstellen Sie Metadaten für Ihre Tags und übergeben Sie diese an den Parameter `openapi_tags`:
{* ../../docs_src/metadata/tutorial004_py310.py hl[3:16,18] *}
{* ../../docs_src/metadata/tutorial004_py39.py hl[3:16,18] *}
Beachten Sie, dass Sie Markdown innerhalb der Beschreibungen verwenden können. Zum Beispiel wird „login“ in Fettschrift (**login**) und „fancy“ in Kursivschrift (_fancy_) angezeigt.
@@ -72,7 +72,7 @@ Sie müssen nicht für alle von Ihnen verwendeten Tags Metadaten hinzufügen.
Verwenden Sie den Parameter `tags` mit Ihren *Pfadoperationen* (und `APIRouter`n), um diese verschiedenen Tags zuzuweisen:
{* ../../docs_src/metadata/tutorial004_py310.py hl[21,26] *}
{* ../../docs_src/metadata/tutorial004_py39.py hl[21,26] *}
/// info | Info
@@ -100,7 +100,7 @@ Sie können das aber mit dem Parameter `openapi_url` konfigurieren.
Um beispielsweise festzulegen, dass es unter `/api/v1/openapi.json` bereitgestellt wird:
{* ../../docs_src/metadata/tutorial002_py310.py hl[3] *}
{* ../../docs_src/metadata/tutorial002_py39.py hl[3] *}
Wenn Sie das OpenAPI-Schema vollständig deaktivieren möchten, können Sie `openapi_url=None` festlegen, wodurch auch die Dokumentationsbenutzeroberflächen deaktiviert werden, die es verwenden.
@@ -117,4 +117,4 @@ Sie können die beiden enthaltenen Dokumentationsbenutzeroberflächen konfigurie
Um beispielsweise Swagger UI so einzustellen, dass sie unter `/documentation` bereitgestellt wird, und ReDoc zu deaktivieren:
{* ../../docs_src/metadata/tutorial003_py310.py hl[3] *}
{* ../../docs_src/metadata/tutorial003_py39.py hl[3] *}

View File

@@ -31,7 +31,7 @@ Die Middleware-Funktion erhält:
* 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.
{* ../../docs_src/middleware/tutorial001_py310.py hl[8:9,11,14] *}
{* ../../docs_src/middleware/tutorial001_py39.py hl[8:9,11,14] *}
/// tip | Tipp
@@ -57,7 +57,7 @@ Und auch nachdem die `response` generiert wurde, bevor sie zurückgegeben wird.
Sie könnten beispielsweise einen benutzerdefinierten Header `X-Process-Time` hinzufügen, der die Zeit in Sekunden enthält, die benötigt wurde, um den Request zu verarbeiten und eine Response zu generieren:
{* ../../docs_src/middleware/tutorial001_py310.py hl[10,12:13] *}
{* ../../docs_src/middleware/tutorial001_py39.py hl[10,12:13] *}
/// tip | Tipp

View File

@@ -46,7 +46,7 @@ In diesem Fall macht es Sinn, die Tags in einem `Enum` zu speichern.
**FastAPI** unterstützt das auf die gleiche Weise wie einfache Strings:
{* ../../docs_src/path_operation_configuration/tutorial002b_py310.py hl[1,8:10,13,18] *}
{* ../../docs_src/path_operation_configuration/tutorial002b_py39.py hl[1,8:10,13,18] *}
## Zusammenfassung und Beschreibung { #summary-and-description }
@@ -56,7 +56,7 @@ Sie können eine <abbr title="Zusammenfassung">`summary`</abbr> und eine <abbr t
## Beschreibung mittels Docstring { #description-from-docstring }
Da Beschreibungen oft mehrere Zeilen lang sind, können Sie die Beschreibung der *Pfadoperation* im <dfn title="Ein mehrzeiliger String (keiner Variable zugewiesen) als erster Ausdruck in einer Funktion, wird für die Dokumentation derselben verwendet">Docstring</dfn> der Funktion deklarieren, und **FastAPI** wird sie daraus auslesen.
Da Beschreibungen oft mehrere Zeilen lang sind, können Sie die Beschreibung der *Pfadoperation* im <abbr title="Ein mehrzeiliger String (keiner Variable zugewiesen) als erster Ausdruck in einer Funktion, wird für die Dokumentation derselben verwendet">Docstring</abbr> der Funktion deklarieren, und **FastAPI** wird sie daraus auslesen.
Sie können <a href="https://en.wikipedia.org/wiki/Markdown" class="external-link" target="_blank">Markdown</a> im Docstring schreiben, es wird korrekt interpretiert und angezeigt (unter Berücksichtigung der Einrückung des Docstring).
@@ -90,9 +90,9 @@ Daher, wenn Sie keine vergeben, wird **FastAPI** automatisch eine für „Erfolg
## Eine *Pfadoperation* deprecaten { #deprecate-a-path-operation }
Wenn Sie eine *Pfadoperation* als <dfn title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</dfn> kennzeichnen möchten, ohne sie zu entfernen, fügen Sie den Parameter `deprecated` hinzu:
Wenn Sie eine *Pfadoperation* als <abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr> kennzeichnen möchten, ohne sie zu entfernen, fügen Sie den Parameter `deprecated` hinzu:
{* ../../docs_src/path_operation_configuration/tutorial006_py310.py hl[16] *}
{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *}
Sie wird in der interaktiven Dokumentation gut sichtbar als deprecatet markiert werden:

View File

@@ -54,11 +54,11 @@ Für **FastAPI** spielt es keine Rolle. Es erkennt die Parameter anhand ihrer Na
Sie können Ihre Funktion also so deklarieren:
{* ../../docs_src/path_params_numeric_validations/tutorial002_py310.py hl[7] *}
{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *}
Aber bedenken Sie, dass Sie dieses Problem nicht haben, wenn Sie `Annotated` verwenden, da es nicht darauf ankommt, dass Sie keine Funktionsparameter-Defaultwerte für `Query()` oder `Path()` verwenden.
{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py310.py *}
{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py *}
## Die Parameter sortieren, wie Sie möchten: Tricks { #order-the-parameters-as-you-need-tricks }
@@ -83,13 +83,13 @@ Wenn Sie:
Python wird nichts mit diesem `*` machen, aber es wird wissen, dass alle folgenden Parameter als Schlüsselwortargumente (Schlüssel-Wert-Paare) verwendet werden sollen, auch bekannt als <abbr title="Von: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>. Selbst wenn diese keinen Defaultwert haben.
{* ../../docs_src/path_params_numeric_validations/tutorial003_py310.py hl[7] *}
{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *}
### Besser mit `Annotated` { #better-with-annotated }
Bedenken Sie, dass Sie, wenn Sie `Annotated` verwenden, da Sie keine Funktionsparameter-Defaultwerte verwenden, dieses Problem nicht haben werden und wahrscheinlich nicht `*` verwenden müssen.
{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py310.py hl[10] *}
{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py hl[10] *}
## Validierung von Zahlen: Größer oder gleich { #number-validations-greater-than-or-equal }
@@ -97,7 +97,7 @@ Mit `Query` und `Path` (und anderen, die Sie später sehen werden) können Sie Z
Hier, mit `ge=1`, muss `item_id` eine ganze Zahl sein, die „`g`reater than or `e`qual to“ (größer oder gleich) `1` ist.
{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py310.py hl[10] *}
{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *}
## Validierung von Zahlen: Größer und kleiner oder gleich { #number-validations-greater-than-and-less-than-or-equal }
@@ -106,7 +106,7 @@ Das Gleiche gilt für:
* `gt`: `g`reater `t`han (größer als)
* `le`: `l`ess than or `e`qual (kleiner oder gleich)
{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py310.py hl[10] *}
{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py hl[10] *}
## Validierung von Zahlen: Floats, größer und kleiner { #number-validations-floats-greater-than-and-less-than }
@@ -118,7 +118,7 @@ Also wäre `0.5` ein gültiger Wert. Aber `0.0` oder `0` nicht.
Und das Gleiche gilt für <abbr title="less than kleiner als"><code>lt</code></abbr>.
{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py310.py hl[13] *}
{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *}
## Zusammenfassung { #recap }

View File

@@ -2,7 +2,7 @@
Sie können Pfad-„Parameter“ oder -„Variablen“ mit der gleichen Syntax deklarieren, welche in Python-<abbr title="Formatstring Formatierter String: Der String enthält Ausdrücke, die mit geschweiften Klammern umschlossen sind. Solche Stellen werden durch den Wert des Ausdrucks ersetzt">Formatstrings</abbr> verwendet wird:
{* ../../docs_src/path_params/tutorial001_py310.py hl[6:7] *}
{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *}
Der Wert des Pfad-Parameters `item_id` wird Ihrer Funktion als das Argument `item_id` übergeben.
@@ -16,7 +16,7 @@ Wenn Sie dieses Beispiel ausführen und auf <a href="http://127.0.0.1:8000/items
Sie können den Typ eines Pfad-Parameters in der Argumentliste der Funktion deklarieren, mit Standard-Python-Typannotationen:
{* ../../docs_src/path_params/tutorial002_py310.py hl[7] *}
{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *}
In diesem Fall wird `item_id` als `int` deklariert, also als Ganzzahl.
@@ -26,7 +26,7 @@ Dadurch erhalten Sie Editor-Unterstützung innerhalb Ihrer Funktion, mit Fehlerp
///
## Daten-<dfn title="auch bekannt als: Serialisierung, Parsen, Marshalling">Konversion</dfn> { #data-conversion }
## Daten-<abbr title="Auch bekannt als: Serialisierung, Parsen, Marshalling">Konversion</abbr> { #data-conversion }
Wenn Sie dieses Beispiel ausführen und Ihren Browser unter <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a> öffnen, sehen Sie als Response:
@@ -38,7 +38,7 @@ Wenn Sie dieses Beispiel ausführen und Ihren Browser unter <a href="http://127.
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`.
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 wird **FastAPI** den <abbr title="Request Anfrage: Daten, die der Client zum Server sendet">Request</abbr> automatisch <abbr title="Den String, der von einem HTTP-Request kommt, in Python-Objekte konvertieren">„parsen“</abbr>.
///
@@ -118,13 +118,13 @@ Und Sie haben auch einen Pfad `/users/{user_id}`, um Daten über einen spezifisc
Weil *Pfadoperationen* in ihrer Reihenfolge ausgewertet werden, müssen Sie sicherstellen, dass der Pfad `/users/me` vor `/users/{user_id}` deklariert wurde:
{* ../../docs_src/path_params/tutorial003_py310.py hl[6,11] *}
{* ../../docs_src/path_params/tutorial003_py39.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.
Sie können eine Pfadoperation auch nicht erneut definieren:
{* ../../docs_src/path_params/tutorial003b_py310.py hl[6,11] *}
{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
Die erste Definition wird immer verwendet werden, da ihr Pfad zuerst übereinstimmt.
@@ -140,11 +140,12 @@ Indem Sie von `str` erben, weiß die API-Dokumentation, dass die Werte vom Typ `
Erstellen Sie dann Klassen-Attribute mit festgelegten Werten, welches die erlaubten Werte sein werden:
{* ../../docs_src/path_params/tutorial005_py310.py hl[1,6:9] *}
{* ../../docs_src/path_params/tutorial005_py39.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, was „AlexNet“, „ResNet“ und „LeNet“ ist, das sind Namen von <abbr title="Genau genommen, Deep-Learning-Modellarchitekturen">Modellen</abbr> für maschinelles Lernen.
///
@@ -152,7 +153,7 @@ Falls Sie sich fragen, was „AlexNet“, „ResNet“ und „LeNet“ ist, das
Dann erstellen Sie einen *Pfad-Parameter*, der als Typ die gerade erstellte Enum-Klasse hat (`ModelName`):
{* ../../docs_src/path_params/tutorial005_py310.py hl[16] *}
{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}
### Die API-Dokumentation testen { #check-the-docs }
@@ -168,13 +169,13 @@ Der *Pfad-Parameter* wird ein *<abbr title="Member Mitglied: Einer der mögl
Sie können ihn mit einem Member Ihrer Enumeration `ModelName` vergleichen:
{* ../../docs_src/path_params/tutorial005_py310.py hl[17] *}
{* ../../docs_src/path_params/tutorial005_py39.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`:
{* ../../docs_src/path_params/tutorial005_py310.py hl[20] *}
{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}
/// tip | Tipp
@@ -188,7 +189,7 @@ Sie können *Enum-Member* in ihrer *Pfadoperation* zurückgeben, sogar verschach
Diese werden zu ihren entsprechenden Werten konvertiert (in diesem Fall Strings), bevor sie zum Client übertragen werden:
{* ../../docs_src/path_params/tutorial005_py310.py hl[18,21,23] *}
{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}
In Ihrem Client erhalten Sie eine JSON-Response, wie etwa:
@@ -227,7 +228,7 @@ In diesem Fall ist der Name des Parameters `file_path`. Der letzte Teil, `:path`
Sie verwenden das also wie folgt:
{* ../../docs_src/path_params/tutorial004_py310.py hl[6] *}
{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
/// tip | Tipp
@@ -242,7 +243,7 @@ In dem Fall wäre die URL: `/files//home/johndoe/myfile.txt`, mit einem doppelte
In **FastAPI** erhalten Sie mittels kurzer, intuitiver 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>“
* Daten "<abbr title="Den String, der von einem HTTP-Request kommt, nach Python-Daten konvertieren">parsen</abbr>"
* Datenvalidierung
* API-Annotationen und automatische Dokumentation

View File

@@ -39,7 +39,7 @@ Stellen Sie sicher, dass Sie [die FastAPI-Version aktualisieren](../deployment/v
///
## `Annotated` im Typ für den `q`-Parameter verwenden { #use-annotated-in-the-type-for-the-q-parameter }
## Verwenden von `Annotated` im Typ für den `q`-Parameter { #use-annotated-in-the-type-for-the-q-parameter }
Erinnern Sie sich, dass ich Ihnen zuvor in [Python-Typen-Intro](../python-types.md#type-hints-with-metadata-annotations){.internal-link target=_blank} gesagt habe, dass `Annotated` verwendet werden kann, um Metadaten zu Ihren Parametern hinzuzufügen?
@@ -47,16 +47,40 @@ Jetzt ist es soweit, dies mit FastAPI zu verwenden. 🚀
Wir hatten diese Typannotation:
//// tab | Python 3.10+
```Python
q: str | None = None
```
////
//// tab | Python 3.9+
```Python
q: Union[str, None] = None
```
////
Was wir tun werden, ist, dies mit `Annotated` zu wrappen, sodass es zu:
//// tab | Python 3.10+
```Python
q: Annotated[str | None] = None
```
////
//// tab | Python 3.9+
```Python
q: Annotated[Union[str, None]] = None
```
////
Beide dieser Versionen bedeuten dasselbe: `q` ist ein Parameter, der ein `str` oder `None` sein kann, und standardmäßig ist er `None`.
Jetzt springen wir zu den spannenden Dingen. 🎉
@@ -85,7 +109,7 @@ FastAPI wird nun:
## Alternative (alt): `Query` als Defaultwert { #alternative-old-query-as-the-default-value }
Frühere Versionen von FastAPI (vor <dfn title="vor 2023-03">0.95.0</dfn>) erforderten, dass Sie `Query` als den Defaultwert Ihres Parameters verwendeten, anstatt es innerhalb von `Annotated` zu platzieren. Es besteht eine hohe Wahrscheinlichkeit, dass Sie Code sehen, der es so verwendet, also werde ich es Ihnen erklären.
Frühere Versionen von FastAPI (vor <abbr title="vor 2023-03">0.95.0</abbr>) erforderten, dass Sie `Query` als den Defaultwert Ihres Parameters verwendeten, anstatt es innerhalb von `Annotated` zu platzieren. Es besteht eine hohe Wahrscheinlichkeit, dass Sie Code sehen, der es so verwendet, also werde ich es Ihnen erklären.
/// tip | Tipp
@@ -167,7 +191,7 @@ Sie können auch einen `min_length`-Parameter hinzufügen:
## Reguläre Ausdrücke hinzufügen { #add-regular-expressions }
Sie können einen <dfn title="Ein regulärer Ausdruck, regex oder regexp genannt, ist eine Sequenz von Zeichen, die ein Suchmuster für Strings definiert.">regulären Ausdruck</dfn> `pattern` definieren, mit dem der Parameter übereinstimmen muss:
Sie können einen <abbr title="Ein regulärer Ausdruck, regex oder regexp genannt, ist eine Sequenz von Zeichen, die ein Suchmuster für Zeichenfolgen definiert.">regulären Ausdruck</abbr> `pattern` definieren, mit dem der Parameter übereinstimmen muss:
{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
@@ -187,7 +211,7 @@ Natürlich können Sie Defaultwerte verwenden, die nicht `None` sind.
Nehmen wir an, Sie möchten, dass der `q` Query-Parameter eine `min_length` von `3` hat und einen Defaultwert von `"fixedquery"`:
{* ../../docs_src/query_params_str_validations/tutorial005_an_py310.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial005_an_py39.py hl[9] *}
/// note | Hinweis
@@ -217,7 +241,7 @@ q: Annotated[str | None, Query(min_length=3)] = None
Wenn Sie einen Wert als erforderlich deklarieren müssen, während Sie `Query` verwenden, deklarieren Sie einfach keinen Defaultwert:
{* ../../docs_src/query_params_str_validations/tutorial006_an_py310.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
### Erforderlich, kann `None` sein { #required-can-be-none }
@@ -268,7 +292,7 @@ Die interaktive API-Dokumentation wird entsprechend aktualisiert, um mehrere Wer
Sie können auch eine Default-`list` von Werten definieren, wenn keine bereitgestellt werden:
{* ../../docs_src/query_params_str_validations/tutorial012_an_py310.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *}
Wenn Sie zu:
@@ -291,7 +315,7 @@ gehen, wird der Default für `q` sein: `["foo", "bar"]`, und Ihre Response wird
Sie können auch `list` direkt verwenden, anstelle von `list[str]`:
{* ../../docs_src/query_params_str_validations/tutorial013_an_py310.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
/// note | Hinweis
@@ -347,7 +371,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 <abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr> anzeigt.
Dann übergeben Sie den Parameter `deprecated=True` an `Query`:
@@ -369,7 +393,7 @@ 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 <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator" class="external-link" target="_blank">Pydantics `AfterValidator`</a> innerhalb von `Annotated` erreichen.
Sie können dies mit <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator" class="external-link" target="_blank">Pydantic's `AfterValidator`</a> innerhalb von `Annotated` erreichen.
/// tip | Tipp
@@ -377,7 +401,7 @@ Pydantic unterstützt auch <a href="https://docs.pydantic.dev/latest/concepts/va
///
Zum Beispiel überprüft dieser benutzerdefinierte Validator, ob die Artikel-ID mit `isbn-` für eine <abbr title="International Standard Book Number - Internationale Standardbuchnummer">ISBN</abbr>-Buchnummer oder mit `imdb-` für eine <abbr title="Internet Movie Database - Internet-Filmdatenbank: eine Website mit Informationen über Filme">IMDB</abbr>-Film-URL-ID beginnt:
Zum Beispiel überprüft dieser benutzerdefinierte Validator, ob die Artikel-ID mit `isbn-` für eine <abbr title="ISBN bedeutet Internationale Standardbuchnummer">ISBN</abbr>-Buchnummer oder mit `imdb-` für eine <abbr title="IMDB (Internet Movie Database) ist eine Website mit Informationen über Filme">IMDB</abbr>-Film-URL-ID beginnt:
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
@@ -411,7 +435,7 @@ Haben Sie bemerkt? Eine Zeichenkette mit `value.startswith()` kann ein Tuple üb
#### Ein zufälliges Item { #a-random-item }
Mit `data.items()` erhalten wir ein <dfn title="Etwas, das man mit einer for-Schleife durchlaufen kann, wie eine Liste, Set, usw.">iterierbares Objekt</dfn> mit Tupeln, die Schlüssel und Wert für jedes <abbr title="Dictionary Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">Dictionary</abbr>-Element enthalten.
Mit `data.items()` erhalten wir ein <abbr title="Etwas, das man mit einer for-Schleife durchlaufen kann, wie eine Liste, Set, usw.">iterierbares Objekt</abbr> mit Tupeln, die Schlüssel und Wert für jedes <abbr title="Dictionary Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">Dictionary</abbr>-Element enthalten.
Wir konvertieren dieses iterierbare Objekt mit `list(data.items())` in eine richtige `list`.

View File

@@ -2,7 +2,7 @@
Wenn Sie in Ihrer Funktion andere Parameter deklarieren, die nicht Teil der Pfad-Parameter sind, dann werden diese automatisch als „Query“-Parameter interpretiert.
{* ../../docs_src/query_params/tutorial001_py310.py hl[9] *}
{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *}
Die <abbr title="Abfrage">Query</abbr> ist die Menge von Schlüssel-Wert-Paaren, die nach dem `?` in einer URL folgen und durch `&`-Zeichen getrennt sind.
@@ -24,7 +24,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)
* Daten-<dfn title="Konvertieren des Strings, der von einem HTTP-Request kommt, in Python-Daten">„Parsen“</dfn>
* Daten-<abbr title="Konvertieren des Strings, der von einem HTTP-Request kommt, in Python-Daten">„Parsen“</abbr>
* Datenvalidierung
* Automatische Dokumentation
@@ -127,7 +127,7 @@ Wenn Sie keinen spezifischen Wert haben wollen, sondern der Parameter einfach op
Aber wenn Sie wollen, dass ein Query-Parameter erforderlich ist, vergeben Sie einfach keinen Defaultwert:
{* ../../docs_src/query_params/tutorial005_py310.py hl[6:7] *}
{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *}
Hier ist `needy` ein erforderlicher Query-Parameter vom Typ `str`.

View File

@@ -20,13 +20,13 @@ Das liegt daran, dass hochgeladene Dateien als „Formulardaten“ gesendet werd
Importieren Sie `File` und `UploadFile` von `fastapi`:
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[3] *}
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[3] *}
## `File`-Parameter definieren { #define-file-parameters }
Erstellen Sie Datei-Parameter, so wie Sie es auch mit `Body` und `Form` machen würden:
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[9] *}
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[9] *}
/// info | Info
@@ -54,7 +54,7 @@ Aber es gibt viele Fälle, in denen Sie davon profitieren, `UploadFile` zu verwe
Definieren Sie einen Datei-Parameter mit dem Typ `UploadFile`:
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[14] *}
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[14] *}
`UploadFile` zu verwenden, hat mehrere Vorzüge gegenüber `bytes`:
@@ -143,7 +143,7 @@ Sie können eine Datei optional machen, indem Sie Standard-Typannotationen verwe
Sie können auch `File()` mit `UploadFile` verwenden, um zum Beispiel zusätzliche Metadaten zu setzen:
{* ../../docs_src/request_files/tutorial001_03_an_py310.py hl[9,15] *}
{* ../../docs_src/request_files/tutorial001_03_an_py39.py hl[9,15] *}
## Mehrere Datei-Uploads { #multiple-file-uploads }
@@ -153,7 +153,7 @@ Diese werden demselben Formularfeld zugeordnet, welches mit den Formulardaten ge
Um das zu machen, deklarieren Sie eine Liste von `bytes` oder `UploadFile`s:
{* ../../docs_src/request_files/tutorial002_an_py310.py hl[10,15] *}
{* ../../docs_src/request_files/tutorial002_an_py39.py hl[10,15] *}
Sie erhalten, wie deklariert, eine `list` von `bytes` oder `UploadFile`s.
@@ -169,7 +169,7 @@ Sie können auch `from starlette.responses import HTMLResponse` verwenden.
Und so wie zuvor können Sie `File()` verwenden, um zusätzliche Parameter zu setzen, sogar für `UploadFile`:
{* ../../docs_src/request_files/tutorial003_an_py310.py hl[11,18:20] *}
{* ../../docs_src/request_files/tutorial003_an_py39.py hl[11,18:20] *}
## Zusammenfassung { #recap }

View File

@@ -24,7 +24,7 @@ Dies wird seit FastAPI Version `0.113.0` unterstützt. 🤓
Sie müssen nur ein **Pydantic-Modell** mit den Feldern deklarieren, die Sie als **Formularfelder** erhalten möchten, und dann den Parameter als `Form` deklarieren:
{* ../../docs_src/request_form_models/tutorial001_an_py310.py hl[9:11,15] *}
{* ../../docs_src/request_form_models/tutorial001_an_py39.py hl[9:11,15] *}
**FastAPI** wird die Daten für **jedes Feld** aus den **Formulardaten** im <abbr title="Request Anfrage: Daten, die der Client zum Server sendet">Request</abbr> **extrahieren** und Ihnen das von Ihnen definierte Pydantic-Modell übergeben.
@@ -48,7 +48,7 @@ Dies wird seit FastAPI Version `0.114.0` unterstützt. 🤓
Sie können die Modellkonfiguration von Pydantic verwenden, um jegliche `extra` Felder zu `verbieten`:
{* ../../docs_src/request_form_models/tutorial002_an_py310.py hl[12] *}
{* ../../docs_src/request_form_models/tutorial002_an_py39.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>**.

View File

@@ -16,13 +16,13 @@ $ pip install python-multipart
## `File` und `Form` importieren { #import-file-and-form }
{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[3] *}
{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[3] *}
## `File` und `Form`-Parameter definieren { #define-file-and-form-parameters }
Erstellen Sie Datei- und Formularparameter, so wie Sie es auch mit `Body` oder `Query` machen würden:
{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[10:12] *}
{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[10:12] *}
Die Datei- und Formularfelder werden als Formulardaten hochgeladen, und Sie erhalten diese Dateien und Formularfelder.

View File

@@ -18,17 +18,17 @@ $ pip install python-multipart
Importieren Sie `Form` von `fastapi`:
{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[3] *}
{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[3] *}
## `Form`-Parameter definieren { #define-form-parameters }
Erstellen Sie Formular-Parameter, so wie Sie es auch mit `Body` und `Query` machen würden:
{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[9] *}
{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[9] *}
Zum Beispiel stellt eine der Möglichkeiten, die OAuth2-Spezifikation zu verwenden (genannt „password flow“), die Bedingung, einen `username` und ein `password` als Formularfelder zu senden.
Die <dfn title="Spezifikation">Spezifikation</dfn> erfordert, dass die Felder exakt `username` und `password` genannt werden und als Formularfelder, nicht JSON, gesendet werden.
Die <abbr title="Specification Spezifikation">Spec</abbr> erfordert, dass die Felder exakt `username` und `password` genannt werden und als Formularfelder, nicht JSON, gesendet werden.
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.

View File

@@ -183,7 +183,7 @@ Es kann Fälle geben, bei denen Sie etwas zurückgeben, das kein gültiges Pydan
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){.internal-link target=_blank}.
{* ../../docs_src/response_model/tutorial003_02_py310.py hl[8,10:11] *}
{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *}
Dieser einfache Anwendungsfall wird automatisch von FastAPI gehandhabt, weil die Annotation des Rückgabetyps die Klasse (oder eine Unterklasse von) `Response` ist.
@@ -193,7 +193,7 @@ Und Tools werden auch glücklich sein, weil sowohl `RedirectResponse` als auch `
Sie können auch eine Unterklasse von `Response` in der Typannotation verwenden.
{* ../../docs_src/response_model/tutorial003_03_py310.py hl[8:9] *}
{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *}
Das wird ebenfalls funktionieren, weil `RedirectResponse` eine Unterklasse von `Response` ist, und FastAPI sich um diesen einfachen Anwendungsfall automatisch kümmert.
@@ -201,7 +201,7 @@ Das wird ebenfalls funktionieren, weil `RedirectResponse` eine Unterklasse von `
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.
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 <abbr title="Eine Union mehrerer Typen bedeutet: „Irgendeiner dieser Typen“">Union</abbr> 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] *}

View File

@@ -8,7 +8,7 @@ Genauso wie Sie ein Responsemodell angeben können, können Sie auch den HTTP-St
* `@app.delete()`
* usw.
{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *}
{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
/// note | Hinweis
@@ -66,7 +66,7 @@ Kurz gefasst:
/// tip | Tipp
Um mehr über die einzelnen Statuscodes zu erfahren und welcher wofür verwendet wird, sehen Sie sich die <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - Mozilla-Entwicklernetzwerk">MDN</abbr> Dokumentation über HTTP-Statuscodes</a> an.
Um mehr über die einzelnen Statuscodes zu erfahren und welcher wofür verwendet wird, sehen Sie sich die <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank"><abbr title="Mozilla Developer Network Mozilla-Entwicklernetzwerk">MDN</abbr> Dokumentation über HTTP-Statuscodes</a> an.
///
@@ -74,7 +74,7 @@ Um mehr über die einzelnen Statuscodes zu erfahren und welcher wofür verwendet
Lassen Sie uns das vorherige Beispiel noch einmal anschauen:
{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *}
{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
`201` ist der Statuscode für „Created“ („Erzeugt“).
@@ -82,7 +82,7 @@ Aber Sie müssen sich nicht merken, was jeder dieser Codes bedeutet.
Sie können die Annehmlichkeit von Variablen aus `fastapi.status` nutzen.
{* ../../docs_src/response_status_code/tutorial002_py310.py hl[1,6] *}
{* ../../docs_src/response_status_code/tutorial002_py39.py hl[1,6] *}
Diese sind nur eine Annehmlichkeit, sie enthalten dieselbe Zahl, aber so können Sie die Autovervollständigung Ihres Editors verwenden, um sie zu finden:

View File

@@ -74,7 +74,7 @@ Sie können natürlich auch mehrere `examples` übergeben:
Wenn Sie das tun, werden die Beispiele Teil des internen **JSON-Schemas** für diese Body-Daten.
Nichtsdestotrotz unterstützt Swagger UI, das für die Anzeige der Dokumentations-Benutzeroberfläche zuständige Tool, zum <dfn title="2023-08-26">Zeitpunkt der Erstellung</dfn> nicht die Anzeige mehrerer Beispiele für die Daten in **JSON Schema**. Aber lesen Sie unten für einen Workaround weiter.
<abbr title="2023-08-26">Während dies geschrieben wird</abbr>, unterstützt Swagger UI, das für die Anzeige der Dokumentations-Benutzeroberfläche zuständige Tool, jedoch nicht die Anzeige mehrerer Beispiele für die Daten in **JSON Schema**. Aber lesen Sie unten für einen Workaround weiter.
### OpenAPI-spezifische `examples` { #openapi-specific-examples }

View File

@@ -20,7 +20,7 @@ Lassen Sie uns zunächst einfach den Code verwenden und sehen, wie er funktionie
Kopieren Sie das Beispiel in eine Datei `main.py`:
{* ../../docs_src/security/tutorial001_an_py310.py *}
{* ../../docs_src/security/tutorial001_an_py39.py *}
## Ausführen { #run-it }
@@ -111,10 +111,10 @@ Betrachten wir es also aus dieser vereinfachten Sicht:
* Der Benutzer klickt im Frontend, um zu einem anderen Abschnitt der Frontend-Web-Anwendung zu gelangen.
* Das Frontend muss weitere Daten von der API abrufen.
* Es benötigt jedoch eine Authentifizierung für diesen bestimmten Endpunkt.
* Um sich also bei unserer API zu authentifizieren, sendet es einen `Authorization`-Header mit dem Wert `Bearer ` plus dem Token.
* Um sich also bei unserer API zu authentifizieren, sendet es einen Header `Authorization` mit dem Wert `Bearer ` plus dem Token.
* Wenn der Token `foobar` enthielte, wäre der Inhalt des `Authorization`-Headers: `Bearer foobar`.
## FastAPIs `OAuth2PasswordBearer` { #fastapis-oauth2passwordbearer }
## **FastAPI**s `OAuth2PasswordBearer` { #fastapis-oauth2passwordbearer }
**FastAPI** bietet mehrere Tools auf unterschiedlichen Abstraktionsebenen zur Implementierung dieser Sicherheitsfunktionen.
@@ -134,7 +134,7 @@ In dem Fall gibt Ihnen **FastAPI** ebenfalls die Tools, die Sie zum Erstellen br
Wenn wir eine Instanz der Klasse `OAuth2PasswordBearer` erstellen, übergeben wir den Parameter `tokenUrl`. Dieser Parameter enthält die URL, die der Client (das Frontend, das im Browser des Benutzers ausgeführt wird) verwendet, wenn er den `username` und das `password` sendet, um einen Token zu erhalten.
{* ../../docs_src/security/tutorial001_an_py310.py hl[8] *}
{* ../../docs_src/security/tutorial001_an_py39.py hl[8] *}
/// tip | Tipp
@@ -172,7 +172,7 @@ Es kann also mit `Depends` verwendet werden.
Jetzt können Sie dieses `oauth2_scheme` als Abhängigkeit `Depends` übergeben.
{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}
{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
Diese Abhängigkeit stellt einen `str` bereit, der dem Parameter `token` der *Pfadoperation-Funktion* zugewiesen wird.

View File

@@ -2,7 +2,7 @@
Im vorherigen Kapitel hat das Sicherheitssystem (das auf dem Dependency Injection System basiert) der *Pfadoperation-Funktion* einen `token` vom Typ `str` überreicht:
{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}
{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
Aber das ist immer noch nicht so nützlich.

View File

@@ -20,7 +20,7 @@ OAuth2 ist eine Spezifikation, die verschiedene Möglichkeiten zur Handhabung vo
Es handelt sich um eine recht umfangreiche Spezifikation, und sie deckt mehrere komplexe Anwendungsfälle ab.
Sie umfasst Möglichkeiten zur Authentifizierung mithilfe eines „Dritten“.
Sie umfasst Möglichkeiten zur Authentifizierung mithilfe eines „Dritten“ („third party“).
Das ist es, was alle diese „Login mit Facebook, Google, X (Twitter), GitHub“-Systeme unter der Haube verwenden.

View File

@@ -116,11 +116,7 @@ Und eine weitere, um zu überprüfen, ob ein empfangenes Passwort mit dem gespei
Und noch eine, um einen Benutzer zu authentifizieren und zurückzugeben.
{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,51,58:59,62:63,72:79] *}
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.
{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,56:57,60:61,70:76] *}
/// note | Hinweis
@@ -156,7 +152,7 @@ Definieren Sie ein Pydantic-Modell, das im Token-Endpunkt für die <abbr title="
Erstellen Sie eine Hilfsfunktion, um einen neuen Zugriffstoken zu generieren.
{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,82:90] *}
{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,79:87] *}
## Die Abhängigkeiten aktualisieren { #update-the-dependencies }
@@ -166,7 +162,7 @@ Dekodieren Sie den empfangenen Token, validieren Sie ihn und geben Sie den aktue
Wenn der Token ungültig ist, geben Sie sofort einen HTTP-Fehler zurück.
{* ../../docs_src/security/tutorial004_an_py310.py hl[93:110] *}
{* ../../docs_src/security/tutorial004_an_py310.py hl[90:107] *}
## Die *Pfadoperation* `/token` aktualisieren { #update-the-token-path-operation }
@@ -174,7 +170,7 @@ Erstellen Sie ein <abbr title="Zeitdifferenz">`timedelta`</abbr> mit der Ablaufz
Erstellen Sie einen echten JWT-Zugriffstoken und geben Sie ihn zurück.
{* ../../docs_src/security/tutorial004_an_py310.py hl[121:136] *}
{* ../../docs_src/security/tutorial004_an_py310.py hl[118:133] *}
### Technische Details zum JWT-„Subjekt“ `sub` { #technical-details-about-the-jwt-subject-sub }

View File

@@ -18,7 +18,7 @@ Aber für die Login-*Pfadoperation* müssen wir diese Namen verwenden, um mit de
Die Spezifikation besagt auch, dass `username` und `password` als Formulardaten gesendet werden müssen (hier also kein JSON).
### `scope` { #scope }
### <abbr title="Geltungsbereich">`scope`</abbr> { #scope }
Ferner sagt die Spezifikation, dass der Client ein weiteres Formularfeld "`scope`" („Geltungsbereich“) senden kann.

View File

@@ -7,7 +7,7 @@ Mit `StaticFiles` können Sie statische Dateien aus einem Verzeichnis automatisc
* Importieren Sie `StaticFiles`.
* „Mounten“ Sie eine `StaticFiles()`-Instanz in einem bestimmten Pfad.
{* ../../docs_src/static_files/tutorial001_py310.py hl[2,6] *}
{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *}
/// note | Technische Details

View File

@@ -30,7 +30,7 @@ Verwenden Sie das `TestClient`-Objekt auf die gleiche Weise wie `httpx`.
Schreiben Sie einfache `assert`-Anweisungen mit den Standard-Python-Ausdrücken, die Sie überprüfen müssen (wiederum, Standard-`pytest`).
{* ../../docs_src/app_testing/tutorial001_py310.py hl[2,12,15:18] *}
{* ../../docs_src/app_testing/tutorial001_py39.py hl[2,12,15:18] *}
/// tip | Tipp
@@ -76,7 +76,7 @@ Nehmen wir an, Sie haben eine Dateistruktur wie in [Größere Anwendungen](bigge
In der Datei `main.py` haben Sie Ihre **FastAPI**-Anwendung:
{* ../../docs_src/app_testing/app_a_py310/main.py *}
{* ../../docs_src/app_testing/app_a_py39/main.py *}
### Testdatei { #testing-file }
@@ -93,7 +93,7 @@ Dann könnten Sie eine Datei `test_main.py` mit Ihren Tests haben. Sie könnte s
Da sich diese Datei im selben Package befindet, können Sie relative Importe verwenden, um das Objekt `app` aus dem `main`-Modul (`main.py`) zu importieren:
{* ../../docs_src/app_testing/app_a_py310/test_main.py hl[3] *}
{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *}
... und haben den Code für die Tests wie zuvor.

View File

@@ -53,7 +53,7 @@ $ cd awesome-project
## Eine virtuelle Umgebung erstellen { #create-a-virtual-environment }
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>**.
Wenn Sie zum **ersten Mal** an einem Python-Projekt arbeiten, erstellen Sie eine virtuelle Umgebung **<abbr title="es gibt andere Optionen, dies ist eine einfache Richtlinie">innerhalb Ihres Projekts</abbr>**.
/// tip | Tipp
@@ -166,7 +166,7 @@ $ source .venv/Scripts/activate
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.
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.
///
@@ -639,7 +639,7 @@ $ source .venv/Scripts/activate
Dieser Befehl erstellt oder ändert einige [Umgebungsvariablen](environment-variables.md){.internal-link target=_blank}, die für die nächsten Befehle verfügbar sein werden.
Eine dieser Variablen ist die `PATH`-Umgebungsvariable.
Eine dieser Variablen ist die `PATH`-Variable.
/// tip | Tipp
@@ -649,7 +649,7 @@ Sie können mehr über die `PATH`-Umgebungsvariable im Abschnitt [Umgebungsvaria
Das Aktivieren einer virtuellen Umgebung fügt deren Pfad `.venv/bin` (auf Linux und macOS) oder `.venv\Scripts` (auf Windows) zur `PATH`-Umgebungsvariable hinzu.
Angenommen, die `PATH`-Umgebungsvariable sah vor dem Aktivieren der Umgebung so aus:
Angenommen, die `PATH`-Variable sah vor dem Aktivieren der Umgebung so aus:
//// tab | Linux, macOS
@@ -678,7 +678,7 @@ Das bedeutet, dass das System nach Programmen sucht in:
////
Nach dem Aktivieren der virtuellen Umgebung würde die `PATH`-Umgebungsvariable folgendermaßen aussehen:
Nach dem Aktivieren der virtuellen Umgebung würde die `PATH`-Variable folgendermaßen aussehen:
//// tab | Linux, macOS
@@ -728,7 +728,7 @@ finden und dieses verwenden.
////
Ein wichtiger Punkt ist, dass es den Pfad der virtuellen Umgebung am **Anfang** der `PATH`-Umgebungsvariable platziert. Das System wird es **vor** allen anderen verfügbaren Pythons finden. Auf diese Weise, wenn Sie `python` ausführen, wird das Python **aus der virtuellen Umgebung** verwendet anstelle eines anderen `python` (zum Beispiel, einem `python` aus einer globalen Umgebung).
Ein wichtiger Punkt ist, dass es den Pfad der virtuellen Umgebung am **Anfang** der `PATH`-Variable platziert. Das System wird es **vor** allen anderen verfügbaren Pythons finden. Auf diese Weise, wenn Sie `python` ausführen, wird das Python **aus der virtuellen Umgebung** verwendet anstelle eines anderen `python` (zum Beispiel, einem `python` aus einer globalen Umgebung).
Das Aktivieren einer virtuellen Umgebung ändert auch ein paar andere Dinge, aber dies ist eines der wichtigsten Dinge, die es tut.

View File

@@ -16,7 +16,7 @@
{* ../../docs_src/additional_status_codes/tutorial001_an_py310.py hl[4,25] *}
/// warning | 注意
/// warning
上の例のように `Response` を直接返すと、それはそのまま返されます。
@@ -38,4 +38,4 @@
追加のステータスコードとレスポンスを直接返す場合、それらは OpenAPI スキーマAPI ドキュメントには含まれません。FastAPI には、事前に何が返されるかを知る方法がないからです。
しかし、[Additional Responses](additional-responses.md){.internal-link target=_blank} を使ってコード内にドキュメント化できます。
しかし、[追加のレスポンス](additional-responses.md){.internal-link target=_blank} を使ってコード内にドキュメント化できます。

View File

@@ -30,7 +30,7 @@
しかし、返そうとしているコンテンツが **JSONでシリアライズ可能**であることが確実なら、それを直接レスポンスクラスに渡して、FastAPIがレスポンスクラスへ渡す前に返却コンテンツを `jsonable_encoder` に通すことで発生する追加のオーバーヘッドを回避できます。
{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial001b_py310.py hl[2,7] *}
/// info | 情報
@@ -55,7 +55,7 @@
* `HTMLResponse` をインポートする。
* *path operation デコレータ* のパラメータ `response_class``HTMLResponse` を渡す。
{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
/// info | 情報
@@ -73,7 +73,7 @@
上記と同じ例において、 `HTMLResponse` を返すと、このようになります:
{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *}
{* ../../docs_src/custom_response/tutorial003_py310.py hl[2,7,19] *}
/// warning | 注意
@@ -97,7 +97,7 @@
例えば、このようになります:
{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *}
{* ../../docs_src/custom_response/tutorial004_py310.py hl[7,21,23] *}
この例では、関数 `generate_html_response()` は、`str` のHTMLを返すのではなく、`Response` を生成して返しています。
@@ -136,7 +136,7 @@
FastAPI実際にはStarletteは自動的にContent-Lengthヘッダーを含みます。また、`media_type` に基づいたContent-Typeヘッダーを含み、テキストタイプのためにcharsetを追加します。
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
### `HTMLResponse` { #htmlresponse }
@@ -146,7 +146,7 @@ FastAPI実際にはStarletteは自動的にContent-Lengthヘッダーを
テキストやバイトを受け取り、プレーンテキストのレスポンスを返します。
{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial005_py310.py hl[2,7,9] *}
### `JSONResponse` { #jsonresponse }
@@ -180,7 +180,7 @@ FastAPI実際にはStarletteは自動的にContent-Lengthヘッダーを
///
{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial001_py310.py hl[2,7] *}
/// tip | 豆知識
@@ -194,13 +194,13 @@ HTTPリダイレクトを返します。デフォルトでは307ステータス
`RedirectResponse` を直接返せます:
{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
{* ../../docs_src/custom_response/tutorial006_py310.py hl[2,9] *}
---
または、`response_class` パラメータで使用できます:
{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial006b_py310.py hl[2,7,9] *}
その場合、*path operation*関数からURLを直接返せます。
@@ -210,13 +210,13 @@ HTTPリダイレクトを返します。デフォルトでは307ステータス
また、`status_code` パラメータを `response_class` パラメータと組み合わせて使うこともできます:
{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial006c_py310.py hl[2,7,9] *}
### `StreamingResponse` { #streamingresponse }
非同期ジェネレータ、または通常のジェネレータ/イテレータを受け取り、レスポンスボディをストリームします。
{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *}
{* ../../docs_src/custom_response/tutorial007_py310.py hl[2,14] *}
#### ファイルライクオブジェクトで `StreamingResponse` を使う { #using-streamingresponse-with-file-like-objects }
@@ -226,7 +226,7 @@ HTTPリダイレクトを返します。デフォルトでは307ステータス
これにはクラウドストレージとの連携、映像処理など、多くのライブラリが含まれます。
{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *}
{* ../../docs_src/custom_response/tutorial008_py310.py hl[2,10:12,14] *}
1. これはジェネレータ関数です。内部に `yield` 文を含むため「ジェネレータ関数」です。
2. `with` ブロックを使うことで、ジェネレータ関数が終わった後つまりレスポンスの送信が完了した後にfile-likeオブジェクトが確実にクローズされるようにします。
@@ -255,11 +255,11 @@ HTTPリダイレクトを返します。デフォルトでは307ステータス
ファイルレスポンスには、適切な `Content-Length``Last-Modified``ETag` ヘッダーが含まれます。
{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
{* ../../docs_src/custom_response/tutorial009_py310.py hl[2,10] *}
`response_class` パラメータを使うこともできます:
{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}
{* ../../docs_src/custom_response/tutorial009b_py310.py hl[2,8,10] *}
この場合、*path operation*関数からファイルパスを直接返せます。
@@ -273,7 +273,7 @@ HTTPリダイレクトを返します。デフォルトでは307ステータス
`CustomORJSONResponse` を作れます。主に必要なのは、コンテンツを `bytes` として返す `Response.render(content)` メソッドを作ることです:
{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *}
{* ../../docs_src/custom_response/tutorial009c_py310.py hl[9:14,17] *}
これまでは次のように返していたものが:
@@ -299,7 +299,7 @@ HTTPリダイレクトを返します。デフォルトでは307ステータス
以下の例では、**FastAPI** はすべての*path operation*で、`JSONResponse` の代わりに `ORJSONResponse` をデフォルトとして使います。
{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}
/// tip | 豆知識

View File

@@ -12,7 +12,7 @@ OpenAPIの「エキスパート」でなければ、これはおそらく必要
各オペレーションで一意になるようにする必要があります。
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py310.py hl[6] *}
### *path operation関数* の名前をoperationIdとして使用する { #using-the-path-operation-function-name-as-the-operationid }
@@ -20,7 +20,7 @@ APIの関数名を `operationId` として利用したい場合、すべてのAP
すべての *path operation* を追加した後に行うべきです。
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2, 12:21, 24] *}
/// tip | 豆知識
@@ -40,7 +40,7 @@ APIの関数名を `operationId` として利用したい場合、すべてのAP
生成されるOpenAPIスキーマつまり、自動ドキュメント生成の仕組みから *path operation* を除外するには、`include_in_schema` パラメータを使用して `False` に設定します。
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py310.py hl[6] *}
## docstringによる説明の高度な設定 { #advanced-description-from-docstring }
@@ -92,7 +92,7 @@ OpenAPI仕様では <a href="https://github.com/OAI/OpenAPI-Specification/blob/m
この `openapi_extra` は、例えば [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions) を宣言するのに役立ちます。
{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py310.py hl[6] *}
自動APIドキュメントを開くと、その拡張は特定の *path operation* の下部に表示されます。
@@ -139,9 +139,9 @@ OpenAPI仕様では <a href="https://github.com/OAI/OpenAPI-Specification/blob/m
それは `openapi_extra` で行えます。
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py310.py hl[19:36, 39:40] *}
この例では、Pydanticモデルを一切宣言していません。実際、リクエストボディはJSONとして <abbr title="converted from some plain format, like bytes, into Python objects bytesなどのプレーンな形式からPythonオブジェクトに変換すること">parsed</abbr> されず、直接 `bytes` として読み取られます。そして `magic_data_reader()` 関数が、何らかの方法でそれをパースする責務を担います。
この例では、Pydanticモデルを一切宣言していません。実際、リクエストボディはJSONとして <dfn title="bytes などのプレーンな形式から Python オブジェクトに変換される">パース</dfn> されず、直接 `bytes` として読み取られます。そして `magic_data_reader()` 関数が、何らかの方法でそれをパースする責務を担います。
それでも、リクエストボディに期待されるスキーマを宣言できます。
@@ -153,7 +153,7 @@ OpenAPI仕様では <a href="https://github.com/OAI/OpenAPI-Specification/blob/m
例えばこのアプリケーションでは、PydanticモデルからJSON Schemaを抽出するFastAPIの統合機能や、JSONの自動バリデーションを使っていません。実際、リクエストのcontent typeをJSONではなくYAMLとして宣言しています。
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[15:20, 22] *}
それでも、デフォルトの統合機能を使っていないにもかかわらず、YAMLで受け取りたいデータのために、Pydanticモデルを使って手動でJSON Schemaを生成しています。
@@ -161,7 +161,7 @@ OpenAPI仕様では <a href="https://github.com/OAI/OpenAPI-Specification/blob/m
その後、コード内でそのYAMLコンテンツを直接パースし、さらに同じPydanticモデルを使ってYAMLコンテンツを検証しています。
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[24:31] *}
/// tip | 豆知識

View File

@@ -54,7 +54,7 @@
XMLを文字列にし、`Response` に含め、それを返します。
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
## 備考 { #notes }

View File

@@ -38,13 +38,13 @@ $ pip install websockets
しかし、これはWebSocketsのサーバーサイドに焦点を当て、動作する例を示す最も簡単な方法です。
{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *}
{* ../../docs_src/websockets/tutorial001_py310.py hl[2,6:38,41:43] *}
## `websocket` を作成する { #create-a-websocket }
**FastAPI** アプリケーションで、`websocket` を作成します。
{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *}
{* ../../docs_src/websockets/tutorial001_py310.py hl[1,46:47] *}
/// note | 技術詳細
@@ -58,7 +58,7 @@ $ pip install websockets
WebSocketルートでは、メッセージを待機して送信するために `await` を使用できます。
{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *}
{* ../../docs_src/websockets/tutorial001_py310.py hl[48:52] *}
バイナリやテキストデータ、JSONデータを送受信できます。
@@ -154,7 +154,7 @@ $ fastapi dev main.py
WebSocket接続が閉じられると、 `await websocket.receive_text()` は例外 `WebSocketDisconnect` を発生させ、この例のようにキャッチして処理することができます。
{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *}
{* ../../docs_src/websockets/tutorial003_py310.py hl[79:81] *}
試してみるには、

View File

@@ -1,8 +1,8 @@
# 代替ツールから受けたインスピレーションと比較
# 代替ツールから受けたインスピレーションと比較 { #alternatives-inspiration-and-comparisons }
何が**FastAPI**にインスピレーションを与えたのか、他の代替ツールと比較してどうか、そしてそこから何を学んだのかについて。
## はじめに
## はじめに { #intro }
**FastAPI**は、代替ツールのこれまでの働きがなければ存在しなかったでしょう。
@@ -12,17 +12,17 @@
しかし、その時点では、これらの機能をすべて提供し、以前のツールから優れたアイデアを取り入れ、可能な限り最高の方法でそれらを組み合わせ、それまで利用できなかった言語機能 (Python 3.6以降の型ヒント) を利用したものを作る以外に選択肢はありませんでした。
## 以前のツール
## 以前のツール { #previous-tools }
### <a href="https://www.djangoproject.com/" class="external-link" target="_blank">Django</a>
### <a href="https://www.djangoproject.com/" class="external-link" target="_blank">Django</a> { #django }
Pythonのフレームワークの中で最もポピュラーで、広く信頼されています。Instagramのようなシステムの構築に使われています。
リレーショナルデータベース (MySQLやPostgreSQLなど) と比較的強固に結合されているので、NoSQLデータベース (Couchbase、MongoDB、Cassandraなど) をメインに利用することは簡単ではありません。
バックエンドでHTMLを生成するために作られたものであり、現代的なフロントエンド (ReactやVue.js、Angularなど) や、他のシステム (IoTデバイスなど) と通信するAPIを構築するために作られたものではありません。
バックエンドでHTMLを生成するために作られたものであり、現代的なフロントエンド (ReactやVue.js、Angularなど) や、他のシステム (<abbr title="Internet of Things - モノのインターネット">IoT</abbr>デバイスなど) と通信するAPIを構築するために作られたものではありません。
### <a href="https://www.django-rest-framework.org/" class="external-link" target="_blank">Django REST Framework</a>
### <a href="https://www.django-rest-framework.org/" class="external-link" target="_blank">Django REST Framework</a> { #django-rest-framework }
Django REST Frameworkは、Djangoを下敷きにしてWeb APIを構築する柔軟なツールキットとして、APIの機能を向上させるために作られました。
@@ -42,7 +42,7 @@ Django REST Framework は Tom Christie によって作成されました。Starl
///
### <a href="http://flask.pocoo.org/" class="external-link" target="_blank">Flask</a>
### <a href="https://flask.palletsprojects.com" class="external-link" target="_blank">Flask</a> { #flask }
Flask は「マイクロフレームワーク」であり、データベースとの統合のようなDjangoがデフォルトで持つ多くの機能は含まれていません。
@@ -64,7 +64,7 @@ Flaskのシンプルさを考えると、APIを構築するのに適している
///
### <a href="http://docs.python-requests.org" class="external-link" target="_blank">Requests</a>
### <a href="https://requests.readthedocs.io" class="external-link" target="_blank">Requests</a> { #requests }
**FastAPI**は実際には**Requests**の代替ではありません。それらのスコープは大きく異なります。
@@ -80,7 +80,7 @@ Requestsは非常にシンプルかつ直感的なデザインで使いやすく
公式サイトで以下のように言われているのは、それが理由です。
> Requestsは今までで最もダウンロードされたPythonパッケージである
> Requestsは史上最もダウンロードされたPythonパッケージのひとつです
使い方はとても簡単です。例えば、`GET`リクエストを実行するには、このように書けば良いです:
@@ -88,7 +88,7 @@ Requestsは非常にシンプルかつ直感的なデザインで使いやすく
response = requests.get("http://example.com/some/url")
```
対応するFastAPIのパスオペレーションはこのようになります:
対応するFastAPIのAPIのpath operationはこのようになります:
```Python hl_lines="1"
@app.get("/some/url")
@@ -106,7 +106,7 @@ def read_url():
///
### <a href="https://swagger.io/" class="external-link" target="_blank">Swagger</a> / <a href="https://github.com/OAI/OpenAPI-Specification/" class="external-link" target="_blank">OpenAPI</a>
### <a href="https://swagger.io/" class="external-link" target="_blank">Swagger</a> / <a href="https://github.com/OAI/OpenAPI-Specification/" class="external-link" target="_blank">OpenAPI</a> { #swagger-openapi }
私がDjango REST Frameworkに求めていた主な機能は、APIの自動的なドキュメント生成でした。
@@ -131,13 +131,13 @@ def read_url():
///
### Flask REST フレームワーク
### Flask REST フレームワーク { #flask-rest-frameworks }
いくつかのFlask RESTフレームワークがありますが、それらを調査してみたところ、多くのものが不適切な問題が残ったまま、中断されたり放置されていることがわかりました。
### <a href="https://marshmallow.readthedocs.io/en/3.0/" class="external-link" target="_blank">Marshmallow</a>
### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a> { #marshmallow }
APIシステムで必要とされる主な機能の一つに、コード (Python) からデータを取り出して、ネットワークを介して送れるものに変換するデータの「<abbr title="marshalling, conversion">シリアライゼーション</abbr>」があります。例えば、データベースのデータを含むオブジェクトをJSONオブジェクトに変換したり、`datetime` オブジェクトを文字列に変換するなどです。
APIシステムで必要とされる主な機能の一つに、コード (Python) からデータを取り出して、ネットワークを介して送れるものに変換するデータの「<dfn title="別名: marshalling、変換">シリアライゼーション</dfn>」があります。例えば、データベースのデータを含むオブジェクトをJSONオブジェクトに変換したり、`datetime` オブジェクトを文字列に変換するなどです。
APIが必要とするもう一つの大きな機能はデータのバリデーションであり、特定のパラメータが与えられた場合にデータが有効であることを確認することです。例えば、あるフィールドがランダムな文字列ではなく `int` であることなどです。これは特に受信するデータに対して便利です。
@@ -145,7 +145,7 @@ APIが必要とするもう一つの大きな機能はデータのバリデー
これらの機能は、Marshmallowが提供するものです。Marshmallowは素晴らしいライブラリで、私も以前に何度も使ったことがあります。
しかし、それはPythonの型ヒントが存在する前に作られたものです。そのため、すべての<abbr title="データがどのように成されるべきかの定義">スキーマ</abbr>を定義するためには、Marshmallowが提供する特定のユーティリティやクラスを使用する必要があります。
しかし、それはPythonの型ヒントが存在する前に作られたものです。そのため、すべての<dfn title="データがどのように成されるべきかの定義">スキーマ</dfn>を定義するためには、Marshmallowが提供する特定のユーティリティやクラスを使用する必要があります。
/// check | **FastAPI**へ与えたインスピレーション
@@ -153,9 +153,9 @@ APIが必要とするもう一つの大きな機能はデータのバリデー
///
### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a>
### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a> { #webargs }
APIに求められる他の大きな機能として、<abbr title="Pythonデータの読み込みと変換">受信したリクエストデータのパース</abbr>があります。
APIに求められる他の大きな機能として、<dfn title="Pythonデータの読み込みと変換">受信したリクエストデータのパース</dfn>があります。
WebargsはFlaskをはじめとするいくつかのフレームワークの上にそれを提供するために作られたツールです。
@@ -175,7 +175,7 @@ Webargsは、Marshmallowと同じ開発者により作られました。
///
### <a href="https://apispec.readthedocs.io/en/stable/" class="external-link" target="_blank">APISpec</a>
### <a href="https://apispec.readthedocs.io/en/stable/" class="external-link" target="_blank">APISpec</a> { #apispec }
MarshmallowとWebargsはバリデーション、パース、シリアライゼーションをプラグインとして提供しています。
@@ -205,7 +205,7 @@ OpenAPIという、APIについてのオープンな標準をサポートして
///
### <a href="https://flask-apispec.readthedocs.io/en/latest/" class="external-link" target="_blank">Flask-apispec</a>
### <a href="https://flask-apispec.readthedocs.io/en/latest/" class="external-link" target="_blank">Flask-apispec</a> { #flask-apispec }
Webargs、Marshmallow、APISpecを連携させたFlaskプラグインです。
@@ -237,7 +237,7 @@ Flask-apispecはMarshmallowと同じ開発者により作成されました。
///
### <a href="https://nestjs.com/" class="external-link" target="_blank">NestJS</a> (と<a href="https://angular.io/" class="external-link" target="_blank">Angular</a>)
### <a href="https://nestjs.com/" class="external-link" target="_blank">NestJS</a> (と<a href="https://angular.io/" class="external-link" target="_blank">Angular</a>) { #nestjs-and-angular }
NestJSはAngularにインスパイアされたJavaScript (TypeScript) NodeJSフレームワークで、Pythonですらありません。
@@ -259,13 +259,13 @@ Angular 2にインスピレーションを受けた、統合された依存性
///
### <a href="https://sanic.readthedocs.io/en/latest/" class="external-link" target="_blank">Sanic</a>
### <a href="https://sanic.readthedocs.io/en/latest/" class="external-link" target="_blank">Sanic</a> { #sanic }
`asyncio`に基づいた、Pythonのフレームワークの中でも非常に高速なものの一つです。Flaskと非常に似た作りになっています。
/// note | 技術詳細
Pythonの`asyncio`ループの代わりに、`uvloop`が利用されています。それにより、非常に高速です。
Pythonの`asyncio`ループの代わりに、<a href="https://github.com/MagicStack/uvloop" class="external-link" target="_blank">`uvloop`</a>が利用されています。それにより、非常に高速です。
`Uvicorn`と`Starlette`に明らかなインスピレーションを与えており、それらは現在オープンなベンチマークにおいてSanicより高速です。
@@ -279,12 +279,10 @@ Pythonの`asyncio`ループの代わりに、`uvloop`が利用されています
///
### <a href="https://falconframework.org/" class="external-link" target="_blank">Falcon</a>
### <a href="https://falconframework.org/" class="external-link" target="_blank">Falcon</a> { #falcon }
Falconはもう一つの高性能Pythonフレームワークで、ミニマムに設計されており、Hugのような他のフレームワークの基盤として動作します。
Pythonのウェブフレームワーク標準規格 (WSGI) を使用していますが、それは同期的であるためWebSocketなどの利用には対応していません。とはいえ、それでも非常に高い性能を持っています。
これは、「リクエスト」と「レスポンス」の2つのパラメータを受け取る関数を持つように設計されています。そして、リクエストからデータを「読み込み」、レスポンスにデータを「書き込み」ます。この設計のため、Python標準の型ヒントでリクエストのパラメータやボディを関数の引数として宣言することはできません。
そのため、データのバリデーション、シリアライゼーション、ドキュメント化は、自動的にできずコードの中で行わなければなりません。あるいは、HugのようにFalconの上にフレームワークとして実装されなければなりません。このような分断は、パラメータとして1つのリクエストオブジェクトと1つのレスポンスオブジェクトを持つというFalconのデザインにインスピレーションを受けた他のフレームワークでも起こります。
@@ -299,7 +297,7 @@ Hug (HugはFalconをベースにしています) と一緒に、**FastAPI**が`r
///
### <a href="https://moltenframework.com/" class="external-link" target="_blank">Molten</a>
### <a href="https://moltenframework.com/" class="external-link" target="_blank">Molten</a> { #molten }
**FastAPI**を構築する最初の段階でMoltenを発見しました。そして、それは非常に似たようなアイデアを持っています。
@@ -323,7 +321,7 @@ Pydanticのようなデータのバリデーション、シリアライゼーシ
///
### <a href="http://www.hug.rest/" class="external-link" target="_blank">Hug</a>
### <a href="https://github.com/hugapi/hug" class="external-link" target="_blank">Hug</a> { #hug }
Hugは、Pythonの型ヒントを利用してAPIパラメータの型宣言を実装した最初のフレームワークの1つです。これは素晴らしいアイデアで、他のツールが同じことをするきっかけとなりました。
@@ -353,7 +351,7 @@ Hugは、**FastAPI**がヘッダーやクッキーを設定するために関数
///
### <a href="https://github.com/encode/apistar" class="external-link" target="_blank">APIStar</a> (<= 0.5)
### <a href="https://github.com/encode/apistar" class="external-link" target="_blank">APIStar</a> (<= 0.5) { #apistar-0-5 }
**FastAPI**を構築することを決める直前に、**APIStar**サーバーを見つけました。それは私が探していたものがほぼすべて含まれており、素晴らしいデザインでした。
@@ -401,9 +399,9 @@ APIStarはTom Christieにより開発されました。以下の開発者でも
///
## **FastAPI**が利用しているもの
## **FastAPI**が利用しているもの { #used-by-fastapi }
### <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>
### <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> { #pydantic }
Pydanticは、Pythonの型ヒントを元にデータのバリデーション、シリアライゼーション、 (JSON Schemaを使用した) ドキュメントを定義するライブラリです。
@@ -419,9 +417,9 @@ Marshmallowに匹敵しますが、ベンチマークではMarshmallowよりも
///
### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a>
### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> { #starlette }
Starletteは、軽量な<abbr title="非同期Python webを構築するための新標準">ASGI</abbr>フレームワーク/ツールキットで、高性能な非同期サービスの構築に最適です。
Starletteは、軽量な<dfn title="非同期Python Webアプリケーションを構築するための新しい標準">ASGI</dfn>フレームワーク/ツールキットで、高性能な非同期サービスの構築に最適です。
非常にシンプルで直感的です。簡単に拡張できるように設計されており、モジュール化されたコンポーネントを持っています。
@@ -429,15 +427,14 @@ Starletteは、軽量な<abbr title="非同期Python webを構築するための
* 非常に感動的な性能。
* WebSocketのサポート。
* GraphQLのサポート。
* インプロセスのバックグラウンドタスク。
* 起動およびシャットダウンイベント。
* requestsに基づいて構築されたテストクライアント。
* HTTPXに基づいて構築されたテストクライアント。
* CORS、GZip、静的ファイル、ストリーミング応答。
* セッションとクッキーのサポート。
* 100%のテストカバレッジ。
* 100%の型注釈付きコードベース。
* ハードな依存関係はない。
* ハードな依存関係はない。
Starletteは、現在テストされているPythonフレームワークの中で最も速いフレームワークです。フレームワークではなくサーバーであるUvicornだけが上回っています。
@@ -465,7 +462,7 @@ webに関するコアな部分を全て扱います。その上に機能を追
///
### <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a>
### <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a> { #uvicorn }
Uvicornは非常に高速なASGIサーバーで、uvloopとhttptoolsにより構成されています。
@@ -477,12 +474,12 @@ Starletteや**FastAPI**のサーバーとして推奨されています。
**FastAPI**アプリケーションを実行するメインのウェブサーバーである点。
Gunicornと組み合わせることで、非同期マルチプロセスサーバーを持つことがきます。
コマンドラインオプション `--workers` を使って、非同期マルチプロセスサーバーにできます。
詳細は[デプロイ](deployment/index.md){.internal-link target=_blank}の項目で確認してください。
///
## ベンチマーク と スピード
## ベンチマーク と スピード { #benchmarks-and-speed }
Uvicorn、Starlette、FastAPIの違いを理解、比較、確認するには、[ベンチマーク](benchmarks.md){.internal-link target=_blank}を確認してください。

View File

@@ -1,18 +1,18 @@
# 並行処理と async / await
# 並行処理と async / await { #concurrency-and-async-await }
*path operation 関数*のための `async def` に関する詳細と非同期 (asynchronous) コード、並行処理 (Concurrency)、そして、並列処理 (Parallelism) の背景について。
*path operation 関数*のための `async def` 構文に関する詳細と非同期コード、並行処理、並列処理の背景についてです
## 急いでいますか?
## 急いでいますか? { #in-a-hurry }
<abbr title="too long; didn't read (長すぎて読めない人のための要約という意味のスラング)"><strong>TL;DR:</strong></abbr>
<abbr title="too long; didn't read - 長すぎて読まなかった"><strong>TL;DR:</strong></abbr>
次のような、`await` を使用して呼び出すべきサードパーティライブラリを使用している場合:
次のよう`await` で呼び出すよう指示されているサードパーティライブラリを使ているなら:
```Python
results = await some_library()
```
以下の様に `async def` を使用して*path operation 関数*を宣言します
*path operation 関数*は次のように `async def`宣言します:
```Python hl_lines="2"
@app.get('/')
@@ -23,13 +23,13 @@ async def read_results():
/// note | 備考
`async def` を使用して作成された関数の内部でしか `await` は使用できません。
`await` は `async def` で作られた関数の内部でしか使えません。
///
---
データベース、API、ファイルシステムなどと通信し`await` の使用をサポートしていないサードパーティライブラリ (現在のほとんどのデータベースライブラリに当てはまります) を使用している場合、次の様に、単に `def` を使用して通常通り *path operation 関数*宣言してください:
データベース、API、ファイルシステムなどと通信しつつ `await` の使用をサポートしていないサードパーティライブラリ (現在のところ多くのデータベースライブラリが該当します) を使ている場合、*path operation 関数*は通常どおり `def` で宣言してください:
```Python hl_lines="2"
@app.get('/')
@@ -40,272 +40,307 @@ def results():
---
アプリケーションが (どういうわけか) 他の何とも通信せず応答を待つ必要がない場合は、`async def` を使用して下さい。
アプリケーションが (何らかの理由で) ほかの何とも通信せず応答を待つ必要がないなら、`await` を内部で使わなくても `async def` を使ってください。
---
よく分からない場合は、通常の `def` を使用して下さい。
よく分からない場合は、通常の `def` を使ってください。
---
**備考**: *path operation 関数*に必要なだけ `def` と `async def` を混在させ、それぞれに最適なオプションを使用して定義できます。それに応じてFastAPIは正しい処理を行います。
**備考**: 必要に応じて *path operation 関数* では `def` と `async def` を混在させ、それぞれに最適な選択肢で定義できます。FastAPI は適切に処理します。
とにかく、上記のいずれの場合でもFastAPIは非同期で動作し非常に高速です。
いずれの場合でもFastAPI は非同期で動作し非常に高速です。
しかし、上記のステップに従うことで、パフォーマンス最適化を行えます。
ただし上記の手順に従うことで、さらにパフォーマンス最適化が可能になります。
## 技術詳細
## 技術詳細 { #technical-details }
現代版のPythonは「**非同期コード**」を、「**コルーチン**」と称されるものを利用してサポートしています。これは **`async` と `await`** 構文を用います。
モダンな Python**非同期コード****コルーチン** と呼ばれる仕組みでサポートしており、構文は **`async` と `await`** す。
のセクションで、フレーズ内のパーツを順に見ていきましょう:
以下のセクションで、このフレーズパーツごとに見ていきま:
* **非同期コード**
* **`async` と `await`**
* **コルーチン**
## 非同期コード
## 非同期コード { #asynchronous-code }
非同期コードとは、言語💬がコードのどこかで、コンピュータ/プログラム🤖に *他の何か* がどこか別の箇所で終了するのを待つように伝える手段を持っていることを意味します。*他の何か* は「遅いファイル📝」と呼ばれているとしましょう.
非同期コードとは、言語 💬 がコードのどこかの時点で、コンピュータ/プログラム 🤖 に「どこか別のところで終わるまで、別の何か」を待つ必要があると伝える手段を持っている、ということです。その「別の何か」を「遅いファイル」📝 と呼ぶことにしましょう
したがって、コンピュータは「遅いファイル📝」が終了するまで、他の処理ができます。
その間、コンピュータは「遅いファイル」📝 が終わるまで、他の作業を進められます。
コンピュータ/プログラム🤖は再び待機する機会があるときや、その時点で行っていたすべての作業が完了するたびに戻ってきます。そして、必要な処理をしながら、コンピュータ/プログラム🤖が待っていた処理のどれかが終わっているかどうか確認します。
その後、コンピュータ/プログラム 🤖 は、また待つ機会が来たときや、その時点で抱えていた作業をすべて終えたときに戻ってきます。そして、待っていたタスクのどれかが終わっていないか確認し、必要な処理を実行します。
次に、それ🤖が最初のタスク (要するに、先程の「遅いファイル📝」)を終わらせて、そのタスクの結果を使う必要がある処理を続けます。
次に、最初に終わったタスク (たとえば「遅いファイル」📝) を取り、続きの処理を行います。
この「の何かを待つ」は、通常以下の様なものを待つような (プロセッサとRAMメモリの速度に比べて) 相対的に「遅い」<abbr title="インプットとアウトプット">I/O</abbr> 操作を指します:
この「の何かを待つ」は、通常 <abbr title="Input and Output - 入出力">I/O</abbr> 操作を指し、(プロセッサや RAM の速度に比べて) 相対的に「遅い」待機を伴います。例えば次のようなものです:
* ネットワーク経由でクライアントから送信されるデータ
* ネットワーク経由でクライアントが受信する、プログラムから送信されたデータ
* システムによって読み取られ、プログラムに渡されるディスク内のファイル内容
* プログラムがシステムに渡して、ディスクに書き込む内容
* リモートAPI操作
* クライアントからネットワーク経由でデータが送られてくるのを待つ
* プログラムが送信したデータをクライアントがネットワーク経由で受け取るのを待つ
* ディスク上のファイル内容がシステムによ読み取られ、プログラムに渡されるのを待つ
* プログラムがシステムに渡した内容がディスクに書き込まれるのを待つ
* リモート API 操作
* データベース操作の完了
* データベースクエリが結果を返すこと
* など
* データベースクエリが結果を返すのを待つ
* など
実行時間のほとんどが<abbr title="インプットとアウトプット">I/O</abbr> 操作の待ち時間が占めるため、このような操作を「I/O バウンド」操作と言います。
実行時間の大半が <abbr title="Input and Output - 入出力">I/O</abbr> 操作の待ち時間に費やされるため、これらは「I/O バウンド」操作と呼ばれます。
コンピュータ/プログラムがこのような遅いタスクと「同期 (タスクの結果を取得して作業を続行するために、何もせずに、タスクが完了する瞬間を正確に待つ)する必要がないため、「非同期」と呼ばれます
「非同期」と呼ばれるのは、コンピュータ/プログラムがその遅いタスクと「同期(タスクがちょうど終わる瞬間を、何もせずに待つ) する必要がないからです。結果を受け取って処理を続けるために、空待ちする必要がありません
その代わりに「非同期」システムであることにより、いったん終了すると、タスクは、コンピュータ/プログラムが既に開始した処理がすべて完了するのをほんの少し (数マイクロ秒) 待って、結果を受け取りに戻ってきます。そして、処理を継続します。
代わりに「非同期」システムでは、タスクが終わったら、コンピュータ/プログラムが取りかかっている作業が終わるまで (数マイクロ秒ほど) 少し待ち、結果を受け取りに戻って処理を続けられます。
「同期」の場合 (「非同期」とは異なり)、「シーケンシャル」という用語もよく使用されます。これは、コンピュータ/プログラムがすべてのステップを (待機が伴う場合でも別のタスクに切り替えることなく) 順番に実行するためです。
同期」と対になる「同期」は、「シーケンシャル」と呼ばれることもあります。待機が含まれていても、別のタスクに切り替える前にコンピュータ/プログラムが手順を順番に実行するためです。
### 並行処理とハンバーガー
### 並行処理とハンバーガー { #concurrency-and-burgers }
記の**非同期**コードのアイデアは、**「並行処理」**と呼ばれることもあります。 **「並列処理」**とは異なります。
で説明した**非同期**コードの考え方は、**「並行処理」** と呼ばれることもあります。これは **「並列処理」** とは異なります。
**並行処理****並列処理**はどちらも「多かれ少なかれ同時に発生するさまざまなことに関連しています。
**並行処理****並列処理** も、「複数のことがだいたい同時に起きる」ことに関係します。
ただし、*並行処理**並列処理*の詳細はまったく異なります。
ただし、*並行処理**並列処理* の詳細はかなり異なります。
違いを確認するには、ハンバーガーに関する次の物語を想像してみてください:
違いを見るために、ハンバーガーに関する次の物語を想像してみてください
### 並行ハンバーガー
### 並行ハンバーガー { #concurrent-burgers }
ファストフード🍔を食べようと、好きな人😍とレジに並んでおり、レジ係💁があなたの前にいる人達の注文を受けつけています。
あなたは好きな人とファストフードを買いに行き、前の人たちの注文をレジ係が受ける間、列に並びます。😍
それからあなたの番になり、好きな人😍と自分のために、2つの非常に豪華なハンバーガー🍔を注文します。
<img src="/img/async/concurrent-burgers/concurrent-burgers-01.png" class="illustration">
料金を支払います💸。
やがてあなたの番になり、好きな人と自分のために、とても豪華なハンバーガーを2つ注文します。🍔🍔
レジ係💁はキッチンの男👨‍🍳に向かって、あなたのハンバーガー🍔を準備しなければならないと伝えるために何か言いました (彼は現在、前のお客さんの商品を準備していますが)。
<img src="/img/async/concurrent-burgers/concurrent-burgers-02.png" class="illustration">
レジ係💁はあなたに番号札を渡します
レジ係はキッチンの料理人に、あなたのハンバーガーを用意するよう声をかけます (料理人はいま前のお客さんの分を作っています)
待っている間、好きな人😍と一緒にテーブルを選んで座り、好きな人😍と長い間話をします (注文したハンバーガーは非常に豪華で、準備に少し時間がかかるので✨🍔✨)。
<img src="/img/async/concurrent-burgers/concurrent-burgers-03.png" class="illustration">
ハンバーガー🍔を待ちながら好きな人😍とテーブルに座っている間、あなたの好きな人がなんて素晴らしく、かわいくて頭がいいんだと✨😍✨惚れ惚れしながら時間を費やすことができます。
支払いをします。💸
好きな人😍と話しながら待っている間、ときどき、カウンターに表示されている番号をチェックして、自分の番かどうかを確認します。
レジ係はあなたに番号札を渡します。
その後、ついにあなたの番になりました。カウンターに行き、ハンバーガー🍔を手に入れてテーブルに戻ります。
<img src="/img/async/concurrent-burgers/concurrent-burgers-04.png" class="illustration">
あなたとあなたの好きな人😍はハンバーガー🍔を食べて、楽しい時間を過ごします
待っている間、好きな人とテーブルに移動して座り、(豪華なハンバーガーは時間がかかるので) しばらく話します。
テーブルで待っている間、好きな人がどれだけ素敵で、かわいくて、頭が良いかを眺めて時間を過ごせます ✨😍✨。
<img src="/img/async/concurrent-burgers/concurrent-burgers-05.png" class="illustration">
時々カウンターの表示を見て、自分の番号になっているか確認します。
やがてあなたの番になります。カウンターに行き、ハンバーガーを受け取り、テーブルに戻ります。
<img src="/img/async/concurrent-burgers/concurrent-burgers-06.png" class="illustration">
あなたと好きな人はハンバーガーを食べて、楽しい時間を過ごします。✨
<img src="/img/async/concurrent-burgers/concurrent-burgers-07.png" class="illustration">
/// info | 情報
美しいイラストは <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">Ketrina Thompson</a> によるものです。🎨
///
---
上記のストーリーで、あなたがコンピュータ/プログラム🤖だと想像してみてください。
この物語で、あなた自身がコンピュータ/プログラム 🤖 だと想像してみてください。
列にいる間、あなたはアイドル状態です😴。何も「生産的」なことをせず、ただ自分の番を待っています。しかし、レジ係💁は注文を受け取るだけなので (商品の準備をしているわけではない)、列は高速です。したがって、何も問題ありません。
列にいる間、何も「生産的」なことをせず、自分の番を待つだけのアイドル状態 😴 です。ただしレジ係は注文を取るだけ (作りはしない) なので列は速く進み、問題ありません。
それから、あなたの番になったら、実に「生産的」作業を行います🤓、メニューを確認し、欲しいものを決め、好きな人😍の欲しいものを聞き、料金を支払い💸、現金またはカードを正しく渡したか確認し、正しく清算されたことを確認し、注文が正しく通っているかなどを確認します。
あなたの番になると、実に「生産的」作業をします。メニューを見て注文を決め、好きな人の分も確認し、支払い、正しい紙幣/カードを渡したか、正しく決済された、注文内容が正しかなどを確認します。
しかし、ハンバーガー🍔をまだできていないので、ハンバーガーの準備ができるまで待機🕙する必要があるため、レジ係💁との作業は「一時停止⏸」になります。
しかし、ハンバーガーはまだ出来上がっていないので、レジ係とのやり取りは「一時停止」⏸ になります。ハンバーガーができるまで待つ 🕙 必要があるからです。
しかし、カウンターから離れて、番号札を持ってテーブルに座っているときは、注意を好きな人😍に切り替え🔀、その上で「仕事⏯🤓」を行なえます。その後、好きな人😍といちゃつくかのような、非常に「生産的な🤓」ことを再び行います。
ただし、番号札を持ってカウンターから離れテーブルに座れば、注意を好きな人に切り替え 🔀、その作業」⏯ 🤓 に取り組めます。好きな人といちゃつくという、とても「生産的」🤓 なことがまたできます。
次に、レジ係💁は、「ハンバーガーの準備ができました🍔」と言って、カウンターのディスプレイに番号を表示しますが、表示番号があなたの番号に変わっても、すぐに狂ったように飛んで行くようなことはありません。あなたは自分の番号札を持っていって、他の人も自分の番号札があるので、あなたのハンバーガー🍔を盗む人がいないことは知っています。
レジ係 💁 がカウンターの表示にあなたの番号を出して「ハンバーガーができました」と知らせても、あなたは表示が切り替わった瞬間に飛び跳ねたりしません。自分の番号札があり、他の人にもそれぞれ番号札があるので、ハンバーガーを盗られることはないと知っているからです。
なので、あなたは好きな人😍が話し終えるのを待って (現在の仕事⏯ / 処理中のタスクを了します🤓)、優しく微笑んでハンバーガーを貰ってくるねと言います⏸。
だから、好きな人の話が終わるのを待 (現在の作業 ⏯ / 処理中のタスクを了し 🤓)、微笑んでハンバーガーってくるねと言います ⏸。
次に、カウンターへ、いまから完了する最初のタスク⏯へ向かい、ハンバーガー🍔を受け取り、感謝の意を表して、テーブルに持っていきます。これでカウンターとのやり取りステップ/タスク完了しました⏹。これにより、「ハンバーガーを食べる🔀⏯」という新しいタスクが作成されます。しかし、前の「ハンバーガーを取得する」というタスクは終了しました⏹
それからカウンターへ行き 🔀、いま完了した初期のタスク ⏯ に戻って、ハンバーガーを受け取り、礼を言ってテーブルに持っていきます。これでカウンターとのやり取りというステップ/タスク完了 ⏹ です。その結果として「ハンバーガーを食べる」🔀 ⏯ という新しいタスクが生まれますが、先の「ハンバーガーを受け取る」タスクは完了 ⏹ しています
### 並列ハンバーガー
### 並列ハンバーガー { #parallel-burgers }
これが「並行ハンバーガー」ではなく「並列ハンバーガー」であるとしましょう。
今度は、これが「並行ハンバーガー」ではなく「並列ハンバーガー」だと想像しましょう。
あなたは好きな人😍と並列ファストフード🍔を買おうとしています。
あなたは好きな人と並列ファストフードを買いに行きます。
列に並んでいますが、何人かの料理人兼、レジ係 (8人としましょう) 👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳があなたの前にいる人達の注文を受けつけています。
複数のレジ係 (例えば 8 人) が同時に料理人でもあり、前の人たちの注文を受けています。
8人のレジ係それぞれ自分で注文を受けるや否や、次の注文を受ける前にハンバーガーを準備するので、あなたの前の人はカウンターを離れず、ハンバーガー🍔ができるのを待っています🕙
8 人のレジ係それぞれ、次の注文をる前にすぐに調理に取りかかるため、あなたの前の人たちはカウンターを離れず、ハンバーガーができるのを待っています。
それからいよいよあなたの番になり、好きな人😍と自分のために、2つの非常に豪華なハンバーガー🍔を注文します。
<img src="/img/async/parallel-burgers/parallel-burgers-01.png" class="illustration">
料金を支払います💸
ようやくあなたの番になり、好きな人と自分のために豪華なハンバーガーを 2 つ注文します。
レジ係はキッチンに行きます👨‍🍳
支払いをします 💸
あなたはカウンターの前に立って待ちます🕙。番号札がないので誰もあなたよりも先にハンバーガー🍔を取らないようにします。
<img src="/img/async/parallel-burgers/parallel-burgers-02.png" class="illustration">
あなたと好きな人😍は忙しいので、誰もあなたの前に来させませんし、あなたのハンバーガーが到着したとき🕙に誰にも取ることを許しません。あなたは好きな人に注意を払えません😞
レジ係はキッチンに向かいます
これは「同期」作業であり、レジ係/料理人👨‍🍳と「同期」します。レジ係/料理人👨‍🍳がハンバーガー🍔を完成させてあなたに渡すまで待つ🕙必要があり、ちょうどその完成の瞬間にそこにいる必要があります。そうでなければ、他の誰かに取られるかもしれません
番号札がないため、他の誰かに先に取られないよう、カウンターの前で立って待ちます 🕙
その後、カウンターの前で長い時間待ってから🕙、ついにレジ係/料理人👨‍🍳がハンバーガー🍔を渡しに戻ってきます。
<img src="/img/async/parallel-burgers/parallel-burgers-03.png" class="illustration">
ハンバーガー🍔を取り、好きな人😍とテーブルに行きます。
あなたと好きな人は、誰にも割り込まれずハンバーガーが来たらすぐ受け取れるよう見張っているので、好きな人に注意を向けられません。😞
ただ食べるだけ、それでおしまいです。🍔⏹
これは「同期」的な作業です。レジ係/料理人 👨‍🍳 と「同期」しています。レジ係/料理人 👨‍🍳 がハンバーガーを作り終えて手渡すその瞬間に、待って 🕙 その場にいなければなりません。そうでないと他の誰かに取られるかもしれません
ほとんどの時間、カウンターの前で待つのに費やされていたので🕙、あまり話したりいちゃつくことはありませんでした😞。
<img src="/img/async/parallel-burgers/parallel-burgers-04.png" class="illustration">
長い時間 🕙 カウンター前で待った後、ようやくレジ係/料理人 👨‍🍳 がハンバーガーを持って戻ってきます。
<img src="/img/async/parallel-burgers/parallel-burgers-05.png" class="illustration">
ハンバーガーを受け取り、好きな人とテーブルに行きます。
食べて、おしまいです。⏹
<img src="/img/async/parallel-burgers/parallel-burgers-06.png" class="illustration">
ほとんどの時間をカウンター前で待つ 🕙 のに費やしたため、あまり話したり、いちゃついたりできませんでした。😞
/// info | 情報
美しいイラストは <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">Ketrina Thompson</a> によるものです。🎨
///
---
この並列ハンバーガーのシナリオでは、あなたは2つのプロセッサを備えたコンピュータ/プログラム🤖 (あなたとあなたの好きな人😍) であり、両方とも待機🕙していて、彼らは「カウンターで待機🕙」することに専念しています
この並列ハンバーガーのシナリオでは、あなたは 2 つのプロセッサ (あなたと好きな人) を持つコンピュータ/プログラム 🤖 で、どちらも長い間 🕙「カウンターで待機」に注意 ⏯ を専念しています。
ファストフード店には8つのプロセッサ (レジ係/料理人) 👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳があります。一方、並行ハンバーガー店には2人 (レジ係と料理人) 💁👨‍🍳しかなかったかもしれません。
ファストフード店には 8 個のプロセッサ (レジ係/料理人) があります。一方、並行ハンバーガー店には (レジ係 1、人、料理人 1 人の) 2 個しかなかったかもしれません。
しかし、それでも、最終的な体験は最高ではありません😞
それでも、最終的な体験は最良とは言えません😞
---
これはハンバーガー🍔の話と同等な話になります。
これはハンバーガーにおける並列版の物語です。🍔
より「現実的な」例として、銀行を想像してみてください。
最近まで、ほとんどの銀行は複数の窓口👨‍💼👨‍💼👨‍💼👨‍💼に、行列🕙🕙🕙🕙🕙🕙🕙🕙ができていました。
つい最近まで、ほとんどの銀行は複数の窓口👨‍💼👨‍💼👨‍💼👨‍💼 と長い行列 🕙🕙🕙🕙🕙🕙🕙🕙 がありました。
すべての窓口で、次々と、一人の客とすべての作業を行います👨‍💼⏯.
各窓口係が、一人ずつ、すべての作業を順番に行います 👨‍💼⏯
の上、長時間、列に並ばなければいけません🕙。そうしないと、順番が回ってきません
して、長時間 🕙 行列で待たなければ順番を失います
銀行🏦での用事にあなたの好きな人😍を連れて行きたくはないでしょう。
銀行の用事 🏦 に、好きな人 😍 を連れて行きたいとは思わないでしょう。
### ハンバーガーのまとめ
### ハンバーガーのまとめ { #burger-conclusion }
この「好きな人とファストフードハンバーガー」のシナリオでは、待機🕙が多いため、並行システム⏸🔀⏯を使用する方がはるかに理にかなっています。
この「好きな人とファストフード」のシナリオでは、待ち時間 🕙 が多いため、並行システム ⏸🔀⏯ を使方がはるかに理にかなっています。
これは、ほとんどのWebアプリケーションに当てはまります。
これは、ほとんどの Web アプリケーションに当てはまります。
多くのユーザーがいますが、サーバーは、あまりくない回線でのリクエストの送信を待機🕙しています。
とても多くのユーザーがいますが、サーバは彼らのあまりくない回線からリクエストが届くのを待ち 🕙、
して、レスポンスがってくるのをもう一度待機🕙します
の後、レスポンスがってくるのをまた待ちます 🕙
この「待機🕙」はマイクロ秒単位ですが、それでも、すべて合算すると、最終的にはかなり待機することになります。
この「待ち」🕙 はマイクロ秒単位で測られますが、すべてを合計すると、結局かなりの待ちになります。
これが、Web APIへの非同期⏸🔀⏯コードの利用が理にかなっている理由です。
だからこそ、Web API には非同期 ⏸🔀⏯ コードを使うのが理にかなっていす。
ほとんどの既存の人気のあるPythonフレームワーク (FlaskやDjangoを含む) は、Pythonの新しい非同期機能ができる前に作成されました。したがって、それらをデプロイする方法は、並列実行と、新機能ほど強力ではない古い形式の非同期実行をサポートします。
これが、NodeJS を人気にした要因 (NodeJS 自体は並列ではありません) であり、プログラミング言語としての Go の強みでもあります。
しかし、WebSocketのサポートを追加するために、非同期Web Python (ASGI) の主な仕様はDjangoで開発されました
そして、それが **FastAPI** で得られるパフォーマンスの水準です
そのような非同期性がNodeJSを人気にした理由です (NodeJSは並列ではありませんが)。そして、プログラミング言語としてのGoの強みでもあります
さらに、並列性と非同期性を同時に活用できるため、テストされた多くの NodeJS フレームワークより高い性能を発揮し、C に近いコンパイル言語である Go と同等の性能になります <a href="https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1" class="external-link" target="_blank">(すべて Starlette のおかげです)</a>
そして、それは**FastAPI**で得られるパフォーマンスと同じレベルです。
### 並行処理は並列処理より優れている? { #is-concurrency-better-than-parallelism }
また、並列処理と非同期処理を同時に実行できるため、テスト済みのほとんどのNodeJSフレームワークよりも高く、Goと同等のパフォーマンスが得られます。Goは、Cに近いコンパイル言語です <a href="https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1" class="external-link" target="_blank">(Starletteに感謝します)</a>
いいえ!それがこの話の教訓ではありません
### 並行は並列よりも優れていますか?
並行処理は並列処理とは異なります。そして多くの待ち時間を伴う**特定の**シナリオでは優れています。そのため、一般に Web アプリ開発では並列処理よりはるかに適しています。しかし、すべてに対して最良というわけではありません。
いや!それはこの話の教訓ではありません
バランスを取るために、次の短い物語を想像してください
並行処理は並列処理とは異なります。多くの待機を伴う**特定の**シナリオに適しています。そのため、一般に、Webアプリケーション開発では並列処理よりもはるかに優れています。しかし、すべてに対してより良いというわけではありません
> 大きくて汚れた家を掃除しなければならない
なので、バランスをとるために、次の物語を想像して下さい:
> あなたは大きくて汚れた家を掃除する必要があります。
*はい、以上です*。
*はい、これで物語は全部です*。
---
待機🕙せず、家の中の複数の場所でたくさんの仕事をするだけです。
どこにも待ち 🕙 はなく、家の複数箇所で大量の作業があるだけです。
あなたはハンバーガーの例のように、最初はリビングルーム、次にキッチンのように順番にやっていくことができますが、何かを待機🕙しているわけではなく、ただひたすら掃除するだけで、順番は何も影響しません。
ハンバーガーの例のように順番を決めて、まずリビング、次にキッチン、と進めてもよいのですが、何かを待つ 🕙 わけではなく、ひたすら掃除するだけなので、順番は何も影響しません。
順番の有無に関係なく (並行に) 同じ時間がかかり、同じ量の作業が行われることになるでしょう
順番の有無 (並行性の有無) に関係なく、終了までに同じ時間がかかり、同じ作業量をこなすことになります
しかしこの場合、8人の元レジ係/料理人/現清掃員👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳を手配できて、それぞれ (さらにあなたも) 家の別々の場所を掃除できれば、追加の助けを借りて、すべての作業を**並列**に行い、はるかに早く終了できるでしょう
しかしこの場合、8 人の元レジ係/料理人/現清掃員を連れてきて、それぞれ (あなたも加えて) 家の別々のエリアを掃除できれば、**並列** に作業でき、より早く終えられます
このシナリオでは、清掃員 (あなたを含む) のそれぞれがプロセッサとなり、それぞれの役割を果たします。
このシナリオでは、清掃員 (あなたを含む) がプロセッサであり、それぞれが自分の役割を果たします。
また、実行時間のほとんどは (待ではなく) 実際の作業に費やされ、コンピュータでの作業は<abbr title="Central Processing Unit">CPU</abbr>によって行われます。これらの問題は「CPUバウンド」と言います。
そして実行時間の大半は (待ではなく) 実作業が占め、コンピュータでの作業は <abbr title="Central Processing Unit - 中央処理装置">CPU</abbr> によって行われます。これらの問題は「CPU バウンド」と呼ばれます。
---
CPUバウンド操作の一般的な例は、複雑な数処理が必要なものです。
CPU バウンド操作の一般的な例は、複雑な数処理が必要なものです。
例えば:
* **オーディオ** や **画像処理**。
* **コンピュータビジョン**: 画像は数百万のピクセルで構成され、各ピクセルには3つの値/色があり、通常、れらのピクセルで何かを同時に計算する必要がある処理
* **機械学習**: 通常、多くの「行列」「ベクトル」の乗算が必要す。巨大なスプレッドシートに数字を入れて、それを同時に全部掛け合わせることを考えてみてください。
* **ディープラーニング**: これは機械学習のサブフィールドであるため、同じことが当てはまります。乗算する数字がある単一のスプレッドシートではなく、それらの膨大な集合で、多くの場合、それらのモデルを構築および/または使用するため特別なプロセッサを使用します。
* **コンピュータビジョン**: 画像は数百万のピクセルで構成され、各ピクセルには 3 つの値/色があり、通常、れらのピクセル上で同時に何かを計算する必要があります
* **機械学習**: 多くの「行列」「ベクトル」の乗算が必要になります。巨大なスプレッドシートに数字が入っていて、それを同時にすべて掛け合わせることを想像してください。
* **ディープラーニング**: 機械学習のサブフィールドなので同様です。掛け合わせる数字が 1 つのスプレッドシートではなく膨大な集合であり、多くの場合、それらのモデルを構築/利用するため特別なプロセッサを使ます。
### 並行処理 + 並列処理: Web + 機械学習
### 並行処理 + 並列処理: Web + 機械学習 { #concurrency-parallelism-web-machine-learning }
**FastAPI**を使用すると、Web開発で非常に一般的な並行処理 (NodeJSの主な魅力と同じもの) を用できます。
**FastAPI** では、Web 開発で非常に一般的な並行処理 (NodeJS の主な魅力と同じ) を用できます。
ただし、機械学習システムのような **CPUバウンド** ワークロードに対して、並列処理マルチプロセッシング (複数プロセス並列実行される) の利点活用することもできます。
同時に、機械学習システムのような **CPU バウンド** ワークロードに対して、並列処理マルチプロセッシング (複数プロセス並列実行) の利点活用できます。
さらに、Python**データサイエンス**、機械学習、特にディープラーニングの主要言語であるという単純な事実により、FastAPIはデータサイエンス/機械学習のWeb APIおよびアプリケーション (他の多くのアプリケーションとの) に非常によく適合しています。
さらに、Python**データサイエンス**、機械学習、特にディープラーニングの主要言語であるという事実も相まって、FastAPI はデータサイエンス/機械学習の Web APIアプリケーション (ほか多数) に非常にしています。
本番環境でこの並列処理を実現する方法については、[デプロイ](deployment/index.md){.internal-link target=_blank}に関するセクションを参照してください。
本番環境でこの並列を実現する方法は、[デプロイ](deployment/index.md){.internal-link target=_blank}セクションを参照してください。
## `async` と `await`
## `async` と `await` { #async-and-await }
現代的なバージョンのPythonには、非同期コードを定義する非常に直感的な方法があります。これにより、通常の「シーケンシャル」コードのように見え、適切なタイミングで「待機」します。
モダンな Python には、非同期コードをとても直感的に定義する方法があります。これにより、通常の「シーケンシャル」コードのように書けて、適切なタイミングで「待ち」を行ってくれます。
結果を返す前に待機する必要があり、これらの新しいPython機能をサポートる操作がある場合、次のようにコーディングできます。
結果を返す前に待ちが必要で、これらの新しい Python 機能をサポートしている操作がある場合、次のように書けます。
```Python
burgers = await get_burgers(2)
```
カギは `await` です。結果を `burgers`保存する前に、`get_burgers(2)`の処理🕙の完了を待つ⏸必要があることをPythonに伝えます。これPythonは、その間に (別のリクエストを受信するなど) 何か他のことができる🔀⏯ことを知ります。
ここでの鍵は `await` です。`burgers` に結果を保存する前に、`get_burgers(2)` がやるべきことを終えるのを ⏸ 待つ 🕙 ように Python に伝えます。これにより Python は、その間に (別のリクエストを受け取るなど) ほかのことを 🔀 ⏯ できると分かります。
`await` が機能するためには、非同期処理をサポートする関数内にある必要があります。これは、`async def` で関数を宣言するだけでよいです:
`await` が機能するには、この非同期をサポートする関数の内部でなければなりません。そのためには `async def` で宣言します:
```Python hl_lines="1"
async def get_burgers(number: int):
# ハンバーガーを作成するために非同期処理を
# ハンバーガーを作るために非同期処理を行
return burgers
```
...`def` のわりに:
...`def` のわりに:
```Python hl_lines="2"
# 非同期ではない
# これは非同期ではない
def get_sequential_burgers(number: int):
# ハンバーガーを作成するためにシーケンシャルな処理を
# ハンバーガーを作るためにシーケンシャルな処理を行
return burgers
```
`async def` を使用すると、Pythonにその関数内で `await` 式 (その関数の実行を「一時停止⏸」し、結果が戻るまで他の何かを実行🔀する) を認識しなければならないと伝えることができます。
`async def` 関数を呼び出すときは、「await」しなければなりません。したがって、これは機能しません:
`async def` を使うと、Python はその関数内で `await` 式に注意し、関数の実行を「一時停止」⏸ してほかのことをしに行き 🔀、戻ってくることができると分かります。
`async def` な関数を呼ぶときは「await」しなければなりません。したがって、次は動きません:
```Python
# get_burgersasync defで定義されているので動作しない
# 動きません。get_burgersasync def で定義されています
burgers = get_burgers(2)
```
---
したがって、 `await` で呼び出すことができるライブラリを使用している場合は、次のように `async def` を使用して、それを使用する*path operation 関数*を作成する必要があります:
そのため、`await` で呼べると謳っているライブラリを使ている場合は、それを使*path operation 関数* を `async def` で作る必要があります。例えば:
```Python hl_lines="2-3"
@app.get('/burgers')
@@ -314,86 +349,96 @@ async def read_burgers():
return burgers
```
### より発展的な技術詳細
### より発展的な技術詳細 { #more-technical-details }
`await` は `async def` で定義された関数内でのみ使用できることがわかったかと思います
`await` は `async def` で定義された関数の内部でしか使えないことに気づいたかもしれません
しかし同時に、`async def` で定義された関数は「awaitされる必要があります。なので、`async def` を持つ関数は、`async def` で定義された関数内でのみ呼び出せます
同時に、`async def` で定義された関数は「awaitされる必要があります。つまり、`async def` を持つ関数は、やはり `async def` で定義された関数の内部からしか呼べません
では、このニワトリと卵の問題について、最初の `async` 関数をどのように呼び出すのでしょうか?
では、ニワトリと卵の話のように、最初の `async` 関数はどう呼ぶのでしょうか?
**FastAPI**を使用している場合その「最初の」関数*path operation 関数*であり、FastAPIが正しく実行する方法を知っているので、心配する必要はありません
**FastAPI** を使ている場合は心配ありません。その「最初の」関数*path operation 関数* で、FastAPI が適切に実行してくれます
しかし、FastAPI以外で `async` / `await` を使用したい場合は、<a href="https://docs.python.org/3/library/asyncio-task.html#coroutine" class="external-link" target="_blank">公式Pythonドキュメントを参照して下さい</a>
しかし、FastAPI を使わずに `async` / `await` を使たい場合もあります
### 非同期コードの他の形式
### 自分で async コードを書く { #write-your-own-async-code }
`async` と `await` を使用するスタイルは、この言語では比較的新しいものです。
Starlette (**FastAPI** も) は <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> の上に構築されており、標準ライブラリの <a href="https://docs.python.org/3/library/asyncio-task.html" class="external-link" target="_blank">asyncio</a> と <a href="https://trio.readthedocs.io/en/stable/" class="external-link" target="_blank">Trio</a> の両方に対応しています。
非同期コードの操作がはるかに簡単になります。
特に、あなた自身のコード内で、より高度なパターンを必要とする発展的な並行処理のユースケースに対して、<a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> を直接使えます。
等価な (またはほとんど同一の) 構文が、最近のバージョンのJavaScript (ブラウザおよびNodeJS) にも最近組み込まれました
仮に FastAPI を使っていなくても、<a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> で独自の async アプリケーションを書けば、高い互換性と利点 (例: 構造化並行性) を得られます
しかし、その前は、非同期コードの処理はかなり複雑で難解でした
私は AnyIO の上に薄い層として、型注釈を少し改善し、より良い**補完**や**インラインエラー**などを得るための別ライブラリも作りました。また、**理解**して**自分で async コードを書く**のに役立つフレンドリーなイントロ/チュートリアルもあります: <a href="https://asyncer.tiangolo.com/" class="external-link" target="_blank">Asyncer</a>。特に、**async コードと通常の** (ブロッキング/同期) **コードを組み合わせる**必要がある場合に有用です
以前のバージョンのPythonでは、スレッドや<a href="https://www.gevent.org/" class="external-link" target="_blank">Gevent</a>が利用できました。しかし、コードは理解、デバック、そして、考察がはるかに複雑です。
### 非同期コードの他の形式 { #other-forms-of-asynchronous-code }
以前のバージョンのNodeJS / ブラウザJavaScriptでは、「コールバック」を使用していました。これは、「コールバック地獄」につながります。
`async` と `await` を使うこのスタイルは、言語としては比較的新しいものです。
## コルーチン
しかし、これにより非同期コードの取り扱いは大幅に簡単になります。
**コルーチン**は、`async def` 関数によって返されるものを指す非常に洒落た用語です。これは、開始できて、いつか終了する関数のようなものであるが、内部に `await` があるときは内部的に一時停止⏸されることもあるものだとPythonは認識しています
同等 (ほぼ同一) の構文が最近の JavaScript (ブラウザと NodeJS) にも導入されました
`async` と `await` を用いた非同期コードを使用するすべての機能は、「コルーチン」を使用するものとして何度もまとめられています。Goの主要機能である「ゴルーチン」に相当します
それ以前は、非同期コードの扱いはかなり複雑で難解でした
## まとめ
以前の Python ではスレッドや <a href="https://www.gevent.org/" class="external-link" target="_blank">Gevent</a> を使えましたが、コードの理解・デバッグ・思考がはるかに難しくなります。
上述したフレーズを見てみましょう:
以前の NodeJS / ブラウザ JavaScript では「コールバック」を使っており、「コールバック地獄」を招きました。
> 現代版のPythonは「**非同期コード**」を、「**コルーチン**」と称されるものを利用してサポートしています。これは **`async` と `await`** 構文を用います。
## コルーチン { #coroutines }
今では、この意味がより理解できるはずです。
**コルーチン**は、`async def` 関数が返すものを指す、ちょっと洒落た用語です。Python はそれを、開始できていつか終了する関数のようなものとして扱いますが、内部に `await` があるたびに内部的に一時停止 ⏸ するかもしれないものとして認識します。
(Starletteを介して) FastAPIに力を与えて、印象的なパフォーマンスを実現しているものはこれがすべてです。
`async` と `await` を用いた非同期コードの機能全体は、しばしば「コルーチンを使う」と要約されます。これは Go の主要機能「Goroutines」に相当します。
## 非常に発展的な技術的詳細
## まとめ { #conclusion }
上のフレーズをもう一度見てみましょう:
> モダンな Python は **「非同期コード」** を **「コルーチン」** と呼ばれる仕組みでサポートしており、構文は **`async` と `await`** です。
今なら、より意味が分かるはずです。✨
これらすべてが (Starlette を通じて) FastAPI を支え、印象的なパフォーマンスを実現しています。
## 非常に発展的な技術的詳細 { #very-technical-details }
/// warning | 注意
恐らくスキップしても良いでしょう
おそらく読み飛ばしても大丈夫です
の部分は**FastAPI**の仕組みに関する非常に技術的な詳細です。
れは **FastAPI** の内部動作に関する、とても技術的な詳細です。
かなりの技術知識 (コルーチン、スレッド、ブロッキングなど) があり、FastAPIが `async def` と通常の `def` をどのように処理するか知りたい場合は、先に進んでください。
(コルーチン、スレッド、ブロッキング等の) 技術知識があり、FastAPI が `async def` と通常の `def` をどう扱うかに興味がある場合は、読み進めてください。
///
### Path operation 関数
### Path operation 関数 { #path-operation-functions }
*path operation 関数*を `async def` の代わりに通常の `def` で宣言すると、(サーバをブロックするので) 直接呼び出す代わりに外部スレッドプール (awaitされる) で実行されます。
*path operation 関数* を `async def` ではなく通常の `def` で宣言した場合、(サーバをブロックしてしまうため) 直接呼び出されるのではなく、外部スレッドプールで実行され、それを待機します。
上記の方法と違った方法の別の非同期フレームワークから来ており、小さなパフォーマンス向上 (約100ナ秒) のために通常の `def` を使用して些細な演算のみ行う *path operation 関数* を定義するに慣れている場合、**FastAPI**ではまったく逆の効果になることに注意してください。このような場合、*path operation 関数* がブロッキング<abbr title="入力/出力: ディスクの読み取りまたは書き込み、ネットワーク通信。">I/O</abbr>を実行しないのであれば、`async def` の使用をお勧めします。
上記とは異なる動作の別の非同期フレームワークから来ており、ほんのわずかなパフォーマンス向上 (約 100 ナノ秒) を狙って、計算のみの些細な *path operation 関数* を素の `def` で定義することに慣れている場合、**FastAPI** では効果がまったく逆になるに注意してください。これらの場合、*path operation 関数* がブロッキング<abbr title="Input/Output - 入出力: ディスクの読み取りまたは書き込み、ネットワーク通信。">I/O</abbr> を行うコードを使っていない限り、`async def` を使った方が良いです。
それでも、どちらの状況でも、**FastAPI**が過去のフレームワークよりも (またはそれに匹敵するほど) [高速になる](index.md#_10){.internal-link target=_blank}可能性があります。
それでも、どちらの状況でも、**FastAPI** はあなたが以前使っていたフレームワークよりも (少なくとも同等に) [高速である](index.md#performance){.internal-link target=_blank} 可能性が高いです。
### 依存関係
### 依存関係 { #dependencies }
依存関係についても同様です。依存関係が `async def` ではなく標準の `def` 関数である場合、外部スレッドプールで実行されます。
[依存関係](tutorial/dependencies/index.md){.internal-link target=_blank} についても同様です。依存関係が `async def` ではなく標準の `def` 関数である場合、外部スレッドプールで実行されます。
### サブ依存関係
### サブ依存関係 { #sub-dependencies }
(関数定義のパラメータとして) 相互に必要な複数の依存関係とサブ依存関係を設定できます。一部は `async def` で作成され、他の一部は通常の `def` で作成されます。それでも動作し通常の `def`で作成されたものは「awaitされる代わりに (スレッドプールから) 外部スレッドで呼び出されます。
複数の依存関係や [サブ依存関係](tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank} を (関数定義のパラメータとして) 相互に要求させられます。その一部は `async def`、他は通常の `def` で作られていても動作します。通常の `def` で作れたものは「awaitされる代わりに、外部スレッドプールからスレッドで呼び出されます。
### その他のユーティリティ関数
### その他のユーティリティ関数 { #other-utility-functions }
あなたが直接呼び出すユーティリティ関数は通常の `def` または `async def` で作成でき、FastAPIは呼び出す方法に影響を与えません。
あなたが直接呼び出すユーティリティ関数は通常の `def` でも `async def` でも構いません。FastAPI はその呼び出し方に影響を与えません。
これは、FastAPIが呼び出す関数と対照的です: *path operation 関数*と依存関係。
これは、FastAPI があなたの代わりに呼び出す関数 (すなわち *path operation 関数* と依存関係) とは対照的です
ユーティリティ関数が `def` を使用した通常関数である場合、スレッドプールではなく直接 (コードで記述したとおりに) 呼び出されます。関数が `async def` を使用して作成されている場合は、呼び出す際に `await` する必要があります。
ユーティリティ関数が `def` 通常関数であれば、(あなたのコードに書いたとおりに) 直接呼び出され、スレッドプールでは実行されません。関数が `async def` で作られている場合は、その関数を呼ぶときに `await` すべきです。
---
繰り返しになりますが、これらは非常に技術的な詳細であり、検索して辿り着いた場合は役立つでしょう。
繰り返しになりますが、これらは非常に技術的な詳細で、該当事項を検索してここにたどり着いた場合は役立つでしょう。
それ以外の場合は、上のセクションのガイドラインで問題ないはずです: <a href="#_1">急いでいますか?</a>。
それ以外の場合は、上のセクションのガイドラインに従えば十分です: <a href="#in-a-hurry">急いでいますか?</a>。

View File

@@ -29,7 +29,6 @@
## セキュリティ - HTTPS { #security-https }
<!-- NOTE: https.md written in Japanese does not exist, so it redirects to English one -->
[前チャプターのHTTPSについて](https.md){.internal-link target=_blank}では、HTTPSがどのようにAPIを暗号化するのかについて学びました。
通常、アプリケーションサーバにとって**外部の**コンポーネントである**TLS Termination Proxy**によって提供されることが一般的です。このプロキシは通信の暗号化を担当します。
@@ -193,7 +192,6 @@ FastAPI アプリケーションでは、Uvicorn を実行する `fastapi` コ
同じAPIプログラムの**複数のプロセス**を実行する場合、それらは一般的に**Workerワーカー**と呼ばれます。
### ワーカー・プロセス と ポート { #worker-processes-and-ports }
<!-- NOTE: https.md written in Japanese does not exist, so it redirects to English one -->
[HTTPSについて](https.md){.internal-link target=_blank}のドキュメントで、1つのサーバーで1つのポートとIPアドレスの組み合わせでリッスンできるのは1つのプロセスだけであることを覚えていますでしょうか

View File

@@ -14,7 +14,7 @@ Linuxコンテナの使用には、**セキュリティ**、**反復可能性(
<summary>Dockerfile Preview 👀</summary>
```Dockerfile
FROM python:3.9
FROM python:3.14
WORKDIR /code
@@ -166,7 +166,7 @@ def read_item(item_id: int, q: str | None = None):
```{ .dockerfile .annotate }
# (1)!
FROM python:3.9
FROM python:3.14
# (2)!
WORKDIR /code
@@ -392,7 +392,7 @@ FastAPI が単一のファイル、例えば `./app` ディレクトリのない
そうすれば、`Dockerfile`の中にファイルをコピーするために、対応するパスを変更するだけでよいです:
```{ .dockerfile .annotate hl_lines="10 13" }
FROM python:3.9
FROM python:3.14
WORKDIR /code
@@ -456,7 +456,7 @@ TraefikはDockerやKubernetesなどと統合されているので、コンテナ
## レプリケーション - プロセス数 { #replication-number-of-processes }
**Kubernetes** や Docker Swarm モード、Nomad、あるいは複数のマシン上で分散コンテナを管理するための同様の複雑なシステムを使ってマシンの<abbr title="A group of machines that are configured to be connected and work together in some way. - ある方法で接続され、連携して動作するように構成されたマシンの集まり">cluster</abbr>を構成している場合、 各コンテナでWorkerを持つUvicornのような**プロセスマネージャ**を使用する代わりに、**クラスター・レベル**で**レプリケーション**を処理したいと思うでしょう。
**Kubernetes** や Docker Swarm モード、Nomad、あるいは複数のマシン上で分散コンテナを管理するための同様の複雑なシステムを使ってマシンの<dfn title="ある方法で接続され、連携して動作するように構成されたマシンの集まり">クラスタ</dfn>を構成している場合、 各コンテナでWorkerを持つUvicornのような**プロセスマネージャ**を使用する代わりに、**クラスター・レベル**で**レプリケーション**を処理したいと思うでしょう。
Kubernetesのような分散コンテナ管理システムの1つは通常、入ってくるリクエストの**ロードバランシング**をサポートしながら、**コンテナのレプリケーション**を処理する統合された方法を持っています。このことはすべて**クラスタレベル**にてです。
@@ -501,7 +501,7 @@ HTTPSに使われるものと同じ**TLS Termination Proxy**コンポーネン
そのような場合、`--workers` コマンドラインオプションを使って、実行したいワーカー数を設定できます:
```{ .dockerfile .annotate }
FROM python:3.9
FROM python:3.14
WORKDIR /code

View File

@@ -28,7 +28,7 @@ HTTPSは単に「有効」か「無効」かで決まるものだと思いがち
* **デフォルトでは**、**IPアドレスごとに1つのHTTPS証明書**しか持てないことになります。
* これは、サーバーの規模やアプリケーションの規模に寄りません。
* しかし、これには**解決策**があります。
* **TLS**プロトコル(HTTPの前に、TCPレベルで暗号化を処理するもの)には、**<a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="Server Name Indication">SNI</abbr></a>**と呼ばれる**拡張**があります。
* **TLS**プロトコル(HTTPの前に、TCPレベルで暗号化を処理するもの)には、**<a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="Server Name Indication - サーバー名表示">SNI</abbr></a>**と呼ばれる**拡張**があります。
* このSNI拡張機能により、1つのサーバー**単一のIPアドレス**を持つ)が**複数のHTTPS証明書**を持ち、**複数のHTTPSドメイン/アプリケーション**にサービスを提供できるようになります。
* これが機能するためには、**パブリックIPアドレス**でリッスンしている、サーバー上で動作している**単一の**コンポーネント(プログラム)が、サーバー内の**すべてのHTTPS証明書**を持っている必要があります。
* セキュアな接続を取得した**後**でも、通信プロトコルは**HTTPのまま**です。
@@ -66,7 +66,7 @@ Let's Encrypt以前は、これらの**HTTPS証明書**は信頼できる第三
ステップの初めは、**ドメイン名**を**取得すること**から始まるでしょう。その後、DNSサーバーおそらく同じクラウドプロバイダーに設定します。
おそらくクラウドサーバー(仮想マシン)かそれに類するものを手に入れ、<abbr title="That doesn't change 変わらない">fixed</abbr> **パブリックIPアドレス**を持つことになるでしょう。
おそらくクラウドサーバー(仮想マシン)かそれに類するものを手に入れ、<dfn title="時間とともに変化しない。動的ではない。">固定の</dfn> **パブリックIPアドレス**を持つことになるでしょう。
DNSサーバーでは、**取得したドメイン**をあなたのサーバーのパプリック**IPアドレス**に向けるレコード(「`A record`」)を設定します。

View File

@@ -1,12 +1,82 @@
# 手動デプロイ
# サーバーを手動で実行する { #run-a-server-manually }
**FastAPI** を手動でデプロイすることもできます。
## fastapi run コマンドを使う { #use-the-fastapi-run-command }
以下の様なASGI対応のサーバをインストールする必要があります:
結論として、FastAPI アプリケーションを提供するには `fastapi run` を使います:
//// tab | Uvicorn
<div class="termy">
* <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a>, uvloopとhttptoolsを基にした高速なASGIサーバ。
```console
$ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:solid">main.py</u>
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting production server 🚀
Searching for package file structure from directories
with <font color="#3465A4">__init__.py</font> files
Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
<span style="background-color:#007166"><font color="#D3D7CF"> module </font></span> 🐍 main.py
<span style="background-color:#007166"><font color="#D3D7CF"> code </font></span> Importing the FastAPI app object from the module with
the following code:
<u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
<span style="background-color:#007166"><font color="#D3D7CF"> app </font></span> Using import string: <font color="#3465A4">main:app</font>
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font>
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000/docs</u></font>
Logs:
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>2306215</b></font><b>]</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font> <b>(</b>Press CTRL+C
to quit<b>)</b>
```
</div>
これでほとんどのケースは動作します。😎
このコマンドは、たとえばコンテナやサーバー内で **FastAPI** アプリを起動するのに使えます。
## ASGIサーバー { #asgi-servers }
少し詳しく見ていきます。
FastAPI は、Python の Web フレームワークとサーバーのための標準である <abbr title="Asynchronous Server Gateway Interface - 非同期サーバーゲートウェイインターフェース">ASGI</abbr> を使います。FastAPI は ASGI Web フレームワークです。
リモートのサーバーマシンで **FastAPI** アプリケーション(や他の ASGI アプリケーション)を実行するのに主に必要なのは **Uvicorn** のような ASGI サーバープログラムです。これは `fastapi` コマンドにデフォルトで含まれています。
他にもいくつかの選択肢があります:
* <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a>: 高性能な ASGI サーバー。
* <a href="https://hypercorn.readthedocs.io/" class="external-link" target="_blank">Hypercorn</a>: HTTP/2 や Trio に対応する ASGI サーバーなど。
* <a href="https://github.com/django/daphne" class="external-link" target="_blank">Daphne</a>: Django Channels のために作られた ASGI サーバー。
* <a href="https://github.com/emmett-framework/granian" class="external-link" target="_blank">Granian</a>: Python アプリケーション向けの Rust 製 HTTP サーバー。
* <a href="https://unit.nginx.org/howto/fastapi/" class="external-link" target="_blank">NGINX Unit</a>: 軽量で多用途な Web アプリケーションランタイム。
## サーバーマシンとサーバープログラム { #server-machine-and-server-program }
名称に関する小さな注意点があります。💡
「サーバー」という言葉は、リモート/クラウド上のコンピュータ(物理/仮想マシン)と、そのマシン上で動作しているプログラム(例: Uvicornの両方を指すのに一般的に使われます。
一般に「サーバー」と書かれているときは、そのどちらかを指している可能性があることを覚えておいてください。
リモートマシンを指す場合、「サーバー」のほか「マシン」「VM仮想マシン」「ード」などとも呼ばれます。いずれも通常 Linux を実行し、そこでプログラムを動かすリモートマシンを指します。
## サーバープログラムをインストール { #install-the-server-program }
FastAPI をインストールすると、本番サーバーの Uvicorn が同梱されており、`fastapi run` コマンドで起動できます。
ただし、ASGI サーバーを手動でインストールすることもできます。
[仮想環境](../virtual-environments.md){.internal-link target=_blank}を作成して有効化し、サーバーアプリケーションをインストールしてください。
例として、Uvicorn をインストールするには:
<div class="termy">
@@ -18,37 +88,21 @@ $ pip install "uvicorn[standard]"
</div>
////
他の ASGI サーバープログラムでも同様の手順です。
/// tip | 豆知識
`standard`加えることで、Uvicornがインストールされ、いくつかの推奨される依存関係を利用するようになります。
`standard`付けると、Uvicorn は推奨の追加依存関係もインストールして使用します。
これには、`asyncio` の高性能な完全互換品である `uvloop` 含まれ、並行処理のパフォーマンスが大幅に向上します。
その中には、`asyncio` の高性能なドロップイン代替であり、大きな並行実行性能の向上をもたらす `uvloop` 含まれます。
`pip install "fastapi[standard]"` のように FastAPI をインストールした場合は、すでに `uvicorn[standard]` も含まれます。
///
//// tab | Hypercorn
## サーバープログラムを起動 { #run-the-server-program }
* <a href="https://github.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>, HTTP/2にも対応しているASGIサーバ。
<div class="termy">
```console
$ pip install hypercorn
---> 100%
```
</div>
...または、これら以外のASGIサーバ。
////
そして、チュートリアルと同様な方法でアプリケーションを起動して下さい。ただし、以下の様に`--reload` オプションは使用しないで下さい:
//// tab | Uvicorn
ASGI サーバーを手動でインストールした場合、通常は FastAPI アプリケーションをインポートさせるために、特別な形式のインポート文字列を渡す必要があります:
<div class="termy">
@@ -60,26 +114,44 @@ $ uvicorn main:app --host 0.0.0.0 --port 80
</div>
////
/// note | 備考
//// tab | Hypercorn
`uvicorn main:app` というコマンドは次を指します:
<div class="termy">
* `main`: ファイル `main.py`Python の「モジュール」)。
* `app`: `main.py` 内で `app = FastAPI()` により作成されたオブジェクト。
```console
$ hypercorn main:app --bind 0.0.0.0:80
これは次と等価です:
Running on 0.0.0.0:8080 over http (CTRL + C to quit)
```Python
from main import app
```
</div>
///
////
他の ASGI サーバープログラムでも同様のコマンドがあり、詳細はそれぞれのドキュメントを参照してください。
停止した場合に自動的に再起動させるツールを設定したいかもしれません。
/// warning | 注意
さらに、<a href="https://gunicorn.org/" class="external-link" target="_blank">Gunicorn</a>をインストールして<a href="https://www.uvicorn.dev/#running-with-gunicorn" class="external-link" target="_blank">Uvicornのマネージャーとして使用したり</a>、複数のワーカーでHypercornを使用したいかもしれません
Uvicorn などのサーバーは、開発時に便利な `--reload` オプションをサポートしています
ワーカー数などの微調整も行いたいかもしれません
しかし `--reload` は多くのリソースを消費し、不安定になるなどの性質があります
しかしこれら全てをやろうとすると、自動的にこれらを行うDockerイメージを使う方が楽かもしれません。
開発中には非常に役立ちますが、 本番環境では使用すべきではありません。
///
## デプロイの概念 { #deployment-concepts }
これらの例は、サーバープログラム(例: Uvicornを実行し、事前に決めたポート例: `80`)で、すべての IP`0.0.0.0`)をリッスンする「単一プロセス」を起動します。
これが基本的な考え方です。ただし、次のような追加事項にも対応したくなるでしょう:
* セキュリティ - HTTPS
* 起動時に実行
* 再起動
* レプリケーション(実行プロセス数)
* メモリ
* 起動前の事前ステップ
これらの各概念についての考え方や、対処するための具体例・戦略を次の章で説明します。🚀

View File

@@ -153,7 +153,7 @@ Hello World from Python
/// tip | 豆知識
詳しくは <a href="https://12factor.net/config" class="external-link" target="_blank">The Twelve-Factor App: Config</a> を参照してください。
詳しくは <a href="https://12factor.net/config" class="external-link" target="_blank">The Twelve-Factor App: 設定</a> を参照してください。
///
@@ -291,7 +291,7 @@ $ C:\opt\custompython\bin\python
これで、**環境変数**とは何か、Pythonでどのように使用するかについて、基本的な理解が得られたはずです。
環境変数についての詳細は、<a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">Wikipedia for Environment Variable</a> も参照してください。
環境変数についての詳細は、<a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">Wikipedia の環境変数</a> も参照してください。
多くの場合、環境変数がどのように役立ち、すぐに適用できるのかはあまり明確ではありません。しかし、開発中のさまざまなシナリオで何度も登場するため、知っておくとよいでしょう。

View File

@@ -1,54 +1,55 @@
# 機能
# 機能 { #features }
## FastAPIの機能
## FastAPIの機能 { #fastapi-features }
**FastAPI**以下の機能をもちます:
**FastAPI**次のものを提供します:
### オープンスタンダード準拠
### オープンスタンダード準拠 { #based-on-open-standards }
* API作成のための<a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a>。これは、<abbr title="also known as: endpoints, routes">path</abbr> <abbr title="also known as HTTP methods, as POST, GET, PUT, DELETE">operations</abbr>の宣言、パラメータ、ボディリクエスト、セキュリティなどを含んでいます。
* <a href="http://json-schema.org/" class="external-link" target="_blank"><strong>JSONスキーマ</strong></a>を使用したデータモデルのドキュメント自動生成OpenAPIはJSONスキーマに基づいてい)。
* 綿密な調査の結果、上層に後付けするのではなく、これらの基準に基づいて設計されました
* API 作成のための <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a>。<dfn title="別名: エンドポイント、ルート">path</dfn> <dfn title="別名: HTTP メソッド(POSTGETPUTDELETE など)">operations</dfn>、パラメータ、リクエストボディ、セキュリティなどの宣言を含みます。
* <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> によるデータモデルの自動ドキュメントOpenAPI 自体が JSON Schema に基づいています)。
* 入念な調査のうえ、これらの標準を中心に設計されています。後付けのレイヤーではありません
* これにより、多くの言語で自動 **クライアントコード生成** が可能です。
### 自動ドキュメント生成
対話的なAPIドキュメントと探索的なwebユーザーインターフェースを提供します。フレームワークはOpenAPIを基にしているため、いくつかのオプションがあり、デフォルトで2つ含まれています。
### 自動ドキュメント { #automatic-docs }
* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank"><strong>Swagger UI</strong></a>で、インタラクティブな探索をしながら、ブラウザから直接APIを呼び出してテストが行えます。
対話的な API ドキュメントと探索的な Web ユーザーインターフェース。フレームワークは OpenAPI に基づいているため、複数のオプションがあり、デフォルトで 2 つ含まれます。
* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank"><strong>Swagger UI</strong></a>。インタラクティブに探索しつつ、ブラウザから直接 API を呼び出してテストできます。
![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)
* <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank"><strong>ReDoc</strong></a>を使用したもう一つのAPIドキュメント生成
* <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank"><strong>ReDoc</strong></a> による代替の API ドキュメント。
![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png)
### 現代的なPython
### 現代的なPythonのみ { #just-modern-python }
FastAPIの機能はすべて標準のPython 3.8型宣言に基づいていますPydanticの功績。新しい構文はありません。ただの現代的な標準のPythonです。
すべて標準の **Python の型** 宣言Pydantic に感謝)に基づいています。新しい構文を学ぶ必要はありません。標準的でモダンな Python だけです。
FastAPIを使用しない場合でもPythonの型の使用方法について簡単な復習が必要な場合は、短いチュートリアル[Python Types](python-types.md){.internal-link target=_blank}を参照してください。
FastAPI を使ない場合でもPython の型の使い方を 2 分で復習したい場合は、短いチュートリアル [Python Types](python-types.md){.internal-link target=_blank} を参照してください。
型を使用した標準的なPythonを記述します:
型を使た標準的な Python を記述します:
```Python
from datetime import date
from pydantic import BaseModel
# Declare a variable as a str
# and get editor support inside the function
# 変数を str として宣言
# そして関数内でエディタ支援を受ける
def main(user_id: str):
return user_id
# A Pydantic model
# Pydantic モデル
class User(BaseModel):
id: int
name: str
joined: date
```
これは以下のように用いられます:
これはのように使えます:
```Python
my_user: User = User(id=3, name="John Doe", joined="2018-07-19")
@@ -62,143 +63,139 @@ second_user_data = {
my_second_user: User = User(**second_user_data)
```
/// info | 情報
/// info
`**second_user_data`以下を意味します:
`**second_user_data`次の意味です:
`second_user_data`辞書のキーと値を直接、キーと値の引数として渡します。これは`User(id=4, name="Mary", joined="2018-11-30")`と同等です。
`second_user_data` 辞書のキーと値を、そのままキーバリュー引数として渡します。これは `User(id=4, name="Mary", joined="2018-11-30")` と同等です。
///
### エディタのサポート
### エディタのサポート { #editor-support }
すべてのフレームワーク使いやすく直感的に使用できるよう設計されており、すべての決定は開発を開始する前でも複数のエディターでテストされ、最高の開発体験が保証されます。
フレームワーク全体が使いやすく直感的にるよう設計されており、最高の開発体験を確保するため、開発開始前から複数のエディタであらゆる判断が検証されています。
前回のPython開発者調査では、<a href="https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features" class="external-link" target="_blank">最も使用されている機能が「オートコンプリート」であることが明らかになりました。</a>
Python 開発者調査では、<a href="https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features" class="external-link" target="_blank">最もよく使われる機能の 1 つが「オートコンプリート」であることが明らかです</a>
**FastAPI** フレームワークは、この要求を満たすことを基本としています。オートコンプリートはどこでも機能します。
**FastAPI** はその要求を満たすことを基盤にしています。オートコンプリートはどこでも機能します。
ドキュメントに戻る必要はほとんどありません。
エディタがどのように役立つかを以下に示します:
エディタがどのように役立つかの例です:
* <a href="https://code.visualstudio.com/" class="external-link" target="_blank">Visual Studio Code</a>の場合:
* <a href="https://code.visualstudio.com/" class="external-link" target="_blank">Visual Studio Code</a> の場合:
![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png)
* <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a>の場合:
* <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> の場合:
![editor support](https://fastapi.tiangolo.com/img/pycharm-completion.png)
以前は不可能だと考えていたコードでさえ補完されます。例えば、リクエストからのJSONボディ(ネストされている可能性ある)内の `price`キーです。
以前は不可能だと思っていたコードでも補完が得られます。例えば、リクエストから届く(ネストされている可能性ある)JSON ボディ内の `price` キーなどです。
間違ったキー名を入力したり、ドキュメントを行き来したり、上下にスクロールして`username``user_name`のどちらを使用したか調べたりする必要はもうありません。
もう間違ったキー名を入力したり、ドキュメントを行き来したり、上下にスクロールして最終的に `username``user_name` のどちらを使ったのか探す必要はありません。
### 簡潔
### 簡潔 { #short }
すべてに適切な**デフォルト**があり、オプション構成できます。必要なことを実行し、必要なAPIを定義するためにすべてのパラメーターを調整できます。
すべてに妥当な **デフォルト** があり、どこでもオプション構成できます。必要に応じてすべてのパラメータを微調整して、求める API を定義できます。
ただし、デフォルトでもすべて **うまくきます**
しかしデフォルトのままでもすべて **うまくきます**
### 検証
### 検証 { #validation }
* 以下の様な、ほとんどの(すべてPython **データ型**の検証:
* JSONオブジェクト`dict`
* 項目の型を定義するJSON配列`list`
* 最小長と最大長のある文字列(`str`)フィールド
* 最小値と最大値のある数値(`int`` float`
* ほとんど(あるいはすべて?)Python **データ型** に対する検証:
* JSON オブジェクト(`dict`
* 項目の型を定義する JSON 配列(`list`
* 文字列(`str`)フィールドの最小/最大長。
* 数値(`int``float`の最小/最大値、など。
* よりエキゾチックな型の検証
* URL
* Eメール
* UUID
* ...その他
* よりエキゾチックな型の検証:
* URL
* Email。
* UUID
* ...その他
すべての検証は、確立され堅牢な **Pydantic** によって処理されます。
すべての検証は、確立され堅牢な **Pydantic** によって処理されます。
### セキュリティと認証
### セキュリティと認証 { #security-and-authentication }
セキュリティと認証が統合されています。 データベースまたはデータモデルについても妥協していません。
セキュリティと認証が統合されています。データベースデータモデルとの妥協はありません。
以下のOpenAPIで定義されているすべてのセキュリティスキームを含む:
OpenAPI で定義されすべてのセキュリティスキームをサポートします:
* HTTPベーシック
* **OAuth2****JWTトークン**も使用)。 JWTを使用したOAuth2のチュートリアル[OAuth2 with JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}を確認してください。
* APIキー
* ヘッダー
* クエリパラメータ
* クッキー、
* HTTP Basic。
* **OAuth2****JWT トークン** も可)。チュートリアル [JWT を用いた OAuth2](tutorial/security/oauth2-jwt.md){.internal-link target=_blank} を確認してください。
* API キー(以下の場所):
* ヘッダー
* クエリパラメータ
* クッキー、など。
さらに、Starletteのすべてのセキュリティ機能も含みます**セッションCookie**を含む)。
さらに、Starlette のすべてのセキュリティ機能(**セッション Cookie** を含む)も利用できます
これらは、システム、データストア、リレーショナルデータベース、NoSQLデータベースなどと簡単に統合できる再利用可能なツールとコンポーネントとして構築されています。
これらはすべて再利用可能なツールやコンポーネントとして構築されており、システム、データストア、リレーショナル/NoSQL データベース等と容易に統合できます。
### 依存性の注入Dependency Injection
### 依存性の注入 { #dependency-injection }
FastAPIには非常に使いやすく、非常に強力な<abbr title='also known as "components", "resources", "services", "providers"'><strong>依存性の注入</strong></abbr>システムを備えています。
FastAPI には非常に使いやすく、かつ非常に強力な <dfn title='別名: コンポーネント、リソース、サービス、プロバイダー'><strong>依存性の注入</strong></dfn> システムがあります。
* 依存関係でさえも依存関係を持つことでき、階層または **依存関係の"グラフ"** を作成することができます。
* 依存関係依存関係を持つことでき、階層または **依存関係のグラフ** を作成できます。
* すべてフレームワークによって**自動的に処理**されます。
* すべての依存関係はリクエストからデータを要求でき、*path operation* の制約と自動ドキュメントを**拡張**できます。
* 依存関係で定義された *path operation* のパラメータについても**自動検証**されます。
* 複雑なユーザー認証システム、**データベース接続** などのサポート。
* **データベースやフロントエンド等との妥協は不要**。すべてと簡単に統合できます。
* フレームワークによってすべて**自動的に処理**されます。
* すべての依存関係はリクエストからのデータを要請できて、**path operationsの制約と自動ドキュメンテーションを拡張できます**。
* 依存関係で定義された *path operation* パラメータも**自動検証**が可能です。
* 複雑なユーザー認証システム、**データベース接続**などのサポート
* **データベース、フロントエンドなどに対する妥協はありません**。それらすべてと簡単に統合できます。
### 無制限の「プラグイン」 { #unlimited-plug-ins }
### 無制限の「プラグイン」
別の言い方をすれば、プラグインは不要で、必要なコードをインポートして使うだけです。
他の方法では、それらを必要とせず、必要なコードをインポートして使用します。
あらゆる統合は(依存関係を用いて)非常に簡単に使えるよう設計されており、*path operation* で使うのと同じ構造と構文で、2 行のコードでアプリケーション用の「プラグイン」を作れます。
統合は非常に簡単に使用できるように設計されており(依存関係を用いて)、*path operations* で使用されているのと同じ構造と構文を使用して、2行のコードでアプリケーションの「プラグイン」を作成できます。
### テスト済み { #tested }
* 100% の <dfn title="自動的にテストされるコードの量">テストカバレッジ</dfn>。
* 100% <dfn title="Python の型アノテーション。これにより、エディタや外部ツールからより良い支援が受けられます">型アノテーション付き</dfn>のコードベース。
* 本番アプリケーションで使用されています。
### テスト
## Starletteの機能 { #starlette-features }
* <abbr title = "自動的にテストされるコードの量">テストカバレッジ</abbr> 100%
* <abbr title = "Python型アテーション。これにより、ユーザーはより良いエディターと外部ツールのサポート受けられる。">型アノテーション</abbr>100%のコードベース
* 本番アプリケーションで使用されます
**FastAPI** は <a href="https://www.starlette.dev/" class="external-link" target="_blank"><strong>Starlette</strong></a> と完全に互換性があり(かつそれに基づいています)。そのため、手元の Starlette の追加コードも動作します。
## Starletteの機能
`FastAPI` は実際には `Starlette` のサブクラスです。すでに Starlette を知っている、あるいは使っているなら、ほとんどの機能は同じように動作します。
**FastAPI**は、<a href="https://www.starlette.dev/" class="external-link" target="_blank"><strong>Starlette </strong></a>と完全に互換性がありますそしてベースになっています。したがって、追加のStarletteコードがあれば、それも機能します。
**FastAPI** では **Starlette** のすべての機能が利用できますFastAPI は強化された Starlette にすぎません):
`FastAPI`は実際には`Starlette`のサブクラスです。したがって、Starletteをすでに知っているか使用している場合は、ほとんどの機能が同じように機能します
**FastAPI**を使用すると、以下のような、**Starlette**のすべての機能を利用できますFastAPIはStarletteを強化したものにすぎないため:
* 見事なパフォーマンス。<a href="https://github.com/encode/starlette#performance" class="external-link" target="_blank"> **NodeJS**および**Go**に匹敵する、最速のPythonフレームワークの1つです。</a>
* **WebSocket**のサポート
* **GraphQL**のサポート
* プロセス内バックグラウンドタスク
* 起動およびシャットダウンイベント
* `httpx`に基づいて構築されたテストクライアント
* **CORS**、GZip、静的ファイル、ストリーミング応答
* **セッションとCookie**のサポート
* テストカバレッジ100%
* 型アテーション100%のコードベース
## Pydanticの特徴
**FastAPI**は<a href="https://docs.pydantic.dev/" class="external-link" target="_blank"><strong>Pydantic </strong></a>と完全に互換性がありますそしてベースになっています。したがって、追加のPydanticコードがあれば、それも機能します。
データベースのために<abbr title = "Object-Relational Mapper">ORM</abbr>sや、<abbr title = "Object-Document Mapper">ODM</abbr>sなどの、Pydanticに基づく外部ライブラリを備えています
これは、すべてが自動的に検証されるため、多くの場合、リクエストから取得したオブジェクトを**データベースに直接**渡すことができるということを意味しています。
同じことがその逆にも当てはまり、多くの場合、データベースから取得したオブジェクトを**クライアントに直接**渡すことができます。
**FastAPI**を使用すると、**Pydantic**のすべての機能を利用できますFastAPIがPydanticに基づいてすべてのデータ処理を行っているため
* **brainfuckなし**
* スキーマ定義のためのマイクロ言語を新たに学習する必要はありません
* Pythonの型を知っている場合は、既にPydanticの使用方法を知っているに等しいです。
* ユーザーの **<abbr title = "コードエディターに似た統合開発環境">IDE</abbr>/<abbr title = "コードエラーをチェックするプログラム">リンター</abbr>/思考 とうまく連携します**
* Pydanticのデータ構造は、ユーザーが定義するクラスの単なるインスタンスであるため、オートコンプリート、リンティング、mypy、およびユーザーの直感はすべて、検証済みのデータで適切に機能するはずです。
* **複雑な構造**を検証:
* 階層的なPydanticモデルや、Pythonの「`typing`」の「`list`」と「`dict`」などの利用。
* バリデーターにより、複雑なデータスキーマを明確かつ簡単に定義、チェックし、JSONスキーマとして文書化できます。
* 深く**ネストされたJSON**オブジェクトを作成し、それらすべてを検証してアノテーションを付けることができます。
* **拡張可能**
* Pydanticでは、カスタムデータ型を定義できます。または、バリデーターデコレーターで装飾されたモデルのメソッドを使用して検証を拡張できます。
* 圧倒的なパフォーマンス。<a href="https://github.com/encode/starlette#performance" class="external-link" target="_blank">利用可能な最速クラスの Python フレームワークの 1 つで、**NodeJS** や **Go** と同等です</a>
* **WebSocket** のサポート。
* プロセス内バックグラウンドタスク。
* 起動およびシャットダウンイベント。
* HTTPX に基づくテストクライアント。
* **CORS**、GZip、静的ファイル、ストリーミングレスポンス。
* **セッションと Cookie** のサポート
* テストカバレッジ 100%。
* 型アノテーション 100% のコードベース。
## Pydanticの機能 { #pydantic-features }
**FastAPI** は <a href="https://docs.pydantic.dev/" class="external-link" target="_blank"><strong>Pydantic</strong></a> と完全に互換性があり(かつそれに基づいています)。そのため、手元の Pydantic の追加コードも動作します。
Pydantic に基づく外部ライブラリ(データベース用の <abbr title="Object-Relational Mapper - オブジェクト関係マッパー">ORM</abbr>、<abbr title="Object-Document Mapper - オブジェクトドキュメントマッパー">ODM</abbr> など)も含まれます。
これは、すべてが自動的に検証されるため、多くの場合、リクエストから取得したオブジェクトを **そのままデータベースに** 渡せることを意味します。
逆方向も同様で、多くの場合、データベースから取得したオブジェクトを **そのままクライアントに** 渡せます。
**FastAPI** では **Pydantic** のすべての機能が利用できますFastAPI はデータ処理のすべてで Pydantic に基づています:
* **brainfuck なし**
* スキーマ定義のための新しいマイクロ言語を学ぶ必要はありません。
* Python の型を知っていれば、Pydantic の使い方もわかります。
* **<abbr title="Integrated Development Environment - 統合開発環境: コードエディタに類似">IDE</abbr>/<dfn title="コードのエラーを検査するプログラム">リンター</dfn>/思考** と気持ちよく連携します:
* Pydantic のデータ構造は、あなたが定義するクラスの単なるインスタンスなので、オートコンプリート、リンティング、mypy、そしてあなたの直感が、検証済みデータに対して適切に機能します
* **複雑な構造** を検証:
* 階層的な Pydantic モデルや、Python の `typing` にある `List``Dict` などを利用できます。
* さらにバリデータにより、複雑なデータスキーマを明確かつ容易に定義・検査でき、JSON Schema として文書化できます
* 深く **ネストされた JSON** オブジェクトを扱え、それらすべてを検証してアノテーションを付与できます。
* **拡張可能**
* Pydantic ではカスタムデータ型を定義できますし、バリデータデコレーターで装飾したモデルメソッドで検証を拡張できます。
* テストカバレッジ 100%。

View File

@@ -1,101 +1,255 @@
# FastAPIを応援 - ヘルプの入手
# FastAPIを応援 - ヘルプの入手 { #help-fastapi-get-help }
**FastAPI** は気に入りましたか?
FastAPIやユーザーや開発者を応援したいですか?
FastAPIや他のユーザー、作者を応援したいですか?
しくは、 **FastAPI** についてヘルプが必要ですか?
それと**FastAPI** についてヘルプが必要ですか?
とても簡単に応援できます (ただ1、2回クリックするだけのものもあります)
とても簡単に応援できる方法があります(1、2回クリックするだけのものもあります
また、ヘルプを入手する手段がいくつかあります。
ヘルプを得る方法もいくつかあります。
## GitHubで **FastAPI** にStar
## ニュースレターを購読 { #subscribe-to-the-newsletter }
GitHubでFastAPIに「Star」をつけることができます (右上部のStarボタンをクリック): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. ⭐️
[**FastAPI and friends** ニュースレター](newsletter.md){.internal-link target=_blank}(配信はまれです)を購読すると、次の情報をキャッチアップできます:
スターを増やすことで、他のユーザーの目につきやすくなり、多くの人にとって便利なものであることを示せます。
* FastAPI と関連プロジェクトのニュース 🚀
* ガイド 📝
* 機能 ✨
* 互換性に影響する変更 🚨
* ヒントやコツ ✅
## GitHubレポジトリのリリースをWatch
## X (Twitter) で FastAPI をフォロー { #follow-fastapi-on-x-twitter }
GitHubでFastAPIを「Watch」できます (右上部のWatchボタンをクリック): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. 👀
<a href="https://x.com/fastapi" class="external-link" target="_blank">**X (Twitter)** で @fastapi をフォロー</a>して、**FastAPI** の最新情報を受け取りましょう。🐦
## GitHubで **FastAPI** にStar { #star-fastapi-in-github }
GitHubでFastAPIに「Star」をつけることができます右上部のStarボタンをクリック: <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>。⭐️
スターを増やすことで、他のユーザーの目につきやすくなり、すでに多くの人の役に立っていることが伝わります。
## GitHubレポジトリのリリースをWatch { #watch-the-github-repository-for-releases }
GitHubでFastAPIを「Watch」できます右上部の「Watch」ボタンをクリック: <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>。👀
そこで「Releases only」を選択できます。
これを行うと、**FastAPI** バグ修正や新機能の実装などの新しいリリース (新しいバージョン) があるたびに (メールで) 通知を受け取れます。
これを行うと、バグ修正や新機能を含む **FastAPI** の新しいリリース(新バージョンがあるたびに、(メールで通知を受け取れます。
## 開発者とつながる
## 開発者とつながる { #connect-with-the-author }
以下で、<a href="https://tiangolo.com" class="external-link" target="_blank">開発者 (Sebastián Ramírez / `tiangolo`)</a> とコンタクトをとれます:
作者である<a href="https://tiangolo.com" class="external-link" target="_blank">私(Sebastián Ramírez / `tiangolo`</a>とつながれます
できること:
* <a href="https://github.com/tiangolo" class="external-link" target="_blank">**GitHub** でフォロー</a>。
* 他のオープンソースプロジェクトを確認できます。何かの助けになるものが見つかるかもしれません
*たなオープンソースプロジェクトを作成したときに通知されます。
* <a href="https://x.com/tiangolo" class="external-link" target="_blank">**X (Twitter)** でフォロー</a>。
* FastAPIの使用用途を教えてください (聞いてみたいです)
*たなツールの発表やリリース聞けます。
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">**Linkedin** でつながる</a>
* 新たなツールの発表やリリースが聞けます (ただしX (Twitter)の方が利用頻度が高いですが 🤷‍♂)
* <a href="https://dev.to/tiangolo" class="external-link" target="_blank">**Dev.to**</a> や <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a> で著作物を読む (またはフォロー)
* アイデアや作成ツールについての記事が読めます
* 新規記事の執筆を通知してくれます。
* 役に立つかもしれない、私が作成した他のオープンソースプロジェクトを見られます
*しいオープンソースプロジェクトを作成したときにわかります。
* <a href="https://x.com/tiangolo" class="external-link" target="_blank">**X (Twitter)** でフォロー</a> または <a href="https://fosstodon.org/@tiangolo" class="external-link" target="_blank">Mastodon</a>
* あなたがどのようにFastAPIを使っているか教えてください聞けると嬉しいです
*しいツールの告知やリリース聞けます。
* さらに、<a href="https://x.com/fastapi" class="external-link" target="_blank">X (Twitter) の @fastapi</a>(別アカウント)もフォローできます
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">**LinkedIn** でフォロー</a>
* 新しいツールの告知やリリースを聞けますただしX (Twitter) の方をよく使っています 🤷‍♂)
* <a href="https://dev.to/tiangolo" class="external-link" target="_blank">**Dev.to**</a> や <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a> で執筆内容を読む(またはフォロー)
* 私のアイデアや、作成したツールに関する記事を読めます。
* 新しい記事を公開したときに読めます。
## **FastAPI** に関するツイート
## **FastAPI** についてツイート { #tweet-about-fastapi }
<a href="https://x.com/compose/tweet?text=I'm loving FastAPI because... https://github.com/fastapi/fastapi cc @tiangolo" class="external-link" target="_blank">**FastAPI** についてツイート</a>し、開発者や他の人にどこが気に入ったのか教えてください。🎉
<a href="https://x.com/compose/tweet?text=I'm loving @fastapi because... https://github.com/fastapi/fastapi" class="external-link" target="_blank">**FastAPI** についてツイート</a>して、なぜ気に入っているのかを私や他の人に教えてください。🎉
**FastAPI** がどのように使われ、どこ気に入られ、どんなプロジェクト/会社で使われているかなどについて知りたいです。
**FastAPI** がどのように使われているか、どこ気に入っているか、どのプロジェクト/会社で使ているか等、聞けると嬉しいです。
## FastAPIに投票
## FastAPIに投票 { #vote-for-fastapi }
* <a href="https://www.slant.co/options/34241/~fastapi-review" class="external-link" target="_blank">Slantで **FastAPI** に投票</a>
* <a href="https://alternativeto.net/software/fastapi/" class="external-link" target="_blank">AlternativeToで **FastAPI** に投票</a>
* <a href="https://github.com/marmelab/awesome-rest/pull/93" class="external-link" target="_blank">awesome-rest**FastAPI** に投票</a>
* <a href="https://www.slant.co/options/34241/~fastapi-review" class="external-link" target="_blank">Slantで **FastAPI** に投票</a>
* <a href="https://alternativeto.net/software/fastapi/about/" class="external-link" target="_blank">AlternativeToで **FastAPI** に投票</a>
* <a href="https://stackshare.io/pypi-fastapi" class="external-link" target="_blank">StackShare **FastAPI** を使っていると宣言</a>
## GitHub issuesで他の人を助ける
## GitHubで質問に困っている人を助ける { #help-others-with-questions-in-github }
<a href="https://github.com/fastapi/fastapi/issues" class="external-link" target="_blank">既存のissues</a>を確認して、他の人を助けてみてください。皆さんが回答を知っているかもしれない質問がほとんどです。🤓
次の場所で、他の人の質問を手助けできます:
## GitHubレポジトリをWatch
* <a href="https://github.com/fastapi/fastapi/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered" class="external-link" target="_blank">GitHub Discussions</a>
* <a href="https://github.com/fastapi/fastapi/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Aquestion+-label%3Aanswered+" class="external-link" target="_blank">GitHub Issues</a>
GitHubでFastAPIを「watch」できます (右上部の「watch」ボタンをクリック): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. 👀
多くの場合、その質問の答えをすでに知っているかもしれません。🤓
「Releases only」ではなく「Watching」を選択すると、新たなissueが立てられた際に通知されます。
もし多くの人の質問に答えて助けてくれたなら、あなたは公式の[FastAPI Expert](fastapi-people.md#fastapi-experts){.internal-link target=_blank}になります。🎉
そして、issueを解決し他の人を助けることができます。
最も大事なポイントは「親切であること」を心がけることです。人はフラストレーションを抱えてやって来るので、必ずしも最良の聞き方をしているとは限りませんが、できる限り親切に対応しましょう。🤗
## issuesを立てる
**FastAPI** コミュニティは親切で歓迎的であることを目指しています。同時に、いじめや他者への無礼な振る舞いは受け入れないでください。お互いを大事にしましょう。
GitHubレポジトリで<a href="https://github.com/fastapi/fastapi/issues/new/choose" class="external-link" target="_blank">新たなissueを立てられます</a>。例えば:
---
* 質問、または、問題の報告
* 新機能の提案
以下はDiscussions や Issues で)他の人の質問を手助けする方法です:
**Note**: issueを立てた人は、他の人の手助けもお願いします。😉
### 質問を理解する { #understand-the-question }
## プルリクエストをする
* 質問者の「目的」やユースケースを理解できるか確認します。
以下の様な<a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">プルリクエストを作成</a>できます:
* 次に、質問(大半は質問です)が「明確」か確認します
* ドキュメントのタイプミスを修正
* 新たなドキュメントセクションを提案。
* 既存のissue/バグを修正。
* 新機能を追加。
* 多くの場合、ユーザーが想像した解決策についての質問になっていますが、もっと「良い」方法があるかもしれません。問題やユースケースをよりよく理解できれば、より良い「代替解決策」を提案できるかもしれません
## 開発者のスポンサーになる
* 質問が理解できない場合は、さらに「詳細」を尋ねます。
<a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub sponsors</a>を通して開発者を経済的にサポートできます。
### 問題を再現する { #reproduce-the-problem }
そこで、感謝の気持ちを伝えるためにコーヒー☕️を買うことができます 😄
多くのケースや質問は、その人の「元のコード」に関係しています
## FastAPIを強化するツールのスポンサーになる
しばしばコードの断片だけが共有されますが、それでは問題を「再現」するには不十分です。
ドキュメントで見たように、FastAPIはStarletteとPydanticという巨人の肩に乗っています。
* ローカルで同じエラーや挙動を確認できるように、またはユースケースをよりよく理解できるように、**コピー&ペースト**して実行できる<a href="https://stackoverflow.com/help/minimal-reproducible-example" class="external-link" target="_blank">最小の再現可能な例</a>の提供を依頼できます。
以下のスポンサーになることもできます:
* とても寛大な気分なら、問題の説明だけをもとに、あなた自身でそのような**例を作成**してみることもできます。ただし時間がかかる可能性が高いので、まずは問題の明確化を依頼した方が良い場合もあります。
* <a href="https://github.com/sponsors/samuelcolvin" class="external-link" target="_blank">Samuel Colvin (Pydantic)</a>
* <a href="https://github.com/sponsors/encode" class="external-link" target="_blank">Encode (Starlette, Uvicorn)</a>
### 解決策を提案する { #suggest-solutions }
* 質問を理解できたら、可能な**回答**を提示できます。
* 多くの場合、相手の「根本的な問題やユースケース」を理解することが重要です。相手が試している方法より良い解決方法があるかもしれないからです。
### クローズを依頼する { #ask-to-close }
もし相手が返信してきて、あなたが問題を解決できたなら、おめでとう、**あなたはヒーロー**です!🦸
* その場合、次のように依頼できます:
* GitHub Discussions: コメントを**回答**としてマークしてもらう。
* GitHub Issues: issue を**クローズ**してもらう。
## GitHubレポジトリをWatch { #watch-the-github-repository }
GitHubでFastAPIを「Watch」できます右上部の「Watch」ボタンをクリック: <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>。👀
「Releases only」ではなく「Watching」を選択すると、新しい issue や質問が作成されたときに通知を受け取れます。新しい issue のみ、Discussions のみ、PR のみ、など通知対象を絞ることもできます。
その上で、そうした質問の解決を手助けできます。
## 質問する { #ask-questions }
GitHubレポジトリで<a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">新しい質問</a>を作成できます。例えば:
* **質問**をする、または**問題**について尋ねる。
* 新しい**機能**を提案する。
**Note**: もしそうするなら、他の人の手助けもお願いします。😉
## プルリクエストをレビュー { #review-pull-requests }
他の人からのプルリクエストのレビューを手伝ってもらえます。
ここでも、できる限り親切であるようにしてください。🤗
---
プルリクエストをレビューするときのポイントです:
### 問題を理解する { #understand-the-problem }
* まず、そのプルリクエストが解決しようとしている**問題を理解**してください。長めの議論が GitHub Discussion や issue にあるかもしれません。
* その問題は実は**別の方法**で解決でき、プルリクエスト自体が不要な場合もあります。その場合は、その提案や質問をしても良いでしょう。
### スタイルは気にしすぎない { #dont-worry-about-style }
* コミットメッセージのスタイルなどはあまり気にしなくて大丈夫です。私は squash and merge を使い、コミットを手動で調整します。
* スタイルルールについても心配無用です。自動化ツールがすでにチェックしています。
ほかにスタイルや一貫性の要件があれば、私から直接依頼しますし、必要な変更を上に積む形でコミットを追加します。
### コードを確認 { #check-the-code }
* コードを確認して読み、妥当かどうかを見て、**ローカルで実行**し、本当に問題を解決しているか確かめてください。
* そのうえで、それを行ったことを**コメント**で伝えてください。そうすれば、実際に確認してくれたとわかります。
/// info | 情報
残念ながら、承認が複数ついただけのPRを、そのまま信頼することはできません。
説明が魅力的なためか、3件、5件以上の承認がついていても、実際にPRを確認すると壊れていたり、バグがあったり、主張する問題を解決していなかったりすることが何度もありました。😅
ですので、実際にコードを読み、実行して確認し、それをコメントで知らせてもらえることが本当に重要です。🤓
///
* もしPRを簡素化できそうなら、その依頼をしても構いませんが、細かい点にこだわり過ぎる必要はありません。主観的な見方が多く私にもあります 🙈)、基本的な点に集中できるとより良いでしょう。
### テスト { #tests }
* PRに**テスト**があるか確認を手伝ってください。
* PR前はテストが**失敗**することを確認します。🚨
* そしてPR後にテストが**成功**することを確認します。✅
* 多くのPRにはテストがありません。テストの追加を**リマインド**したり、テストを**提案**したりできます。これは最も時間を消費する部分の一つで、大いに助けになります。
* 何を試したかもコメントしてください。そうすれば、確認してくれたことがわかります。🤓
## プルリクエストを作成 { #create-a-pull-request }
[貢献](contributing.md){.internal-link target=_blank}として、次のようにプルリクエストでソースコードに貢献できます:
* ドキュメントで見つけたタイポの修正。
* 自分が作成/発見した FastAPI に関する記事・動画・ポッドキャストを、<a href="https://github.com/fastapi/fastapi/edit/master/docs/en/data/external_links.yml" class="external-link" target="_blank">このファイルを編集</a>して共有。
* 該当セクションの先頭にリンクを追加してください。
* 自分の言語への[ドキュメント翻訳を手伝う](contributing.md#translations){.internal-link target=_blank}。
* 他の人が作成した翻訳のレビューも手伝えます。
* 新しいドキュメントセクションの提案。
* 既存のissue/バグの修正。
* テストを追加してください。
* 新機能の追加。
* テストを追加してください。
* 関連があればドキュメントも追加してください。
## FastAPIのメンテナンスを手伝う { #help-maintain-fastapi }
**FastAPI** のメンテナンスを手伝ってください!🤓
やることはたくさんあり、その多くは**あなた**にもできます。
今すぐできる主なタスクは次のとおりです:
* [GitHubで質問に困っている人を助ける](#help-others-with-questions-in-github){.internal-link target=_blank}(上のセクションを参照)。
* [プルリクエストをレビュー](#review-pull-requests){.internal-link target=_blank}(上のセクションを参照)。
この2つが**最も時間を消費**します。FastAPI のメンテナンス作業の中心です。
これを手伝ってもらえると、**FastAPIのメンテナンスに貢献**し、**より速く・より良く前進**できるようになります。🚀
## チャットに参加 { #join-the-chat }
👥 <a href="https://discord.gg/VQjSZaeJmf" class="external-link" target="_blank">Discord チャットサーバー</a> 👥 に参加し、FastAPI コミュニティのみんなと交流しましょう。
/// tip | 豆知識
質問は <a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">GitHub Discussions</a> に投稿してください。そこなら[FastAPI Experts](fastapi-people.md#fastapi-experts){.internal-link target=_blank}から助けてもらえる可能性がずっと高いです。
チャットは一般的な会話のみに使いましょう。
///
### 質問でチャットを使わない { #dont-use-the-chat-for-questions }
チャットは「自由な会話」がしやすいため、一般的すぎて答えにくい質問になりがちです。そのため、回答が得られない可能性があります。
GitHub では、テンプレートが正しい形で質問を書くのを助けてくれるため、良い回答を得やすくなりますし、質問する前に自分で問題を解決できることもあります。さらにGitHubなら、時間がかかっても私が必ずすべてに回答できるようにできます。チャットでは私個人にはそれができません。😅
チャットでの会話はGitHubほど検索しやすくないため、質問と回答が会話に埋もれがちです。そして、[FastAPI Expert](fastapi-people.md#fastapi-experts){.internal-link target=_blank}になるためにカウントされるのはGitHub上の活動だけです。ですから、GitHubの方が注目を集めやすいでしょう。
一方で、チャットには数千人のユーザーがいるため、ほぼ常に誰かと会話できる可能性が高いです。😄
## 作者をスポンサー { #sponsor-the-author }
あなたの**製品/会社**が **FastAPI** に依存している、または関連しており、そのユーザーにリーチしたい場合は、<a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub sponsors</a> を通じて作者(私)を支援できます。プランに応じて、ドキュメントにバッジが表示されるなどの特典がある場合があります。🎁
---

View File

@@ -1,13 +1,12 @@
# 歴史、設計、そしてこれから
# 歴史、設計、そしてこれから { #history-design-and-future }
少し前に、<a href="https://github.com/fastapi/fastapi/issues/3#issuecomment-454956920" class="external-link" target="_blank">**FastAPI**
のユーザーに以下の様に尋ねられました</a>:
少し前に、<a href="https://github.com/fastapi/fastapi/issues/3#issuecomment-454956920" class="external-link" target="_blank">**FastAPI**のユーザーに以下の様に尋ねられました</a>:
> このプロジェクトの歴史は?何もないところから、数週間ですごいものができているようです。 [...]
これがその歴史のほんの一部です。
## 代替手段
## 代替手段 { #alternatives }
数年前から、私は複雑な要件を持つAPI (機械学習、分散システム、非同期ジョブ、NoSQLデータベースなど) を作成しており、いくつかの開発者チームを率いています。
@@ -19,7 +18,7 @@
<blockquote markdown="1">
**FastAPI**は、代替ツールのこれまでの働きがなければ存在しなかったでしょう。
**FastAPI**は、他の人々のこれまでの働きがなければ存在しなかったでしょう。
以前に作られた多くのツールが、作成における刺激として役立ってきました。
@@ -29,7 +28,7 @@
</blockquote>
## 調査
## 調査 { #investigation }
すべて既存の代替手段を使うことで、そのすべてを学び、アイデアを得て、自分や一緒に仕事をしてきた開発者のチームにとって最良の方法で組み合わせる機会を得ました。
@@ -39,7 +38,7 @@
そこで、**FastAPI**のコードを書き始める前に、OpenAPI、JSON Schema、OAuth2などの仕様を数ヶ月かけて勉強し、それらの関係、重複する箇所、相違点を理解しました。
## 設計
## 設計 { #design }
その後、 (FastAPIを使う開発者として) ユーザーが欲しい「API」の設計に時間を費やしました。
@@ -53,19 +52,19 @@
すべての箇所で、すべての開発者に最高の開発体験を提供しました。
## 要件
## 要件 { #requirements }
いくつかの代替手法を試したあと、私は<a href="https://docs.pydantic.dev/" class="external-link" target="_blank">**Pydantic**</a>の強みを利用することを決めました。
そして、JSON Schemaに完全に準拠するようにしたり、制約宣言を定義するさまざまな方法をサポートしたり、いくつかのエディターでのテストに基づいてエディターのサポート (型チェック、自動補完) を改善するために貢献しました。
開発中、もう1つの重要な鍵となる<a href="https://www.starlette.dev/" class="external-link" target="_blank">**Starlette**</a>にも貢献しました。
開発中、もう1つの重要な鍵となる<a href="https://www.starlette.dev/" class="external-link" target="_blank">**Starlette**</a>にも貢献しました。
## 開発
## 開発 { #development }
私が**FastAPI**自体の作成を開始した時には、ほとんどの部分がすでに準備されており、設計が定義され、必要な条件とツールの準備ができていました。そして規格や仕様に関する知識が、明確になり、更新されていました。
## これから
## これから { #future }
この時点ですでに、これらのアイデアを持った**FastAPI**が多くの人の役に立っていることは明らかです。

Some files were not shown because too many files have changed in this diff Show More