diff --git a/docs/fr/docs/tutorial/query-params.md b/docs/fr/docs/tutorial/query-params.md
index 7bf3b9e79..962135f63 100644
--- a/docs/fr/docs/tutorial/query-params.md
+++ b/docs/fr/docs/tutorial/query-params.md
@@ -75,7 +75,7 @@ Ici, le paramรจtre `q` sera optionnel, et aura `None` comme valeur par dรฉfaut.
!!! note
**FastAPI** saura que `q` est optionnel grรขce au `=None`.
- Le `Optional` dans `Optional[str]` n'est pas utilisรฉ par **FastAPI** (**FastAPI** n'en utilisera que la partie `str`), mais il servira tout de mรชme ร votre editeur de texte pour dรฉtecter des erreurs dans votre code.
+ Le `Optional` dans `Optional[str]` n'est pas utilisรฉ par **FastAPI** (**FastAPI** n'en utilisera que la partie `str`), mais il servira tout de mรชme ร votre รฉditeur de texte pour dรฉtecter des erreurs dans votre code.
## Conversion des types des paramรจtres de requรชte
diff --git a/docs/ja/docs/deployment/deta.md b/docs/ja/docs/deployment/deta.md
deleted file mode 100644
index 723f169a0..000000000
--- a/docs/ja/docs/deployment/deta.md
+++ /dev/null
@@ -1,240 +0,0 @@
-# Deta ใซใใใญใค
-
-ใใฎใปใฏใทใงใณใงใฏใ**FastAPI** ใขใใชใฑใผใทใงใณใ
Deta ใฎ็กๆใใฉใณใๅฉ็จใใฆใ็ฐกๅใซใใใญใคใใๆนๆณใๅญฆ็ฟใใพใใ๐
-
-ๆ่ฆๆ้ใฏ็ด**10ๅ**ใงใใ
-
-!!! info "ๅ่"
-
Deta ใฏ **FastAPI** ใฎในใใณใตใผใงใใ๐
-
-## ใใผใทใใฏใช **FastAPI** ใขใใช
-
-* ใขใใชใฎใใใฎใใฃใฌใฏใใช (ไพใใฐ `./fastapideta/`) ใไฝๆใใใใฎไธญใซๅ
ฅใฃใฆใใ ใใใ
-
-### FastAPI ใฎใณใผใ
-
-* ไปฅไธใฎ `main.py` ใใกใคใซใไฝๆใใฆใใ ใใ:
-
-```Python
-from fastapi import FastAPI
-
-app = FastAPI()
-
-
-@app.get("/")
-def read_root():
- return {"Hello": "World"}
-
-
-@app.get("/items/{item_id}")
-def read_item(item_id: int):
- return {"item_id": item_id}
-```
-
-### Requirements
-
-ใงใฏใๅใใใฃใฌใฏใใชใซไปฅไธใฎ `requirements.txt` ใใกใคใซใไฝๆใใฆใใ ใใ:
-
-```text
-fastapi
-```
-
-!!! tip "่ฑ็ฅ่ญ"
- ใขใใชใฎใญใผใซใซใในใใฎใใใซ Uvicorn ใใคใณในใใผใซใใใใชใใใใใใพใใใใDeta ใธใฎใใใญใคใซใฏไธ่ฆใงใใ
-
-### ใใฃใฌใฏใใชๆง้
-
-ไปฅไธใฎ2ใคใฎใใกใคใซใจ1ใคใฎ `./fastapideta/` ใใฃใฌใฏใใชใใใใฏใใงใ:
-
-```
-.
-โโโ main.py
-โโโ requirements.txt
-```
-
-## Detaใฎ็กๆใขใซใฆใณใใฎไฝๆ
-
-ใใใงใฏใ
Detaใฎ็กๆใขใซใฆใณใใไฝๆใใพใใใใๅฟ
่ฆใชใใฎใฏใกใผใซใขใใฌในใจใในใฏใผใใ ใใงใใ
-
-ใฏใฌใธใใใซใผใใใๅฟ
่ฆใใใพใใใ
-
-## CLIใฎใคใณในใใผใซ
-
-ใขใซใฆใณใใๅๅพใใใใDeta
CLI ใใคใณในใใผใซใใฆใใ ใใ:
-
-=== "Linux, macOS"
-
-
-
- ```console
- $ curl -fsSL https://get.deta.dev/cli.sh | sh
- ```
-
-
-
-=== "Windows PowerShell"
-
-
-
- ```console
- $ iwr https://get.deta.dev/cli.ps1 -useb | iex
- ```
-
-
-
-ใคใณในใใผใซใใใใใคใณในใใผใซใใ CLI ใๆๅนใซใใใใใซๆฐใใชใฟใผใใใซใ้ใใฆใใ ใใใ
-
-ๆฐใใชใฟใผใใใซไธใงใๆญฃใใใคใณในใใผใซใใใใ็ขบ่ชใใพใ:
-
-
-
-```console
-$ deta --help
-
-Deta command line interface for managing deta micros.
-Complete documentation available at https://docs.deta.sh
-
-Usage:
- deta [flags]
- deta [command]
-
-Available Commands:
- auth Change auth settings for a deta micro
-
-...
-```
-
-
-
-!!! tip "่ฑ็ฅ่ญ"
- CLI ใฎใคใณในใใผใซใซๅ้กใ็บ็ใใๅ ดๅใฏใ
Deta ๅ
ฌๅผใใญใฅใกใณใใๅ็
งใใฆใใ ใใใ
-
-## CLIใงใญใฐใคใณ
-
-CLI ใใ Deta ใซใญใฐใคใณใใฆใฟใพใใใ:
-
-
-
-```console
-$ deta login
-
-Please, log in from the web page. Waiting..
-Logged in successfully.
-```
-
-
-
-่ชๅ็ใซใฆใงใใใฉใฆใถใ้ใใฆใ่ช่จผๅฆ็ใ่กใใใพใใ
-
-## Deta ใงใใใญใค
-
-ๆฌกใซใใขใใชใฑใผใทใงใณใ Deta CLIใงใใใญใคใใพใใใ:
-
-
-
-```console
-$ deta new
-
-Successfully created a new micro
-
-// Notice the "endpoint" ๐
-
-{
- "name": "fastapideta",
- "runtime": "python3.7",
- "endpoint": "https://qltnci.deta.dev",
- "visor": "enabled",
- "http_auth": "enabled"
-}
-
-Adding dependencies...
-
-
----> 100%
-
-
-Successfully installed fastapi-0.61.1 pydantic-1.7.2 starlette-0.13.6
-```
-
-
-
-ๆฌกใฎใใใชJSONใกใใปใผใธใ่กจ็คบใใใพใ:
-
-```JSON hl_lines="4"
-{
- "name": "fastapideta",
- "runtime": "python3.7",
- "endpoint": "https://qltnci.deta.dev",
- "visor": "enabled",
- "http_auth": "enabled"
-}
-```
-
-!!! tip "่ฑ็ฅ่ญ"
- ใใชใใฎใใใญใคใงใฏ็ฐใชใ `"endpoint"` URLใ่กจ็คบใใใใงใใใใ
-
-## ็ขบ่ช
-
-ใใใงใฏใ`endpoint` URLใใใฉใฆใถใง้ใใฆใฟใพใใใใไธ่จใฎไพใงใฏ `https://qltnci.deta.dev` ใงใใใใใชใใฎURLใฏ็ฐใชใใฏใใงใใ
-
-FastAPIใขใใชใใ่ฟใฃใฆใใJSONใฌในใใณในใ่กจ็คบใใใพใ:
-
-```JSON
-{
- "Hello": "World"
-}
-```
-
-ใใใฆ `/docs` ใธ็งปๅใใฆใใ ใใใไธ่จใฎไพใงใฏใ`https://qltnci.deta.dev/docs` ใงใใ
-
-ๆฌกใฎใใใชใใญใฅใกใณใใ่กจ็คบใใใพใ:
-
-

-
-## ใใใชใใฏใขใฏใปในใฎๆๅนๅ
-
-ใใใฉใซใใงใฏใDeta ใฏใฏใใญใผใ็จใใฆใขใซใฆใณใใฎ่ช่จผใ่กใใพใใ
-
-ใใใใๆบๅใๆดใใฐใไปฅไธใฎๆงใซๅ
ฌ้ใงใใพใ:
-
-
-
-```console
-$ deta auth disable
-
-Successfully disabled http auth
-```
-
-
-
-ใใใงใURLใๅ
ฑๆใใใจAPIใซใขใฏใปในใงใใใใใซใชใใพใใ๐
-
-## HTTPS
-
-ใใใงใจใใใใใพใ๏ผใใชใใฎ FastAPI ใขใใชใ Deta ใธใใใญใคใใใพใใ๏ผ๐ ๐ฐ
-
-ใพใใDetaใHTTPSใๆญฃใใๅฆ็ใใใใใใใฎๅฆ็ใ่กใๅฟ
่ฆใใชใใใฏใฉใคใขใณใใฏๆๅทๅใใใๅฎๅ
จใช้ไฟกใๅฉ็จใงใใพใใโ
๐
-
-## Visor ใ็ขบ่ช
-
-ใใญใฅใกใณใUI (`https://qltnci.deta.dev/docs` ใฎใใใชURLใซใใ) ใฏ *path operation* `/items/{item_id}` ใธใชใฏใจในใใ้ใใใจใใงใใพใใ
-
-ID `5` ใฎไพใ็คบใใพใใ
-
-ใพใใ
https://web.deta.sh ใธใขใฏใปในใใพใใ
-
-ๅทฆๅดใซๅใขใใชใฎ
ใMicrosใ ใจใใใปใฏใทใงใณใ่กจ็คบใใใพใใ
-
-ใพใใใDetailsใใใVisorใใฟใใ่กจ็คบใใใฆใใพใใใVisorใใฟใใธ็งปๅใใฆใใ ใใใ
-
-ใใใงใขใใชใซ้ใใใ็ด่ฟใฎใชใฏใจในใใ่ชฟในใใใพใใ
-
-ใพใใใใใใ็ทจ้ใใฆใชใใฌใคใงใใพใใ
-
-

-
-## ใใใซ่ฉณใใ็ฅใ
-
-ๆงใ
ใช็ฎๆใงๆฐธ็ถ็ใซใใผใฟใไฟๅญใใใใชใใงใใใใใใฎใใใซใฏ
Deta Base ใไฝฟ็จใงใใพใใๆใใฟใชใ **็กๆๅฉ็จๆ ** ใใใใพใใ
-
-่ฉณใใใฏ
Deta ใใญใฅใกใณใใๅ็
งใใฆใใ ใใใ
diff --git a/docs/ja/docs/deployment/https.md b/docs/ja/docs/deployment/https.md
new file mode 100644
index 000000000..a291f870f
--- /dev/null
+++ b/docs/ja/docs/deployment/https.md
@@ -0,0 +1,200 @@
+# HTTPS ใซใคใใฆ
+
+HTTPSใฏๅใซใๆๅนใใใ็กๅนใใใงๆฑบใพใใใฎใ ใจๆใใใกใงใใ
+
+ใใใใใใใใใใฏใใใซ่ค้ใงใใ
+
+!!! tip
+ ใใๆฅใใงใใใใHTTPSใฎไป็ตใฟใซใคใใฆๆฐใซใใชใใฎใงใใใฐใๆฌกใฎใปใฏใทใงใณใซ้ฒใฟใใใพใใพใชใใฏใใใฏใไฝฟใฃใฆใในใฆใใปใใใขใใใใในใใใใปใใคใปในใใใใฎๆ้ ใใ่ฆงใใ ใใใ
+
+ๅฉ็จ่
ใฎ่ฆ็นใใ **HTTPS ใฎๅบๆฌใๅญฆใถ**ใซๅฝใใฃใฆใฏใๆฌกใฎใชใฝใผในใใชในในใกใใพใ:
https://howhttps.works/.
+
+ใใฆใ**้็บ่
ใฎ่ฆ็น**ใใใHTTPSใซใคใใฆ่ใใ้ใซๅฟต้ ญใซ็ฝฎใในใใใจใใใใคใใฟใฆใใใพใใใ๏ผ
+
+* HTTPSใฎๅ ดๅใ**ใตใผใ**ใฏ**็ฌฌไธ่
**ใซใใฃใฆ็ๆใใใ**ใ่จผๆๆธใใๆใค**ๅฟ
่ฆใใใใพใใ
+ * ใใใใฎ่จผๆๆธใฏใ็ๆใใใใใใฎใงใฏใชใใๅฎ้ใซใฏ็ฌฌไธ่
ใใ**ๅๅพ**ใใใใใฎใงใใ
+* ่จผๆๆธใซใฏ**ๆๅนๆ้**ใใใใพใใ
+ * ใคใพใใใใๅคฑๅนใใพใใ
+ * ใใฎใใ**ๆดๆฐ**ใใใ็ฌฌไธ่
ใใ**ๅๅบฆๅๅพ**ใใๅฟ
่ฆใใใใพใใ
+* ๆฅ็ถใฎๆๅทๅใฏ**TCPใฌใใซ**ใง่กใใใพใใ
+ * ใใใฏ**HTTPใฎ1ใคไธ**ใฎใฌใคใคใผใงใใ
+ * ใคใพใใ**่จผๆๆธใจๆๅทๅ**ใฎๅฆ็ใฏใ**HTTPใฎๅ**ใซ่กใใใพใใ
+* **TCPใฏ "ใใกใคใณ "ใซใคใใฆ็ฅใใพใใ**ใIPใขใใฌในใซใคใใฆใฎใฟ็ฅใฃใฆใใพใใ
+ * ่ฆๆฑใใใ**็นๅฎใฎใใกใคใณ**ใซ้ขใใๆ
ๅ ฑใฏใ**HTTPใใผใฟ**ใซๅ
ฅใใพใใ
+* **HTTPS่จผๆๆธ**ใฏใ**็นๅฎใฎใใกใคใณ**ใใ่จผๆใใใพใใใใใญใใณใซใจๆๅทๅใฏTCPใฌใใซใง่กใใใใฉใฎใใกใคใณใๆฑใใใฆใใใใ**็ฅใๅ**ใซ่กใใใพใใ
+* **ใใใฉใซใใงใฏ**ใ**IPใขใใฌในใใจใซ1ใคใฎHTTPS่จผๆๆธ**ใใๆใฆใชใใใจใซใชใใพใใ
+ * ใใใฏใใตใผใใผใฎ่ฆๆจกใใขใใชใฑใผใทใงใณใฎ่ฆๆจกใซๅฏใใพใใใ
+ * ใใใใใใใซใฏ**่งฃๆฑบ็ญ**ใใใใพใใ
+* **TLS**ใใญใใณใซ(HTTPใฎๅใซใTCPใฌใใซใงๆๅทๅใๅฆ็ใใใใฎ)ใซใฏใ**
SNI**ใจๅผใฐใใ**ๆกๅผต**ใใใใพใใ
+ * ใใฎSNIๆกๅผตๆฉ่ฝใซใใใ1ใคใฎใตใผใใผ๏ผ**ๅไธใฎIPใขใใฌใน**ใๆใค๏ผใ**่คๆฐใฎHTTPS่จผๆๆธ**ใๆใกใ**่คๆฐใฎHTTPSใใกใคใณ/ใขใใชใฑใผใทใงใณ**ใซใตใผใในใๆไพใงใใใใใซใชใใพใใ
+ * ใใใๆฉ่ฝใใใใใซใฏใ**ใใใชใใฏIPใขใใฌใน**ใงใชใในใณใใฆใใใใตใผใใผไธใงๅไฝใใฆใใ**ๅไธใฎ**ใณใณใใผใใณใ(ใใญใฐใฉใ )ใใใตใผใใผๅ
ใฎ**ใในใฆใฎHTTPS่จผๆๆธ**ใๆใฃใฆใใๅฟ
่ฆใใใใพใใ
+
+* ใปใญใฅใขใชๆฅ็ถใๅๅพใใ**ๅพ**ใงใใ้ไฟกใใญใใณใซใฏ**HTTPใฎใพใพ**ใงใใ
+ * ใณใณใใณใใฏ**HTTPใใญใใณใซ**ใง้ไฟกใใใฆใใใซใใใใใใใ**ๆๅทๅ**ใใใฆใใพใใ
+
+
+ใตใผใใผ๏ผใใทใณใใในใใชใฉ๏ผไธใง**1ใคใฎใใญใฐใฉใ /HTTPใตใผใใผ**ใๅฎ่กใใใ**HTTPSใซ้ขใใๅ
จใฆใฎใใจ**ใ็ฎก็ใใใฎใไธ่ฌ็ใงใใ
+
+**ๆๅทๅใใใ HTTPS ใชใฏใจในใ** ใๅไฟกใใ**ๅพฉๅทๅใใใ HTTP ใชใฏใจในใ** ใๅใใตใผใใผใงๅฎ่กใใใฆใใๅฎ้ใฎ HTTP ใขใใชใฑใผใทใงใณ๏ผใใฎๅ ดๅใฏ **FastAPI** ใขใใชใฑใผใทใงใณ๏ผใซ้ไฟกใใใขใใชใฑใผใทใงใณใใ **HTTP ใฌในใใณใน** ใๅใๅใใ้ฉๅใช **HTTPS ่จผๆๆธ** ใไฝฟ็จใใฆ **ๆๅทๅ** ใใใใใฆ**HTTPS** ใไฝฟ็จใใฆใฏใฉใคใขใณใใซ้ใ่ฟใใพใใ
+
+ใใฎใตใผใใผใฏใใฐใใฐ **
TLS Termination Proxy**ใจๅผใฐใใพใใ
+
+TLS Termination Proxyใจใใฆไฝฟใใใชใใทใงใณใซใฏใไปฅไธใฎใใใชใใฎใใใใพใ๏ผ
+
+* Traefik๏ผ่จผๆๆธใฎๆดๆฐใๅฏพๅฟ๏ผ
+* Caddy (่จผๆๆธใฎๆดๆฐใๅฏพๅฟ)
+* Nginx
+* HAProxy
+
+
+## Let's Encrypt
+
+Let's Encryptไปฅๅใฏใใใใใฎ**HTTPS่จผๆๆธ**ใฏไฟก้ ผใงใใ็ฌฌไธ่
ใซใใฃใฆ่ฒฉๅฃฒใใใฆใใพใใใ
+
+ใใใใฎ่จผๆๆธใๅๅพใใใใใฎๆ็ถใใฏ้ขๅใงใใใชใใฎๆธ้กใๅฟ
่ฆใจใใ่จผๆๆธใฏใใชใ้ซไพกใชใใฎใงใใใ
+
+ใใใใใฎๅพใ**
Let's Encrypt** ใไฝใใใพใใใ
+
+ใใใฏLinux Foundationใฎใใญใธใงใฏใใใ็ใพใใใใฎใงใใ ่ชๅๅใใใๆนๆณใงใ**HTTPS่จผๆๆธใ็กๆใง**ๆไพใใพใใใใใใฎ่จผๆๆธใฏใใในใฆใฎๆจๆบ็ใชๆๅทๅใปใญใฅใชใใฃใไฝฟ็จใใใพใ็ญๅฝ๏ผ็ด3ใถๆ๏ผใงใใใใใใใฃใๅฏฟๅฝใฎ็ญใใซใใฃใฆใ**ใปใญใฅใชใใฃใฏๅฎ้ใซๅชใใฆใใพใ**ใ
+
+ใใกใคใณใฏๅฎๅ
จใซๆค่จผใใใ่จผๆๆธใฏ่ชๅ็ใซ็ๆใใใพใใใพใใ่จผๆๆธใฎๆดๆฐใ่ชๅๅใใใพใใ
+
+ใใฎใขใคใใขใฏใใใใใฎ่จผๆๆธใฎๅๅพใจๆดๆฐใ่ชๅๅใใใใจใงใ**ๅฎๅ
จใชHTTPSใใ็กๆใงใๆฐธ้ ใซ**ๅฉ็จใงใใใใใซใใใใจใงใใ
+
+## ้็บ่
ใฎใใใฎ HTTPS
+
+ใใใงใฏใHTTPS APIใใฉใฎใใใซ่ฆใใใใฎไพใใไธปใซ้็บ่
ใซใจใฃใฆ้่ฆใชใขใคใใขใซๆณจๆใๆใใชใใใในใใใใปใใคใปในใใใใง่ชฌๆใใพใใ
+
+### ใใกใคใณๅ
+
+ในใใใใฎๅใใฏใ**ใใกใคใณๅ**ใ**ๅๅพใใใใจ**ใใๅงใพใใงใใใใใใฎๅพใDNSใตใผใใผ๏ผใใใใๅใใฏใฉใฆใใใญใใคใใผ๏ผใซ่จญๅฎใใพใใ
+
+ใใใใใฏใฉใฆใใตใผใใผ๏ผไปฎๆณใใทใณ๏ผใใใใซ้กใใใใฎใๆใซๅ
ฅใใ
ๅบๅฎใฎ **ใใใชใใฏIPใขใใฌใน**ใๆใคใใจใซใชใใงใใใใ
+
+DNSใตใผใใผใงใฏใ**ๅๅพใใใใกใคใณ**ใใใชใใฎใตใผใใผใฎใใใชใใฏ**IPใขใใฌใน**ใซๅใใใฌใณใผใ๏ผใ`Aใฌใณใผใ`ใ๏ผใ่จญๅฎใใพใใ
+
+ใใใฏใใใใใๆๅใฎ1ๅใ ใใใใใในใฆใใปใใใขใใใใใจใใซ่กใใงใใใใ
+
+!!! tip
+ ใใกใคใณๅใฎ่ฉฑใฏHTTPSใซ้ขใใ่ฉฑใฎใฏใใๅใซใใใพใใใใในใฆใใใกใคใณใจIPใขใใฌในใซไพๅญใใใใใใใใง่จๅใใไพกๅคใใใใพใใ
+
+### DNS
+
+ใงใฏใๅฎ้ใฎHTTPSใฎ้จๅใซๆณจ็ฎใใฆใฟใใใ
+
+ใพใใใใฉใฆใถใฏ**DNSใตใผใใผ**ใซ**ใใกใคใณใซๅฏพใใIP**ใไฝใงใใใใ็ขบ่ชใใพใใไปๅใฏใ`someapp.example.com`ใจใใพใใ
+
+DNSใตใผใใผใฏใใใฉใฆใถใซ็นๅฎใฎ**IPใขใใฌใน**ใไฝฟ็จใใใใใซๆ็คบใใพใใใใฎIPใขใใฌในใฏใDNSใตใผใใผใง่จญๅฎใใใใใชใใฎใตใผใใผใไฝฟ็จใใใใใชใใฏIPใขใใฌในใซใชใใพใใ
+
+

+
+### TLS Handshake ใฎ้ๅง
+
+ใใฉใฆใถใฏIPใขใใฌในใจ**ใใผใ443**๏ผHTTPSใใผใ๏ผใง้ไฟกใใพใใ
+
+้ไฟกใฎๆๅใฎ้จๅใฏใใฏใฉใคใขใณใใจใตใผใใผ้ใฎๆฅ็ถใ็ขบ็ซใใไฝฟ็จใใๆๅท้ตใชใฉใๆฑบใใใ ใใงใใ
+
+

+
+TLSๆฅ็ถใ็ขบ็ซใใใใใฎใฏใฉใคใขใณใใจใตใผใใผ้ใฎใใฎใใใจใใฏใ**TLSใใณใใทใงใคใฏ**ใจๅผใฐใใพใใ
+
+### SNIๆกๅผตๆฉ่ฝไปใใฎTLS
+
+ใตใผใใผๅ
ใฎ**1ใคใฎใใญใปใน**ใ ใใใ็นๅฎ ใฎ**IPใขใใฌใน**ใฎ็นๅฎใฎ**ใใผใ** ใงๅพ
ใกๅใใใใจใใงใใพใใ
+
+ๅใIPใขใใฌในใฎไปใฎใใผใใงไปใฎใใญใปในใใชใในใณใใฆใใๅฏ่ฝๆงใใใใพใใใIPใขใใฌในใจใใผใใฎ็ตใฟๅใใใใจใซ1ใคใ ใใงใใ
+
+TLS๏ผHTTPS๏ผใฏใใใฉใซใใง`443`ใจใใ็นๅฎใฎใใผใใไฝฟ็จใใใใคใพใใใใใๅฟ
่ฆใชใใผใใงใใ
+
+ใใฎใใผใใใชใในใณใงใใใฎใฏ1ใคใฎใใญใปในใ ใใชใฎใงใใใใๅฎ่กใใใใญใปในใฏ**TLS Termination Proxy**ใจใชใใพใใ
+
+TLS Termination Proxyใฏใ1ใคไปฅไธใฎ**TLS่จผๆๆธ**๏ผHTTPS่จผๆๆธ๏ผใซใขใฏใปในใงใใพใใ
+
+ๅ่ฟฐใใ**SNIๆกๅผตๆฉ่ฝ**ใไฝฟ็จใใฆใTLS Termination Proxy ใฏใๅฉ็จๅฏ่ฝใชTLS (HTTPS)่จผๆๆธใฎใฉใใๆฅ็ถๅ
ใจใใฆไฝฟ็จใในใใใใใงใใฏใใใฏใฉใคใขใณใใๆๅพ
ใใใใกใคใณใซไธ่ดใใใใฎใไฝฟ็จใใพใใ
+
+ไปๅใฏใ`someapp.example.com`ใฎ่จผๆๆธใไฝฟใใใจใซใชใใพใใ
+
+

+
+ใฏใฉใคใขใณใใฏใใใฎTLS่จผๆๆธใ็ๆใใใจใณใใฃใใฃ๏ผใใฎๅ ดๅใฏLet's Encryptใงใใใใใใซใคใใฆใฏๅพ่ฟฐใใพใ๏ผใใใงใซ**ไฟก้ ผ**ใใฆใใใใใใใฎ่จผๆๆธใๆๅนใงใใใใจใ**ๆค่จผ**ใใใใจใใงใใพใใ
+
+ๆฌกใซ่จผๆๆธใไฝฟ็จใใฆใใฏใฉใคใขใณใใจTLS Termination Proxy ใฏใ **TCP้ไฟก**ใฎๆฎใใ**ใฉใฎใใใซๆๅทๅใใใใๆฑบๅฎ**ใใพใใใใใง**TLSใใณใใทใงใคใฏ**ใฎ้จๅใๅฎไบใใพใใ
+
+ใใฎๅพใใฏใฉใคใขใณใใจใตใผใใผใฏ**ๆๅทๅใใใTCPๆฅ็ถ**ใๆใกใพใใใใใฆใใใฎๆฅ็ถใไฝฟใฃใฆๅฎ้ใฎ**HTTP้ไฟก**ใ้ๅงใใใใจใใงใใพใใ
+
+ใใใ**HTTPS**ใงใใใ็ด็ฒใช๏ผๆๅทๅใใใฆใใชใ๏ผTCPๆฅ็ถใงใฏใชใใ**ใปใญใฅใขใชTLSๆฅ็ถ**ใฎไธญใซ**HTTP**ใใใใ ใใงใใ
+
+!!! tip
+ ้ไฟกใฎๆๅทๅใฏใHTTPใฌใใซใงใฏใชใใ**TCPใฌใใซ**ใง่กใใใใใจใซๆณจๆใใฆใใ ใใใ
+
+### HTTPS ใชใฏใจในใ
+
+ใใใงใฏใฉใคใขใณใใจใตใผใใผ๏ผๅ
ทไฝ็ใซใฏใใฉใฆใถใจTLS Termination Proxy๏ผใฏ**ๆๅทๅใใใTCPๆฅ็ถ**ใๆใคใใจใซใชใใ**HTTP้ไฟก**ใ้ๅงใใใใจใใงใใพใใ
+
+ใใใงใใฏใฉใคใขใณใใฏ**HTTPSใชใฏใจในใ**ใ้ไฟกใใพใใใใใฏใๆๅทๅใใใTLSใณใใฏใทใงใณใไปใใๅใชใHTTPใชใฏใจในใใงใใ
+
+

+
+### ใชใฏใจในใใฎๅพฉๅทๅ
+
+TLS Termination Proxy ใฏใๅๆใๅใใฆใใๆๅทๅใไฝฟ็จใใฆใ**ใชใฏใจในใใๅพฉๅทๅ**ใใ**ใใฌใผใณ (ๅพฉๅทๅใใใ) HTTP ใชใฏใจในใ** ใใขใใชใฑใผใทใงใณใๅฎ่กใใฆใใใใญใปใน (ไพใใฐใFastAPI ใขใใชใฑใผใทใงใณใๅฎ่กใใฆใใ Uvicorn ใๆใคใใญใปใน) ใซ้ไฟกใใพใใ
+
+

+
+### HTTP ใฌในใใณใน
+
+ใขใใชใฑใผใทใงใณใฏใชใฏใจในใใๅฆ็ใใ**ใใฌใผใณ(ๆๅทๅใใใฆใใชใ)HTTPใฌในใใณใน** ใTLS Termination Proxyใซ้ไฟกใใพใใ
+
+

+
+### HTTPS ใฌในใใณใน
+
+TLS Termination Proxyใฏๆฌกใซใไบๅใซๅๆใๅใใฆใใๆๅท(`someapp.example.com`ใฎ่จผๆๆธใใๅงใพใ)ใไฝฟใฃใฆ**ใฌในใใณในใๆๅทๅใ**ใใใฉใฆใถใซ้ใ่ฟใใ
+
+ใใฎๅพใใฉใฆใถใงใฏใใฌในใใณในใๆๅนใงๆญฃใใๆๅทใญใผใงๆๅทๅใใใฆใใใใจใชใฉใๆค่จผใใพใใใใใฆใใใฉใฆใถใฏใฌในใใณในใ**ๅพฉๅทๅ**ใใฆๅฆ็ใใพใใ
+
+

+
+ใฏใฉใคใขใณใ๏ผใใฉใฆใถ๏ผใฏใใฌในใใณในใๆญฃใใใตใผใใผใใๆฅใใใจใ็ฅใใใจใใงใใพใใ ใชใใชใใใใฎใตใผใใผใฏใไปฅๅใซ**HTTPS่จผๆๆธ**ใไฝฟใฃใฆๅๆใใๆๅทใไฝฟใฃใฆใใใใใงใใ
+
+### ่คๆฐใฎใขใใชใฑใผใทใงใณ
+
+ๅใใตใผใใผ๏ผใพใใฏ่คๆฐใฎใตใผใใผ๏ผใซใไพใใฐไปใฎAPIใใญใฐใฉใ ใใใผใฟใใผในใชใฉใ**่คๆฐใฎใขใใชใฑใผใทใงใณ**ใๅญๅจใใๅฏ่ฝๆงใใใใพใใ
+
+็นๅฎใฎIPใจใใผใ๏ผใใฎไพใงใฏTLS Termination Proxy๏ผใๆฑใใใจใใงใใใฎใฏ1ใคใฎใใญใปในใ ใใงใใใไปใฎใขใใชใฑใผใทใงใณ/ใใญใปในใใๅใ**ใใใชใใฏIPใจใใผใ**ใฎ็ตใฟๅใใใไฝฟ็จใใใใจใใชใ้ใใใตใผใใผไธใงๅฎ่กใใใใจใใงใใพใใ
+
+

+
+ใใใใใฐใTLS Termination Proxy ใฏใ**่คๆฐใฎใใกใคใณ**ใ่คๆฐใฎใขใใชใฑใผใทใงใณใฎHTTPSใจ่จผๆๆธใๅฆ็ใใใใใใใฎใฑใผในใง้ฉๅใชใขใใชใฑใผใทใงใณใซใชใฏใจในใใ้ไฟกใใใใจใใงใใพใใ
+
+### ่จผๆๆธใฎๆดๆฐ
+
+ๅฐๆฅใฎใใๆ็นใงใๅ่จผๆๆธใฏ๏ผๅๅพๅพ็ด3ใถๆใง๏ผ**ๅคฑๅน**ใใพใใ
+
+ใใฎๅพใLet's Encryptใจ้ไฟกใใๅฅใฎใใญใฐใฉใ ๏ผๅฅใฎใใญใฐใฉใ ใงใใๅ ดๅใใใใฐใๅใTLS Termination Proxyใงใใๅ ดๅใใใ๏ผใซใใฃใฆใ่จผๆๆธใๆดๆฐใใพใใ
+
+

+
+**TLS่จผๆๆธ**ใฏใIPใขใใฌในใงใฏใชใใ**ใใกใคใณๅใซ้ข้ฃไปใใใใฆ**ใใพใใ
+
+ใใใใฃใฆใ่จผๆๆธใๆดๆฐใใใใใซใๆดๆฐใใญใฐใฉใ ใฏใ่ช่จผๅฑ๏ผLet's Encrypt๏ผใซๅฏพใใฆใ**ใใฎใใกใคใณใๆฌๅฝใซใๆๆใใใ็ฎก็ใใฆใใ**ใใจใ**่จผๆ**ใใๅฟ
่ฆใใใใพใใ
+
+ใใฎใใใซใใพใใใพใใพใชใขใใชใฑใผใทใงใณใฎใใผใบใซๅฏพๅฟใใใใใซใใใใคใใฎๆนๆณใใใใพใใใใไฝฟใใใๆนๆณใจใใฆใฏ:
+
+* **ใใใคใใฎDNSใฌใณใผใใไฟฎๆญฃใใพใใ**
+ * ใใใใใใใใซใฏใๆดๆฐใใญใฐใฉใ ใฏDNSใใญใใคใใผใฎAPIใใตใใผใใใๅฟ
่ฆใใใใพใใใใใใฃใฆใไฝฟ็จใใฆใใDNSใใญใใคใใผใซใใฃใฆใฏใใใฎใชใใทใงใณใไฝฟใใๅ ดๅใใใใฐใไฝฟใใชใๅ ดๅใใใใพใใ
+* ใใกใคใณใซ้ข้ฃไปใใใใใใใชใใฏIPใขใใฌในไธใงใ๏ผๅฐใชใใจใ่จผๆๆธๅๅพใใญใปในไธญใฏ๏ผ**ใตใผใใผ**ใจใใฆๅฎ่กใใพใใ
+ * ไธใง่ฟฐในใใใใซใ็นๅฎใฎIPใจใใผใใงใชใในใณใงใใใใญใปในใฏ1ใคใ ใใงใใ
+ * ใใใฏใๅใTLS Termination Proxyใ่จผๆๆธใฎๆดๆฐๅฆ็ใ่กใๅ ดๅใซ้ๅธธใซไพฟๅฉใช็็ฑใฎ1ใคใงใใ
+ * ใใใงใชใใใฐใTLS Termination Proxyใไธๆ็ใซๅๆญขใใ่จผๆๆธใๅๅพใใใใใซๆดๆฐใใญใฐใฉใ ใ่ตทๅใใTLS Termination Proxyใง่จผๆๆธใ่จญๅฎใใTLS Termination Proxyใๅ่ตทๅใใชใใใฐใชใใชใใใใใใพใใใTLS Termination Proxyใๅๆญขใใฆใใ้ใฏใขใใชใๅฉ็จใงใใชใใชใใใใใใใฏ็ๆณ็ใงใฏใใใพใใใ
+
+
+ใขใใชใๆไพใใชใใใใฎใใใชๆดๆฐๅฆ็ใ่กใใใจใฏใใขใใชใฑใผใทใงใณใปใตใผใใผ๏ผUvicornใชใฉ๏ผใงTLS่จผๆๆธใ็ดๆฅไฝฟ็จใใใฎใงใฏใชใใTLS Termination Proxyใไฝฟ็จใใฆ**HTTPSใๅฆ็ใใๅฅใฎใทในใใ **ใ็จๆใใใใชใไธปใช็็ฑใฎ1ใคใงใใ
+
+## ใพใจใ
+
+**HTTPS**ใๆใคใใจใฏ้ๅธธใซ้่ฆใงใใใใปใจใใฉใฎๅ ดๅใใใชใ**ใฏใชใใฃใซใซ**ใงใใ้็บ่
ใจใใฆ HTTPS ใซ้ขใใๅดๅใฎใปใจใใฉใฏใใใใใฎ**ๆฆๅฟตใจใใฎไป็ตใฟใ็่งฃใใ**ใใจใงใใ
+
+ใใใใใฒใจใใณ**้็บ่
ๅใHTTPS**ใฎๅบๆฌ็ใชๆ
ๅ ฑใ็ฅใใฐใ็ฐกๅใชๆนๆณใงใในใฆใ็ฎก็ใใใใใซใใใพใใพใชใใผใซใ็ตใฟๅใใใฆ่จญๅฎใใใใจใใงใใพใใ
+
+ๆฌกใฎ็ซ ใงใฏใ**FastAPI** ใขใใชใฑใผใทใงใณใฎใใใซ **HTTPS** ใใปใใใขใใใใๆนๆณใซใคใใฆใใใใคใใฎๅ
ทไฝไพใ็ดนไปใใพใใ๐
diff --git a/docs/ja/docs/external-links.md b/docs/ja/docs/external-links.md
index 6703f5fc2..aca5d5b34 100644
--- a/docs/ja/docs/external-links.md
+++ b/docs/ja/docs/external-links.md
@@ -9,70 +9,21 @@
!!! tip "่ฑ็ฅ่ญ"
ใใใซใพใ ่ผใฃใฆใใชใ**FastAPI**ใซ้ข้ฃใใ่จไบใใใญใธใงใฏใใใใผใซใชใฉใใใๅ ดๅใฏใ
ใใซใชใฏใจในใใใฆไธใใใ
-## ่จไบ
+{% for section_name, section_content in external_links.items() %}
-### ่ฑ่ช
+## {{ section_name }}
-{% if external_links %}
-{% for article in external_links.articles.english %}
+{% for lang_name, lang_content in section_content.items() %}
+
+### {{ lang_name }}
+
+{% for item in lang_content %}
+
+*
{{ item.title }} by
{{ item.author }}.
-*
{{ article.title }} by
{{ article.author }}.
{% endfor %}
-{% endif %}
-
-### ๆฅๆฌ่ช
-
-{% if external_links %}
-{% for article in external_links.articles.japanese %}
-
-*
{{ article.title }} by
{{ article.author }}.
{% endfor %}
-{% endif %}
-
-### ใใใใ ่ช
-
-{% if external_links %}
-{% for article in external_links.articles.vietnamese %}
-
-*
{{ article.title }} by
{{ article.author }}.
{% endfor %}
-{% endif %}
-
-### ใญใทใข่ช
-
-{% if external_links %}
-{% for article in external_links.articles.russian %}
-
-*
{{ article.title }} by
{{ article.author }}.
-{% endfor %}
-{% endif %}
-
-### ใใคใ่ช
-
-{% if external_links %}
-{% for article in external_links.articles.german %}
-
-*
{{ article.title }} by
{{ article.author }}.
-{% endfor %}
-{% endif %}
-
-## ใใใใญใฃในใ
-
-{% if external_links %}
-{% for article in external_links.podcasts.english %}
-
-*
{{ article.title }} by
{{ article.author }}.
-{% endfor %}
-{% endif %}
-
-## ใใผใฏ
-
-{% if external_links %}
-{% for article in external_links.talks.english %}
-
-*
{{ article.title }} by
{{ article.author }}.
-{% endfor %}
-{% endif %}
## ใใญใธใงใฏใ
diff --git a/docs/ja/docs/features.md b/docs/ja/docs/features.md
index a40b48cf0..853364f11 100644
--- a/docs/ja/docs/features.md
+++ b/docs/ja/docs/features.md
@@ -24,7 +24,7 @@
### ็พไปฃ็ใชPython
-FastAPIใฎๆฉ่ฝใฏใในใฆใๆจๆบใฎPython 3.6ๅๅฎฃ่จใซๅบใฅใใฆใใพใ๏ผPydanticใฎๅ็ธพ๏ผใๆฐใใๆงๆใฏใใใพใใใใใ ใฎ็พไปฃ็ใชๆจๆบใฎPythonใงใใ
+FastAPIใฎๆฉ่ฝใฏใในใฆใๆจๆบใฎPython 3.8ๅๅฎฃ่จใซๅบใฅใใฆใใพใ๏ผPydanticใฎๅ็ธพ๏ผใๆฐใใๆงๆใฏใใใพใใใใใ ใฎ็พไปฃ็ใชๆจๆบใฎPythonใงใใ
๏ผFastAPIใไฝฟ็จใใชใๅ ดๅใงใ๏ผPythonใฎๅใฎไฝฟ็จๆนๆณใซใคใใฆ็ฐกๅใชๅพฉ็ฟใๅฟ
่ฆใชๅ ดๅใฏใ็ญใใใฅใผใใชใขใซ๏ผ[Python Types](python-types.md){.internal-link target=_blank}๏ผใๅ็
งใใฆใใ ใใใ
diff --git a/docs/ja/docs/help-fastapi.md b/docs/ja/docs/help-fastapi.md
index 166acb586..e753b7ce3 100644
--- a/docs/ja/docs/help-fastapi.md
+++ b/docs/ja/docs/help-fastapi.md
@@ -82,20 +82,6 @@ GitHubใฌใใธใใชใง
https://gitter.im/tiangolo/fastapi.
-
-ใใใงใไปใฎไบบใจๆๆฉใไผ่ฉฑใใใใๆๅฉใใใขใคใใขใฎๅ
ฑๆใชใฉใใงใใพใใ
-
-ใใใใใ่ช็ฑใชไผ่ฉฑใใ่จฑๅฎนใใใฆใใใฎใงไธ่ฌ็ใใใฆๅ็ญใ้ฃใใ่ณชๅใใใใใใชใใพใใใใฎใใใงๅ็ญใๅพใใใชใใใใใใพใใใ
-
-GitHub issuesใงใฏ่ฏใๅ็ญใๅพใใใ่ณชๅใใงใใใใใซใใใใใฏใ่ณชๅใใๅใซ่ช่บซใง่งฃๆฑบใงใใใใใซใใณใใฌใผใใใฌใคใใใฆใใใพใใใใใฆใGitHubใงใฏใใจใๆ้ใใใใฃใฆใๅ
จใฆใซ็ญใใฆใใใ็ขบ่ชใงใใพใใๅไบบ็ใซใฏGitterใใฃใใใงใฏๅใใใจใฏใงใใชใใงใใ๐
-
-Gitterใงใฎไผ่ฉฑใฏGitHubใปใฉ็ฐกๅใซๆค็ดขใงใใชใใฎใงใ่ณชๅใจๅ็ญใไผ่ฉฑใฎไธญใซๅใใใฆใใพใใพใใ
-
-ไธๆนใใใฃใใใซใฏ1000ไบบไปฅไธใใใฎใงใใใคใงใ่ฉฑใ็ธๆใ่ฆใคใใๅฏ่ฝๆงใ้ซใใงใใ๐
-
## ้็บ่
ใฎในใใณใตใผใซใชใ
GitHub sponsorsใ้ใใฆ้็บ่
ใ็ตๆธ็ใซใตใใผใใงใใพใใ
diff --git a/docs/ja/docs/advanced/conditional-openapi.md b/docs/ja/docs/how-to/conditional-openapi.md
similarity index 100%
rename from docs/ja/docs/advanced/conditional-openapi.md
rename to docs/ja/docs/how-to/conditional-openapi.md
diff --git a/docs/ja/docs/index.md b/docs/ja/docs/index.md
index a9c381a23..f340fdb87 100644
--- a/docs/ja/docs/index.md
+++ b/docs/ja/docs/index.md
@@ -107,7 +107,7 @@ FastAPI ใฏใPythonใฎๆจๆบใงใใๅใใณใใซๅบใฅใใฆPython 3.6 ไปฅ
## ๅฟ
่ฆๆกไปถ
-Python 3.7+
+Python 3.8+
FastAPI ใฏๅทจไบบใฎ่ฉใฎไธใซ็ซใฃใฆใใพใใ
diff --git a/docs/ko/docs/deployment/cloud.md b/docs/ko/docs/deployment/cloud.md
new file mode 100644
index 000000000..f2b965a91
--- /dev/null
+++ b/docs/ko/docs/deployment/cloud.md
@@ -0,0 +1,17 @@
+# FastAPI๋ฅผ ํด๋ผ์ฐ๋ ์ ๊ณต์
์ฒด์์ ๋ฐฐํฌํ๊ธฐ
+
+์ฌ์ค์ ๊ฑฐ์ **๋ชจ๋ ํด๋ผ์ฐ๋ ์ ๊ณต์
์ฒด**๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ๋ฌ๋ถ์ FastAPI ์ ํ๋ฆฌ์ผ์ด์
์ ๋ฐฐํฌํ ์ ์์ต๋๋ค.
+
+๋๋ถ๋ถ์ ๊ฒฝ์ฐ, ์ฃผ์ ํด๋ผ์ฐ๋ ์ ๊ณต์
์ฒด์์๋ FastAPI๋ฅผ ๋ฐฐํฌํ ์ ์๋๋ก ๊ฐ์ด๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
+
+## ํด๋ผ์ฐ๋ ์ ๊ณต์
์ฒด - ํ์์๋ค
+
+๋ช๋ช ํด๋ผ์ฐ๋ ์ ๊ณต์
์ฒด๋ค์ [**FastAPI๋ฅผ ํ์ํ๋ฉฐ**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} โจ, ์ด๋ฅผ ํตํด FastAPI์ FastAPI **์ํ๊ณ**๊ฐ ์ง์์ ์ด๊ณ ๊ฑด์ ํ **๋ฐ์ **์ ํ ์ ์์ต๋๋ค.
+
+์ด๋ FastAPI์ **์ปค๋ฎค๋ํฐ** (์ฌ๋ฌ๋ถ)์ ๋ํ ์ง์ ํ ํ์ ์ ๋ณด์ฌ์ค๋๋ค. ๊ทธ๋ค์ ์ฌ๋ฌ๋ถ์๊ฒ **์ข์ ์๋น์ค**๋ฅผ ์ ๊ณตํ ๋ฟ ๋ง์ด ์๋๋ผ ์ฌ๋ฌ๋ถ์ด **ํ๋ฅญํ๊ณ ๊ฑด๊ฐํ ํ๋ ์์ํฌ์ธ** FastAPI ๋ฅผ ์ฌ์ฉํ๊ธธ ์ํ๊ธฐ ๋๋ฌธ์
๋๋ค. ๐
+
+์๋์ ๊ฐ์ ์๋น์ค๋ฅผ ์ฌ์ฉํด๋ณด๊ณ ๊ฐ ์๋น์ค์ ๊ฐ์ด๋๋ฅผ ๋ฐ๋ฅผ ์๋ ์์ต๋๋ค:
+
+*
Platform.sh
+*
Porter
+*
Deta
diff --git a/docs/ko/docs/index.md b/docs/ko/docs/index.md
index a6991a9b8..7ce938106 100644
--- a/docs/ko/docs/index.md
+++ b/docs/ko/docs/index.md
@@ -107,7 +107,7 @@ FastAPI๋ ํ๋์ ์ด๊ณ , ๋น ๋ฅด๋ฉฐ(๊ณ ์ฑ๋ฅ), ํ์ด์ฌ ํ์ค ํ์
ํํธ
## ์๊ตฌ์ฌํญ
-Python 3.7+
+Python 3.8+
FastAPI๋ ๊ฑฐ์ธ๋ค์ ์ด๊นจ ์์ ์ ์์ต๋๋ค:
diff --git a/docs/pl/docs/features.md b/docs/pl/docs/features.md
index 49d362dd9..ed10af9bc 100644
--- a/docs/pl/docs/features.md
+++ b/docs/pl/docs/features.md
@@ -25,7 +25,7 @@ Interaktywna dokumentacja i webowe interfejsy do eksploracji API. Z racji tego,
### Nowoczesny Python
-Wszystko opiera siฤ na standardowych deklaracjach typu **Python 3.6** (dziฤki Pydantic). Brak nowej skลadni do uczenia. Po prostu standardowy, wspรณลczesny Python.
+Wszystko opiera siฤ na standardowych deklaracjach typu **Python 3.8** (dziฤki Pydantic). Brak nowej skลadni do uczenia. Po prostu standardowy, wspรณลczesny Python.
Jeลli potrzebujesz szybkiego przypomnienia jak uลผywaฤ deklaracji typรณw w Pythonie (nawet jeลli nie uลผywasz FastAPI), sprawdลบ krรณtki samouczek: [Python Types](python-types.md){.internal-link target=_blank}.
diff --git a/docs/pl/docs/help-fastapi.md b/docs/pl/docs/help-fastapi.md
new file mode 100644
index 000000000..3d02a8741
--- /dev/null
+++ b/docs/pl/docs/help-fastapi.md
@@ -0,0 +1,263 @@
+# Pomรณลผ FastAPI - Uzyskaj pomoc
+
+Czy podoba Ci siฤ **FastAPI**?
+
+Czy chciaลbyล pomรณc FastAPI, jego uลผytkownikom i autorowi?
+
+Moลผe napotkaลeล na trudnoลci z **FastAPI** i potrzebujesz pomocy?
+
+Istnieje kilka bardzo ลatwych sposobรณw, aby pomรณc (czasami wystarczy jedno lub dwa klikniฤcia).
+
+Istnieje rรณwnieลผ kilka sposobรณw uzyskania pomocy.
+
+## Zapisz siฤ do newslettera
+
+Moลผesz zapisaฤ siฤ do rzadkiego [newslettera o **FastAPI i jego przyjacioลach**](/newsletter/){.internal-link target=_blank}, aby byฤ na bieลผฤ
co z:
+
+* Aktualnoลciami o FastAPI i przyjacioลach ๐
+* Przewodnikami ๐
+* Funkcjami โจ
+* Przeลomowymi zmianami ๐จ
+* Poradami i sztuczkami โ
+
+## ลledลบ FastAPI na Twitterze
+
+
ลledลบ @fastapi na **Twitterze** aby byฤ na bieลผฤ
co z najnowszymi wiadomoลciami o **FastAPI**. ๐ฆ
+
+## Dodaj gwiazdkฤ **FastAPI** na GitHubie
+
+Moลผesz "dodaฤ gwiazdkฤ" FastAPI na GitHubie (klikajฤ
c przycisk gwiazdki w prawym gรณrnym rogu):
https://github.com/tiangolo/fastapi. โญ๏ธ
+
+Dodajฤ
c gwiazdkฤ, inni uลผytkownicy bฤdฤ
mogli ลatwiej znaleลบฤ projekt i zobaczyฤ, ลผe byล juลผ przydatny dla innych.
+
+## Obserwuj repozytorium GitHub w poszukiwaniu nowych wydaล
+
+Moลผesz "obserwowaฤ" FastAPI na GitHubie (klikajฤ
c przycisk "obserwuj" w prawym gรณrnym rogu):
https://github.com/tiangolo/fastapi. ๐
+
+Wybierz opcjฤ "Tylko wydania".
+
+Dziฤki temu bฤdziesz otrzymywaฤ powiadomienia (na swรณj adres e-mail) za kaลผdym razem, gdy pojawi siฤ nowe wydanie (nowa wersja) **FastAPI** z poprawkami bลฤdรณw i nowymi funkcjami.
+
+## Skontaktuj siฤ z autorem
+
+Moลผesz skontaktowaฤ siฤ
ze mnฤ
(Sebastiรกn Ramรญrez / `tiangolo`), autorem.
+
+Moลผesz:
+
+*
ลledziฤ mnie na **GitHubie**.
+ * Zobacz inne projekty open source, ktรณre stworzyลem, a mogฤ
byฤ dla Ciebie pomocne.
+ * ลledลบ mnie, aby dostaฤ powiadomienie, gdy utworzฤ nowy projekt open source.
+*
ลledziฤ mnie na **Twitterze** lub na
Mastodonie.
+ * Napisz mi, w jaki sposรณb korzystasz z FastAPI (uwielbiam o tym czytaฤ).
+ * Dowiedz siฤ, gdy ogลoszฤ coล nowego lub wypuszczฤ nowe narzฤdzia.
+ * Moลผesz takลผe
ลledziฤ @fastapi na Twitterze (to oddzielne konto).
+*
Nawiฤ
ลผ ze mnฤ
kontakt na **Linkedinie**.
+ * Dowiedz siฤ, gdy ogลoszฤ coล nowego lub wypuszczฤ nowe narzฤdzia (chociaลผ czฤลciej korzystam z Twittera ๐คทโโ).
+* Czytaj moje posty (lub ลledลบ mnie) na
**Dev.to** lub na
**Medium**.
+ * Czytaj o innych pomysลach, artykuลach i dowiedz siฤ o narzฤdziach, ktรณre stworzyลem.
+ * ลledลบ mnie, by wiedzieฤ gdy opublikujฤ coล nowego.
+
+## Napisz tweeta o **FastAPI**
+
+
Napisz tweeta o **FastAPI** i powiedz czemu Ci siฤ podoba. ๐
+
+Uwielbiam czytaฤ w jaki sposรณb **FastAPI** jest uลผywane, co Ci siฤ w nim podobaลo, w jakim projekcie/firmie go uลผywasz itp.
+
+## Gลosuj na FastAPI
+
+*
Gลosuj na **FastAPI** w Slant.
+*
Gลosuj na **FastAPI** w AlternativeTo.
+*
Powiedz, ลผe uลผywasz **FastAPI** na StackShare.
+
+## Pomagaj innym, odpowiadajฤ
c na ich pytania na GitHubie
+
+Moลผesz sprรณbowaฤ pomรณc innym, odpowiadajฤ
c w:
+
+*
Dyskusjach na GitHubie
+*
Problemach na GitHubie
+
+W wielu przypadkach moลผesz juลผ znaฤ odpowiedลบ na te pytania. ๐ค
+
+Jeลli pomoลผesz wielu ludziom, moลผesz zostaฤ oficjalnym [Ekspertem FastAPI](fastapi-people.md#experts){.internal-link target=_blank}. ๐
+
+Pamiฤtaj tylko o najwaลผniejszym: bฤ
dลบ ลผyczliwy. Ludzie przychodzฤ
sfrustrowani i w wielu przypadkach nie zadajฤ
pytaล w najlepszy sposรณb, ale mimo to postaraj siฤ byฤ dla nich jak najbardziej ลผyczliwy. ๐ค
+
+Chciaลbym, by spoลecznoลฤ **FastAPI** byลa ลผyczliwa i przyjazna. Nie akceptuj przeลladowania ani braku szacunku wobec innych. Dbajmy o siebie nawzajem.
+
+---
+
+Oto, jak pomรณc innym z pytaniami (w dyskusjach lub problemach):
+
+### Zrozum pytanie
+
+* Upewnij siฤ, czy rozumiesz **cel** i przypadek uลผycia osoby pytajฤ
cej.
+
+* Nastฤpnie sprawdลบ, czy pytanie (wiฤkszoลฤ to pytania) jest **jasne**.
+
+* W wielu przypadkach zadane pytanie dotyczy rozwiฤ
zania wymyลlonego przez uลผytkownika, ale moลผe istnieฤ **lepsze** rozwiฤ
zanie. Jeลli dokลadnie zrozumiesz problem i przypadek uลผycia, byฤ moลผe bฤdziesz mรณgล zaproponowaฤ lepsze **alternatywne rozwiฤ
zanie**.
+
+* Jeลli nie rozumiesz pytania, poproล o wiฤcej **szczegรณลรณw**.
+
+### Odtwรณrz problem
+
+W wiฤkszoลci przypadkรณw problem wynika z **autorskiego kodu** osoby pytajฤ
cej.
+
+Czฤsto pytajฤ
cy umieszczajฤ
tylko fragment kodu, niewystarczajฤ
cy do **odtworzenia problemu**.
+
+* Moลผesz poprosiฤ ich o dostarczenie
minimalnego, odtwarzalnego przykลadu, ktรณry moลผesz **skopiowaฤ i wkleiฤ** i uruchomiฤ lokalnie, aby zobaczyฤ ten sam bลฤ
d lub zachowanie, ktรณre widzฤ
, lub lepiej zrozumieฤ ich przypadki uลผycia.
+
+* Jeลli jesteล wyjฤ
tkowo pomocny, moลผesz sprรณbowaฤ **stworzyฤ taki przykลad** samodzielnie, opierajฤ
c siฤ tylko na opisie problemu. Miej na uwadze, ลผe moลผe to zajฤ
ฤ duลผo czasu i lepiej moลผe byฤ najpierw poprosiฤ ich o wyjaลnienie problemu.
+
+### Proponuj rozwiฤ
zania
+
+* Po zrozumieniu pytania moลผesz podaฤ im moลผliwฤ
**odpowiedลบ**.
+
+* W wielu przypadkach lepiej zrozumieฤ ich **podstawowy problem lub przypadek uลผycia**, poniewaลผ moลผe istnieฤ lepszy sposรณb rozwiฤ
zania niลผ to, co prรณbujฤ
zrobiฤ.
+
+### Poproล o zamkniฤcie
+
+Jeลli odpowiedzฤ
, jest duลผa szansa, ลผe rozwiฤ
zaลeล ich problem, gratulacje, **jesteล bohaterem**! ๐ฆธ
+
+* Jeลli Twoja odpowiedลบ rozwiฤ
zaลa problem, moลผesz poprosiฤ o:
+
+ * W Dyskusjach na GitHubie: oznaczenie komentarza jako **odpowiedลบ**.
+ * W Problemach na GitHubie: **zamkniฤcie** problemu.
+
+## Obserwuj repozytorium na GitHubie
+
+Moลผesz "obserwowaฤ" FastAPI na GitHubie (klikajฤ
c przycisk "obserwuj" w prawym gรณrnym rogu):
https://github.com/tiangolo/fastapi. ๐
+
+Jeลli wybierzesz "Obserwuj" zamiast "Tylko wydania", otrzymasz powiadomienia, gdy ktoล utworzy nowy problem lub pytanie. Moลผesz rรณwnieลผ okreลliฤ, ลผe chcesz byฤ powiadamiany tylko o nowych problemach, dyskusjach, PR-ach itp.
+
+Nastฤpnie moลผesz sprรณbowaฤ pomรณc rozwiฤ
zaฤ te problemy.
+
+## Zadawaj pytania
+
+Moลผesz
utworzyฤ nowe pytanie w repozytorium na GitHubie, na przykลad aby:
+
+* Zadaฤ **pytanie** lub zapytaฤ o **problem**.
+* Zaproponowaฤ nowฤ
**funkcjฤ**.
+
+**Uwaga**: jeลli to zrobisz, poproszฤ Ciฤ rรณwnieลผ o pomoc innym. ๐
+
+## Przeglฤ
daj Pull Requesty
+
+Moลผesz pomรณc mi w przeglฤ
daniu pull requestรณw autorstwa innych osรณb.
+
+Jak wczeลniej wspomniaลem, postaraj siฤ byฤ jak najbardziej ลผyczliwy. ๐ค
+
+---
+
+Oto, co warto mieฤ na uwadze podczas oceny pull requestu:
+
+### Zrozum problem
+
+* Najpierw upewnij siฤ, ลผe **rozumiesz problem**, ktรณry prรณbuje rozwiฤ
zaฤ pull request. Moลผe byฤ osadzony w wiฤkszym kontekลcie w GitHubowej dyskusji lub problemie.
+
+* Jest teลผ duลผa szansa, ลผe pull request nie jest konieczny, poniewaลผ problem moลผna rozwiฤ
zaฤ w **inny sposรณb**. Wtedy moลผesz to zasugerowaฤ lub o to zapytaฤ.
+
+### Nie martw siฤ stylem
+
+* Nie przejmuj siฤ zbytnio rzeczami takimi jak style wiadomoลci commitรณw, przy wcielaniu pull requesta ลฤ
czฤ commity i modyfikujฤ opis sumarycznego commita rฤcznie.
+
+* Nie przejmuj siฤ rรณwnieลผ stylem kodu, automatyczne narzฤdzia w repozytorium sprawdzajฤ
to samodzielnie.
+
+A jeลli istnieje jakaล konkretna potrzeba dotyczฤ
ca stylu lub spรณjnoลci, sam poproszฤ o zmiany lub dodam commity z takimi zmianami.
+
+### Sprawdลบ kod
+
+* Przeczytaj kod, zastanรณw siฤ czy ma sens, **uruchom go lokalnie** i potwierdลบ czy faktycznie rozwiฤ
zuje problem.
+
+* Nastฤpnie dodaj **komentarz** z informacjฤ
o tym, ลผe sprawdziลeล kod, dziฤki temu bฤdฤ miaล pewnoลฤ, ลผe faktycznie go sprawdziลeล.
+
+!!! info
+ Niestety, nie mogฤ ลlepo ufaฤ PR-om, nawet jeลli majฤ
kilka zatwierdzeล.
+
+ Kilka razy zdarzyลo siฤ, ลผe PR-y miaลy 3, 5 lub wiฤcej zatwierdzeล (prawdopodobnie dlatego, ลผe opis obiecuje rozwiฤ
zanie waลผnego problemu), ale gdy sam sprawdziลem danego PR-a, okazaล siฤ byฤ zbugowany lub nie rozwiฤ
zywaล problemu, ktรณry rzekomo miaล rozwiฤ
zywaฤ. ๐
+
+ Dlatego tak waลผne jest, abyล faktycznie przeczytaล i uruchomiล kod oraz napisaล w komentarzu, ลผe to zrobiลeล. ๐ค
+
+* Jeลli PR moลผna uproลciฤ w jakiล sposรณb, moลผesz o to poprosiฤ, ale nie ma potrzeby byฤ zbyt wybrednym, moลผe byฤ wiele subiektywnych punktรณw widzenia (a ja teลผ bฤdฤ miaล swรณj ๐), wiฤc lepiej ลผebyล skupiล siฤ na kluczowych rzeczach.
+
+### Testy
+
+* Pomรณลผ mi sprawdziฤ, czy PR ma **testy**.
+
+* Sprawdลบ, czy testy **nie przechodzฤ
** przed PR. ๐จ
+
+* Nastฤpnie sprawdลบ, czy testy **przechodzฤ
** po PR. โ
+
+* Wiele PR-รณw nie ma testรณw, moลผesz **przypomnieฤ** im o dodaniu testรณw, a nawet **zaproponowaฤ** samemu jakieล testy. To jedna z rzeczy, ktรณre pochลaniajฤ
najwiฤcej czasu i moลผesz w tym bardzo pomรณc.
+
+* Nastฤpnie skomentuj rรณwnieลผ to, czego sprรณbowaลeล, wtedy bฤdฤ wiedziaล, ลผe to sprawdziลeล. ๐ค
+
+## Utwรณrz Pull Request
+
+Moลผesz [wnieลฤ wkลad](contributing.md){.internal-link target=_blank} do kodu ลบrรณdลowego za pomocฤ
Pull Requestu, na przykลad:
+
+* Naprawiฤ literรณwkฤ, ktรณrฤ
znalazลeล w dokumentacji.
+* Podzieliฤ siฤ artykuลem, filmem lub podcastem, ktรณry stworzyลeล lub znalazลeล na temat FastAPI,
edytujฤ
c ten plik.
+ * Upewnij siฤ, ลผe dodajesz swรณj link na poczฤ
tku odpowiedniej sekcji.
+* Pomรณc w [tลumaczeniu dokumentacji](contributing.md#translations){.internal-link target=_blank} na Twรณj jฤzyk.
+ * Moลผesz rรณwnieลผ pomรณc w weryfikacji tลumaczeล stworzonych przez innych.
+* Zaproponowaฤ nowe sekcje dokumentacji.
+* Naprawiฤ istniejฤ
cy problem/bลฤ
d.
+ * Upewnij siฤ, ลผe dodajesz testy.
+* Dodaฤ nowฤ
funkcjฤ.
+ * Upewnij siฤ, ลผe dodajesz testy.
+ * Upewnij siฤ, ลผe dodajesz dokumentacjฤ, jeลli jest to istotne.
+
+## Pomรณลผ w utrzymaniu FastAPI
+
+Pomรณลผ mi utrzymaฤ **FastAPI**! ๐ค
+
+Jest wiele pracy do zrobienia, a w wiฤkszoลci przypadkรณw **TY** moลผesz to zrobiฤ.
+
+Gลรณwne zadania, ktรณre moลผesz wykonaฤ teraz to:
+
+* [Pomรณc innym z pytaniami na GitHubie](#help-others-with-questions-in-github){.internal-link target=_blank} (zobacz sekcjฤ powyลผej).
+* [Oceniaฤ Pull Requesty](#review-pull-requests){.internal-link target=_blank} (zobacz sekcjฤ powyลผej).
+
+Te dwie czynnoลci **zajmujฤ
najwiฤcej czasu**. To gลรณwna praca zwiฤ
zana z utrzymaniem FastAPI.
+
+Jeลli moลผesz mi w tym pomรณc, **pomoลผesz mi utrzymaฤ FastAPI** i zapewnisz ลผe bฤdzie **rozwijaฤ siฤ szybciej i lepiej**. ๐
+
+## Doลฤ
cz do czatu
+
+Doลฤ
cz do ๐ฅ
serwera czatu na Discordzie ๐ฅ i spฤdzaj czas z innymi w spoลecznoลci FastAPI.
+
+!!! wskazรณwka
+ Jeลli masz pytania, zadaj je w
Dyskusjach na GitHubie, jest duลผo wiฤksza szansa, ลผe otrzymasz pomoc od [Ekspertรณw FastAPI](fastapi-people.md#experts){.internal-link target=_blank}.
+
+ Uลผywaj czatu tylko do innych ogรณlnych rozmรณw.
+
+### Nie zadawaj pytaล na czacie
+
+Miej na uwadze, ลผe poniewaลผ czaty pozwalajฤ
na bardziej "swobodnฤ
rozmowฤ", ลatwo jest zadawaฤ pytania, ktรณre sฤ
zbyt ogรณlne i trudniejsze do odpowiedzi, wiฤc moลผesz nie otrzymaฤ odpowiedzi.
+
+Na GitHubie szablon poprowadzi Ciฤ do napisania odpowiedniego pytania, dziฤki czemu ลatwiej uzyskasz dobrฤ
odpowiedลบ, a nawet rozwiฤ
ลผesz problem samodzielnie, zanim zapytasz. Ponadto na GitHubie mogฤ siฤ upewniฤ, ลผe zawsze odpowiadam na wszystko, nawet jeลli zajmuje to trochฤ czasu. Osobiลcie nie mogฤ tego zrobiฤ z systemami czatu. ๐
+
+Rozmรณw w systemach czatu nie moลผna tak ลatwo przeszukiwaฤ, jak na GitHubie, wiฤc pytania i odpowiedzi mogฤ
zaginฤ
ฤ w rozmowie. A tylko te na GitHubie liczฤ
siฤ do zostania [Ekspertem FastAPI](fastapi-people.md#experts){.internal-link target=_blank}, wiฤc najprawdopodobniej otrzymasz wiฤcej uwagi na GitHubie.
+
+Z drugiej strony w systemach czatu sฤ
tysiฤ
ce uลผytkownikรณw, wiฤc jest duลผa szansa, ลผe znajdziesz tam kogoล do rozmowy, prawie w kaลผdej chwili. ๐
+
+## Wspieraj autora
+
+Moลผesz rรณwnieลผ finansowo wesprzeฤ autora (mnie) poprzez
sponsoring na GitHubie.
+
+Tam moลผesz postawiฤ mi kawฤ โ๏ธ aby podziฤkowaฤ. ๐
+
+Moลผesz takลผe zostaฤ srebrnym lub zลotym sponsorem FastAPI. ๐
๐
+
+## Wspieraj narzฤdzia, ktรณre napฤdzajฤ
FastAPI
+
+Jak widziaลeล w dokumentacji, FastAPI stoi na ramionach gigantรณw, Starlette i Pydantic.
+
+Moลผesz rรณwnieลผ wesprzeฤ:
+
+*
Samuel Colvin (Pydantic)
+*
Encode (Starlette, Uvicorn)
+
+---
+
+Dziฤkujฤ! ๐
diff --git a/docs/pl/docs/index.md b/docs/pl/docs/index.md
index bade7a88c..43a20383c 100644
--- a/docs/pl/docs/index.md
+++ b/docs/pl/docs/index.md
@@ -106,7 +106,7 @@ Jeลผeli tworzysz aplikacje
CLI<
## Wymagania
-Python 3.7+
+Python 3.8+
FastAPI oparty jest na:
@@ -321,7 +321,7 @@ Robisz to tak samo jak ze standardowymi typami w Pythonie.
Nie musisz sie uczyฤ ลผadnej nowej skลadni, metod lub klas ze specyficznych bibliotek itp.
-Po prostu standardowy **Python 3.6+**.
+Po prostu standardowy **Python 3.8+**.
Na przykลad, dla danych typu `int`:
diff --git a/docs/pt/docs/deployment/deta.md b/docs/pt/docs/deployment/deta.md
deleted file mode 100644
index 9271bba42..000000000
--- a/docs/pt/docs/deployment/deta.md
+++ /dev/null
@@ -1,258 +0,0 @@
-# Implantaรงรฃo FastAPI na Deta
-
-Nessa seรงรฃo vocรช aprenderรก sobre como realizar a implantaรงรฃo de uma aplicaรงรฃo **FastAPI** na Deta utilizando o plano gratuito. ๐
-
-Isso tudo levarรก aproximadamente **10 minutos**.
-
-!!! info "Informaรงรฃo"
- Deta รฉ uma patrocinadora do **FastAPI**. ๐
-
-## Uma aplicaรงรฃo **FastAPI** simples
-
-* Crie e entre em um diretรณrio para a sua aplicaรงรฃo, por exemplo, `./fastapideta/`.
-
-### Cรณdigo FastAPI
-
-* Crie o arquivo `main.py` com:
-
-```Python
-from fastapi import FastAPI
-
-app = FastAPI()
-
-
-@app.get("/")
-def read_root():
- return {"Hello": "World"}
-
-
-@app.get("/items/{item_id}")
-def read_item(item_id: int):
- return {"item_id": item_id}
-```
-
-### Requisitos
-
-Agora, no mesmo diretรณrio crie o arquivo `requirements.txt` com:
-
-```text
-fastapi
-```
-
-!!! tip "Dica"
- Vocรช nรฃo precisa instalar Uvicorn para realizar a implantaรงรฃo na Deta, embora provavelmente queira instalรก-lo para testar seu aplicativo localmente.
-
-### Estrutura de diretรณrio
-
-Agora vocรช terรก o diretรณrio `./fastapideta/` com dois arquivos:
-
-```
-.
-โโโ main.py
-โโโ requirements.txt
-```
-
-## Crie uma conta gratuita na Deta
-
-Agora crie uma conta gratuita na Deta, vocรช precisarรก apenas de um email e senha.
-
-Vocรช nem precisa de um cartรฃo de crรฉdito.
-
-## Instale a CLI
-
-Depois de ter sua conta criada, instale Deta CLI:
-
-=== "Linux, macOS"
-
-
-
- ```console
- $ curl -fsSL https://get.deta.dev/cli.sh | sh
- ```
-
-
-
-=== "Windows PowerShell"
-
-
-
- ```console
- $ iwr https://get.deta.dev/cli.ps1 -useb | iex
- ```
-
-
-
-Apรณs a instalaรงรฃo, abra um novo terminal para que a CLI seja detectada.
-
-Em um novo terminal, confirme se foi instalado corretamente com:
-
-
-
-```console
-$ deta --help
-
-Deta command line interface for managing deta micros.
-Complete documentation available at https://docs.deta.sh
-
-Usage:
- deta [flags]
- deta [command]
-
-Available Commands:
- auth Change auth settings for a deta micro
-
-...
-```
-
-
-
-!!! tip "Dica"
- Se vocรช tiver problemas ao instalar a CLI, verifique a documentaรงรฃo oficial da Deta.
-
-## Login pela CLI
-
-Agora faรงa login na Deta pela CLI com:
-
-
-
-```console
-$ deta login
-
-Please, log in from the web page. Waiting..
-Logged in successfully.
-```
-
-
-
-Isso abrirรก um navegador da Web e autenticarรก automaticamente.
-
-## Implantaรงรฃo com Deta
-
-Em seguida, implante seu aplicativo com a Deta CLI:
-
-
-
-```console
-$ deta new
-
-Successfully created a new micro
-
-// Notice the "endpoint" ๐
-
-{
- "name": "fastapideta",
- "runtime": "python3.7",
- "endpoint": "https://qltnci.deta.dev",
- "visor": "enabled",
- "http_auth": "enabled"
-}
-
-Adding dependencies...
-
-
----> 100%
-
-
-Successfully installed fastapi-0.61.1 pydantic-1.7.2 starlette-0.13.6
-```
-
-
-
-Vocรช verรก uma mensagem JSON semelhante a:
-
-```JSON hl_lines="4"
-{
- "name": "fastapideta",
- "runtime": "python3.7",
- "endpoint": "https://qltnci.deta.dev",
- "visor": "enabled",
- "http_auth": "enabled"
-}
-```
-
-!!! tip "Dica"
- Sua implantaรงรฃo terรก um URL `"endpoint"` diferente.
-
-## Confira
-
-Agora, abra seu navegador na URL do `endpoint`. No exemplo acima foi `https://qltnci.deta.dev`, mas o seu serรก diferente.
-
-Vocรช verรก a resposta JSON do seu aplicativo FastAPI:
-
-```JSON
-{
- "Hello": "World"
-}
-```
-
-Agora vรก para o `/docs` da sua API, no exemplo acima seria `https://qltnci.deta.dev/docs`.
-
-Ele mostrarรก sua documentaรงรฃo como:
-
-
-
-## Permitir acesso pรบblico
-
-Por padrรฃo, a Deta lidarรก com a autenticaรงรฃo usando cookies para sua conta.
-
-Mas quando estiver pronto, vocรช pode tornรก-lo pรบblico com:
-
-
-
-```console
-$ deta auth disable
-
-Successfully disabled http auth
-```
-
-
-
-Agora vocรช pode compartilhar essa URL com qualquer pessoa e elas conseguirรฃo acessar sua API. ๐
-
-## HTTPS
-
-Parabรฉns! Vocรช realizou a implantaรงรฃo do seu app FastAPI na Deta! ๐ ๐ฐ
-
-Alรฉm disso, observe que a Deta lida corretamente com HTTPS para vocรช, para que vocรช nรฃo precise cuidar disso e tenha a certeza de que seus clientes terรฃo uma conexรฃo criptografada segura. โ
๐
-
-## Verifique o Visor
-
-Na UI da sua documentaรงรฃo (vocรช estarรก em um URL como `https://qltnci.deta.dev/docs`) envie um request para *operaรงรฃo de rota* `/items/{item_id}`.
-
-Por exemplo com ID `5`.
-
-Agora vรก para https://web.deta.sh.
-
-Vocรช verรก que hรก uma seรงรฃo ร esquerda chamada "Micros" com cada um dos seus apps.
-
-Vocรช verรก uma aba com "Detalhes", e tambรฉm a aba "Visor", vรก para "Visor".
-
-Lรก vocรช pode inspecionar as solicitaรงรตes recentes enviadas ao seu aplicativo.
-
-Vocรช tambรฉm pode editรก-los e reproduzi-los novamente.
-
-
-
-## Saiba mais
-
-Em algum momento, vocรช provavelmente desejarรก armazenar alguns dados para seu aplicativo de uma forma que persista ao longo do tempo. Para isso vocรช pode usar Deta Base, que tambรฉm tem um generoso **nรญvel gratuito**.
-
-Vocรช tambรฉm pode ler mais na documentaรงรฃo da Deta.
-
-## Conceitos de implantaรงรฃo
-
-Voltando aos conceitos que discutimos em [Deployments Concepts](./concepts.md){.internal-link target=_blank}, veja como cada um deles seria tratado com a Deta:
-
-* **HTTPS**: Realizado pela Deta, eles fornecerรฃo um subdomรญnio e lidarรฃo com HTTPS automaticamente.
-* **Executando na inicializaรงรฃo**: Realizado pela Deta, como parte de seu serviรงo.
-* **Reinicializaรงรฃo**: Realizado pela Deta, como parte de seu serviรงo.
-* **Replicaรงรฃo**: Realizado pela Deta, como parte de seu serviรงo.
-* **Memรณria**: Limite predefinido pela Deta, vocรช pode contatรก-los para aumentรก-lo.
-* **Etapas anteriores a inicializaรงรฃo**: Nรฃo suportado diretamente, vocรช pode fazรช-lo funcionar com o sistema Cron ou scripts adicionais.
-
-!!! note "Nota"
- O Deta foi projetado para facilitar (e gratuitamente) a implantaรงรฃo rรกpida de aplicativos simples.
-
- Ele pode simplificar vรกrios casos de uso, mas, ao mesmo tempo, nรฃo suporta outros, como o uso de bancos de dados externos (alรฉm do prรณprio sistema de banco de dados NoSQL da Deta), mรกquinas virtuais personalizadas, etc.
-
- Vocรช pode ler mais detalhes na documentaรงรฃo da Deta para ver se รฉ a escolha certa para vocรช.
diff --git a/docs/pt/docs/external-links.md b/docs/pt/docs/external-links.md
index 6ec6c3a27..77ec32351 100644
--- a/docs/pt/docs/external-links.md
+++ b/docs/pt/docs/external-links.md
@@ -9,70 +9,21 @@ Aqui tem uma lista, incompleta, de algumas delas.
!!! tip "Dica"
Se vocรช tem um artigo, projeto, ferramenta ou qualquer coisa relacionada ao **FastAPI** que ainda nรฃo estรก listada aqui, crie um _Pull Request_ adicionando ele.
-## Artigos
+{% for section_name, section_content in external_links.items() %}
-### Inglรชs
+## {{ section_name }}
-{% if external_links %}
-{% for article in external_links.articles.english %}
+{% for lang_name, lang_content in section_content.items() %}
+
+### {{ lang_name }}
+
+{% for item in lang_content %}
+
+* {{ item.title }} by {{ item.author }}.
-* {{ article.title }} by {{ article.author }}.
{% endfor %}
-{% endif %}
-
-### Japonรชs
-
-{% if external_links %}
-{% for article in external_links.articles.japanese %}
-
-* {{ article.title }} by {{ article.author }}.
{% endfor %}
-{% endif %}
-
-### Vietnamita
-
-{% if external_links %}
-{% for article in external_links.articles.vietnamese %}
-
-* {{ article.title }} by {{ article.author }}.
{% endfor %}
-{% endif %}
-
-### Russo
-
-{% if external_links %}
-{% for article in external_links.articles.russian %}
-
-* {{ article.title }} by {{ article.author }}.
-{% endfor %}
-{% endif %}
-
-### Alemรฃo
-
-{% if external_links %}
-{% for article in external_links.articles.german %}
-
-* {{ article.title }} by {{ article.author }}.
-{% endfor %}
-{% endif %}
-
-## Podcasts
-
-{% if external_links %}
-{% for article in external_links.podcasts.english %}
-
-* {{ article.title }} by {{ article.author }}.
-{% endfor %}
-{% endif %}
-
-## Palestras
-
-{% if external_links %}
-{% for article in external_links.talks.english %}
-
-* {{ article.title }} by {{ article.author }}.
-{% endfor %}
-{% endif %}
## Projetos
diff --git a/docs/pt/docs/features.md b/docs/pt/docs/features.md
index bd0db8e76..822992c5b 100644
--- a/docs/pt/docs/features.md
+++ b/docs/pt/docs/features.md
@@ -25,7 +25,7 @@ Documentaรงรฃo interativa da API e navegaรงรฃo _web_ da interface de usuรกrio. C
### Apenas Python moderno
-Tudo รฉ baseado no padrรฃo das declaraรงรตes de **tipos do Python 3.6** (graรงas ao Pydantic). Nenhuma sintaxe nova para aprender. Apenas o padrรฃo moderno do Python.
+Tudo รฉ baseado no padrรฃo das declaraรงรตes de **tipos do Python 3.8** (graรงas ao Pydantic). Nenhuma sintaxe nova para aprender. Apenas o padrรฃo moderno do Python.
Se vocรช precisa refrescar a memรณria rapidamente sobre como usar tipos do Python (mesmo que vocรช nรฃo use o FastAPI), confira esse rรกpido tutorial: [Tipos do Python](python-types.md){.internal-link target=_blank}.
diff --git a/docs/pt/docs/help-fastapi.md b/docs/pt/docs/help-fastapi.md
index d82ce3414..d04905197 100644
--- a/docs/pt/docs/help-fastapi.md
+++ b/docs/pt/docs/help-fastapi.md
@@ -114,8 +114,6 @@ do FastAPI.
Use o chat apenas para outro tipo de assunto.
-Tambรฉm existe o chat do Gitter, porรฉm ele nรฃo possuรญ canais e recursos avanรงados, conversas sรฃo mais engessadas, por isso o Discord รฉ mais recomendado.
-
### Nรฃo faรงa perguntas no chat
Tenha em mente que os chats permitem uma "conversa mais livre", dessa forma รฉ muito fรกcil fazer perguntas que sรฃo muito genรฉricas e dificeรญs de responder, assim vocรช pode acabar nรฃo sendo respondido.
diff --git a/docs/pt/docs/index.md b/docs/pt/docs/index.md
index 591e7f3d4..d1e64b3b9 100644
--- a/docs/pt/docs/index.md
+++ b/docs/pt/docs/index.md
@@ -24,7 +24,7 @@
---
-FastAPI รฉ um moderno e rรกpido (alta performance) _framework web_ para construรงรฃo de APIs com Python 3.6 ou superior, baseado nos _type hints_ padrรตes do Python.
+FastAPI รฉ um moderno e rรกpido (alta performance) _framework web_ para construรงรฃo de APIs com Python 3.8 ou superior, baseado nos _type hints_ padrรตes do Python.
Os recursos chave sรฃo:
@@ -100,7 +100,7 @@ Se vocรช estiver construindo uma aplicaรงรฃo ../../../docs_src/body_multiple_params/tutorial001.py!}
@@ -44,7 +44,7 @@ Mas vocรช pode tambรฉm declarar mรบltiplos parรขmetros de corpo, por exemplo, `i
{!> ../../../docs_src/body_multiple_params/tutorial002_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="22"
{!> ../../../docs_src/body_multiple_params/tutorial002.py!}
@@ -87,7 +87,7 @@ Se vocรช declarรก-lo como รฉ, porque รฉ um valor singular, o **FastAPI** assumir
Mas vocรช pode instruir o **FastAPI** para tratรก-lo como outra chave do corpo usando `Body`:
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="22"
{!> ../../../docs_src/body_multiple_params/tutorial003.py!}
@@ -143,7 +143,7 @@ Por exemplo:
{!> ../../../docs_src/body_multiple_params/tutorial004_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="27"
{!> ../../../docs_src/body_multiple_params/tutorial004.py!}
@@ -172,7 +172,7 @@ como em:
{!> ../../../docs_src/body_multiple_params/tutorial005_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="17"
{!> ../../../docs_src/body_multiple_params/tutorial005.py!}
diff --git a/docs/pt/docs/tutorial/encoder.md b/docs/pt/docs/tutorial/encoder.md
index bb4483fdc..b9bfbf63b 100644
--- a/docs/pt/docs/tutorial/encoder.md
+++ b/docs/pt/docs/tutorial/encoder.md
@@ -26,7 +26,7 @@ A funรงรฃo recebe um objeto, como um modelo Pydantic e retorna uma versรฃo compa
{!> ../../../docs_src/encoder/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="5 22"
{!> ../../../docs_src/encoder/tutorial001.py!}
diff --git a/docs/pt/docs/tutorial/extra-models.md b/docs/pt/docs/tutorial/extra-models.md
index dd5407eb2..1343a3ae4 100644
--- a/docs/pt/docs/tutorial/extra-models.md
+++ b/docs/pt/docs/tutorial/extra-models.md
@@ -17,7 +17,7 @@ Isso รฉ especialmente o caso para modelos de usuรกrios, porque:
Aqui estรก uma ideia geral de como os modelos poderiam parecer com seus campos de senha e os lugares onde sรฃo usados:
-=== "Python 3.6 and above"
+=== "Python 3.8 and above"
```Python hl_lines="9 11 16 22 24 29-30 33-35 40-41"
{!> ../../../docs_src/extra_models/tutorial001.py!}
@@ -158,7 +158,7 @@ Toda conversรฃo de dados, validaรงรฃo, documentaรงรฃo, etc. ainda funcionarรก no
Dessa forma, podemos declarar apenas as diferenรงas entre os modelos (com `password` em texto claro, com `hashed_password` e sem senha):
-=== "Python 3.6 and above"
+=== "Python 3.8 and above"
```Python hl_lines="9 15-16 19-20 23-24"
{!> ../../../docs_src/extra_models/tutorial002.py!}
@@ -181,7 +181,7 @@ Para fazer isso, use a dica de tipo padrรฃo do Python `Union`, inclua o tipo mais especรญfico primeiro, seguido pelo tipo menos especรญfico. No exemplo abaixo, o tipo mais especรญfico `PlaneItem` vem antes de `CarItem` em `Union[PlaneItem, CarItem]`.
-=== "Python 3.6 and above"
+=== "Python 3.8 and above"
```Python hl_lines="1 14-15 18-20 33"
{!> ../../../docs_src/extra_models/tutorial003.py!}
@@ -213,7 +213,7 @@ Da mesma forma, vocรช pode declarar respostas de listas de objetos.
Para isso, use o padrรฃo Python `typing.List` (ou simplesmente `list` no Python 3.9 e superior):
-=== "Python 3.6 and above"
+=== "Python 3.8 and above"
```Python hl_lines="1 20"
{!> ../../../docs_src/extra_models/tutorial004.py!}
@@ -233,7 +233,7 @@ Isso รฉ รบtil se vocรช nรฃo souber os nomes de campo / atributo vรกlidos (que se
Neste caso, vocรช pode usar `typing.Dict` (ou simplesmente dict no Python 3.9 e superior):
-=== "Python 3.6 and above"
+=== "Python 3.8 and above"
```Python hl_lines="1 8"
{!> ../../../docs_src/extra_models/tutorial005.py!}
diff --git a/docs/pt/docs/tutorial/header-params.md b/docs/pt/docs/tutorial/header-params.md
index bc8843327..4bdfb7e9c 100644
--- a/docs/pt/docs/tutorial/header-params.md
+++ b/docs/pt/docs/tutorial/header-params.md
@@ -12,7 +12,7 @@ Primeiro importe `Header`:
{!> ../../../docs_src/header_params/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="3"
{!> ../../../docs_src/header_params/tutorial001.py!}
@@ -30,7 +30,7 @@ O primeiro valor รฉ o valor padrรฃo, vocรช pode passar todas as validaรงรตes adi
{!> ../../../docs_src/header_params/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9"
{!> ../../../docs_src/header_params/tutorial001.py!}
@@ -66,7 +66,7 @@ Se por algum motivo vocรช precisar desabilitar a conversรฃo automรกtica de subli
{!> ../../../docs_src/header_params/tutorial002_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="10"
{!> ../../../docs_src/header_params/tutorial002.py!}
@@ -97,7 +97,7 @@ Por exemplo, para declarar um cabeรงalho de `X-Token` que pode aparecer mais de
{!> ../../../docs_src/header_params/tutorial003_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9"
{!> ../../../docs_src/header_params/tutorial003.py!}
diff --git a/docs/pt/docs/tutorial/path-operation-configuration.md b/docs/pt/docs/tutorial/path-operation-configuration.md
index e0a23f665..13a87240f 100644
--- a/docs/pt/docs/tutorial/path-operation-configuration.md
+++ b/docs/pt/docs/tutorial/path-operation-configuration.md
@@ -13,7 +13,7 @@ Vocรช pode passar diretamente o cรณdigo `int`, como `404`.
Mas se vocรช nรฃo se lembrar o que cada cรณdigo numรฉrico significa, pode usar as constantes de atalho em `status`:
-=== "Python 3.6 and above"
+=== "Python 3.8 and above"
```Python hl_lines="3 17"
{!> ../../../docs_src/path_operation_configuration/tutorial001.py!}
@@ -42,7 +42,7 @@ Esse cรณdigo de status serรก usado na resposta e serรก adicionado ao esquema Ope
Vocรช pode adicionar tags para sua *operaรงรฃo de rota*, passe o parรขmetro `tags` com uma `list` de `str` (comumente apenas um `str`):
-=== "Python 3.6 and above"
+=== "Python 3.8 and above"
```Python hl_lines="17 22 27"
{!> ../../../docs_src/path_operation_configuration/tutorial002.py!}
@@ -80,7 +80,7 @@ Nestes casos, pode fazer sentido armazenar as tags em um `Enum`.
Vocรช pode adicionar um `summary` e uma `description`:
-=== "Python 3.6 and above"
+=== "Python 3.8 and above"
```Python hl_lines="20-21"
{!> ../../../docs_src/path_operation_configuration/tutorial003.py!}
@@ -104,7 +104,7 @@ Como as descriรงรตes tendem a ser longas e cobrir vรกrias linhas, vocรช pode dec
Vocรช pode escrever Markdown na docstring, ele serรก interpretado e exibido corretamente (levando em conta a indentaรงรฃo da docstring).
-=== "Python 3.6 and above"
+=== "Python 3.8 and above"
```Python hl_lines="19-27"
{!> ../../../docs_src/path_operation_configuration/tutorial004.py!}
@@ -131,7 +131,7 @@ Ela serรก usada nas documentaรงรตes interativas:
Vocรช pode especificar a descriรงรฃo da resposta com o parรขmetro `response_description`:
-=== "Python 3.6 and above"
+=== "Python 3.8 and above"
```Python hl_lines="21"
{!> ../../../docs_src/path_operation_configuration/tutorial005.py!}
diff --git a/docs/pt/docs/tutorial/path-params-numeric-validations.md b/docs/pt/docs/tutorial/path-params-numeric-validations.md
index ec9b74b30..eb0d31dc3 100644
--- a/docs/pt/docs/tutorial/path-params-numeric-validations.md
+++ b/docs/pt/docs/tutorial/path-params-numeric-validations.md
@@ -12,7 +12,7 @@ Primeiro, importe `Path` de `fastapi`:
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="3"
{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
@@ -30,7 +30,7 @@ Por exemplo para declarar um valor de metadado `title` para o parรขmetro de rota
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="10"
{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
diff --git a/docs/pt/docs/tutorial/path-params.md b/docs/pt/docs/tutorial/path-params.md
index 5de3756ed..cd8c18858 100644
--- a/docs/pt/docs/tutorial/path-params.md
+++ b/docs/pt/docs/tutorial/path-params.md
@@ -236,7 +236,6 @@ Entรฃo, vocรช poderia usar ele com:
Com o **FastAPI**, usando as declaraรงรตes de tipo do Python, vocรช obtรฉm:
* Suporte no editor: verificaรงรฃo de erros, e opรงรฃo de autocompletar, etc.
-* Parsing de dados
* "Parsing" de dados
* Validaรงรฃo de dados
* Anotaรงรฃo da API e documentaรงรฃo automรกtica
diff --git a/docs/pt/docs/tutorial/query-params.md b/docs/pt/docs/tutorial/query-params.md
index 3ada4fd21..08bb99dbc 100644
--- a/docs/pt/docs/tutorial/query-params.md
+++ b/docs/pt/docs/tutorial/query-params.md
@@ -69,7 +69,7 @@ Da mesma forma, vocรช pode declarar parรขmetros de consulta opcionais, definindo
{!> ../../../docs_src/query_params/tutorial002_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9"
{!> ../../../docs_src/query_params/tutorial002.py!}
@@ -91,7 +91,7 @@ Vocรช tambรฉm pode declarar tipos `bool`, e eles serรฃo convertidos:
{!> ../../../docs_src/query_params/tutorial003_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9"
{!> ../../../docs_src/query_params/tutorial003.py!}
@@ -143,7 +143,7 @@ Eles serรฃo detectados pelo nome:
{!> ../../../docs_src/query_params/tutorial004_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="8 10"
{!> ../../../docs_src/query_params/tutorial004.py!}
@@ -209,7 +209,7 @@ E claro, vocรช pode definir alguns parรขmetros como obrigatรณrios, alguns possui
{!> ../../../docs_src/query_params/tutorial006_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="10"
{!> ../../../docs_src/query_params/tutorial006.py!}
diff --git a/docs/ru/docs/external-links.md b/docs/ru/docs/external-links.md
index 4daf65898..2448ef82e 100644
--- a/docs/ru/docs/external-links.md
+++ b/docs/ru/docs/external-links.md
@@ -9,70 +9,21 @@
!!! tip
ะัะปะธ ั ะฒะฐั ะตััั ััะฐััั, ะฟัะพะตะบั, ะธะฝััััะผะตะฝั ะธะปะธ ััะพ-ะปะธะฑะพ, ัะฒัะทะฐะฝะฝะพะต ั **FastAPI**, ััะพ ะตัะต ะฝะต ะฟะตัะตัะธัะปะตะฝะพ ะทะดะตัั, ัะพะทะดะฐะนัะต Pull Request.
-## ะกัะฐััะธ
+{% for section_name, section_content in external_links.items() %}
-### ะะฐ ะฐะฝะณะปะธะนัะบะพะผ
+## {{ section_name }}
-{% if external_links %}
-{% for article in external_links.articles.english %}
+{% for lang_name, lang_content in section_content.items() %}
+
+### {{ lang_name }}
+
+{% for item in lang_content %}
+
+* {{ item.title }} by {{ item.author }}.
-* {{ article.title }} by {{ article.author }}.
{% endfor %}
-{% endif %}
-
-### ะะฐ ัะฟะพะฝัะบะพะผ
-
-{% if external_links %}
-{% for article in external_links.articles.japanese %}
-
-* {{ article.title }} by {{ article.author }}.
{% endfor %}
-{% endif %}
-
-### ะะฐ ะฒัะตัะฝะฐะผัะบะพะผ
-
-{% if external_links %}
-{% for article in external_links.articles.vietnamese %}
-
-* {{ article.title }} by {{ article.author }}.
{% endfor %}
-{% endif %}
-
-### ะะฐ ััััะบะพะผ
-
-{% if external_links %}
-{% for article in external_links.articles.russian %}
-
-* {{ article.title }} by {{ article.author }}.
-{% endfor %}
-{% endif %}
-
-### ะะฐ ะฝะตะผะตัะบะพะผ
-
-{% if external_links %}
-{% for article in external_links.articles.german %}
-
-* {{ article.title }} by {{ article.author }}.
-{% endfor %}
-{% endif %}
-
-## ะะพะดะบะฐััั
-
-{% if external_links %}
-{% for article in external_links.podcasts.english %}
-
-* {{ article.title }} by {{ article.author }}.
-{% endfor %}
-{% endif %}
-
-## Talks
-
-{% if external_links %}
-{% for article in external_links.talks.english %}
-
-* {{ article.title }} by {{ article.author }}.
-{% endfor %}
-{% endif %}
## ะัะพะตะบัั
diff --git a/docs/ru/docs/features.md b/docs/ru/docs/features.md
index e18f7bc87..97841cc83 100644
--- a/docs/ru/docs/features.md
+++ b/docs/ru/docs/features.md
@@ -27,7 +27,7 @@
### ะขะพะปัะบะพ ัะพะฒัะตะผะตะฝะฝัะน Python
-ะัะต ััะธ ะฒะพะทะผะพะถะฝะพััะธ ะพัะฝะพะฒะฐะฝั ะฝะฐ ััะฐะฝะดะฐััะฝัั
**ะฐะฝะฝะพัะฐัะธัั
ัะธะฟะพะฒ Python 3.6** (ะฑะปะฐะณะพะดะฐัั Pydantic). ะะต ะฝัะถะฝะพ ะธะทััะฐัั ะฝะพะฒัะน ัะธะฝัะฐะบัะธั. ะขะพะปัะบะพ ะปะธัั ััะฐะฝะดะฐััะฝัะน ัะพะฒัะตะผะตะฝะฝัะน Python.
+ะัะต ััะธ ะฒะพะทะผะพะถะฝะพััะธ ะพัะฝะพะฒะฐะฝั ะฝะฐ ััะฐะฝะดะฐััะฝัั
**ะฐะฝะฝะพัะฐัะธัั
ัะธะฟะพะฒ Python 3.8** (ะฑะปะฐะณะพะดะฐัั Pydantic). ะะต ะฝัะถะฝะพ ะธะทััะฐัั ะฝะพะฒัะน ัะธะฝัะฐะบัะธั. ะขะพะปัะบะพ ะปะธัั ััะฐะฝะดะฐััะฝัะน ัะพะฒัะตะผะตะฝะฝัะน Python.
ะัะปะธ ะฒะฐะผ ะฝัะถะฝะพ ะพัะฒะตะถะธัั ะทะฝะฐะฝะธั, ะบะฐะบ ะธัะฟะพะปัะทะพะฒะฐัั ะฐะฝะฝะพัะฐัะธะธ ัะธะฟะพะฒ ะฒ Python (ะดะฐะถะต ะตัะปะธ ะฒั ะฝะต ะธัะฟะพะปัะทัะตัะต FastAPI), ะฒัะดะตะปะธัะต 2 ะผะธะฝััั ะธ ะฟัะพัะผะพััะธัะต ะบัะฐัะบะพะต ััะบะพะฒะพะดััะฒะพ: [ะะฒะตะดะตะฝะธะต ะฒ ะฐะฝะฝะพัะฐัะธะธ ัะธะฟะพะฒ Pythonยถ
](python-types.md){.internal-link target=_blank}.
diff --git a/docs/ru/docs/help-fastapi.md b/docs/ru/docs/help-fastapi.md
index a69e37bd8..65ff768d1 100644
--- a/docs/ru/docs/help-fastapi.md
+++ b/docs/ru/docs/help-fastapi.md
@@ -223,8 +223,6 @@
ะัะฟะพะปัะทัะนัะต ััะพั ัะฐั ัะพะปัะบะพ ะดะปั ะฑะตัะตะด ะฝะฐ ะพัะฒะปะตััะฝะฝัะต ัะตะผั.
-ะกััะตััะฒัะตั ัะฐะบะถะต ัะฐั ะฒ Gitter, ะฝะพ ะฟะพัะบะพะปัะบั ะฒ ะฝะตะผ ะฝะตั ะบะฐะฝะฐะปะพะฒ ะธ ัะฐััะธัะตะฝะฝัั
ััะฝะบัะธะน, ะพะฑัะตะฝะธะต ะฒ ะฝัะผ ัะปะพะถะฝะตะต, ะฟะพัะพะผั ัะตะบะพะผะตะฝะดัะตะผะพะน ัะธััะตะผะพะน ัะฒะปัะตััั Discord.
-
### ะะต ะธัะฟะพะปัะทะพะฒะฐัั ัะฐัั ะดะปั ะฒะพะฟัะพัะพะฒ
ะะผะตะนัะต ะฒ ะฒะธะดั, ััะพ ัะฐัั ะฟะพะทะฒะพะปััั ะฑะพะปััะต "ัะฒะพะฑะพะดะฝะพะณะพ ะพะฑัะตะฝะธั", ะฟะพัะพะผั ัะฐะผ ะปะตะณะบะพ ะทะฐะดะฐะฒะฐัั ะฒะพะฟัะพัั, ะบะพัะพััะต ัะปะธัะบะพะผ ะพะฑัะธะต ะธ ะฝะฐ ะบะพัะพััะต ัััะดะฝะตะต ะพัะฒะตัะธัั, ัะฐะบ ััะพ ะั ะผะพะถะตัะต ะฝะต ะฟะพะปััะธัั ะฝัะถะฝัะต ะะฐะผ ะพัะฒะตัั.
diff --git a/docs/ru/docs/index.md b/docs/ru/docs/index.md
index 30c32e046..97a3947bd 100644
--- a/docs/ru/docs/index.md
+++ b/docs/ru/docs/index.md
@@ -27,7 +27,7 @@
---
-FastAPI โ ััะพ ัะพะฒัะตะผะตะฝะฝัะน, ะฑัััััะน (ะฒััะพะบะพะฟัะพะธะทะฒะพะดะธัะตะปัะฝัะน) ะฒะตะฑ-ััะตะนะผะฒะพัะบ ะดะปั ัะพะทะดะฐะฝะธั API ะธัะฟะพะปัะทัั Python 3.6+, ะฒ ะพัะฝะพะฒะต ะบะพัะพัะพะณะพ ะปะตะถะธั ััะฐะฝะดะฐััะฝะฐั ะฐะฝะฝะพัะฐัะธั ัะธะฟะพะฒ Python.
+FastAPI โ ััะพ ัะพะฒัะตะผะตะฝะฝัะน, ะฑัััััะน (ะฒััะพะบะพะฟัะพะธะทะฒะพะดะธัะตะปัะฝัะน) ะฒะตะฑ-ััะตะนะผะฒะพัะบ ะดะปั ัะพะทะดะฐะฝะธั API ะธัะฟะพะปัะทัั Python 3.8+, ะฒ ะพัะฝะพะฒะต ะบะพัะพัะพะณะพ ะปะตะถะธั ััะฐะฝะดะฐััะฝะฐั ะฐะฝะฝะพัะฐัะธั ัะธะฟะพะฒ Python.
ะะปััะตะฒัะต ะพัะพะฑะตะฝะฝะพััะธ:
@@ -109,7 +109,7 @@ FastAPI โ ััะพ ัะพะฒัะตะผะตะฝะฝัะน, ะฑัััััะน (ะฒััะพะบะพะฟัะพะธ
## ะะฐะฒะธัะธะผะพััะธ
-Python 3.7+
+Python 3.8+
FastAPI ััะพะธั ะฝะฐ ะฟะปะตัะฐั
ะณะธะณะฐะฝัะพะฒ:
@@ -325,7 +325,7 @@ def update_item(item_id: int, item: Item):
ะะฐะผ ะฝะต ะฝัะถะฝะพ ะธะทััะฐัั ะฝะพะฒัะน ัะธะฝัะฐะบัะธั, ะผะตัะพะดั ะธะปะธ ะบะปะฐััั ะบะพะฝะบัะตัะฝะพะน ะฑะธะฑะปะธะพัะตะบะธ ะธ ั. ะด.
-ะขะพะปัะบะพ ััะฐะฝะดะฐััะฝัะน **Python 3.6+**.
+ะขะพะปัะบะพ ััะฐะฝะดะฐััะฝัะน **Python 3.8+**.
ะะฐะฟัะธะผะตั, ะดะปั `int`:
diff --git a/docs/ru/docs/tutorial/background-tasks.md b/docs/ru/docs/tutorial/background-tasks.md
index 81efda786..7a3cf6d83 100644
--- a/docs/ru/docs/tutorial/background-tasks.md
+++ b/docs/ru/docs/tutorial/background-tasks.md
@@ -63,7 +63,7 @@
{!> ../../../docs_src/background_tasks/tutorial002_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="13 15 22 25"
{!> ../../../docs_src/background_tasks/tutorial002.py!}
diff --git a/docs/ru/docs/tutorial/body-fields.md b/docs/ru/docs/tutorial/body-fields.md
index 674b8bde4..02a598004 100644
--- a/docs/ru/docs/tutorial/body-fields.md
+++ b/docs/ru/docs/tutorial/body-fields.md
@@ -12,7 +12,7 @@
{!> ../../../docs_src/body_fields/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="4"
{!> ../../../docs_src/body_fields/tutorial001.py!}
@@ -31,13 +31,13 @@
{!> ../../../docs_src/body_fields/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="11-14"
{!> ../../../docs_src/body_fields/tutorial001.py!}
```
-ะคัะฝะบัะธั `Field` ัะฐะฑะพัะฐะตั ัะฐะบ ะถะต, ะบะฐะบ `Query`, `Path` ะธ `Body`, ั ะตะต ัะฐะบะธะต ะถะต ะฟะฐัะฐะผะตััั ะธ ั.ะด.
+ะคัะฝะบัะธั `Field` ัะฐะฑะพัะฐะตั ัะฐะบ ะถะต, ะบะฐะบ `Query`, `Path` ะธ `Body`, ั ะฝะตั ัะฐะบะธะต ะถะต ะฟะฐัะฐะผะตััั ะธ ั.ะด.
!!! note "ะขะตั
ะฝะธัะตัะบะธะต ะดะตัะฐะปะธ"
ะะฐ ัะฐะผะพะผ ะดะตะปะต, `Query`, `Path` ะธ ะดััะณะธะต ััะฝะบัะธะธ, ะบะพัะพััะต ะฒั ัะฒะธะดะธัะต ะฒ ะดะฐะปัะฝะตะนัะตะผ, ัะพะทะดะฐัั ะพะฑัะตะบัั ะฟะพะดะบะปะฐััะพะฒ ะพะฑัะตะณะพ ะบะปะฐััะฐ `Param`, ะบะพัะพััะน ัะฐะผ ะฟะพ ัะตะฑะต ัะฒะปัะตััั ะฟะพะดะบะปะฐััะพะผ `FieldInfo` ะธะท Pydantic.
diff --git a/docs/ru/docs/tutorial/body-multiple-params.md b/docs/ru/docs/tutorial/body-multiple-params.md
index a20457092..e52ef6f6f 100644
--- a/docs/ru/docs/tutorial/body-multiple-params.md
+++ b/docs/ru/docs/tutorial/body-multiple-params.md
@@ -20,7 +20,7 @@
{!> ../../../docs_src/body_multiple_params/tutorial001_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="19-21"
{!> ../../../docs_src/body_multiple_params/tutorial001_an.py!}
@@ -35,7 +35,7 @@
{!> ../../../docs_src/body_multiple_params/tutorial001_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! ะะฐะผะตัะบะฐ
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated`, ะตัะปะธ ััะพ ะฒะพะทะผะพะถะฝะพ.
@@ -68,7 +68,7 @@
{!> ../../../docs_src/body_multiple_params/tutorial002_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="22"
{!> ../../../docs_src/body_multiple_params/tutorial002.py!}
@@ -123,7 +123,7 @@
{!> ../../../docs_src/body_multiple_params/tutorial003_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="24"
{!> ../../../docs_src/body_multiple_params/tutorial003_an.py!}
@@ -138,7 +138,7 @@
{!> ../../../docs_src/body_multiple_params/tutorial003_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! ะะฐะผะตัะบะฐ
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั `Annotated` ะฒะตััะธั, ะตัะปะธ ััะพ ะฒะพะทะผะพะถะฝะพ.
@@ -197,7 +197,7 @@ q: str | None = None
{!> ../../../docs_src/body_multiple_params/tutorial004_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="28"
{!> ../../../docs_src/body_multiple_params/tutorial004_an.py!}
@@ -212,7 +212,7 @@ q: str | None = None
{!> ../../../docs_src/body_multiple_params/tutorial004_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! ะะฐะผะตัะบะฐ
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั `Annotated` ะฒะตััะธั, ะตัะปะธ ััะพ ะฒะพะทะผะพะถะฝะพ.
@@ -250,7 +250,7 @@ item: Item = Body(embed=True)
{!> ../../../docs_src/body_multiple_params/tutorial005_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="18"
{!> ../../../docs_src/body_multiple_params/tutorial005_an.py!}
@@ -265,7 +265,7 @@ item: Item = Body(embed=True)
{!> ../../../docs_src/body_multiple_params/tutorial005_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! ะะฐะผะตัะบะฐ
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั `Annotated` ะฒะตััะธั, ะตัะปะธ ััะพ ะฒะพะทะผะพะถะฝะพ.
diff --git a/docs/ru/docs/tutorial/body-nested-models.md b/docs/ru/docs/tutorial/body-nested-models.md
index 6435e316f..a6d123d30 100644
--- a/docs/ru/docs/tutorial/body-nested-models.md
+++ b/docs/ru/docs/tutorial/body-nested-models.md
@@ -12,7 +12,7 @@
{!> ../../../docs_src/body_nested_models/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="14"
{!> ../../../docs_src/body_nested_models/tutorial001.py!}
@@ -73,7 +73,7 @@ my_list: List[str]
{!> ../../../docs_src/body_nested_models/tutorial002_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="14"
{!> ../../../docs_src/body_nested_models/tutorial002.py!}
@@ -99,7 +99,7 @@ my_list: List[str]
{!> ../../../docs_src/body_nested_models/tutorial003_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="1 14"
{!> ../../../docs_src/body_nested_models/tutorial003.py!}
@@ -137,7 +137,7 @@ my_list: List[str]
{!> ../../../docs_src/body_nested_models/tutorial004_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9-11"
{!> ../../../docs_src/body_nested_models/tutorial004.py!}
@@ -159,7 +159,7 @@ my_list: List[str]
{!> ../../../docs_src/body_nested_models/tutorial004_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="20"
{!> ../../../docs_src/body_nested_models/tutorial004.py!}
@@ -208,7 +208,7 @@ my_list: List[str]
{!> ../../../docs_src/body_nested_models/tutorial005_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="4 10"
{!> ../../../docs_src/body_nested_models/tutorial005.py!}
@@ -232,7 +232,7 @@ my_list: List[str]
{!> ../../../docs_src/body_nested_models/tutorial006_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="20"
{!> ../../../docs_src/body_nested_models/tutorial006.py!}
@@ -283,7 +283,7 @@ my_list: List[str]
{!> ../../../docs_src/body_nested_models/tutorial007_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9 14 20 23 27"
{!> ../../../docs_src/body_nested_models/tutorial007.py!}
@@ -314,7 +314,7 @@ images: list[Image]
{!> ../../../docs_src/body_nested_models/tutorial008_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="15"
{!> ../../../docs_src/body_nested_models/tutorial008.py!}
@@ -354,7 +354,7 @@ images: list[Image]
{!> ../../../docs_src/body_nested_models/tutorial009_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9"
{!> ../../../docs_src/body_nested_models/tutorial009.py!}
diff --git a/docs/ru/docs/tutorial/cookie-params.md b/docs/ru/docs/tutorial/cookie-params.md
index a6f2caa26..5f99458b6 100644
--- a/docs/ru/docs/tutorial/cookie-params.md
+++ b/docs/ru/docs/tutorial/cookie-params.md
@@ -12,7 +12,7 @@
{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="3"
{!> ../../../docs_src/cookie_params/tutorial001.py!}
@@ -30,7 +30,7 @@
{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9"
{!> ../../../docs_src/cookie_params/tutorial001.py!}
diff --git a/docs/ru/docs/tutorial/dependencies/global-dependencies.md b/docs/ru/docs/tutorial/dependencies/global-dependencies.md
index 870d42cf5..eb1b4d7c1 100644
--- a/docs/ru/docs/tutorial/dependencies/global-dependencies.md
+++ b/docs/ru/docs/tutorial/dependencies/global-dependencies.md
@@ -12,13 +12,13 @@
{!> ../../../docs_src/dependencies/tutorial012_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="16"
{!> ../../../docs_src/dependencies/tutorial012_an.py!}
```
-=== "Python 3.6 non-Annotated"
+=== "Python 3.8 non-Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั 'Annotated' ะฒะตััะธั, ะตัะปะธ ััะพ ะฒะพะทะผะพะถะฝะพ.
diff --git a/docs/ru/docs/tutorial/extra-data-types.md b/docs/ru/docs/tutorial/extra-data-types.md
index efcbcb38a..0f613a6b2 100644
--- a/docs/ru/docs/tutorial/extra-data-types.md
+++ b/docs/ru/docs/tutorial/extra-data-types.md
@@ -55,7 +55,7 @@
ะะพั ะฟัะธะผะตั *ะพะฟะตัะฐัะธะธ ะฟััะธ* ั ะฟะฐัะฐะผะตััะฐะผะธ, ะบะพัะพััะน ะดะตะผะพะฝัััะธััะตั ะฝะตะบะพัะพััะต ะธะท ะฒััะตะฟะตัะตัะธัะปะตะฝะฝัั
ัะธะฟะพะฒ.
-=== "Python 3.6 ะธ ะฒััะต"
+=== "Python 3.8 ะธ ะฒััะต"
```Python hl_lines="1 3 12-16"
{!> ../../../docs_src/extra_data_types/tutorial001.py!}
@@ -69,7 +69,7 @@
ะะฑัะฐัะธัะต ะฒะฝะธะผะฐะฝะธะต, ััะพ ะฟะฐัะฐะผะตััั ะฒะฝัััะธ ััะฝะบัะธะธ ะธะผะตัั ัะฒะพะน ะตััะตััะฒะตะฝะฝัะน ัะธะฟ ะดะฐะฝะฝัั
, ะธ ะฒั, ะฝะฐะฟัะธะผะตั, ะผะพะถะตัะต ะฒัะฟะพะปะฝััั ะพะฑััะฝัะต ะผะฐะฝะธะฟัะปััะธะธ ั ะดะฐัะฐะผะธ, ัะฐะบะธะต ะบะฐะบ:
-=== "Python 3.6 ะธ ะฒััะต"
+=== "Python 3.8 ะธ ะฒััะต"
```Python hl_lines="18-19"
{!> ../../../docs_src/extra_data_types/tutorial001.py!}
diff --git a/docs/ru/docs/tutorial/extra-models.md b/docs/ru/docs/tutorial/extra-models.md
index a346f7432..30176b4e3 100644
--- a/docs/ru/docs/tutorial/extra-models.md
+++ b/docs/ru/docs/tutorial/extra-models.md
@@ -23,7 +23,7 @@
{!> ../../../docs_src/extra_models/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9 11 16 22 24 29-30 33-35 40-41"
{!> ../../../docs_src/extra_models/tutorial001.py!}
@@ -164,7 +164,7 @@ UserInDB(
{!> ../../../docs_src/extra_models/tutorial002_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9 15-16 19-20 23-24"
{!> ../../../docs_src/extra_models/tutorial002.py!}
@@ -187,7 +187,7 @@ UserInDB(
{!> ../../../docs_src/extra_models/tutorial003_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="1 14-15 18-20 33"
{!> ../../../docs_src/extra_models/tutorial003.py!}
@@ -219,7 +219,7 @@ some_variable: PlaneItem | CarItem
{!> ../../../docs_src/extra_models/tutorial004_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="1 20"
{!> ../../../docs_src/extra_models/tutorial004.py!}
@@ -239,7 +239,7 @@ some_variable: PlaneItem | CarItem
{!> ../../../docs_src/extra_models/tutorial005_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="1 8"
{!> ../../../docs_src/extra_models/tutorial005.py!}
diff --git a/docs/ru/docs/tutorial/header-params.md b/docs/ru/docs/tutorial/header-params.md
new file mode 100644
index 000000000..1be4ac707
--- /dev/null
+++ b/docs/ru/docs/tutorial/header-params.md
@@ -0,0 +1,227 @@
+# Header-ะฟะฐัะฐะผะตััั
+
+ะั ะผะพะถะตัะต ะพะฟัะตะดะตะปะธัั ะฟะฐัะฐะผะตััั ะทะฐะณะพะปะพะฒะบะฐ ัะฐะบะธะผ ะถะต ะพะฑัะฐะทะพะผ, ะบะฐะบ ะฒั ะพะฟัะตะดะตะปัะตัะต ะฟะฐัะฐะผะตััั `Query`, `Path` ะธ `Cookie`.
+
+## ะะผะฟะพัั `Header`
+
+ะกะฟะตัะฒะฐ ะธะผะฟะพััะธััะนัะต `Header`:
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="3"
+ {!> ../../../docs_src/header_params/tutorial001_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="3"
+ {!> ../../../docs_src/header_params/tutorial001_an_py39.py!}
+ ```
+
+=== "Python 3.8+"
+
+ ```Python hl_lines="3"
+ {!> ../../../docs_src/header_params/tutorial001_an.py!}
+ ```
+
+=== "Python 3.10+ ะฑะตะท Annotated"
+
+ !!! tip "ะะพะดัะบะฐะทะบะฐ"
+ ะัะตะดะฟะพััะธัะตะปัะฝะตะต ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั ะฐะฝะฝะพัะฐัะธะตะน, ะตัะปะธ ััะพ ะฒะพะทะผะพะถะฝะพ.
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/header_params/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.8+ ะฑะตะท Annotated"
+
+ !!! tip "ะะพะดัะบะฐะทะบะฐ"
+ ะัะตะดะฟะพััะธัะตะปัะฝะตะต ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั ะฐะฝะฝะพัะฐัะธะตะน, ะตัะปะธ ััะพ ะฒะพะทะผะพะถะฝะพ.
+
+ ```Python hl_lines="3"
+ {!> ../../../docs_src/header_params/tutorial001.py!}
+ ```
+
+## ะะฑััะฒะปะตะฝะธะต ะฟะฐัะฐะผะตััะพะฒ `Header`
+
+ะะฐัะตะผ ะพะฑััะฒะธัะต ะฟะฐัะฐะผะตััั ะทะฐะณะพะปะพะฒะบะฐ, ะธัะฟะพะปัะทัั ัั ะถะต ััััะบัััั, ััะพ ะธ ั `Path`, `Query` ะธ `Cookie`.
+
+ะะตัะฒะพะต ะทะฝะฐัะตะฝะธะต ัะฒะปัะตััั ะทะฝะฐัะตะฝะธะตะผ ะฟะพ ัะผะพะปัะฐะฝะธั, ะฒั ะผะพะถะตัะต ะฟะตัะตะดะฐัั ะฒัะต ะดะพะฟะพะปะฝะธัะตะปัะฝัะต ะฟะฐัะฐะผะตััั ะฒะฐะปะธะดะฐัะธะธ ะธะปะธ ะฐะฝะฝะพัะฐัะธะธ:
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/header_params/tutorial001_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/header_params/tutorial001_an_py39.py!}
+ ```
+
+=== "Python 3.8+"
+
+ ```Python hl_lines="10"
+ {!> ../../../docs_src/header_params/tutorial001_an.py!}
+ ```
+
+=== "Python 3.10+ ะฑะตะท Annotated"
+
+ !!! tip "ะะพะดัะบะฐะทะบะฐ"
+ ะัะตะดะฟะพััะธัะตะปัะฝะตะต ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั ะฐะฝะฝะพัะฐัะธะตะน, ะตัะปะธ ััะพ ะฒะพะทะผะพะถะฝะพ.
+
+ ```Python hl_lines="7"
+ {!> ../../../docs_src/header_params/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.8+ ะฑะตะท Annotated"
+
+ !!! tip "ะะพะดัะบะฐะทะบะฐ"
+ ะัะตะดะฟะพััะธัะตะปัะฝะตะต ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั ะฐะฝะฝะพัะฐัะธะตะน, ะตัะปะธ ััะพ ะฒะพะทะผะพะถะฝะพ.
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/header_params/tutorial001.py!}
+ ```
+
+!!! note "ะขะตั
ะฝะธัะตัะบะธะต ะดะตัะฐะปะธ"
+ `Header` - ััะพ "ัะพะดััะฒะตะฝะฝัะน" ะบะปะฐัั `Path`, `Query` ะธ `Cookie`. ะะฝ ัะฐะบะถะต ะฝะฐัะปะตะดัะตััั ะพั ัะพะณะพ ะถะต ะพะฑัะตะณะพ ะบะปะฐััะฐ `Param`.
+
+ ะะพ ะฟะพะผะฝะธัะต, ััะพ ะบะพะณะดะฐ ะฒั ะธะผะฟะพััะธััะตัะต `Query`, `Path`, `Header` ะธ ะดััะณะธะต ะธะท `fastapi`, ะฝะฐ ัะฐะผะพะผ ะดะตะปะต ััะพ ััะฝะบัะธะธ, ะบะพัะพััะต ะฒะพะทะฒัะฐัะฐัั ัะฟะตัะธะฐะปัะฝัะต ะบะปะฐััั.
+
+!!! info "ะะพะฟะพะปะฝะธัะตะปัะฝะฐั ะธะฝัะพัะผะฐัะธั"
+ ะงัะพะฑั ะพะฑััะฒะธัั ะทะฐะณะพะปะพะฒะบะธ, ะฒะฐะถะฝะพ ะธัะฟะพะปัะทะพะฒะฐัั `Header`, ะธะฝะฐัะต ะฟะฐัะฐะผะตััั ะธะฝัะตัะฟัะตัะธัััััั ะบะฐะบ query-ะฟะฐัะฐะผะตััั.
+
+## ะะฒัะพะผะฐัะธัะตัะบะพะต ะฟัะตะพะฑัะฐะทะพะฒะฐะฝะธะต
+
+`Header` ะพะฑะปะฐะดะฐะตั ะฝะตะฑะพะปััะพะน ะดะพะฟะพะปะฝะธัะตะปัะฝะพะน ััะฝะบัะธะพะฝะฐะปัะฝะพัััั ะฒ ะดะพะฟะพะปะฝะตะฝะธะต ะบ ัะพะผั, ััะพ ะฟัะตะดะพััะฐะฒะปััั `Path`, `Query` ะธ `Cookie`.
+
+ะะพะปััะธะฝััะฒะพ ััะฐะฝะดะฐััะฝัั
ะทะฐะณะพะปะพะฒะบะพะฒ ัะฐะทะดะตะปะตะฝั ัะธะผะฒะพะปะพะผ "ะดะตัะธั", ัะฐะบะถะต ะธะทะฒะตััะฝัะผ ะบะฐะบ "ะผะธะฝัั" (`-`).
+
+ะะพ ะฟะตัะตะผะตะฝะฝะฐั ะฒัะพะดะต `user-agent` ะฝะตะดะพะฟัััะธะผะฐ ะฒ Python.
+
+ะะพ ัะผะพะปัะฐะฝะธั `Header` ะฟัะตะพะฑัะฐะทัะตั ัะธะผะฒะพะปั ะธะผะตะฝ ะฟะฐัะฐะผะตััะพะฒ ะธะท ัะธะผะฒะพะปะฐ ะฟะพะดัะตัะบะธะฒะฐะฝะธั (`_`) ะฒ ะดะตัะธั (`-`) ะดะปั ะธะทะฒะปะตัะตะฝะธั ะธ ะดะพะบัะผะตะฝัะธัะพะฒะฐะฝะธั ะทะฐะณะพะปะพะฒะบะพะฒ.
+
+ะัะพะผะต ัะพะณะพ, HTTP-ะทะฐะณะพะปะพะฒะบะธ ะฝะต ััะฒััะฒะธัะตะปัะฝั ะบ ัะตะณะธัััั, ะฟะพััะพะผั ะฒั ะผะพะถะตัะต ะพะฑััะฒะธัั ะธั
ะฒ ััะฐะฝะดะฐััะฝะพะผ ััะธะปะต Python (ัะฐะบะถะต ะธะทะฒะตััะฝะพะผ ะบะฐะบ "snake_case").
+
+ะขะฐะบะธะผ ะพะฑัะฐะทะพะผ ะฒั ะผะพะถะตัะต ะธัะฟะพะปัะทะพะฒะฐัั `user_agent`, ะบะฐะบ ะพะฑััะฝะพ, ะฒ ะบะพะดะต Python, ะฒะผะตััะพ ัะพะณะพ, ััะพะฑั ะฒะฒะพะดะธัั ะทะฐะณะปะฐะฒะฝัะต ะฑัะบะฒั ะบะฐะบ `User_Agent` ะธะปะธ ััะพ-ัะพ ะฟะพะดะพะฑะฝะพะต.
+
+ะัะปะธ ะฟะพ ะบะฐะบะพะน-ะปะธะฑะพ ะฟัะธัะธะฝะต ะฒะฐะผ ะฝะตะพะฑั
ะพะดะธะผะพ ะพัะบะปััะธัั ะฐะฒัะพะผะฐัะธัะตัะบะพะต ะฟัะตะพะฑัะฐะทะพะฒะฐะฝะธะต ะฟะพะดัะตัะบะธะฒะฐะฝะธะน ะฒ ะดะตัะธัั, ัััะฐะฝะพะฒะธัะต ะดะปั ะฟะฐัะฐะผะตััะฐ `convert_underscores` ะฒ `Header` ะทะฝะฐัะตะฝะธะต `False`:
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="10"
+ {!> ../../../docs_src/header_params/tutorial002_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="11"
+ {!> ../../../docs_src/header_params/tutorial002_an_py39.py!}
+ ```
+
+=== "Python 3.8+"
+
+ ```Python hl_lines="12"
+ {!> ../../../docs_src/header_params/tutorial002_an.py!}
+ ```
+
+=== "Python 3.10+ ะฑะตะท Annotated"
+
+ !!! tip "ะะพะดัะบะฐะทะบะฐ"
+ ะัะตะดะฟะพััะธัะตะปัะฝะตะต ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั ะฐะฝะฝะพัะฐัะธะตะน, ะตัะปะธ ััะพ ะฒะพะทะผะพะถะฝะพ.
+
+ ```Python hl_lines="8"
+ {!> ../../../docs_src/header_params/tutorial002_py310.py!}
+ ```
+
+=== "Python 3.8+ ะฑะตะท Annotated"
+
+ !!! tip "ะะพะดัะบะฐะทะบะฐ"
+ ะัะตะดะฟะพััะธัะตะปัะฝะตะต ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั ะฐะฝะฝะพัะฐัะธะตะน, ะตัะปะธ ััะพ ะฒะพะทะผะพะถะฝะพ.
+
+ ```Python hl_lines="10"
+ {!> ../../../docs_src/header_params/tutorial002.py!}
+ ```
+
+!!! warning "ะะฝะธะผะฐะฝะธะต"
+ ะัะตะถะดะต ัะตะผ ัััะฐะฝะพะฒะธัั ะดะปั `convert_underscores` ะทะฝะฐัะตะฝะธะต `False`, ะธะผะตะนัะต ะฒ ะฒะธะดั, ััะพ ะฝะตะบะพัะพััะต HTTP-ะฟัะพะบัะธ ะธ ัะตัะฒะตัั ะทะฐะฟัะตัะฐัั ะธัะฟะพะปัะทะพะฒะฐะฝะธะต ะทะฐะณะพะปะพะฒะบะพะฒ ั ะฟะพะดัะตัะบะธะฒะฐะฝะธะตะผ.
+
+## ะะพะฒัะพััััะธะตัั ะทะฐะณะพะปะพะฒะบะธ
+
+ะััั ะฒะพะทะผะพะถะฝะพััั ะฟะพะปััะฐัั ะฝะตัะบะพะปัะบะพ ะทะฐะณะพะปะพะฒะบะพะฒ ั ะพะดะฝะธะผ ะธ ัะตะผ ะถะต ะธะผะตะฝะตะผ, ะฝะพ ัะฐะทะฝัะผะธ ะทะฝะฐัะตะฝะธัะผะธ.
+
+ะั ะผะพะถะตัะต ะพะฟัะตะดะตะปะธัั ััะธ ัะปััะฐะธ, ะธัะฟะพะปัะทัั ัะฟะธัะพะบ ะฒ ะพะฑััะฒะปะตะฝะธะธ ัะธะฟะฐ.
+
+ะั ะฟะพะปััะธัะต ะฒัะต ะทะฝะฐัะตะฝะธั ะธะท ะฟะพะฒัะพััััะตะณะพัั ะทะฐะณะพะปะพะฒะบะฐ ะฒ ะฒะธะดะต `list` Python.
+
+ะะฐะฟัะธะผะตั, ััะพะฑั ะพะฑััะฒะธัั ะทะฐะณะพะปะพะฒะพะบ `X-Token`, ะบะพัะพััะน ะผะพะถะตั ะฟะพัะฒะปััััั ะฑะพะปะตะต ะพะดะฝะพะณะพ ัะฐะทะฐ, ะฒั ะผะพะถะตัะต ะฝะฐะฟะธัะฐัั:
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/header_params/tutorial003_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/header_params/tutorial003_an_py39.py!}
+ ```
+
+=== "Python 3.8+"
+
+ ```Python hl_lines="10"
+ {!> ../../../docs_src/header_params/tutorial003_an.py!}
+ ```
+
+=== "Python 3.10+ ะฑะตะท Annotated"
+
+ !!! tip "ะะพะดัะบะฐะทะบะฐ"
+ ะัะตะดะฟะพััะธัะตะปัะฝะตะต ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั ะฐะฝะฝะพัะฐัะธะตะน, ะตัะปะธ ััะพ ะฒะพะทะผะพะถะฝะพ.
+
+ ```Python hl_lines="7"
+ {!> ../../../docs_src/header_params/tutorial003_py310.py!}
+ ```
+
+=== "Python 3.9+ ะฑะตะท Annotated"
+
+ !!! tip "ะะพะดัะบะฐะทะบะฐ"
+ ะัะตะดะฟะพััะธัะตะปัะฝะตะต ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั ะฐะฝะฝะพัะฐัะธะตะน, ะตัะปะธ ััะพ ะฒะพะทะผะพะถะฝะพ.
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/header_params/tutorial003_py39.py!}
+ ```
+
+=== "Python 3.8+ ะฑะตะท Annotated"
+
+ !!! tip "ะะพะดัะบะฐะทะบะฐ"
+ ะัะตะดะฟะพััะธัะตะปัะฝะตะต ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั ะฐะฝะฝะพัะฐัะธะตะน, ะตัะปะธ ััะพ ะฒะพะทะผะพะถะฝะพ.
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/header_params/tutorial003.py!}
+ ```
+
+ะัะปะธ ะฒั ะฒะทะฐะธะผะพะดะตะนััะฒัะตัะต ั ััะพะน *ะพะฟะตัะฐัะธะตะน ะฟััะธ*, ะพัะฟัะฐะฒะปัั ะดะฒะฐ HTTP-ะทะฐะณะพะปะพะฒะบะฐ, ัะฐะบะธั
ะบะฐะบ:
+
+```
+X-Token: foo
+X-Token: bar
+```
+
+ะัะฒะตั ะฑัะป ะฑั ัะฐะบะธะผ:
+
+```JSON
+{
+ "X-Token values": [
+ "bar",
+ "foo"
+ ]
+}
+```
+
+## ะ ะตะทัะผะต
+
+ะะฑััะฒะปัะนัะต ะทะฐะณะพะปะพะฒะบะธ ั ะฟะพะผะพััั `Header`, ะธัะฟะพะปัะทัั ัะพั ะถะต ะพะฑัะธะน ัะฐะฑะปะพะฝ, ะบะฐะบ ะฟัะธ `Query`, `Path` ะธ `Cookie`.
+
+ะ ะฝะต ะฑะตัะฟะพะบะพะนัะตัั ะพ ัะธะผะฒะพะปะฐั
ะฟะพะดัะตัะบะธะฒะฐะฝะธั ะฒ ะฒะฐัะธั
ะฟะตัะตะผะตะฝะฝัั
, **FastAPI** ะฟะพะทะฐะฑะพัะธััั ะพะฑ ะธั
ะฟัะตะพะฑัะฐะทะพะฒะฐะฝะธะธ.
diff --git a/docs/ru/docs/tutorial/path-operation-configuration.md b/docs/ru/docs/tutorial/path-operation-configuration.md
index 013903add..db99409f4 100644
--- a/docs/ru/docs/tutorial/path-operation-configuration.md
+++ b/docs/ru/docs/tutorial/path-operation-configuration.md
@@ -25,7 +25,7 @@
{!> ../../../docs_src/path_operation_configuration/tutorial001_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="3 17"
{!> ../../../docs_src/path_operation_configuration/tutorial001.py!}
@@ -54,7 +54,7 @@
{!> ../../../docs_src/path_operation_configuration/tutorial002_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="17 22 27"
{!> ../../../docs_src/path_operation_configuration/tutorial002.py!}
@@ -92,7 +92,7 @@
{!> ../../../docs_src/path_operation_configuration/tutorial003_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="20-21"
{!> ../../../docs_src/path_operation_configuration/tutorial003.py!}
@@ -116,7 +116,7 @@
{!> ../../../docs_src/path_operation_configuration/tutorial004_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="19-27"
{!> ../../../docs_src/path_operation_configuration/tutorial004.py!}
@@ -142,7 +142,7 @@
{!> ../../../docs_src/path_operation_configuration/tutorial005_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="21"
{!> ../../../docs_src/path_operation_configuration/tutorial005.py!}
diff --git a/docs/ru/docs/tutorial/path-params-numeric-validations.md b/docs/ru/docs/tutorial/path-params-numeric-validations.md
index 0d034ef34..bd2c29d0a 100644
--- a/docs/ru/docs/tutorial/path-params-numeric-validations.md
+++ b/docs/ru/docs/tutorial/path-params-numeric-validations.md
@@ -18,7 +18,7 @@
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="3-4"
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
@@ -33,7 +33,7 @@
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
@@ -67,7 +67,7 @@
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="11"
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
@@ -82,7 +82,7 @@
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
@@ -117,7 +117,7 @@
ะะพััะพะผั ะฒั ะผะพะถะตัะต ะพะฟัะตะดะตะปะธัั ััะฝะบัะธั ัะฐะบ:
-=== "Python 3.6 ะฑะตะท Annotated"
+=== "Python 3.8 ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
@@ -134,7 +134,7 @@
{!> ../../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9"
{!> ../../../docs_src/path_params_numeric_validations/tutorial002_an.py!}
@@ -174,7 +174,7 @@ Python ะฝะต ะฑัะดะตั ะฝะธัะตะณะพ ะดะตะปะฐัั ั `*`, ะฝะพ ะพะฝ ะฑัะดะตั ะท
{!> ../../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9"
{!> ../../../docs_src/path_params_numeric_validations/tutorial003_an.py!}
@@ -192,13 +192,13 @@ Python ะฝะต ะฑัะดะตั ะฝะธัะตะณะพ ะดะตะปะฐัั ั `*`, ะฝะพ ะพะฝ ะฑัะดะตั ะท
{!> ../../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9"
{!> ../../../docs_src/path_params_numeric_validations/tutorial004_an.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
@@ -220,13 +220,13 @@ Python ะฝะต ะฑัะดะตั ะฝะธัะตะณะพ ะดะตะปะฐัั ั `*`, ะฝะพ ะพะฝ ะฑัะดะตั ะท
{!> ../../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9"
{!> ../../../docs_src/path_params_numeric_validations/tutorial005_an.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
@@ -251,13 +251,13 @@ Python ะฝะต ะฑัะดะตั ะฝะธัะตะณะพ ะดะตะปะฐัั ั `*`, ะฝะพ ะพะฝ ะฑัะดะตั ะท
{!> ../../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="12"
{!> ../../../docs_src/path_params_numeric_validations/tutorial006_an.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
diff --git a/docs/ru/docs/tutorial/query-params-str-validations.md b/docs/ru/docs/tutorial/query-params-str-validations.md
index 68042db63..cc826b871 100644
--- a/docs/ru/docs/tutorial/query-params-str-validations.md
+++ b/docs/ru/docs/tutorial/query-params-str-validations.md
@@ -10,7 +10,7 @@
{!> ../../../docs_src/query_params_str_validations/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9"
{!> ../../../docs_src/query_params_str_validations/tutorial001.py!}
@@ -42,7 +42,7 @@ Query-ะฟะฐัะฐะผะตัั `q` ะธะผะตะตั ัะธะฟ `Union[str, None]` (ะธะปะธ `str | N
{!> ../../../docs_src/query_params_str_validations/tutorial002_an_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
ะ ะฒะตััะธัั
Python ะฝะธะถะต Python 3.9 `Annotation` ะธะผะฟะพััะธััะตััั ะธะท `typing_extensions`.
@@ -66,7 +66,7 @@ Query-ะฟะฐัะฐะผะตัั `q` ะธะผะตะตั ัะธะฟ `Union[str, None]` (ะธะปะธ `str | N
q: str | None = None
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python
q: Union[str, None] = None
@@ -80,7 +80,7 @@ Query-ะฟะฐัะฐะผะตัั `q` ะธะผะตะตั ัะธะฟ `Union[str, None]` (ะธะปะธ `str | N
q: Annotated[str | None] = None
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python
q: Annotated[Union[str, None]] = None
@@ -100,7 +100,7 @@ Query-ะฟะฐัะฐะผะตัั `q` ะธะผะตะตั ัะธะฟ `Union[str, None]` (ะธะปะธ `str | N
{!> ../../../docs_src/query_params_str_validations/tutorial002_an_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="10"
{!> ../../../docs_src/query_params_str_validations/tutorial002_an.py!}
@@ -131,7 +131,7 @@ Query-ะฟะฐัะฐะผะตัั `q` ะธะผะตะตั ัะธะฟ `Union[str, None]` (ะธะปะธ `str | N
{!> ../../../docs_src/query_params_str_validations/tutorial002_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9"
{!> ../../../docs_src/query_params_str_validations/tutorial002.py!}
@@ -244,7 +244,7 @@ q: str = Query(default="rick")
{!> ../../../docs_src/query_params_str_validations/tutorial003_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="11"
{!> ../../../docs_src/query_params_str_validations/tutorial003_an.py!}
@@ -259,7 +259,7 @@ q: str = Query(default="rick")
{!> ../../../docs_src/query_params_str_validations/tutorial003_py310.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
@@ -284,7 +284,7 @@ q: str = Query(default="rick")
{!> ../../../docs_src/query_params_str_validations/tutorial004_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="12"
{!> ../../../docs_src/query_params_str_validations/tutorial004_an.py!}
@@ -299,7 +299,7 @@ q: str = Query(default="rick")
{!> ../../../docs_src/query_params_str_validations/tutorial004_py310.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
@@ -330,13 +330,13 @@ q: str = Query(default="rick")
{!> ../../../docs_src/query_params_str_validations/tutorial005_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="8"
{!> ../../../docs_src/query_params_str_validations/tutorial005_an.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
@@ -384,13 +384,13 @@ q: Union[str, None] = None
{!> ../../../docs_src/query_params_str_validations/tutorial006_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="8"
{!> ../../../docs_src/query_params_str_validations/tutorial006_an.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
@@ -414,13 +414,13 @@ q: Union[str, None] = None
{!> ../../../docs_src/query_params_str_validations/tutorial006b_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="8"
{!> ../../../docs_src/query_params_str_validations/tutorial006b_an.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
@@ -454,7 +454,7 @@ q: Union[str, None] = None
{!> ../../../docs_src/query_params_str_validations/tutorial006c_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="10"
{!> ../../../docs_src/query_params_str_validations/tutorial006c_an.py!}
@@ -469,7 +469,7 @@ q: Union[str, None] = None
{!> ../../../docs_src/query_params_str_validations/tutorial006c_py310.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
@@ -491,13 +491,13 @@ q: Union[str, None] = None
{!> ../../../docs_src/query_params_str_validations/tutorial006d_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="2 9"
{!> ../../../docs_src/query_params_str_validations/tutorial006d_an.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
@@ -527,7 +527,7 @@ q: Union[str, None] = None
{!> ../../../docs_src/query_params_str_validations/tutorial011_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="10"
{!> ../../../docs_src/query_params_str_validations/tutorial011_an.py!}
@@ -551,7 +551,7 @@ q: Union[str, None] = None
{!> ../../../docs_src/query_params_str_validations/tutorial011_py39.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
@@ -596,7 +596,7 @@ http://localhost:8000/items/?q=foo&q=bar
{!> ../../../docs_src/query_params_str_validations/tutorial012_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="10"
{!> ../../../docs_src/query_params_str_validations/tutorial012_an.py!}
@@ -611,7 +611,7 @@ http://localhost:8000/items/?q=foo&q=bar
{!> ../../../docs_src/query_params_str_validations/tutorial012_py39.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
@@ -647,13 +647,13 @@ http://localhost:8000/items/
{!> ../../../docs_src/query_params_str_validations/tutorial013_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="8"
{!> ../../../docs_src/query_params_str_validations/tutorial013_an.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
@@ -692,7 +692,7 @@ http://localhost:8000/items/
{!> ../../../docs_src/query_params_str_validations/tutorial007_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="11"
{!> ../../../docs_src/query_params_str_validations/tutorial007_an.py!}
@@ -707,7 +707,7 @@ http://localhost:8000/items/
{!> ../../../docs_src/query_params_str_validations/tutorial007_py310.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
@@ -730,7 +730,7 @@ http://localhost:8000/items/
{!> ../../../docs_src/query_params_str_validations/tutorial008_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="15"
{!> ../../../docs_src/query_params_str_validations/tutorial008_an.py!}
@@ -741,11 +741,11 @@ http://localhost:8000/items/
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
- ```Python hl_lines="12"
+ ```Python hl_lines="11"
{!> ../../../docs_src/query_params_str_validations/tutorial008_py310.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
@@ -784,7 +784,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
{!> ../../../docs_src/query_params_str_validations/tutorial009_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="10"
{!> ../../../docs_src/query_params_str_validations/tutorial009_an.py!}
@@ -799,7 +799,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
{!> ../../../docs_src/query_params_str_validations/tutorial009_py310.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
@@ -828,7 +828,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
{!> ../../../docs_src/query_params_str_validations/tutorial010_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="20"
{!> ../../../docs_src/query_params_str_validations/tutorial010_an.py!}
@@ -839,11 +839,11 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
- ```Python hl_lines="17"
+ ```Python hl_lines="16"
{!> ../../../docs_src/query_params_str_validations/tutorial010_py310.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
@@ -872,7 +872,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
{!> ../../../docs_src/query_params_str_validations/tutorial014_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="11"
{!> ../../../docs_src/query_params_str_validations/tutorial014_an.py!}
@@ -887,7 +887,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
{!> ../../../docs_src/query_params_str_validations/tutorial014_py310.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated` ะตัะปะธ ะฒะพะทะผะพะถะฝะพ.
diff --git a/docs/ru/docs/tutorial/query-params.md b/docs/ru/docs/tutorial/query-params.md
index 68333ec56..6e885cb65 100644
--- a/docs/ru/docs/tutorial/query-params.md
+++ b/docs/ru/docs/tutorial/query-params.md
@@ -69,7 +69,7 @@ http://127.0.0.1:8000/items/?skip=20
{!> ../../../docs_src/query_params/tutorial002_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9"
{!> ../../../docs_src/query_params/tutorial002.py!}
@@ -90,7 +90,7 @@ http://127.0.0.1:8000/items/?skip=20
{!> ../../../docs_src/query_params/tutorial003_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9"
{!> ../../../docs_src/query_params/tutorial003.py!}
@@ -143,7 +143,7 @@ http://127.0.0.1:8000/items/foo?short=yes
{!> ../../../docs_src/query_params/tutorial004_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="8 10"
{!> ../../../docs_src/query_params/tutorial004.py!}
@@ -209,7 +209,7 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
{!> ../../../docs_src/query_params/tutorial006_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="10"
{!> ../../../docs_src/query_params/tutorial006.py!}
diff --git a/docs/ru/docs/tutorial/request-forms.md b/docs/ru/docs/tutorial/request-forms.md
index a20cf78e0..0fc9e4eda 100644
--- a/docs/ru/docs/tutorial/request-forms.md
+++ b/docs/ru/docs/tutorial/request-forms.md
@@ -17,13 +17,13 @@
{!> ../../../docs_src/request_forms/tutorial001_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="1"
{!> ../../../docs_src/request_forms/tutorial001_an.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั 'Annotated' ะฒะตััะธั, ะตัะปะธ ััะพ ะฒะพะทะผะพะถะฝะพ.
@@ -42,13 +42,13 @@
{!> ../../../docs_src/request_forms/tutorial001_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="8"
{!> ../../../docs_src/request_forms/tutorial001_an.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั 'Annotated' ะฒะตััะธั, ะตัะปะธ ััะพ ะฒะพะทะผะพะถะฝะพ.
diff --git a/docs/ru/docs/tutorial/response-model.md b/docs/ru/docs/tutorial/response-model.md
index c5e111790..38b45e2a5 100644
--- a/docs/ru/docs/tutorial/response-model.md
+++ b/docs/ru/docs/tutorial/response-model.md
@@ -16,7 +16,7 @@ FastAPI ะฟะพะทะฒะพะปัะตั ะธัะฟะพะปัะทะพะฒะฐัั **ะฐะฝะฝะพัะฐัะธะธ ัะธะฟ
{!> ../../../docs_src/response_model/tutorial001_01_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="18 23"
{!> ../../../docs_src/response_model/tutorial001_01.py!}
@@ -65,7 +65,7 @@ FastAPI ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐัั ััะพั ะฒะพะทะฒัะฐัะฐะตะผัะน ั
{!> ../../../docs_src/response_model/tutorial001_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="17 22 24-27"
{!> ../../../docs_src/response_model/tutorial001.py!}
@@ -101,7 +101,7 @@ FastAPI ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐัั ะทะฝะฐัะตะฝะธะต `response_model` ะด
{!> ../../../docs_src/response_model/tutorial002_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9 11"
{!> ../../../docs_src/response_model/tutorial002.py!}
@@ -120,7 +120,7 @@ FastAPI ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐัั ะทะฝะฐัะตะฝะธะต `response_model` ะด
{!> ../../../docs_src/response_model/tutorial002_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="18"
{!> ../../../docs_src/response_model/tutorial002.py!}
@@ -145,7 +145,7 @@ FastAPI ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐัั ะทะฝะฐัะตะฝะธะต `response_model` ะด
{!> ../../../docs_src/response_model/tutorial003_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9 11 16"
{!> ../../../docs_src/response_model/tutorial003.py!}
@@ -159,7 +159,7 @@ FastAPI ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐัั ะทะฝะฐัะตะฝะธะต `response_model` ะด
{!> ../../../docs_src/response_model/tutorial003_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="24"
{!> ../../../docs_src/response_model/tutorial003.py!}
@@ -173,7 +173,7 @@ FastAPI ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐัั ะทะฝะฐัะตะฝะธะต `response_model` ะด
{!> ../../../docs_src/response_model/tutorial003_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="22"
{!> ../../../docs_src/response_model/tutorial003.py!}
@@ -207,7 +207,7 @@ FastAPI ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐัั ะทะฝะฐัะตะฝะธะต `response_model` ะด
{!> ../../../docs_src/response_model/tutorial003_01_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9-13 15-16 20"
{!> ../../../docs_src/response_model/tutorial003_01.py!}
@@ -283,7 +283,7 @@ FastAPI ัะพะฒะผะตััะฝะพ ั Pydantic ะฒัะฟะพะปะฝะธั ะฝะตะบะพัะพััั ะผะฐ
{!> ../../../docs_src/response_model/tutorial003_04_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="10"
{!> ../../../docs_src/response_model/tutorial003_04.py!}
@@ -305,7 +305,7 @@ FastAPI ัะพะฒะผะตััะฝะพ ั Pydantic ะฒัะฟะพะปะฝะธั ะฝะตะบะพัะพััั ะผะฐ
{!> ../../../docs_src/response_model/tutorial003_05_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9"
{!> ../../../docs_src/response_model/tutorial003_05.py!}
@@ -329,7 +329,7 @@ FastAPI ัะพะฒะผะตััะฝะพ ั Pydantic ะฒัะฟะพะปะฝะธั ะฝะตะบะพัะพััั ะผะฐ
{!> ../../../docs_src/response_model/tutorial004_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="11 13-14"
{!> ../../../docs_src/response_model/tutorial004.py!}
@@ -359,7 +359,7 @@ FastAPI ัะพะฒะผะตััะฝะพ ั Pydantic ะฒัะฟะพะปะฝะธั ะฝะตะบะพัะพััั ะผะฐ
{!> ../../../docs_src/response_model/tutorial004_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="24"
{!> ../../../docs_src/response_model/tutorial004.py!}
@@ -446,7 +446,7 @@ FastAPI ะดะพััะฐัะพัะฝะพ ัะผะตะฝ (ะฝะฐ ัะฐะผะพะผ ะดะตะปะต, ััะพ ะทะฐัะป
{!> ../../../docs_src/response_model/tutorial005_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="31 37"
{!> ../../../docs_src/response_model/tutorial005.py!}
@@ -467,7 +467,7 @@ FastAPI ะดะพััะฐัะพัะฝะพ ัะผะตะฝ (ะฝะฐ ัะฐะผะพะผ ะดะตะปะต, ััะพ ะทะฐัะป
{!> ../../../docs_src/response_model/tutorial006_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="31 37"
{!> ../../../docs_src/response_model/tutorial006.py!}
diff --git a/docs/ru/docs/tutorial/schema-extra-example.md b/docs/ru/docs/tutorial/schema-extra-example.md
index a0363b9ba..a13ab5935 100644
--- a/docs/ru/docs/tutorial/schema-extra-example.md
+++ b/docs/ru/docs/tutorial/schema-extra-example.md
@@ -14,7 +14,7 @@
{!> ../../../docs_src/schema_extra_example/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="15-23"
{!> ../../../docs_src/schema_extra_example/tutorial001.py!}
@@ -39,7 +39,7 @@
{!> ../../../docs_src/schema_extra_example/tutorial002_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="4 10-13"
{!> ../../../docs_src/schema_extra_example/tutorial002.py!}
@@ -78,7 +78,7 @@
{!> ../../../docs_src/schema_extra_example/tutorial003_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="23-28"
{!> ../../../docs_src/schema_extra_example/tutorial003_an.py!}
@@ -93,7 +93,7 @@
{!> ../../../docs_src/schema_extra_example/tutorial003_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip ะะฐะผะตัะบะฐ
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated`, ะตัะปะธ ััะพ ะฒะพะทะผะพะถะฝะพ.
@@ -133,7 +133,7 @@
{!> ../../../docs_src/schema_extra_example/tutorial004_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="24-50"
{!> ../../../docs_src/schema_extra_example/tutorial004_an.py!}
@@ -148,7 +148,7 @@
{!> ../../../docs_src/schema_extra_example/tutorial004_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip ะะฐะผะตัะบะฐ
ะ ะตะบะพะผะตะฝะดัะตััั ะธัะฟะพะปัะทะพะฒะฐัั ะฒะตััะธั ั `Annotated`, ะตัะปะธ ััะพ ะฒะพะทะผะพะถะฝะพ.
diff --git a/docs/ru/docs/tutorial/testing.md b/docs/ru/docs/tutorial/testing.md
index 3f9005112..ca47a6f51 100644
--- a/docs/ru/docs/tutorial/testing.md
+++ b/docs/ru/docs/tutorial/testing.md
@@ -122,7 +122,7 @@
{!> ../../../docs_src/app_testing/app_b_an_py39/main.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python
{!> ../../../docs_src/app_testing/app_b_an/main.py!}
@@ -137,7 +137,7 @@
{!> ../../../docs_src/app_testing/app_b_py310/main.py!}
```
-=== "Python 3.6+ ะฑะตะท Annotated"
+=== "Python 3.8+ ะฑะตะท Annotated"
!!! tip "ะะพะดัะบะฐะทะบะฐ"
ะะพ ะฒะพะทะผะพะถะฝะพััะธ ะธัะฟะพะปัะทัะนัะต ะฒะตััะธั ั `Annotated`.
diff --git a/docs/tr/docs/features.md b/docs/tr/docs/features.md
index f8220fb58..8b143ffe7 100644
--- a/docs/tr/docs/features.md
+++ b/docs/tr/docs/features.md
@@ -27,7 +27,7 @@ OpenAPI standartlarฤฑna dayalฤฑ olan bir framework olarak, geliลtiricilerin bir
### Sadece modern Python
-Tamamiyle standartlar **Python 3.6**'nฤฑn type hintlerine dayanฤฑyor (Pydantic'in sayesinde). Yeni bir syntax รถฤrenmene gerek yok. Sadece modern Python.
+Tamamiyle standartlar **Python 3.8**'nฤฑn type hintlerine dayanฤฑyor (Pydantic'in sayesinde). Yeni bir syntax รถฤrenmene gerek yok. Sadece modern Python.
Eฤer Python type hintlerini bilmiyorsan veya bir hatฤฑrlatmaya ihtiyacฤฑn var ise(FastAPI kullanmasan bile) ลu iki dakikalฤฑk kรผรงรผk bilgilendirici iรงeriฤe bir gรถz at: [Python Types](python-types.md){.internal-link target=_blank}.
diff --git a/docs/tr/docs/index.md b/docs/tr/docs/index.md
index e74efbc2f..e61f5b82c 100644
--- a/docs/tr/docs/index.md
+++ b/docs/tr/docs/index.md
@@ -24,7 +24,7 @@
---
-FastAPI, Python 3.6+'nฤฑn standart type hintlerine dayanan modern ve hฤฑzlฤฑ (yรผksek performanslฤฑ) API'lar oluลturmak iรงin kullanฤฑlabilecek web framework'รผ.
+FastAPI, Python 3.8+'nฤฑn standart type hintlerine dayanan modern ve hฤฑzlฤฑ (yรผksek performanslฤฑ) API'lar oluลturmak iรงin kullanฤฑlabilecek web framework'รผ.
Ana รถzellikleri:
@@ -115,7 +115,7 @@ Eฤer API yerine komut satฤฑrฤฑ uygulamasฤฑ
## Gereksinimler
-Python 3.7+
+Python 3.8+
FastAPI iki devin omuzlarฤฑ รผstรผnde duruyor:
@@ -331,7 +331,7 @@ Type-hinting iลlemini Python dilindeki standart veri tipleri ile yapabilirsin
Yeni bir syntax'e alฤฑลmana gerek yok, metodlar ve classlar zaten spesifik kรผtรผphanelere ait.
-Sadece standart **Python 3.6+**.
+Sadece standart **Python 3.8+**.
รrnek olarak, `int` tanฤฑmlamak iรงin:
diff --git a/docs/uk/docs/alternatives.md b/docs/uk/docs/alternatives.md
new file mode 100644
index 000000000..e71257976
--- /dev/null
+++ b/docs/uk/docs/alternatives.md
@@ -0,0 +1,412 @@
+# ะะปััะตัะฝะฐัะธะฒะธ, ะฝะฐัั
ะฝะตะฝะฝั ัะฐ ะฟะพััะฒะฝัะฝะฝั
+
+ะฉะพ ะฝะฐะดะธั
ะฝัะปะพ ะฝะฐ ััะฒะพัะตะฝะฝั **FastAPI**, ัะบะธะน ะฒัะฝ ั ะฟะพััะฝัะฝะฝั ะท ัะฝัะธะผะธ ะฐะปััะตัะฝะฐัะธะฒะฐะผะธ ัะฐ ัะพะณะพ ะฒัะฝ ั ะฝะธั
ะฝะฐะฒัะธะฒัั.
+
+## ะัััะฟ
+
+**FastAPI** ะฝะต ััะฝัะฒะฐะปะพ ะฑ, ัะบะฑะธ ะฝะต ะฟะพะฟะตัะตะดะฝั ัะพะฑะพัะธ ัะฝัะธั
.
+
+ะ ะฐะฝััะต ะฑัะปะพ ััะฒะพัะตะฝะพ ะฑะฐะณะฐัะพ ัะฝััััะผะตะฝััะฒ, ัะบั ะฝะฐะดะธั
ะฝัะปะธ ะฝะฐ ะนะพะณะพ ััะฒะพัะตะฝะฝั.
+
+ะฏ ะบัะปัะบะฐ ัะพะบัะฒ ัะฝะธะบะฐะฒ ััะฒะพัะตะฝะฝั ะฝะพะฒะพะณะพ ััะตะนะผะฒะพัะบั. ะกะฟะพัะฐัะบั ั ัะฟัะพะฑัะฒะฐะฒ ะฒะธัััะธัะธ ะฒัั ััะฝะบััั, ะพั
ะพะฟะปะตะฝั **FastAPI**, ะฒะธะบะพัะธััะพะฒัััะธ ะฑะฐะณะฐัะพ ััะทะฝะธั
ััะตะนะผะฒะพัะบัะฒ, ะฟะปะฐะณัะฝัะฒ ัะฐ ัะฝััััะผะตะฝััะฒ.
+
+ะะปะต ะฒ ัะบะธะนัั ะผะพะผะตะฝั ะฝะต ะฑัะปะพ ัะฝัะพะณะพ ะฒะธั
ะพะดั, ะพะบััะผ ััะฒะพัะตะฝะฝั ัะพะณะพัั, ัะพ ะฝะฐะดะฐะฒะฐะปะพ ะฑ ััั ัั ััะฝะบััั, ะฒะทัะฒัะธ ะฝะฐะนะบัะฐัั ัะดะตั ะท ะฟะพะฟะตัะตะดะฝัั
ัะฝััััะผะตะฝััะฒ ั ะฟะพัะดะฝะฐะฒัะธ ัั
ะฝะฐะนะบัะฐัะธะผ ัะธะฝะพะผ, ะฒะธะบะพัะธััะพะฒัััะธ ะผะพะฒะฝั ััะฝะบััั, ัะบั ะฝะฐะฒััั ะฝะต ะฑัะปะธ ะดะพัััะฟะฝั ัะฐะฝััะต (Python 3.6+ ะฟัะดะบะฐะทะบะธ ัะธะฟัะฒ).
+
+## ะะพะฟะตัะตะดะฝั ัะฝััััะผะตะฝัะธ
+
+### Django
+
+ะฆะต ะฝะฐะนะฟะพะฟัะปััะฝััะธะน ััะตะนะผะฒะพัะบ Python, ัะบะธะน ะบะพัะธัััััััั ัะธัะพะบะพั ะดะพะฒััะพั. ะัะฝ ะฒะธะบะพัะธััะพะฒัััััั ะดะปั ััะฒะพัะตะฝะฝั ัะฐะบะธั
ัะธััะตะผ, ัะบ Instagram.
+
+ะัะฝ ะฒัะดะฝะพัะฝะพ ัััะฝะพ ะฟะพะฒโัะทะฐะฝะธะน ะท ัะตะปัััะนะฝะธะผะธ ะฑะฐะทะฐะผะธ ะดะฐะฝะธั
(ะฝะฐะฟัะธะบะปะฐะด, MySQL ะฐะฑะพ PostgreSQL), ัะพะผั ะผะฐัะธ ะฑะฐะทั ะดะฐะฝะธั
NoSQL (ะฝะฐะฟัะธะบะปะฐะด, Couchbase, MongoDB, Cassandra ัะพัะพ) ัะบ ะพัะฝะพะฒะฝะธะน ะผะตั
ะฐะฝัะทะผ ะทะฑะตััะณะฐะฝะฝั ะฝะต ะดัะถะต ะฟัะพััะพ.
+
+ะัะฝ ะฑัะฒ ััะฒะพัะตะฝะธะน ะดะปั ััะฒะพัะตะฝะฝั HTML ั ัะตัะฒะตัะฝัะน ัะฐััะธะฝั, ะฐ ะฝะต ะดะปั ััะฒะพัะตะฝะฝั API, ัะบั ะฒะธะบะพัะธััะพะฒัััััั ัััะฐัะฝะธะผ ัะฝัะตััะตะนัะพะผ (ัะบ-ะพั React, Vue.js ั Angular) ะฐะฑะพ ัะฝัะธะผะธ ัะธััะตะผะฐะผะธ (ัะบ-ะพั IoT ะฟัะธัััะพั), ัะบั ัะฟัะปะบัััััั ะท ะฝะธะผ.
+
+### Django REST Framework
+
+ะคัะตะนะผะฒะพัะบ Django REST ะฑัะฒ ััะฒะพัะตะฝะธะน ัะบ ะณะฝััะบะธะน ัะฝััััะผะตะฝัะฐััะน ะดะปั ััะฒะพัะตะฝะฝั ะฒะตะฑ-ัะฝัะตััะตะนััะฒ API ะฒะธะบะพัะธััะพะฒัััะธ Django ะฒ ะพัะฝะพะฒั, ัะพะฑ ะฟะพะบัะฐัะธัะธ ะนะพะณะพ ะผะพะถะปะธะฒะพััั API.
+
+ะะพะณะพ ะฒะธะบะพัะธััะพะฒัััั ะฑะฐะณะฐัะพ ะบะพะผะฟะฐะฝัะน, ะฒะบะปััะฐััะธ Mozilla, Red Hat ั Eventbrite.
+
+ะฆะต ะฑัะฒ ะพะดะธะฝ ัะท ะฟะตััะธั
ะฟัะธะบะปะฐะดัะฒ **ะฐะฒัะพะผะฐัะธัะฝะพั ะดะพะบัะผะตะฝัะฐััั API**, ั ัะฐะผะต ัะต ะฑัะปะฐ ะพะดะฝะฐ ะท ะฟะตััะธั
ัะดะตะน, ัะบะฐ ะฝะฐะดะธั
ะฝัะปะฐ ะฝะฐ ยซะฟะพััะบยป **FastAPI**.
+
+!!! ะัะธะผััะบะฐ
+ Django REST Framework ััะฒะพัะธะฒ ะขะพะผ ะััััั. ะขะพะน ัะฐะผะธะน ัะฒะพัะตัั Starlette ั Uvicorn, ะฝะฐ ัะบะธั
ะฑะฐะทัััััั **FastAPI**.
+
+
+!!! ะะตัะตะณะปัะฝััะต "ะะฐะดะธั
ะฝัะปะพ **FastAPI** ะฝะฐ"
+ ะะฐัะธ ะฐะฒัะพะผะฐัะธัะฝะธะน ะฒะตะฑ-ัะฝัะตััะตะนั ะดะพะบัะผะตะฝัะฐััั API.
+
+### Flask
+
+Flask โ ัะต ยซะผัะบัะพััะตะนะผะฒะพัะบยป, ะฒัะฝ ะฝะต ะฒะบะปััะฐั ัะฝัะตะณัะฐััั ะฑะฐะทะธ ะดะฐะฝะธั
, ะฐ ัะฐะบะพะถ ะฑะฐะณะฐัะพ ัะตัะตะน, ัะบั ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ ั ะฒ Django.
+
+ะฆั ะฟัะพััะพัะฐ ัะฐ ะณะฝััะบัััั ะดะพะทะฒะพะปัััั ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ะฑะฐะทะธ ะดะฐะฝะธั
NoSQL ัะบ ะพัะฝะพะฒะฝั ัะธััะตะผั ะทะฑะตััะณะฐะฝะฝั ะดะฐะฝะธั
.
+
+ะัะบัะปัะบะธ ะฒัะฝ ะดัะถะต ะฟัะพััะธะน, ะฒัะฝ ะฟะพััะฒะฝัะฝะพ ะปะตะณะบะธะน ัะฐ ัะฝััััะธะฒะฝะธะน ะดะปั ะพัะฒะพัะฝะฝั, ั
ะพัะฐ ะฒ ะดะตัะบะธั
ะผะพะผะตะฝัะฐั
ะดะพะบัะผะตะฝัะฐััั ััะฐั ะดะตัะพ ัะตั
ะฝััะฝะพั.
+
+ะัะฝ ัะฐะบะพะถ ะทะฐะทะฒะธัะฐะน ะฒะธะบะพัะธััะพะฒัััััั ะดะปั ัะฝัะธั
ะฟัะพะณัะฐะผ, ัะบะธะผ ะฝะต ะพะฑะพะฒโัะทะบะพะฒะพ ะฟะพัััะฑะฝะฐ ะฑะฐะทะฐ ะดะฐะฝะธั
, ะบะตััะฒะฐะฝะฝั ะบะพัะธัััะฒะฐัะฐะผะธ ะฐะฑะพ ะฑัะดั-ัะบะฐ ะท ะฑะฐะณะฐััะพั
ััะฝะบััะน, ัะบั ั ะฟะพะฟะตัะตะดะฝัะพ ะฒะฑัะดะพะฒะฐะฝะธะผะธ ะฒ Django. ะฅะพัะฐ ะฑะฐะณะฐัะพ ะท ัะธั
ััะฝะบััะน ะผะพะถะฝะฐ ะดะพะดะฐัะธ ะทะฐ ะดะพะฟะพะผะพะณะพั ะฟะปะฐะณัะฝัะฒ.
+
+ะัะดะพะบัะตะผะปะตะฝะฝั ัะฐััะธะฝ ะฑัะปะพ ะบะปััะพะฒะพั ะพัะพะฑะปะธะฒัััั, ัะบั ั ั
ะพััะฒ ะทะฑะตัะตะณัะธ, ะฟัะธ ััะพะผั ะทะฐะปะธัะฐััะธัั ยซะผัะบัะพััะตะนะผะฒะพัะบะพะผยป, ัะบะธะน ะผะพะถะฝะฐ ัะพะทัะธัะธัะธ, ัะพะฑ ะพั
ะพะฟะธัะธ ัะฐะผะต ัะต, ัะพ ะฟะพัััะฑะฝะพ.
+
+ะัะฐั
ะพะฒัััะธ ะฟัะพััะพัั Flask, ะฒัะฝ ะทะดะฐะฒะฐะฒัั ั
ะพัะพัะธะผ ะฟัะดั
ะพะดะพะผ ะดะปั ััะฒะพัะตะฝะฝั API. ะะฐัััะฟะฝะธะผ, ัะพ ะทะฝะฐะนัะพะฒ, ะฑัะฒ ยซDjango REST Frameworkยป ะดะปั Flask.
+
+!!! ะะตัะตะณะปัะฝัะต "ะะฐะดะธั
ะฝัะปะพ **FastAPI** ะฝะฐ"
+ ะััะธ ะผัะบัะพััะตะนะผะพะฒะพัะบะพะผ. ะัะพะฑะธัะธ ะปะตะณะบะธะผ ะบะพะผะฑัะฝัะฒะฐะฝะฝั ัะฐ ะฟะพัะดะฝะฐะฝะฝั ะฝะตะพะฑั
ัะดะฝะธั
ัะฝััััะผะตะฝััะฒ ัะฐ ัะฐััะธะฝ.
+
+ ะะฐัะธ ะฟัะพััั ัะฐ ะปะตะณะบั ั ะฒะธะบะพัะธััะฐะฝะฝั ัะธััะตะผั ะผะฐัััััะธะทะฐััั.
+
+
+### Requests
+
+**FastAPI** ะฝะฐัะฟัะฐะฒะดั ะฝะต ั ะฐะปััะตัะฝะฐัะธะฒะพั **Requests**. ะกัะตัะฐ ัั
ะทะฐััะพััะฒะฐะฝะฝั ะดัะถะต ััะทะฝะฐ.
+
+ะะฐัะฟัะฐะฒะดั ััะปะบะพะผ ะทะฒะธัะฝะฐ ััั ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ Requests *ะฒัะตัะตะดะธะฝั* ะฟัะพะณัะฐะผะธ FastAPI.
+
+ะะปะต ะฒัะต ะถ FastAPI ัะตัะฟะฐะฒ ะฝะฐัั
ะฝะตะฝะฝั ะท Requests.
+
+**Requests** โ ัะต ะฑัะฑะปัะพัะตะบะฐ ะดะปั *ะฒะทะฐัะผะพะดัั* ะท API (ัะบ ะบะปััะฝั), ะฐ **FastAPI** โ ัะต ะฑัะฑะปัะพัะตะบะฐ ะดะปั *ััะฒะพัะตะฝะฝั* API (ัะบ ัะตัะฒะตั).
+
+ะะพะฝะธ ะฑัะปัั-ะผะตะฝั ะทะฝะฐั
ะพะดััััั ะฝะฐ ะฟัะพัะธะปะตะถะฝะธั
ะบัะฝััั
, ะดะพะฟะพะฒะฝัััะธ ะพะดะฝะฐ ะพะดะฝั.
+
+Requests ะผะฐััั ะดัะถะต ะฟัะพััะธะน ัะฐ ัะฝััััะธะฒะฝะพ ะทัะพะทัะผัะปะธะน ะดะธะทะฐะนะฝ, ะดัะถะต ะฟัะพััะธะน ั ะฒะธะบะพัะธััะฐะฝะฝั, ะท ัะพะทัะผะฝะธะผะธ ะฟะฐัะฐะผะตััะฐะผะธ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ. ะะปะต ะฒ ัะพะน ะถะต ัะฐั ะฒัะฝ ะดัะถะต ะฟะพััะถะฝะธะน ั ะฝะฐะปะฐััะพะฒัััััั.
+
+ะัั ัะพะผั, ัะบ ัะบะฐะทะฐะฝะพ ะฝะฐ ะพััััะนะฝะพะผั ัะฐะนัั:
+
+> Requests ั ะพะดะฝะธะผ ัะท ะฝะฐะนะฑัะปัั ะทะฐะฒะฐะฝัะฐะถัะฒะฐะฝะธั
ะฟะฐะบะตััะฒ Python ัััั
ัะฐััะฒ
+
+ะะธะบะพัะธััะพะฒัะฒะฐัะธ ะนะพะณะพ ะดัะถะต ะฟัะพััะพ. ะะฐะฟัะธะบะปะฐะด, ัะพะฑ ะฒะธะบะพะฝะฐัะธ ะทะฐะฟะธั `GET`, ะฒะธ ะฟะพะฒะธะฝะฝั ะฝะฐะฟะธัะฐัะธ:
+
+```Python
+response = requests.get("http://example.com/some/url")
+```
+
+ะัะดะฟะพะฒัะดะฝะฐ ะพะฟะตัะฐััั *ัะพััั* API FastAPI ะผะพะถะต ะฒะธะณะปัะดะฐัะธ ัะฐะบ:
+
+```Python hl_lines="1"
+@app.get("/some/url")
+def read_url():
+ return {"message": "Hello World"}
+```
+
+ะะฒะตัะฝััั ัะฒะฐะณั ะฝะฐ ัั
ะพะถัััั ั `requests.get(...)` ั `@app.get(...)`.
+
+!!! ะะตัะตะณะปัะฝััะต "ะะฐะดะธั
ะฝัะปะพ **FastAPI** ะฝะฐ"
+ * ะะฐะนัะต ะฟัะพััะธะน ัะฐ ัะฝััััะธะฒะฝะพ ะทัะพะทัะผัะปะธะน API.
+ * ะะธะบะพัะธััะพะฒัะนัะต ัะผะตะฝะฐ (ะพะฟะตัะฐััั) ะผะตัะพะดัะฒ HTTP ะฑะตะทะฟะพัะตัะตะดะฝัะพ, ะฟัะพััะธะผ ัะฐ ัะฝััััะธะฒะฝะพ ะทัะพะทัะผัะปะธะผ ัะฟะพัะพะฑะพะผ.
+ * ะ ะพะทัะผะฝั ะฟะฐัะฐะผะตััะธ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ, ะฐะปะต ะฟะพััะถะฝั ะฝะฐะปะฐัััะฒะฐะฝะฝั.
+
+
+### Swagger / OpenAPI
+
+ะะพะปะพะฒะฝะพั ััะฝะบัััั, ัะบั ั ั
ะพััะฒ ะฒัะด Django REST Framework, ะฑัะปะฐ ะฐะฒัะพะผะฐัะธัะฝะฐ API ะดะพะบัะผะตะฝัะฐััั.
+
+ะะพััะผ ั ะฒะธัะฒะธะฒ, ัะพ ััะฝัั ััะฐะฝะดะฐัั ะดะปั ะดะพะบัะผะตะฝััะฒะฐะฝะฝั API ะท ะฒะธะบะพัะธััะฐะฝะฝัะผ JSON (ะฐะฑะพ YAML, ัะพะทัะธัะตะฝะฝั JSON) ะฟัะด ะฝะฐะทะฒะพั Swagger.
+
+ะ ะฒะถะต ะฑัะฒ ััะฒะพัะตะฝะธะน ะฒะตะฑ-ัะฝัะตััะตะนั ะบะพัะธัััะฒะฐัะฐ ะดะปั Swagger API. ะัะถะต, ะผะพะถะปะธะฒัััั ะณะตะฝะตััะฒะฐัะธ ะดะพะบัะผะตะฝัะฐััั Swagger ะดะปั API ะดะพะทะฒะพะปะธัั ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ัะตะน ะฒะตะฑ-ัะฝัะตััะตะนั ะฐะฒัะพะผะฐัะธัะฝะพ.
+
+ะฃ ัะบะธะนัั ะผะพะผะตะฝั Swagger ะฑัะปะพ ะฟะตัะตะดะฐะฝะพ Linux Foundation, ัะพะฑ ะฟะตัะตะนะผะตะฝัะฒะฐัะธ ะนะพะณะพ ะฝะฐ OpenAPI.
+
+ะขะพะผั, ะบะพะปะธ ะณะพะฒะพัััั ะฟัะพ ะฒะตัััั 2.0, ะฟัะธะนะฝััะพ ะณะพะฒะพัะธัะธ ยซSwaggerยป, ะฐ ะฟัะพ ะฒะตัััั 3+ ยซOpenAPIยป.
+
+!!! ะะตัะตะณะปัะฝััะต "ะะฐะดะธั
ะฝัะปะพ **FastAPI** ะฝะฐ"
+ ะัะธะนะฝััะธ ั ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ะฒัะดะบัะธัะธะน ััะฐะฝะดะฐัั ะดะปั ัะฟะตัะธััะบะฐััะน API ะทะฐะผัััั ัะฟะตััะฐะปัะฝะพั ัั
ะตะผะธ.
+
+ ะะฝัะตะณััะฒะฐัะธ ัะฝััััะผะตะฝัะธ ัะฝัะตััะตะนัั ะฝะฐ ะพัะฝะพะฒั ััะฐะฝะดะฐัััะฒ:
+
+ * ะะฝัะตััะตะนั Swagger
+ * ReDoc
+
+ ะฆั ะดะฒะฐ ะฑัะปะพ ะพะฑัะฐะฝะพ ัะตัะตะท ัะต, ัะพ ะฒะพะฝะธ ะดะพัะธัั ะฟะพะฟัะปััะฝั ัะฐ ััะฐะฑัะปัะฝั, ะฐะปะต, ะฒะธะบะพะฝะฐะฒัะธ ัะฒะธะดะบะธะน ะฟะพััะบ, ะฒะธ ะผะพะถะตัะต ะทะฝะฐะนัะธ ะดะตัััะบะธ ะดะพะดะฐัะบะพะฒะธั
ะฐะปััะตัะฝะฐัะธะฒะฝะธั
ัะฝัะตััะตะนััะฒ ะดะปั OpenAPI (ัะบั ะผะพะถะฝะฐ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ะท **FastAPI**).
+
+### ะคัะตะนะผะฒะพัะบะธ REST ะดะปั Flask
+
+ะัะฝัั ะบัะปัะบะฐ ััะตะนะผะฒะพัะบัะฒ Flask REST, ะฐะปะต, ะฒะธััะฐัะธะฒัะธ ัะฐั ั ัะพะฑะพัั ะฝะฐ ัั
ะดะพัะปัะดะถะตะฝะฝั, ั ะฒะธัะฒะธะฒ, ัะพ ะฑะฐะณะฐัะพ ะท ะฝะธั
ะฟัะธะฟะธะฝะตะฝะพ ะฐะฑะพ ะทะฐะปะธัะตะฝะพ, ะท ะบัะปัะบะพะผะฐ ะฟะพัััะนะฝะธะผะธ ะฟัะพะฑะปะตะผะฐะผะธ, ัะบั ะทัะพะฑะธะปะธ ัั
ะฝะตะฟัะธะดะฐัะฝะธะผะธ.
+
+### Marshmallow
+
+ะะดะฝััั ะท ะณะพะปะพะฒะฝะธั
ััะฝะบััะน, ะฝะตะพะฑั
ัะดะฝะธั
ะดะปั ัะธััะตะผ API, ั "ัะตััะฐะปัะทะฐััั", ัะบะฐ ะฑะตัะต ะดะฐะฝั ะท ะบะพะดั (Python) ั ะฟะตัะตัะฒะพััั ัั
ะฝะฐ ัะพัั, ัะพ ะผะพะถะฝะฐ ะฝะฐะดััะปะฐัะธ ัะตัะตะท ะผะตัะตะถั. ะะฐะฟัะธะบะปะฐะด, ะฟะตัะตัะฒะพัะตะฝะฝั ะพะฑโัะบัะฐ, ัะพ ะผัััะธัั ะดะฐะฝั ะท ะฑะฐะทะธ ะดะฐะฝะธั
, ะฝะฐ ะพะฑโัะบั JSON. ะะตัะตัะฒะพัะตะฝะฝั ะพะฑโัะบััะฒ `datetime` ะฝะฐ ัััะพะบะธ ัะพัะพ.
+
+ะะฝัะพั ะฒะฐะถะปะธะฒะพั ััะฝะบัััั, ะฝะตะพะฑั
ัะดะฝะพั ะดะปั API, ั ะฟะตัะตะฒััะบะฐ ะดะฐะฝะธั
, ัะบะฐ ะทะฐะฑะตะทะฟะตััั ะดัะนัะฝัััั ะดะฐะฝะธั
ะทะฐ ะฟะตะฒะฝะธะผะธ ะฟะฐัะฐะผะตััะฐะผะธ. ะะฐะฟัะธะบะปะฐะด, ัะพ ะดะตัะบะต ะฟะพะปะต ั `int`, ะฐ ะฝะต ะดะตัะบะฐ ะฒะธะฟะฐะดะบะพะฒะฐ ัััะพะบะฐ. ะฆะต ะพัะพะฑะปะธะฒะพ ะบะพัะธัะฝะพ ะดะปั ะฒั
ัะดะฝะธั
ะดะฐะฝะธั
.
+
+ะะตะท ัะธััะตะผะธ ะฟะตัะตะฒััะบะธ ะดะฐะฝะธั
ะฒะฐะผ ะดะพะฒะตะปะพัั ะฑ ะฒะธะบะพะฝัะฒะฐัะธ ะฒัั ะฟะตัะตะฒััะบะธ ะฒัััะฝั, ั ะบะพะดั.
+
+Marshmallow ััะฒะพัะตะฝะพ ะดะปั ะทะฐะฑะตะทะฟะตัะตะฝะฝั ัะธั
ััะฝะบััะน. ะฆะต ััะดะพะฒะฐ ะฑัะฑะปัะพัะตะบะฐ, ั ั ัะฐััะพ ะฝะตั ะบะพัะธัััะฒะฐะฒัั ัะฐะฝััะต.
+
+ะะปะต ะฒัะฝ ะฑัะฒ ััะฒะพัะตะฝะธะน ะดะพ ัะพะณะพ, ัะบ ััะฝัะฒะฐะปะธ ะฟัะดะบะฐะทะบะธ ัะธะฟั Python. ะัะถะต, ัะพะฑ ะฒะธะทะฝะฐัะธัะธ ะบะพะถะฝั ัั
ะตะผั, ะฒะฐะผ ะฟะพัััะฑะฝะพ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ัะฟะตััะฐะปัะฝั ััะธะปััะธ ัะฐ ะบะปะฐัะธ, ะฝะฐะดะฐะฝั Marshmallow.
+
+!!! ะะตัะตะณะปัะฝััะต "ะะฐะดะธั
ะฝัะปะพ **FastAPI** ะฝะฐ"
+ ะะธะบะพัะธััะพะฒัะฒะฐัะธ ะบะพะด ะดะปั ะฐะฒัะพะผะฐัะธัะฝะพะณะพ ะฒะธะทะฝะฐัะตะฝะฝั "ัั
ะตะผ", ัะบั ะฝะฐะดะฐััั ัะธะฟะธ ะดะฐะฝะธั
ั ะฟะตัะตะฒััะบั.
+
+### Webargs
+
+ะะฝัะพั ะฒะฐะถะปะธะฒะพั ััะฝะบัััั, ะฝะตะพะฑั
ัะดะฝะพั ะดะปั API, ั ะฐะฝะฐะปัะท ะดะฐะฝะธั
ัะท ะฒั
ัะดะฝะธั
ะทะฐะฟะธััะฒ.
+
+Webargs โ ัะต ัะฝััััะผะตะฝั, ััะฒะพัะตะฝะธะน, ัะพะฑ ะทะฐะฑะตะทะฟะตัะธัะธ ัะต ะฟะพะฒะตัั
ะบัะปัะบะพั
ััะตะนะผะฒะพัะบัะฒ, ะฒะบะปััะฐััะธ Flask.
+
+ะัะฝ ะฒะธะบะพัะธััะพะฒัั Marshmallow ะฒ ะพัะฝะพะฒั ะดะปั ะฟะตัะตะฒััะบะธ ะดะฐะฝะธั
. ะ ััะฒะพัะตะฝะธะน ัะธะผะธ ะถ ัะพะทัะพะฑะฝะธะบะฐะผะธ.
+
+ะฆะต ััะดะพะฒะธะน ัะฝััััะผะตะฝั, ั ั ัะฐะบะพะถ ัะฐััะพ ะฒะธะบะพัะธััะพะฒัะฒะฐะฒ ะนะพะณะพ, ะฟะตัั ะฝัะถ ััะฒะพัะธัะธ **FastAPI**.
+
+!!! ะะฝัะพัะผะฐััั
+ Webargs ะฑัะฒ ััะฒะพัะตะฝะธะน ัะธะผะธ ะถ ัะพะทัะพะฑะฝะธะบะฐะผะธ Marshmallow.
+
+!!! ะะตัะตะณะปัะฝััะต "ะะฐะดะธั
ะฝัะปะพ **FastAPI** ะฝะฐ"
+ ะะฐัะธ ะฐะฒัะพะผะฐัะธัะฝั ะฟะตัะตะฒััะบั ะดะฐะฝะธั
ะฒั
ัะดะฝะพะณะพ ะทะฐะฟะธัั.
+
+### APISpec
+
+Marshmallow ั Webargs ะทะฐะฑะตะทะฟะตััััั ะฟะตัะตะฒััะบั, ะฐะฝะฐะปัะท ั ัะตััะฐะปัะทะฐััั ัะบ ะฟะปะฐะณัะฝะธ.
+
+ะะปะต ะดะพะบัะผะตะฝัะฐััั ะดะพัั ะฒัะดัััะฝั. ะะพััะผ ะฑัะปะพ ััะฒะพัะตะฝะพ APISpec.
+
+ะฆะต ะฟะปะฐะณัะฝ ะดะปั ะฑะฐะณะฐััะพั
ััะตะนะผะฒะพัะบัะฒ (ัะฐะบะพะถ ั ะฟะปะฐะณัะฝ ะดะปั Starlette).
+
+ะัะธะฝัะธะฟ ัะพะฑะพัะธ ะฟะพะปัะณะฐั ะฒ ัะพะผั, ัะพ ะฒะธ ะฟะธัะตัะต ะฒะธะทะฝะฐัะตะฝะฝั ัั
ะตะผะธ, ะฒะธะบะพัะธััะพะฒัััะธ ัะพัะผะฐั YAML, ั docstring ะบะพะถะฝะพั ััะฝะบััั, ัะพ ะพะฑัะพะฑะปัั ะผะฐััััั.
+
+ะ ะฒัะฝ ะณะตะฝะตััั ัั
ะตะผะธ OpenAPI.
+
+ะขะฐะบ ัะต ะฟัะฐััั ั Flask, Starlette, Responder ัะพัะพ.
+
+ะะปะต ะฟะพััะผ ะผะธ ะทะฝะพะฒั ะผะฐัะผะพ ะฟัะพะฑะปะตะผั ะฝะฐัะฒะฝะพััั ะผัะบัะพัะธะฝัะฐะบัะธัั ะฒัะตัะตะดะธะฝั Python ัััะพะบะธ (ะฒะตะปะธะบะธะน YAML).
+
+ะ ะตะดะฐะบัะพั ััั ะฝััะธะผ ะฝะต ะผะพะถะต ะดะพะฟะพะผะพะณัะธ. ะ ัะบัะพ ะผะธ ะทะผัะฝะธะผะพ ะฟะฐัะฐะผะตััะธ ัะธ ัั
ะตะผะธ Marshmallow ั ะทะฐะฑัะดะตะผะพ ัะฐะบะพะถ ะทะผัะฝะธัะธ ัั ัััะพะบั ะดะพะบัะผะตะฝัะฐ YAML, ะทะณะตะฝะตัะพะฒะฐะฝะฐ ัั
ะตะผะฐ ะฑัะดะต ะทะฐััะฐััะปะพั.
+
+!!! ะะฝัะพัะผะฐััั
+ APISpec ะฑัะฒ ััะฒะพัะตะฝะธะน ัะธะผะธ ะถ ัะพะทัะพะฑะฝะธะบะฐะผะธ Marshmallow.
+
+
+!!! ะะตัะตะณะปัะฝััะต "ะะฐะดะธั
ะฝัะปะพ **FastAPI** ะฝะฐ"
+ ะัะดััะธะผัะฒะฐัะธ ะฒัะดะบัะธัะธะน ััะฐะฝะดะฐัั API, OpenAPI.
+
+### Flask-apispec
+
+ะฆะต ะฟะปะฐะณัะฝ Flask, ัะบะธะน ะพะฑโัะดะฝัั Webargs, Marshmallow ั APISpec.
+
+ะัะฝ ะฒะธะบะพัะธััะพะฒัั ัะฝัะพัะผะฐััั ะท Webargs ั Marshmallow ะดะปั ะฐะฒัะพะผะฐัะธัะฝะพะณะพ ััะฒะพัะตะฝะฝั ัั
ะตะผ OpenAPI ะทะฐ ะดะพะฟะพะผะพะณะพั APISpec.
+
+ะฆะต ััะดะพะฒะธะน ัะฝััััะผะตะฝั, ะดัะถะต ะฝะตะดะพะพััะฝะตะฝะธะน. ะัะฝ ะผะฐั ะฑััะธ ะฝะฐะฑะฐะณะฐัะพ ะฟะพะฟัะปััะฝััะธะผ, ะฝัะถ ะฑะฐะณะฐัะพ ะฟะปะฐะณัะฝัะฒ Flask. ะฆะต ะผะพะถะต ะฑััะธ ะฟะพะฒโัะทะฐะฝะพ ะท ัะธะผ, ัะพ ะนะพะณะพ ะดะพะบัะผะตะฝัะฐััั ะฝะฐะดัะพ ััะธัะปะฐ ะน ะฐะฑัััะฐะบัะฝะฐ.
+
+ะฆะต ะฒะธัััะธะปะพ ะฝะตะพะฑั
ัะดะฝัััั ะฟะธัะฐัะธ YAML (ัะฝัะธะน ัะธะฝัะฐะบัะธั) ะฒัะตัะตะดะธะฝั ััะดะบัะฒ ะดะพะบัะผะตะฝััะฒ Python.
+
+ะฆั ะบะพะผะฑัะฝะฐััั Flask, Flask-apispec ัะท Marshmallow ั Webargs ะฑัะปะฐ ะผะพัะผ ัะปัะฑะปะตะฝะธะผ ะฑะตะบะตะฝะด-ััะตะบะพะผ ะดะพ ััะฒะพัะตะฝะฝั **FastAPI**.
+
+ะั ะฒะธะบะพัะธััะฐะฝะฝั ะฟัะธะทะฒะตะปะพ ะดะพ ััะฒะพัะตะฝะฝั ะบัะปัะบะพั
ะณะตะฝะตัะฐัะพััะฒ ะฟะพะฒะฝะพะณะพ ััะตะบะฐ Flask. ะฆะต ะพัะฝะพะฒะฝะธะน ััะตะบ, ัะบะธะน ั (ัะฐ ะบัะปัะบะฐ ะทะพะฒะฝััะฝัั
ะบะพะผะฐะฝะด) ะฒะธะบะพัะธััะพะฒัะฒะฐะฒ ะดะพัั:
+
+* https://github.com/tiangolo/full-stack
+* https://github.com/tiangolo/full-stack-flask-couchbase
+* https://github.com/tiangolo/full-stack-flask-couchdb
+
+ะ ัั ัะฐะผั ะณะตะฝะตัะฐัะพัะธ ะฟะพะฒะฝะพะณะพ ััะตะบั ะฑัะปะธ ะพัะฝะพะฒะพั [**FastAPI** ะณะตะฝะตัะฐัะพััะฒ ะฟัะพะตะบััะฒ](project-generation.md){.internal-link target=_blank}.
+
+!!! ะะฝัะพัะผะฐััั
+ Flask-apispec ะฑัะฒ ััะฒะพัะตะฝะธะน ัะธะผะธ ะถ ัะพะทัะพะฑะฝะธะบะฐะผะธ Marshmallow.
+
+!!! ะะตัะตะณะปัะฝััะต "ะะฐะดะธั
ะฝัะปะพ **FastAPI** ะฝะฐ"
+ ะกัะฒะพัะตะฝะฝั ัั
ะตะผะธ OpenAPI ะฐะฒัะพะผะฐัะธัะฝะพ ะท ัะพะณะพ ัะฐะผะพะณะพ ะบะพะดั, ัะบะธะน ะฒะธะทะฝะฐัะฐั ัะตััะฐะปัะทะฐััั ัะฐ ะฟะตัะตะฒััะบั.
+
+### NestJS (ัะฐ Angular)
+
+ะฆะต ะฝะฐะฒััั ะฝะต Python, NestJS โ ัะต ััะตะนะผะฒะพัะบ NodeJS JavaScript (TypeScript), ะฝะฐัั
ะฝะตะฝะฝะธะน Angular.
+
+ะฆะต ะดะพััะณะฐั ัะพะณะพัั ะฟะพะดัะฑะฝะพะณะพ ะดะพ ัะพะณะพ, ัะพ ะผะพะถะฝะฐ ะทัะพะฑะธัะธ ะท Flask-apispec.
+
+ะัะฝ ะผะฐั ัะฝัะตะณัะพะฒะฐะฝั ัะธััะตะผั ะฒะฟัะพะฒะฐะดะถะตะฝะฝั ะทะฐะปะตะถะฝะพััะตะน, ะฝะฐัั
ะฝะตะฝะฝั Angular two. ะัะฝ ะฟะพััะตะฑัั ะฟะพะฟะตัะตะดะฝัะพั ัะตััััะฐััั ยซinjectablesยป (ัะบ ั ะฒัั ัะฝัั ัะธััะตะผะธ ะฒะฟัะพะฒะฐะดะถะตะฝะฝั ะทะฐะปะตะถะฝะพััะตะน, ัะบั ั ะทะฝะฐั), ัะพะผั ัะต ะทะฑัะปัััั ะฑะฐะณะฐัะพัะปัะฒะฝัััั ัะฐ ะฟะพะฒัะพัะตะฝะฝั ะบะพะดั.
+
+ะัะบัะปัะบะธ ะฟะฐัะฐะผะตััะธ ะพะฟะธัะฐะฝั ะทะฐ ะดะพะฟะพะผะพะณะพั ัะธะฟัะฒ TypeScript (ะฟะพะดัะฑะฝะพ ะดะพ ะฟัะดะบะฐะทะพะบ ัะธะฟั Python), ะฟัะดััะธะผะบะฐ ัะตะดะฐะบัะพัะฐ ะดะพัะธัั ั
ะพัะพัะฐ.
+
+ะะปะต ะพัะบัะปัะบะธ ะดะฐะฝั TypeScript ะฝะต ะทะฑะตััะณะฐััััั ะฟััะปั ะบะพะผะฟัะปัััั ะฒ JavaScript, ะฒะพะฝะธ ะฝะต ะผะพะถััั ะฟะพะบะปะฐะดะฐัะธัั ะฝะฐ ัะธะฟะธ ะดะปั ะฒะธะทะฝะฐัะตะฝะฝั ะฟะตัะตะฒััะบะธ, ัะตััะฐะปัะทะฐััั ัะฐ ะดะพะบัะผะตะฝัะฐััั ะพะดะฝะพัะฐัะฝะพ. ะงะตัะตะท ัะต ัะฐ ะดะตัะบั ะดะธะทะฐะนะฝะตัััะบั ัััะตะฝะฝั, ัะพะฑ ะพััะธะผะฐัะธ ะฟะตัะตะฒััะบั, ัะตััะฐะปัะทะฐััั ัะฐ ะฐะฒัะพะผะฐัะธัะฝั ะณะตะฝะตัะฐััั ัั
ะตะผะธ, ะฟะพัััะฑะฝะพ ะดะพะดะฐัะธ ะดะตะบะพัะฐัะพัะธ ะฒ ะฑะฐะณะฐััะพั
ะผััััั
. ะขะฐะบะธะผ ัะธะฝะพะผ ะบะพะด ััะฐั ะดะพัะธัั ะฑะฐะณะฐัะพัะปัะฒะฝะธะผ.
+
+ะัะฝ ะฝะต ะดัะถะต ะดะพะฑัะต ะพะฑัะพะฑะปัั ะฒะบะปะฐะดะตะฝั ะผะพะดะตะปั. ะัะถะต, ัะบัะพ ััะปะพ JSON ั ะทะฐะฟะธัั ั ะพะฑโัะบัะพะผ JSON ัะท ะฒะฝัััััะฝัะผะธ ะฟะพะปัะผะธ, ัะบั, ั ัะฒะพั ัะตัะณั, ั ะฒะบะปะฐะดะตะฝะธะผะธ ะพะฑโัะบัะฐะผะธ JSON, ะนะพะณะพ ะฝะตะผะพะถะปะธะฒะพ ะฝะฐะปะตะถะฝะธะผ ัะธะฝะพะผ ะทะฐะดะพะบัะผะตะฝััะฒะฐัะธ ัะฐ ะฟะตัะตะฒััะธัะธ.
+
+!!! ะะตัะตะณะปัะฝััะต "ะะฐะดะธั
ะฝัะปะพ **FastAPI** ะฝะฐ"
+ ะะธะบะพัะธััะพะฒัะฒะฐัะธ ัะธะฟะธ Python, ัะพะฑ ะผะฐัะธ ััะดะพะฒั ะฟัะดััะธะผะบั ัะตะดะฐะบัะพัะฐ.
+
+ ะะฐัะธ ะฟะพััะถะฝั ัะธััะตะผั ะฒะฟัะพะฒะฐะดะถะตะฝะฝั ะทะฐะปะตะถะฝะพััะตะน. ะะฝะฐะนะดััั ัะฟะพััะฑ ะทะฒะตััะธ ะดะพ ะผัะฝัะผัะผั ะฟะพะฒัะพัะตะฝะฝั ะบะพะดั.
+
+### Sanic
+
+ะฆะต ะฑัะฒ ะพะดะธะฝ ัะท ะฟะตััะธั
ะฝะฐะดะทะฒะธัะฐะนะฝะพ ัะฒะธะดะบะธั
ััะตะนะผะฒะพัะบัะฒ Python ะฝะฐ ะพัะฝะพะฒั `asyncio`. ะัะฝ ะฑัะฒ ะดัะถะต ัั
ะพะถะธะน ะฝะฐ Flask.
+
+!!! ะัะธะผััะบะฐ "ะขะตั
ะฝััะฝั ะดะตัะฐะปั"
+ ะัะฝ ะฒะธะบะพัะธััะพะฒัะฒะฐะฒ `uvloop` ะทะฐะผัััั ััะฐะฝะดะฐััะฝะพะณะพ ัะธะบะปั Python `asyncio`. ะัั ัะพ ะทัะพะฑะธะปะพ ะนะพะณะพ ัะฐะบะธะผ ัะฒะธะดะบะธะผ.
+
+ ะฆะต ัะฒะฝะพ ะฝะฐะดะธั
ะฝัะปะพ Uvicorn ั Starlette, ัะบั ะทะฐัะฐะท ัะฒะธะดัั ะทะฐ Sanic ั ะฒัะดะบัะธัะธั
ัะตััะฐั
.
+
+!!! ะะตัะตะณะปัะฝััะต "ะะฐะดะธั
ะฝัะปะพ **FastAPI** ะฝะฐ"
+ ะะฝะฐะนัะธ ัะฟะพััะฑ ะพััะธะผะฐัะธ ะฑะพะถะตะฒัะปัะฝั ะฟัะพะดัะบัะธะฒะฝัััั.
+
+ ะัั ัะพะผั **FastAPI** ะฑะฐะทัััััั ะฝะฐ Starlette, ะพัะบัะปัะบะธ ัะต ะฝะฐะนัะฒะธะดัะฐ ะดะพัััะฟะฝะฐ ััััะบัััะฐ (ะฟะตัะตะฒััะตะฝะฐ ัะตััะฐะผะธ ััะพัะพะฝะฝัั
ัะพะทัะพะฑะฝะธะบัะฒ).
+
+### Falcon
+
+Falcon โ ัะต ะพะดะธะฝ ะฒะธัะพะบะพะฟัะพะดัะบัะธะฒะฝะธะน ััะตะนะผะฒะพัะบ Python, ะฒัะฝ ัะพะทัะพะฑะปะตะฝะธะน ัะบ ะผัะฝัะผะฐะปัะฝะธะน ั ะฟัะฐััั ัะบ ะพัะฝะพะฒะฐ ัะฝัะธั
ััะตะนะผะฒะพัะบัะฒ, ัะฐะบะธั
ัะบ Hug.
+
+ะัะฝ ัะพะทัะพะฑะปะตะฝะธะน ัะฐะบะธะผ ัะธะฝะพะผ, ัะพะฑ ะผะฐัะธ ััะฝะบััั, ัะบั ะพััะธะผัััั ะดะฒะฐ ะฟะฐัะฐะผะตััะธ, ะพะดะธะฝ ยซะทะฐะฟะธัยป ั ะพะดะธะฝ ยซะฒัะดะฟะพะฒัะดัยป. ะะพััะผ ะฒะธ ยซัะธัะฐััะตยป ัะฐััะธะฝะธ ะทะฐะฟะธัั ัะฐ ยซะทะฐะฟะธััััะตยป ัะฐััะธะฝะธ ั ะฒัะดะฟะพะฒัะดั. ะงะตัะตะท ัะฐะบะธะน ะดะธะทะฐะนะฝ ะฝะตะผะพะถะปะธะฒะพ ะพะณะพะปะพัะธัะธ ะฟะฐัะฐะผะตััะธ ะทะฐะฟะธัั ัะฐ ััะปะฐ ะทะฐ ะดะพะฟะพะผะพะณะพั ััะฐะฝะดะฐััะฝะธั
ะฟัะดะบะฐะทะพะบ ัะธะฟั Python ัะบ ะฟะฐัะฐะผะตััะธ ััะฝะบััั.
+
+ะขะฐะบะธะผ ัะธะฝะพะผ, ะฟะตัะตะฒััะบะฐ ะดะฐะฝะธั
, ัะตััะฐะปัะทะฐััั ัะฐ ะดะพะบัะผะตะฝัะฐััั ะฟะพะฒะธะฝะฝั ะฒะธะบะพะฝัะฒะฐัะธัั ะฒ ะบะพะดั, ะฐ ะฝะต ะฐะฒัะพะผะฐัะธัะฝะพ. ะะฑะพ ะฒะพะฝะธ ะฟะพะฒะธะฝะฝั ะฑััะธ ัะตะฐะปัะทะพะฒะฐะฝั ัะบ ััะตะนะผะฒะพัะบ ะฟะพะฒะตัั
Falcon, ัะบ Hug. ะขะฐะบะฐ ัะฐะผะฐ ะฒัะดะผัะฝะฝัััั ัะฟะพััะตััะณะฐััััั ะฒ ัะฝัะธั
ััะตะนะผะฒะพัะบะฐั
, ะฝะฐัั
ะฝะตะฝะฝะธั
ะดะธะทะฐะนะฝะพะผ Falcon, ัะพ ะผะฐััั ะพะดะธะฝ ะพะฑโัะบั ะทะฐะฟะธัั ัะฐ ะพะดะธะฝ ะพะฑโัะบั ะฒัะดะฟะพะฒัะดั ัะบ ะฟะฐัะฐะผะตััะธ.
+
+!!! ะะตัะตะณะปัะฝััะต "ะะฐะดะธั
ะฝัะปะพ **FastAPI** ะฝะฐ"
+ ะะฝะฐะนัะธ ัะฟะพัะพะฑะธ ะพััะธะผะฐัะธ ััะดะพะฒั ะฟัะพะดัะบัะธะฒะฝัััั.
+
+ ะ ะฐะทะพะผ ัะท Hug (ะพัะบัะปัะบะธ Hug ะฑะฐะทัััััั ะฝะฐ Falcon) ะฝะฐะดะธั
ะฝัะฒ **FastAPI** ะพะณะพะปะพัะธัะธ ะฟะฐัะฐะผะตัั `response` ั ััะฝะบัััั
.
+
+ ะฅะพัะฐ ั FastAPI ัะต ะฝะตะพะฑะพะฒโัะทะบะพะฒะพ, ั ะฒะธะบะพัะธััะพะฒัััััั ะฒ ะพัะฝะพะฒะฝะพะผั ะดะปั ะฒััะฐะฝะพะฒะปะตะฝะฝั ะทะฐะณะพะปะพะฒะบัะฒ, ัะฐะนะปัะฒ cookie ัะฐ ะฐะปััะตัะฝะฐัะธะฒะฝะธั
ะบะพะดัะฒ ััะฐะฝั.
+
+### Molten
+
+ะฏ ะฒัะดะบัะธะฒ ะดะปั ัะตะฑะต Molten ะฝะฐ ะฟะตััะธั
ะตัะฐะฟะฐั
ััะฒะพัะตะฝะฝั **FastAPI**. ะ ะฒัะฝ ะผะฐั ะดะพัะธัั ัั
ะพะถั ัะดะตั:
+
+* ะะฐะทัััััั ะฝะฐ ะฟัะดะบะฐะทะบะฐั
ัะธะฟั Python.
+* ะะตัะตะฒััะบะฐ ัะฐ ะดะพะบัะผะตะฝัะฐััั ัะธั
ัะธะฟัะฒ.
+* ะกะธััะตะผะฐ ะฒะฟัะพะฒะฐะดะถะตะฝะฝั ะทะฐะปะตะถะฝะพััะตะน.
+
+ะัะฝ ะฝะต ะฒะธะบะพัะธััะพะฒัั ะฟะตัะตะฒััะบั ะดะฐะฝะธั
, ัะตััะฐะปัะทะฐััั ัะฐ ะฑัะฑะปัะพัะตะบั ะดะพะบัะผะตะฝัะฐััั ััะพัะพะฝะฝัั
ัะพะทัะพะฑะฝะธะบัะฒ, ัะบ Pydantic, ะฒัะฝ ะผะฐั ัะฒะพั ะฒะปะฐัะฝั. ะขะฐะบะธะผ ัะธะฝะพะผ, ัั ะฒะธะทะฝะฐัะตะฝะฝั ัะธะฟัะฒ ะดะฐะฝะธั
ะฝะต ะผะพะถะฝะฐ ะฑัะปะพ ะฑ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ะฟะพะฒัะพัะฝะพ ัะฐะบ ะปะตะณะบะพ.
+
+ะฆะต ะฒะธะผะฐะณะฐั ััะพั
ะธ ะฑัะปัั ะดะพะบะปะฐะดะฝะธั
ะบะพะฝััะณััะฐััะน. ะ ะพัะบัะปัะบะธ ะฒัะฝ ะทะฐัะฝะพะฒะฐะฝะธะน ะฝะฐ WSGI (ะทะฐะผัััั ASGI), ะฒัะฝ ะฝะต ะฟัะธะทะฝะฐัะตะฝะธะน ะดะปั ะฒะธะบะพัะธััะฐะฝะฝั ะฒะธัะพะบะพะฟัะพะดัะบัะธะฒะฝะธั
ัะฝััััะผะตะฝััะฒ, ัะฐะบะธั
ัะบ Uvicorn, Starlette ั Sanic.
+
+ะกะธััะตะผะฐ ะฒะฟัะพะฒะฐะดะถะตะฝะฝั ะทะฐะปะตะถะฝะพััะตะน ะฒะธะผะฐะณะฐั ะฟะพะฟะตัะตะดะฝัะพั ัะตััััะฐััั ะทะฐะปะตะถะฝะพััะตะน, ั ะทะฐะปะตะถะฝะพััั ะฒะธััััััััั ะฝะฐ ะพัะฝะพะฒั ะพะณะพะปะพัะตะฝะธั
ัะธะฟัะฒ. ะัะถะต, ะฝะตะผะพะถะปะธะฒะพ ะพะณะพะปะพัะธัะธ ะฑัะปััะต ะฝัะถ ะพะดะธะฝ ยซะบะพะผะฟะพะฝะตะฝัยป, ัะบะธะน ะฝะฐะดะฐั ะฟะตะฒะฝะธะน ัะธะฟ.
+
+ะะฐัััััะธ ะพะณะพะปะพััััััั ะฒ ะพะดะฝะพะผั ะผัััั ะท ะฒะธะบะพัะธััะฐะฝะฝัะผ ััะฝะบััะน, ะพะณะพะปะพัะตะฝะธั
ะฒ ัะฝัะธั
ะผััััั
(ะทะฐะผัััั ะฒะธะบะพัะธััะฐะฝะฝั ะดะตะบะพัะฐัะพััะฒ, ัะบั ะผะพะถะฝะฐ ัะพะทะผัััะธัะธ ะฑะตะทะฟะพัะตัะตะดะฝัะพ ะฟะพะฒะตัั
ััะฝะบััั, ัะบะฐ ะพะฑัะพะฑะปัั ะบัะฝัะตะฒั ัะพัะบั). ะฆะต ะฑะปะธะถัะต ะดะพ ัะพะณะพ, ัะบ ัะต ัะพะฑะธัั Django, ะฝัะถ ะดะพ Flask (ั Starlette). ะัะฝ ัะพะทะดัะปัั ะฒ ะบะพะดั ัะตัั, ัะบั ะฒัะดะฝะพัะฝะพ ัััะฝะพ ะฟะพะฒโัะทะฐะฝั.
+
+!!! ะะตัะตะณะปัะฝััะต "ะะฐะดะธั
ะฝัะปะพ **FastAPI** ะฝะฐ"
+ ะะธะทะฝะฐัะธัะธ ะดะพะดะฐัะบะพะฒั ะฟะตัะตะฒััะบะธ ะดะปั ัะธะฟัะฒ ะดะฐะฝะธั
, ะฒะธะบะพัะธััะพะฒัััะธ ะทะฝะฐัะตะฝะฝั "ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ" ะฐััะธะฑัััะฒ ะผะพะดะตะปั. ะฆะต ะฟะพะบัะฐััั ะฟัะดััะธะผะบั ัะตะดะฐะบัะพัะฐ, ะฐ ัะฐะฝััะต ะฒะพะฝะฐ ะฑัะปะฐ ะฝะตะดะพัััะฟะฝะฐ ะฒ Pydantic.
+
+ ะฆะต ัะฐะบัะธัะฝะพ ะฝะฐะดะธั
ะฝัะปะพ ะพะฝะพะฒะธัะธ ัะฐััะธะฝะธ Pydantic, ัะพะฑ ะฟัะดััะธะผัะฒะฐัะธ ัะพะน ัะฐะผะธะน ััะธะปั ะพะณะพะปะพัะตะฝะฝั ะฟะตัะตะฒััะบะธ (ะฒัั ัั ััะฝะบััั ะฒะถะต ะดะพัััะฟะฝั ะฒ Pydantic).
+
+### Hug
+
+Hug ะฑัะฒ ะพะดะฝะธะผ ัะท ะฟะตััะธั
ััะตะนะผะฒะพัะบัะฒ, ัะบะธะน ัะตะฐะปัะทัะฒะฐะฒ ะพะณะพะปะพัะตะฝะฝั ัะธะฟัะฒ ะฟะฐัะฐะผะตัััะฒ API ะทะฐ ะดะพะฟะพะผะพะณะพั ะฟัะดะบะฐะทะพะบ ัะธะฟั Python. ะฆะต ะฑัะปะฐ ััะดะพะฒะฐ ัะดะตั, ัะบะฐ ะฝะฐะดะธั
ะฝัะปะฐ ัะฝัั ัะฝััััะผะตะฝัะธ ะทัะพะฑะธัะธ ัะต ัะฐะผะต.
+
+ะัะฝ ะฒะธะบะพัะธััะพะฒัะฒะฐะฒ ัะฟะตััะฐะปัะฝั ัะธะฟะธ ั ัะฒะพัั
ะพะณะพะปะพัะตะฝะฝัั
ะทะฐะผัััั ััะฐะฝะดะฐััะฝะธั
ัะธะฟัะฒ Python, ะฐะปะต ัะต ะฒัะต ะพะดะฝะพ ะฑัะฒ ะฒะตะปะธัะตะทะฝะธะน ะบัะพะบ ะฒะฟะตัะตะด.
+
+ะฆะต ัะฐะบะพะถ ะฑัะฒ ะพะดะธะฝ ัะท ะฟะตััะธั
ััะตะนะผะฒะพัะบัะฒ, ัะบะธะน ะณะตะฝะตััะฒะฐะฒ ัะฟะตััะฐะปัะฝั ัั
ะตะผั, ัะพ ะพะณะพะปะพััะฒะฐะปะฐ ะฒะตัั API ั JSON.
+
+ะัะฝ ะฝะต ะฑะฐะทัะฒะฐะฒัั ะฝะฐ ัะฐะบะธั
ััะฐะฝะดะฐััะฐั
, ัะบ OpenAPI ัะฐ JSON Schema. ะขะพะผั ะฑัะปะพ ะฑ ะฝะตะฟัะพััะพ ัะฝัะตะณััะฒะฐัะธ ะนะพะณะพ ะท ัะฝัะธะผะธ ัะฝััััะผะตะฝัะฐะผะธ, ัะบ-ะพั Swagger UI. ะะปะต ะทะฝะพะฒั ะถ ัะฐะบะธ, ัะต ะฑัะปะฐ ะดัะถะต ัะฝะฝะพะฒะฐััะนะฝะฐ ัะดะตั.
+
+ะัะฝ ะผะฐั ััะบะฐะฒั ะฝะตะทะฒะธัะฐะนะฝั ััะฝะบััั: ะฒะธะบะพัะธััะพะฒัััะธ ัั ัะฐะผั ััััะบัััั, ะผะพะถะฝะฐ ััะฒะพััะฒะฐัะธ API, ะฐ ัะฐะบะพะถ CLI.
+
+ะัะบัะปัะบะธ ะฒัะฝ ะทะฐัะฝะพะฒะฐะฝะธะน ะฝะฐ ะฟะพะฟะตัะตะดะฝัะพะผั ััะฐะฝะดะฐััั ะดะปั ัะธะฝั
ัะพะฝะฝะธั
ะฒะตะฑ-ััะตะนะผะฒะพัะบัะฒ Python (WSGI), ะฒัะฝ ะฝะต ะผะพะถะต ะฟัะฐััะฒะฐัะธ ะท Websockets ัะฐ ัะฝัะธะผะธ ัะตัะฐะผะธ, ั
ะพัะฐ ะฒัะฝ ัะฐะบะพะถ ะผะฐั ะฒะธัะพะบั ะฟัะพะดัะบัะธะฒะฝัััั.
+
+!!! ะะฝัะพัะผะฐััั
+ Hug ััะฒะพัะธะฒ ะขัะผะพัั ะัะพัะปั, ัะพะน ัะฐะผะธะน ัะฒะพัะตัั `isort`, ััะดะพะฒะธะน ัะฝััััะผะตะฝั ะดะปั ะฐะฒัะพะผะฐัะธัะฝะพะณะพ ัะพัััะฒะฐะฝะฝั ัะผะฟะพััั ั ัะฐะนะปะฐั
Python.
+
+!!! ะะตัะตะณะปัะฝััะต "ะะฐะดะธั
ะฝัะปะพ **FastAPI** ะฝะฐ"
+ Hug ะฝะฐะดะธั
ะฝัะฒ ัะฐััะธะฝั APIStar ั ะฑัะฒ ะพะดะฝะธะผ ัะท ะฝะฐะนะฑัะปัั ะฟะตััะฟะตะบัะธะฒะฝะธั
ัะฝััััะผะตะฝััะฒ, ะฟะพััะด ัะท APIStar.
+
+ Hug ะฝะฐะดะธั
ะฝัะฒ **FastAPI** ะฝะฐ ะฒะธะบะพัะธััะฐะฝะฝั ะฟัะดะบะฐะทะพะบ ัะธะฟั Python ะดะปั ะพะณะพะปะพัะตะฝะฝั ะฟะฐัะฐะผะตัััะฒ ั ะฐะฒัะพะผะฐัะธัะฝะพะณะพ ััะฒะพัะตะฝะฝั ัั
ะตะผะธ, ัะพ ะฒะธะทะฝะฐัะฐั API.
+
+ Hug ะฝะฐะดะธั
ะฝัะฒ **FastAPI** ะพะณะพะปะพัะธัะธ ะฟะฐัะฐะผะตัั `response` ั ััะฝะบัััั
ะดะปั ะฒััะฐะฝะพะฒะปะตะฝะฝั ะทะฐะณะพะปะพะฒะบัะฒ ั ัะฐะนะปัะฒ cookie.
+
+### APIStar (<= 0,5)
+
+ะะตะทะฟะพัะตัะตะดะฝัะพ ะฟะตัะตะด ัะธะผ, ัะบ ะฒะธัััะธัะธ ััะฒะพัะธัะธ **FastAPI**, ั ะทะฝะฐะนัะพะฒ ัะตัะฒะตั **APIStar**. ะัะฝ ะผะฐะฒ ะผะฐะนะถะต ะฒัะต, ัะพ ั ััะบะฐะฒ, ั ะผะฐะฒ ััะดะพะฒะธะน ะดะธะทะฐะนะฝ.
+
+ะฆะต ะฑัะปะฐ ะพะดะฝะฐ ะท ะฟะตััะธั
ัะตะฐะปัะทะฐััะน ััะตะนะผะฒะพัะบั, ัะพ ะฒะธะบะพัะธััะพะฒัั ะฟัะดะบะฐะทะบะธ ัะธะฟั Python ะดะปั ะพะณะพะปะพัะตะฝะฝั ะฟะฐัะฐะผะตัััะฒ ั ะทะฐะฟะธััะฒ, ัะบั ั ะบะพะปะธ-ะฝะตะฑัะดั ะฑะฐัะธะฒ (ะดะพ NestJS ั Molten). ะฏ ะทะฝะฐะนัะพะฒ ะนะพะณะพ ะฑัะปัั-ะผะตะฝั ะพะดะฝะพัะฐัะฝะพ ะท Hug. ะะปะต APIStar ะฒะธะบะพัะธััะพะฒัะฒะฐะฒ ััะฐะฝะดะฐัั OpenAPI.
+
+ะัะฝ ะผะฐะฒ ะฐะฒัะพะผะฐัะธัะฝั ะฟะตัะตะฒััะบั ะดะฐะฝะธั
, ัะตััะฐะปัะทะฐััั ะดะฐะฝะธั
ั ะณะตะฝะตัะฐััั ัั
ะตะผะธ OpenAPI ะฝะฐ ะพัะฝะพะฒั ะฟัะดะบะฐะทะพะบ ัะพะณะพ ัะฐะผะพะณะพ ัะธะฟั ะฒ ะบัะปัะบะพั
ะผััััั
.
+
+ะะธะทะฝะฐัะตะฝะฝั ัั
ะตะผะธ ััะปะฐ ะฝะต ะฒะธะบะพัะธััะพะฒัะฒะฐะปะธ ัั ัะฐะผั ะฟัะดะบะฐะทะบะธ ัะธะฟั Python, ัะบ Pydantic, ะฒะพะฝะพ ะฑัะปะพ ััะพั
ะธ ัั
ะพะถะต ะฝะฐ Marshmallow, ัะพะผั ะฟัะดััะธะผะบะฐ ัะตะดะฐะบัะพัะฐ ะฑัะปะฐ ะฑ ะฝะต ัะฐะบะพั ั
ะพัะพัะพั, ะฐะปะต ะฒัะต ะถ APIStar ะฑัะฒ ะฝะฐะนะบัะฐัะธะผ ะดะพัััะฟะฝะธะผ ะฒะฐััะฐะฝัะพะผ.
+
+ะัะฝ ะผะฐะฒ ะฝะฐะนะบัะฐัั ะฟะพะบะฐะทะฝะธะบะธ ะฟัะพะดัะบัะธะฒะฝะพััั ะฝะฐ ัะพะน ัะฐั (ะฟะตัะตะฒะตััะธะฒ ะปะธัะต Starlette).
+
+ะกะฟะพัะฐัะบั ะฒัะฝ ะฝะต ะผะฐะฒ ะฐะฒัะพะผะฐัะธัะฝะพะณะพ ะฒะตะฑ-ัะฝัะตััะตะนัั ะดะพะบัะผะตะฝัะฐััั API, ะฐะปะต ั ะทะฝะฐะฒ, ัะพ ะผะพะถั ะดะพะดะฐัะธ ะดะพ ะฝัะพะณะพ ัะฝัะตััะตะนั ะบะพัะธัััะฒะฐัะฐ Swagger.
+
+ะัะฝ ะผะฐะฒ ัะธััะตะผั ะฒะฒะตะดะตะฝะฝั ะทะฐะปะตะถะฝะพััะตะน. ะัะฝ ะฒะธะผะฐะณะฐะฒ ะฟะพะฟะตัะตะดะฝัะพั ัะตััััะฐััั ะบะพะผะฟะพะฝะตะฝััะฒ, ัะบ ั ัะฝัั ัะฝััััะผะตะฝัะธ, ัะพะทะณะปัะฝััั ะฒะธัะต. ะะปะต ะฒัะต ะพะดะฝะพ ัะต ะฑัะปะฐ ััะดะพะฒะฐ ััะฝะบััั.
+
+ะฏ ะฝัะบะพะปะธ ะฝะต ะผัะณ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ะนะพะณะพ ะฒ ะฟะพะฒะฝะพััะฝะฝะพะผั ะฟัะพะตะบัั, ะพัะบัะปัะบะธ ะฒัะฝ ะฝะต ะผะฐะฒ ัะฝัะตะณัะฐััั ะฑะตะทะฟะตะบะธ, ัะพะผั ั ะฝะต ะผัะณ ะทะฐะผัะฝะธัะธ ะฒัั ััะฝะบััั, ัะบั ะผะฐะฒ, ะณะตะฝะตัะฐัะพัะฐะผะธ ะฟะพะฒะฝะพะณะพ ััะตะบั ะฝะฐ ะพัะฝะพะฒั Flask-apispec. ะฃ ะผะพัั
ะฝะตะฒะธะบะพะฝะฐะฝะธั
ะฟัะพะตะบัะฐั
ั ะผะฐะฒ ััะฒะพัะธัะธ ะทะฐะฟะธั ะฝะฐ ะฒะธะปััะตะฝะฝั, ะดะพะดะฐะฒัะธ ัั ััะฝะบััั.
+
+ะะปะต ะฟะพััะผ ัะพะบัั ะฟัะพะตะบัั ะทะผัะฝะธะฒัั.
+
+ะฆะต ะฒะถะต ะฝะต ะฑัะฒ ะฒะตะฑ-ััะตะนะผะฒะพัะบ API, ะพัะบัะปัะบะธ ัะฒะพััั ะฟะพัััะฑะฝะพ ะฑัะปะพ ะทะพัะตัะตะดะธัะธัั ะฝะฐ Starlette.
+
+ะขะตะฟะตั APIStar โ ัะต ะฝะฐะฑัั ัะฝััััะผะตะฝััะฒ ะดะปั ะฟะตัะตะฒััะบะธ ัะฟะตัะธััะบะฐััะน OpenAPI, ะฐ ะฝะต ะฒะตะฑ-ััะตะนะผะฒะพัะบ.
+
+!!! ะะฝัะพัะผะฐััั
+ APIStar ััะฒะพัะธะฒ ะขะพะผ ะััััั. ะขะพะน ัะฐะผะธะน ั
ะปะพะฟะตัั, ัะบะธะน ััะฒะพัะธะฒ:
+
+ * Django REST Framework
+ * Starlette (ะฝะฐ ัะบะพะผั ะฑะฐะทัััััั **FastAPI**)
+ * Uvicorn (ะฒะธะบะพัะธััะพะฒัััััั Starlette ั **FastAPI**)
+
+!!! ะะตัะตะณะปัะฝััะต "ะะฐะดะธั
ะฝัะปะพ **FastAPI** ะฝะฐ"
+ ะัะฝัะฒะฐัะธ.
+
+ ะะดะตั ะพะณะพะปะพัะตะฝะฝั ะบัะปัะบะพั
ัะตัะตะน (ะฟะตัะตะฒััะบะธ ะดะฐะฝะธั
, ัะตััะฐะปัะทะฐััั ัะฐ ะดะพะบัะผะตะฝัะฐััั) ะทะฐ ะดะพะฟะพะผะพะณะพั ัะธั
ัะฐะผะธั
ัะธะฟัะฒ Python, ัะบั ะฒ ัะพะน ะถะต ัะฐั ะทะฐะฑะตะทะฟะตััะฒะฐะปะธ ััะดะพะฒั ะฟัะดััะธะผะบั ัะตะดะฐะบัะพัะฐ, ั ะฒะฒะฐะถะฐะฒ ะณะตะฝัะฐะปัะฝะพั ัะดะตัั.
+
+ ะ ะฟััะปั ััะธะฒะฐะปะพะณะพ ะฟะพััะบั ะฟะพะดัะฑะฝะพั ััััะบัััะธ ัะฐ ัะตัััะฒะฐะฝะฝั ะฑะฐะณะฐััะพั
ััะทะฝะธั
ะฐะปััะตัะฝะฐัะธะฒ, APIStar ััะฐะฒ ะฝะฐะนะบัะฐัะธะผ ะดะพัััะฟะฝะธะผ ะฒะฐััะฐะฝัะพะผ.
+
+ ะะพััะผ APIStar ะฟะตัะตััะฐะฒ ััะฝัะฒะฐัะธ ัะบ ัะตัะฒะตั, ั ะฑัะปะพ ััะฒะพัะตะฝะพ Starlette, ัะบะธะน ััะฐะฒ ะฝะพะฒะพั ะบัะฐัะพั ะพัะฝะพะฒะพั ะดะปั ัะฐะบะพั ัะธััะตะผะธ. ะฆะต ััะฐะปะพ ะพััะฐะฝะฝัะผ ะดะถะตัะตะปะพะผ ะฝะฐัั
ะฝะตะฝะฝั ะดะปั ััะฒะพัะตะฝะฝั **FastAPI**. ะฏ ะฒะฒะฐะถะฐั **FastAPI** ยซะดัั
ะพะฒะฝะธะผ ัะฟะฐะดะบะพัะผัะตะผยป APIStar, ัะดะพัะบะพะฝะฐะปัััะธ ัะฐ ัะพะทัะธััััะธ ััะฝะบััั, ัะธััะตะผั ะฒะฒะตะดะตะฝะฝั ัะตะบััั ัะฐ ัะฝัั ัะฐััะธะฝะธ ะฝะฐ ะพัะฝะพะฒั ะดะพัะฒัะดั, ะพััะธะผะฐะฝะพะณะพ ะฒัะด ัััั
ัะธั
ะฟะพะฟะตัะตะดะฝัั
ัะฝััััะผะตะฝััะฒ.
+
+## ะะธะบะพัะธััะพะฒัััััั **FastAPI**
+
+### Pydantic
+
+Pydantic โ ัะต ะฑัะฑะปัะพัะตะบะฐ ะดะปั ะฒะธะทะฝะฐัะตะฝะฝั ะฟะตัะตะฒััะบะธ ะดะฐะฝะธั
, ัะตััะฐะปัะทะฐััั ัะฐ ะดะพะบัะผะตะฝัะฐััั (ะทะฐ ะดะพะฟะพะผะพะณะพั ัั
ะตะผะธ JSON) ะฝะฐ ะพัะฝะพะฒั ะฟัะดะบะฐะทะพะบ ัะธะฟั Python.
+
+ะฆะต ัะพะฑะธัั ะนะพะณะพ ะฝะฐะดะทะฒะธัะฐะนะฝะพ ัะฝััััะธะฒะฝะธะผ.
+
+ะะพะณะพ ะผะพะถะฝะฐ ะฟะพััะฒะฝััะธ ะท Marshmallow. ะฅะพัะฐ ะฒัะฝ ัะฒะธะดัะธะน ะทะฐ Marshmallow ั ัะตััะฐั
. ะัะบัะปัะบะธ ะฒัะฝ ะฑะฐะทัััััั ะฝะฐ ัะธั
ัะฐะผะธั
ะฟัะดะบะฐะทะบะฐั
ัะธะฟั Python, ะฟัะดััะธะผะบะฐ ัะตะดะฐะบัะพัะฐ ััะดะพะฒะฐ.
+
+!!! ะะตัะตะณะปัะฝััะต "**FastAPI** ะฒะธะบะพัะธััะพะฒัั ะนะพะณะพ ะดะปั"
+ ะะธะบะพะฝะฐะฝะฝั ะฟะตัะตะฒััะบะธ ะฒััั
ะดะฐะฝะธั
, ัะตััะฐะปัะทะฐััั ะดะฐะฝะธั
ั ะฐะฒัะพะผะฐัะธัะฝะพั ะดะพะบัะผะตะฝัะฐััั ะผะพะดะตะปั (ะฝะฐ ะพัะฝะพะฒั ัั
ะตะผะธ JSON).
+
+ ะะพััะผ **FastAPI** ะฑะตัะต ัั ะดะฐะฝั ัั
ะตะผะธ JSON ั ัะพะทะผัััั ัั
ั OpenAPI, ะพะบัะตะผะพ ะฒัะด ัััั
ัะฝัะธั
ัะตัะตะน, ัะบั ะฒัะฝ ัะพะฑะธัั.
+
+### Starlette
+
+Starlette โ ัะต ะปะตะณะบะธะน ััะตะนะผะฒะพัะบ/ะฝะฐะฑัั ัะฝััััะผะตะฝััะฒ ASGI, ัะบะธะน ัะดะตะฐะปัะฝะพ ะฟัะดั
ะพะดะธัั ะดะปั ััะฒะพัะตะฝะฝั ะฒะธัะพะบะพะฟัะพะดัะบัะธะฒะฝะธั
asyncio ัะตัะฒัััะฒ.
+
+ะัะฝ ะดัะถะต ะฟัะพััะธะน ัะฐ ัะฝััััะธะฒะฝะพ ะทัะพะทัะผัะปะธะน. ะะพะณะพ ัะพะทัะพะฑะปะตะฝะพ ัะฐะบะธะผ ัะธะฝะพะผ, ัะพะฑ ะนะพะณะพ ะผะพะถะฝะฐ ะฑัะปะพ ะปะตะณะบะพ ัะพะทัะธััะฒะฐัะธ ัะฐ ะผะฐัะธ ะผะพะดัะปัะฝั ะบะพะผะฟะพะฝะตะฝัะธ.
+
+ะัะฝ ะผะฐั:
+
+* ะกะตัะนะพะทะฝะพ ะฒัะฐะถะฐััั ะฟัะพะดัะบัะธะฒะฝัััั.
+* ะัะดััะธะผะบั WebSocket.
+* ะคะพะฝะพะฒั ะทะฐะฒะดะฐะฝะฝั ะฒ ะฟัะพัะตัั.
+* ะะพะดัั ะทะฐะฟััะบั ัะฐ ะทะฐะฒะตััะตะฝะฝั ัะพะฑะพัะธ.
+* ะขะตััะพะฒะพะณะพ ะบะปััะฝัะฐ, ะฟะพะฑัะดะพะฒะฐะฝะธะน ะฝะฐ HTTPX.
+* CORS, GZip, ััะฐัะธัะฝั ัะฐะนะปะธ, ะฟะพัะพะบะพะฒั ะฒัะดะฟะพะฒัะดั.
+* ะัะดััะธะผะบั ัะตะฐะฝััะฒ ั ัะฐะนะปัะฒ cookie.
+* 100% ะฟะพะบัะธััั ัะตััะพะผ.
+* 100% ะฐะฝะพัะพะฒะฐะฝั ะบะพะดะพะฒั ะฑะฐะทั.
+* ะัะปัะบะฐ ะถะพัััะบะธั
ะทะฐะปะตะถะฝะพััะตะน.
+
+Starlette ะฝะฐัะฐะทั ั ะฝะฐะนัะฒะธะดัะธะผ ััะตะนะผะฒะพัะบะพะผ Python ัะท ะฟะตัะตะฒััะตะฝะธั
. ะะตัะตะฒะตัััั ะปะธัะต Uvicorn, ัะบะธะน ั ะฝะต ััะตะนะผะฒะพัะบะพะผ, ะฐ ัะตัะฒะตัะพะผ.
+
+Starlette ะฝะฐะดะฐั ะฒัั ะพัะฝะพะฒะฝั ััะฝะบััั ะฒะตะฑ-ะผัะบัะพััะตะนะผะฒะพัะบั.
+
+ะะปะต ะฒัะฝ ะฝะต ะทะฐะฑะตะทะฟะตััั ะฐะฒัะพะผะฐัะธัะฝะพั ะฟะตัะตะฒััะบะธ ะดะฐะฝะธั
, ัะตััะฐะปัะทะฐััั ัะธ ะดะพะบัะผะตะฝัะฐััั.
+
+ะฆะต ะพะดะฝะฐ ะท ะณะพะปะพะฒะฝะธั
ัะตัะตะน, ัะบั **FastAPI** ะดะพะดะฐั ะทะฒะตัั
ั, ะฒัะต ะฝะฐ ะพัะฝะพะฒั ะฟัะดะบะฐะทะพะบ ัะธะฟั Python (ะท ะฒะธะบะพัะธััะฐะฝะฝัะผ Pydantic). ะฆะต, ะฐ ัะฐะบะพะถ ัะธััะตะผะฐ ะฒะฟัะพะฒะฐะดะถะตะฝะฝั ะทะฐะปะตะถะฝะพััะตะน, ััะธะปััะธ ะฑะตะทะฟะตะบะธ, ััะฒะพัะตะฝะฝั ัั
ะตะผะธ OpenAPI ัะพัะพ.
+
+!!! ะัะธะผััะบะฐ "ะขะตั
ะฝััะฝั ะดะตัะฐะปั"
+ ASGI โ ัะต ะฝะพะฒะธะน ยซััะฐะฝะดะฐััยป, ัะบะธะน ัะพะทัะพะฑะปัััััั ัะปะตะฝะฐะผะธ ะพัะฝะพะฒะฝะพั ะบะพะผะฐะฝะดะธ Django. ะฆะต ัะต ะฝะต ยซััะฐะฝะดะฐัั Pythonยป (PEP), ั
ะพัะฐ ะฒะพะฝะธ ะฒ ะฟัะพัะตัั ััะพะณะพ.
+
+ ะขะธะผ ะฝะต ะผะตะฝั, ะฒัะฝ ัะถะต ะฒะธะบะพัะธััะพะฒัััััั ัะบ ยซััะฐะฝะดะฐััยป ะบัะปัะบะพะผะฐ ัะฝััััะผะตะฝัะฐะผะธ. ะฆะต ะทะฝะฐัะฝะพ ะฟะพะบัะฐััั ััะผััะฝัััั, ะพัะบัะปัะบะธ ะฒะธ ะผะพะถะตัะต ะฟะตัะตะบะปััะธัะธ Uvicorn ะฝะฐ ะฑัะดั-ัะบะธะน ัะฝัะธะน ัะตัะฒะตั ASGI (ะฝะฐะฟัะธะบะปะฐะด, Daphne ะฐะฑะพ Hypercorn), ะฐะฑะพ ะฒะธ ะผะพะถะตัะต ะดะพะดะฐัะธ ัะฝััััะผะตะฝัะธ, ััะผััะฝั ะท ASGI, ัะบ-ะพั `python-socketio`.
+
+!!! ะะตัะตะณะปัะฝััะต "**FastAPI** ะฒะธะบะพัะธััะพะฒัั ะนะพะณะพ ะดะปั"
+ ะะตััะฒะฐะฝะฝั ะฒััะผะฐ ะพัะฝะพะฒะฝะธะผะธ ะฒะตะฑ-ัะฐััะธะฝะฐะผะธ. ะะพะดะฐะฒะฐะฝะฝั ััะฝะบััะน ะทะฒะตัั
ั.
+
+ ะกะฐะผ ะบะปะฐั `FastAPI` ะฑะตะทะฟะพัะตัะตะดะฝัะพ ััะฟะฐะดะบะพะฒัั ะบะปะฐั `Starlette`.
+
+ ะัะถะต, ััะต, ัะพ ะฒะธ ะผะพะถะตัะต ัะพะฑะธัะธ ะทั Starlette, ะฒะธ ะผะพะถะตัะต ัะพะฑะธัะธ ัะต ะฑะตะทะฟะพัะตัะตะดะฝัะพ ะทะฐ ะดะพะฟะพะผะพะณะพั **FastAPI**, ะพัะบัะปัะบะธ ัะต, ะฟะพ ัััั, Starlette ะฝะฐ ััะตัะพัะดะฐั
.
+
+### Uvicorn
+
+Uvicorn โ ัะต ะฑะปะธัะบะฐะฒะธัะฝะธะน ัะตัะฒะตั ASGI, ะฟะพะฑัะดะพะฒะฐะฝะธะน ะฝะฐ uvloop ั httptools.
+
+ะฆะต ะฝะต ะฒะตะฑ-ััะตะนะผะฒะพัะบ, ะฐ ัะตัะฒะตั. ะะฐะฟัะธะบะปะฐะด, ะฒัะฝ ะฝะต ะฝะฐะดะฐั ัะฝััััะผะตะฝััะฒ ะดะปั ะผะฐัััััะธะทะฐััั. ะฆะต ัะต, ัะพ ััะตะนะผะฒะพัะบ ะฝะฐ ะบััะฐะปั Starlette (ะฐะฑะพ **FastAPI**) ะทะฐะฑะตะทะฟะตัะธัั ะฟะพะฒะตัั
ะฝัะพะณะพ.
+
+ะฆะต ัะตะบะพะผะตะฝะดะพะฒะฐะฝะธะน ัะตัะฒะตั ะดะปั Starlette ั **FastAPI**.
+
+!!! ะะตัะตะณะปัะฝััะต "**FastAPI** ัะตะบะพะผะตะฝะดัั ัะต ัะบ"
+ ะัะฝะพะฒะฝะธะน ะฒะตะฑ-ัะตัะฒะตั ะดะปั ะทะฐะฟััะบั ะฟัะพะณัะฐะผ **FastAPI**.
+
+ ะะธ ะผะพะถะตัะต ะฟะพัะดะฝะฐัะธ ะนะพะณะพ ะท Gunicorn, ัะพะฑ ะผะฐัะธ ะฐัะธะฝั
ัะพะฝะฝะธะน ะฑะฐะณะฐัะพะฟัะพัะตัะฝะธะน ัะตัะฒะตั.
+
+ ะะพะดะฐัะบะพะฒั ัะฝัะพัะผะฐััั ะดะธะฒ. ั ัะพะทะดัะปั [ะ ะพะทะณะพััะฐะฝะฝั](deployment/index.md){.internal-link target=_blank}.
+
+## ะัััะฝัะธัะธ ัะฐ ัะฒะธะดะบัััั
+
+ะฉะพะฑ ะทัะพะทัะผััะธ, ะฟะพััะฒะฝััะธ ัะฐ ะฟะพะฑะฐัะธัะธ ััะทะฝะธัั ะผัะถ Uvicorn, Starlette ั FastAPI, ะฟะตัะตะณะปัะฝััะต ัะพะทะดัะป ะฟัะพ [ะะตะฝัะผะฐัะบะธ](benchmarks.md){.internal-link target=_blank}.
diff --git a/docs/uk/docs/python-types.md b/docs/uk/docs/python-types.md
new file mode 100644
index 000000000..6c8e29016
--- /dev/null
+++ b/docs/uk/docs/python-types.md
@@ -0,0 +1,448 @@
+# ะัััะฟ ะดะพ ัะธะฟัะฒ Python
+
+Python ะฟัะดััะธะผัั ะดะพะดะฐัะบะพะฒั "ะฟัะดะบะฐะทะบะธ ัะธะฟั" ("type hints") (ัะฐะบะพะถ ะทะฒะฐะฝั "ะฐะฝะพัะฐัััะผะธ ัะธะฟั" ("type annotations")).
+
+ะฆั **"type hints"** ั ัะฟะตััะฐะปัะฝะธะผ ัะธะฝัะฐะบัะธัะพะผ, ัะพ ะดะพะทะฒะพะปัั ะพะณะพะปะพััะฒะฐัะธ ัะธะฟ ะทะผัะฝะฝะพั.
+
+ะะฐ ะดะพะฟะพะผะพะณะพั ะพะณะพะปะพัะตะฝะฝั ัะธะฟัะฒ ะดะปั ะฒะฐัะธั
ะทะผัะฝะฝะธั
, ัะตะดะฐะบัะพัะธ ัะฐ ัะฝััััะผะตะฝัะธ ะผะพะถััั ะฝะฐะดะฐัะธ ะฒะฐะผ ะบัะฐัั ะฟัะดััะธะผะบั.
+
+ะฆะต ะฟัะพััะพ **ัะฒะธะดะบะธะน ะฟะพััะฑะฝะธะบ / ะฝะฐะณะฐะดัะฒะฐะฝะฝั** ะฟัะพ ะฐะฝะพัะฐััั ัะธะฟัะฒ ั Python. ะัะฝ ะฟะพะบัะธะฒะฐั ะปะธัะต ะผัะฝัะผัะผ, ะฝะตะพะฑั
ัะดะฝะธะน ัะพะฑ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ัั
ะท **FastAPI**... ัะพ ะฝะฐัะฟัะฐะฒะดั ะดัะถะต ะผะฐะปะพ.
+
+**FastAPI** ะฟะพะฒะฝัััั ะฑะฐะทัััััั ะฝะฐ ัะธั
ะฐะฝะพัะฐัััั
ัะธะฟัะฒ, ะฒะพะฝะธ ะดะฐััั ะนะพะผั ะฑะฐะณะฐัะพ ะฟะตัะตะฒะฐะณ.
+
+ะะปะต ะฝะฐะฒััั ัะบัะพ ะฒะธ ะฝัะบะพะปะธ ะฝะต ะฒะธะบะพัะธััะฐััะต **FastAPI**, ะฒะฐะผ ะฑัะดะต ะบะพัะธัะฝะพ ะดัะทะฝะฐัะธัั ััะพั
ะธ ะฟัะพ ะฝะธั
.
+
+!!! note
+ ะฏะบัะพ ะฒะธ ะตะบัะฟะตัั ั Python ั ะฒะธ ะฒะถะต ะทะฝะฐััะต ััะต ะฟัะพ ะฐะฝะพัะฐััั ัะธะฟัะฒ - ะฟะตัะตะนะดััั ะดะพ ะฝะฐัััะฟะฝะพะณะพ ัะพะทะดัะปั.
+
+## ะะพัะธะฒะฐััั
+
+ะะฐะฒะฐะนัะต ะฟะพัะฝะตะผะพ ะท ะฟัะพััะพะณะพ ะฟัะธะบะปะฐะดั:
+
+```Python
+{!../../../docs_src/python_types/tutorial001.py!}
+```
+
+ะะธะบะปะธะบ ัััั ะฟัะพะณัะฐะผะธ ะฒะธะฒะพะดะธัั:
+
+```
+John Doe
+```
+
+ะคัะฝะบััั ะฒะธะบะพะฝัั ะฝะฐัััะฟะฝะต:
+
+* ะะตัะต `first_name` ัะฐ `last_name`.
+* ะะพะฝะฒะตัััั ะบะพะถะฝั ะปััะตัั ะบะพะถะฝะพะณะพ ัะปะพะฒะฐ ั ะฒะตัั
ะฝัะน ัะตะณัััั ะทะฐ ะดะพะฟะพะผะพะณะพั `title()`.
+* ะะพะฝะบะฐัะตะฝัั ัั
ัะฐะทะพะผ ัะท ะฟัะพะฑัะปะพะผ ะฟะพ ัะตัะตะดะธะฝั.
+
+```Python hl_lines="2"
+{!../../../docs_src/python_types/tutorial001.py!}
+```
+
+### ะ ะตะดะฐะณัะนัะต ัะต
+
+ะฆะต ะดัะถะต ะฟัะพััะฐ ะฟัะพะณัะฐะผะฐ.
+
+ะะปะต ัะตะฟะตั ััะฒััั, ัะพ ะฒะธ ะฟะธัะฐะปะธ ัะต ะท ะฝัะปั.
+
+ะฃ ะฟะตะฒะฝะธะน ะผะพะผะตะฝั ะฒะธ ัะพะทะฟะพัะฐะปะธ ะฑ ะฒะธะทะฝะฐัะตะฝะฝั ััะฝะบััั, ั ะฒะฐั ะฑัะปะธ ะฑ ะณะพัะพะฒั ะฟะฐัะฐะผะตััะธ...
+
+ะะปะต ัะพะดั ะฒะฐะผ ะฟะพัััะฑะฝะพ ะฒะธะบะปะธะบะฐัะธ "ัะพะน ะผะตัะพะด, ัะบะธะน ะฟะตัะตะฒะพะดะธัั ะฟะตััั ะปััะตัั ั ะฒะตัั
ะฝัะน ัะตะณัััั".
+
+ะฆะต ะฑัะดะต `upper`? ะงะธ `uppercase`? `first_uppercase`? `capitalize`?
+
+ะขะพะดั ะฒะธ ัะฟัะพะฑัััะต ะดะฐะฒะฝัะพะณะพ ะดััะณะฐ ะฟัะพะณัะฐะผัััะฐ - ะฐะฒัะพะทะฐะฟะพะฒะฝะตะฝะฝั ัะตะดะฐะบัะพัะฐ ะบะพะดั.
+
+ะะธ ะฝะฐะดััะบัััะต ะฟะตััะธะน ะฟะฐัะฐะผะตัั ััะฝะบััั, `first_name`, ัะพะดั ะบัะฐะฟะบั (`.`), ะฐ ัะพะดั ะฝะฐัะธัะฝะตัะต `Ctrl+Space`, ัะพะฑ ะทะฐะฟัััะธัะธ ะฐะฒัะพะทะฐะฟะพะฒะฝะตะฝะฝั.
+
+ะะปะต, ะฝะฐ ะถะฐะปั, ะฒะธ ะฝะต ะพััะธะผะฐััะต ะฝััะพะณะพ ะบะพัะธัะฝะพะณะพ:
+
+
+
+### ะะพะดะฐะนัะต ัะธะฟะธ
+
+ะะฐะฒะฐะนัะต ะทะผัะฝะธะผะพ ะพะดะธะฝ ััะดะพะบ ะท ะฟะพะฟะตัะตะดะฝัะพั ะฒะตัััั.
+
+ะะธ ะทะผัะฝะธะผะพ ัะฐะผะต ัะตะน ััะฐะณะผะตะฝั, ะฟะฐัะฐะผะตััะธ ััะฝะบััั, ะท:
+
+```Python
+ first_name, last_name
+```
+
+ะฝะฐ:
+
+```Python
+ first_name: str, last_name: str
+```
+
+ะัั ั ะฒัะต.
+
+ะฆะต "type hints":
+
+```Python hl_lines="1"
+{!../../../docs_src/python_types/tutorial002.py!}
+```
+
+ะฆะต ะฝะต ัะต ัะฐะผะต, ัะพ ะพะณะพะปะพัะตะฝะฝั ะทะฝะฐัะตะฝั ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ, ัะบ ัะต ะฑัะปะพ ะฑ ะท:
+
+```Python
+ first_name="john", last_name="doe"
+```
+
+ะฆะต ะทะพะฒััะผ ัะฝัะต.
+
+ะะธ ะฒะธะบะพัะธััะพะฒััะผะพ ะดะฒะพะบัะฐะฟะบั (`:`), ะฝะต ะดะพััะฒะฝัั (`=`).
+
+ะ ะดะพะดะฐะฒะฐะฝะฝั ะฐะฝะพัะฐััั ัะธะฟั ะทะฐะทะฒะธัะฐะน ะฝะต ะทะผัะฝัั ัะพะณะพ, ัะพ ััะฐะปะพัั ะฑะธ ะฑะตะท ะฝะธั
.
+
+ะะปะต ัะตะฟะตั, ััะฒััั ัะพ ะฒะธ ะฟะพัะตัะตะด ะฟัะพัะตัั ััะฒะพัะตะฝะฝั ััะฝะบััั, ะฐะปะต ะท ะฐะฝะพัะฐัััะผะธ ัะธะฟัะฒ.
+
+ะ ัะตะน ะถะต ะผะพะผะตะฝั, ะฒะธ ัะฟัะพะฑัััะต ะฒะธะบะปะธะบะฐัะธ ะฐะฒัะพะทะฐะฟะพะฒะฝะตะฝะฝั ะท ะดะพะฟะพะผะพะณะพั `Ctrl+Space` ั ะฟะพะฑะฐัะธัะต:
+
+
+
+ะ ะฐะทะพะผ ะท ัะธะผ, ะฒะธ ะผะพะถะตัะต ะฟัะพะบััััะฒะฐัะธ, ะฟะตัะตะณะปัะดะฐัะธ ะพะฟััั, ะดะพะฟะพะบะธ ะฒะธ ะฝะต ะทะฝะฐะนะดะตัะต ะพะดะฝั, ัะพ ะทะฒััะธัั ัั
ะพะถะต:
+
+
+
+## ะัะปััะต ะผะพัะธะฒะฐััั
+
+ะะตัะตะฒัััะต ัั ััะฝะบััั, ะฒะพะฝะฐ ะฒะถะต ะผะฐั ะฐะฝะพัะฐััั ัะธะฟั:
+
+```Python hl_lines="1"
+{!../../../docs_src/python_types/tutorial003.py!}
+```
+
+ะัะบัะปัะบะธ ัะตะดะฐะบัะพั ะทะฝะฐั ัะธะฟะธ ะทะผัะฝะฝะธั
, ะฒะธ ะฝะต ััะปัะบะธ ะพััะธะผะฐััะต ะฐะฒัะพะทะฐะฟะพะฒะฝะตะฝะฝั, ะฒะธ ัะฐะบะพะถ ะพััะธะผะฐััะต ะฟะตัะตะฒััะบั ะฟะพะผะธะปะพะบ:
+
+
+
+ะขะตะฟะตั ะฒะธ ะทะฝะฐััะต, ัะพะฑ ะฒะธะฟัะฐะฒะธัะธ ัะต, ะฒะฐะผ ะฟะพัััะฑะฝะพ ะฟะตัะตัะฒะพัะธัะธ `age` ั ัััะพะบั ะท ะดะพะฟะพะผะพะณะพั `str(age)`:
+
+```Python hl_lines="2"
+{!../../../docs_src/python_types/tutorial004.py!}
+```
+
+## ะะณะพะปะพัะตะฝะฝั ัะธะฟัะฒ
+
+ะฉะพะนะฝะพ ะฒะธ ะฟะพะฑะฐัะธะปะธ ะพัะฝะพะฒะฝะต ะผัััะต ะดะปั ะพะณะพะปะพัะตะฝะฝั ะฐะฝะพัะฐััะน ัะธะฟั. ะฏะบ ะฟะฐัะฐะผะตััะธ ััะฝะบััั.
+
+ะฆะต ัะฐะบะพะถ ะพัะฝะพะฒะฝะต ะผัััะต, ะดะต ะฒะธ ะฑ ัั
ะฒะธะบะพัะธััะพะฒัะฒะฐะปะธ ั **FastAPI**.
+
+### ะัะพััั ัะธะฟะธ
+
+ะะธ ะผะพะถะตัะต ะพะณะพะปะพััะฒะฐัะธ ััั ััะฐะฝะดะฐััะฝั ัะธะฟะธ ั Python, ะฝะต ััะปัะบะธ `str`.
+
+ะะธ ะผะพะถะตัะต ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ, ะฝะฐะฟัะธะบะปะฐะด:
+
+* `int`
+* `float`
+* `bool`
+* `bytes`
+
+```Python hl_lines="1"
+{!../../../docs_src/python_types/tutorial005.py!}
+```
+
+### Generic-ัะธะฟะธ ะท ะฟะฐัะฐะผะตััะฐะผะธ ัะธะฟัะฒ
+
+ะัะฝัััั ะดะตัะบั ััััะบัััะธ ะดะฐะฝะธั
, ัะบั ะผะพะถััั ะผัััะธัะธ ัะฝัั ะทะฝะฐัะตะฝะฝั, ะฝะฐะฟัะธะบะปะฐะด `dict`, `list`, `set` ัะฐ `tuple`. ะ ะฒะฝัััััะฝั ะทะฝะฐัะตะฝะฝั ัะฐะบะพะถ ะผะพะถััั ะผะฐัะธ ัะฒัะน ัะธะฟ.
+
+ะฆั ัะธะฟะธ, ัะบั ะผะฐััั ะฒะฝัััััะฝั ัะธะฟะธ, ะฝะฐะทะธะฒะฐััััั "**generic**" ัะธะฟะฐะผะธ. ะ ะพะณะพะปะพัะธัะธ ัั
ะผะพะถะฝะฐ ะฝะฐะฒััั ัะท ะฒะฝัััััะฝัะผะธ ัะธะฟะฐะผะธ.
+
+ะฉะพะฑ ะพะณะพะปะพัะธัะธ ัั ัะธะฟะธ ัะฐ ะฒะฝัััััะฝั ัะธะฟะธ, ะฒะธ ะผะพะถะตัะต ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ััะฐะฝะดะฐััะฝะธะน ะผะพะดัะปั Python `typing`. ะัะฝ ััะฝัั ัะฟะตััะฐะปัะฝะพ ะดะปั ะฟัะดััะธะผะบะธ ะฐะฝะพัะฐััะน ัะธะฟัะฒ.
+
+#### ะะพะฒััั ะฒะตัััั Python
+
+ะกะธะฝัะฐะบัะธั ัะท ะฒะธะบะพัะธััะฐะฝะฝัะผ `typing` **ััะผััะฝะธะน** ะท ัััะผะฐ ะฒะตััััะผะธ, ะฒัะด Python 3.6 ะดะพ ะพััะฐะฝะฝัั
, ะฒะบะปััะฐััะธ Python 3.9, Python 3.10 ัะพัะพ.
+
+ะฃ ะผััั ัะพะทะฒะธัะบั Python **ะฝะพะฒััั ะฒะตัััั** ะผะฐััั ะฟะพะบัะฐัะตะฝั ะฟัะดััะธะผะบั ะฐะฝะพัะฐััะน ัะธะฟัะฒ ั ะฒ ะฑะฐะณะฐััะพั
ะฒะธะฟะฐะดะบะฐั
ะฒะฐะผ ะฝะฐะฒััั ะฝะต ะฟะพัััะฑะฝะพ ะฑัะดะต ัะผะฟะพัััะฒะฐัะธ ัะฐ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ะผะพะดัะปั `typing` ะดะปั ะพะณะพะปะพัะตะฝะฝั ะฐะฝะพัะฐััะน ัะธะฟั.
+
+ะฏะบัะพ ะฒะธ ะผะพะถะตัะต ะฒะธะฑัะฐัะธ ะฝะพะฒััั ะฒะตัััั Python ะดะปั ัะฒะพะณะพ ะฟัะพะตะบัั, ะฒะธ ะทะผะพะถะตัะต ัะบะพัะธััะฐัะธัั ัััั ะดะพะดะฐัะบะพะฒะพั ะฟัะพััะพัะพั. ะะธะฒััััั ะบัะปัะบะฐ ะฟัะธะบะปะฐะดัะฒ ะฝะธะถัะต.
+
+#### List (ัะฟะธัะพะบ)
+
+ะะฐะฟัะธะบะปะฐะด, ะดะฐะฒะฐะนัะต ะฒะธะทะฝะฐัะธะผะพ ะทะผัะฝะฝั, ัะบะฐ ะฑัะดะต `list` ัะท `str`.
+
+=== "Python 3.8 ั ะฒะธัะต"
+
+ ะ ะผะพะดัะปั `typing`, ัะผะฟะพััััะผะพ `List` (ะท ะฒะตะปะธะบะพั ะปััะตัะธ `L`):
+
+ ``` Python hl_lines="1"
+ {!> ../../../docs_src/python_types/tutorial006.py!}
+ ```
+
+ ะะณะพะปะพัะธะผะพ ะทะผัะฝะฝั ะท ัะธะผ ัะฐะผะธะผ ัะธะฝัะฐะบัะธัะพะผ ะดะฒะพะบัะฐะฟะบะธ (`:`).
+
+ ะฏะบ ัะธะฟ ะฒะบะฐะถะตะผะพ `List`, ัะบะธะน ะฒะธ ัะผะฟะพัััะฒะฐะปะธ ะท `typing`.
+
+ ะัะบัะปัะบะธ ัะฟะธัะพะบ ั ัะธะฟะพะผ, ัะบะธะน ะผัััะธัั ะดะตัะบั ะฒะฝัััััะฝั ัะธะฟะธ, ะฒะธ ะฟะพะผััะฐััะต ัั
ั ะบะฒะฐะดัะฐัะฝั ะดัะถะบะธ:
+
+ ```Python hl_lines="4"
+ {!> ../../../docs_src/python_types/tutorial006.py!}
+ ```
+
+=== "Python 3.9 ั ะฒะธัะต"
+
+ ะะณะพะปะพัะธะผะพ ะทะผัะฝะฝั ะท ัะธะผ ัะฐะผะธะผ ัะธะฝัะฐะบัะธัะพะผ ะดะฒะพะบัะฐะฟะบะธ (`:`).
+
+ ะฏะบ ัะธะฟ ะฒะบะฐะถะตะผะพ `list`.
+
+ ะัะบัะปัะบะธ ัะฟะธัะพะบ ั ัะธะฟะพะผ, ัะบะธะน ะผัััะธัั ะดะตัะบั ะฒะฝัััััะฝั ัะธะฟะธ, ะฒะธ ะฟะพะผััะฐััะต ัั
ั ะบะฒะฐะดัะฐัะฝั ะดัะถะบะธ:
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/python_types/tutorial006_py39.py!}
+ ```
+
+!!! info
+ ะฆั ะฒะฝัััััะฝั ัะธะฟะธ ะฒ ะบะฒะฐะดัะฐัะฝะธั
ะดัะถะบะฐั
ะฝะฐะทะธะฒะฐััััั "ะฟะฐัะฐะผะตััะฐะผะธ ัะธะฟั".
+
+ ะฃ ััะพะผั ะฒะธะฟะฐะดะบั, `str` ัะต ะฟะฐัะฐะผะตัั ัะธะฟั ะฟะตัะตะดะฐะฝะธะน ั `List` (ะฐะฑะพ `list` ั Python 3.9 ั ะฒะธัะต).
+
+ะฆะต ะพะทะฝะฐัะฐั: "ะทะผัะฝะฝะฐ `items` ัะต `list`, ั ะบะพะถะตะฝ ะท ะตะปะตะผะตะฝััะฒ ั ััะพะผั ัะฟะธัะบั - `str`".
+
+!!! tip
+ ะฏะบัะพ ะฒะธ ะฒะธะบะพัะธััะพะฒัััะต Python 3.9 ั ะฒะธัะต, ะฒะฐะผ ะฝะต ะฟะพัััะฑะฝะพ ัะผะฟะพัััะฒะฐัะธ `List` ะท `typing`, ะฒะธ ะผะพะถะตัะต ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ะฝะฐัะพะผัััั ัะธะฟ `list`.
+
+ะัะพะฑะธะฒัะธ ัะต, ะฒะฐั ัะตะดะฐะบัะพั ะผะพะถะต ะฝะฐะดะฐัะธ ะฟัะดััะธะผะบั ะฝะฐะฒััั ะฟัะด ัะฐั ะพะฑัะพะฑะบะธ ะตะปะตะผะตะฝััะฒ ะทั ัะฟะธัะบั:
+
+
+
+ะะตะท ัะธะฟัะฒ ััะพะณะพ ะผะฐะนะถะต ะฝะตะผะพะถะปะธะฒะพ ะดะพััะณัะธ.
+
+ะะฒะตัะฝััั ัะฒะฐะณั, ัะพ ะทะผัะฝะฝะฐ `item` ั ะพะดะฝะธะผ ัะท ะตะปะตะผะตะฝััะฒ ั ัะฟะธัะบั `items`.
+
+ะ ะฒัะต ะถ ัะตะดะฐะบัะพั ะทะฝะฐั, ัะพ ัะต `str`, ั ะฝะฐะดะฐั ะฟัะดััะธะผะบั ะดะปั ััะพะณะพ.
+
+#### Tuple and Set (ะบะพััะตะถ ัะฐ ะฝะฐะฑัั)
+
+ะะธ ะฟะพะฒะธะฝะฝั ะทัะพะฑะธัะธ ัะต ะถ ัะฐะผะต, ัะพะฑ ะพะณะพะปะพัะธัะธ `tuple` ั `set`:
+
+=== "Python 3.8 ั ะฒะธัะต"
+
+ ```Python hl_lines="1 4"
+ {!> ../../../docs_src/python_types/tutorial007.py!}
+ ```
+
+=== "Python 3.9 ั ะฒะธัะต"
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/python_types/tutorial007_py39.py!}
+ ```
+
+ะฆะต ะพะทะฝะฐัะฐั:
+
+* ะะผัะฝะฝะฐ `items_t` ัะต `tuple` ะท 3 ะตะปะตะผะตะฝัะฐะผะธ, `int`, ัะต `int`, ัะฐ `str`.
+* ะะผัะฝะฝะฐ `items_s` ัะต `set`, ั ะบะพะถะตะฝ ะนะพะณะพ ะตะปะตะผะตะฝั ัะธะฟั `bytes`.
+
+#### Dict (ัะปะพะฒะฝะธะบ)
+
+ะฉะพะฑ ะพะณะพะปะพัะธัะธ `dict`, ะฒะฐะผ ะฟะพัััะฑะฝะพ ะฟะตัะตะดะฐัะธ 2 ะฟะฐัะฐะผะตััะธ ัะธะฟั, ัะพะทะดัะปะตะฝั ะบะพะผะฐะผะธ.
+
+ะะตััะธะน ะฟะฐัะฐะผะตัั ัะธะฟั ะดะปั ะบะปััะฐ ั `dict`.
+
+ะััะณะธะน ะฟะฐัะฐะผะตัั ัะธะฟั ะดะปั ะทะฝะฐัะตะฝะฝั ั `dict`:
+
+=== "Python 3.8 ั ะฒะธัะต"
+
+ ```Python hl_lines="1 4"
+ {!> ../../../docs_src/python_types/tutorial008.py!}
+ ```
+
+=== "Python 3.9 ั ะฒะธัะต"
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/python_types/tutorial008_py39.py!}
+ ```
+
+ะฆะต ะพะทะฝะฐัะฐั:
+
+* ะะผัะฝะฝะฐ `prices` ัะต `dict`:
+ * ะะปััั ััะพะณะพ `dict` ัะธะฟั `str` (ะฝะฐะฟัะธะบะปะฐะด, ะฝะฐะทะฒะฐ ะบะพะถะฝะพะณะพ ะตะปะตะผะตะฝัั).
+ * ะะฝะฐัะตะฝะฝั ััะพะณะพ `dict` ัะธะฟั `float` (ะฝะฐะฟัะธะบะปะฐะด, ััะฝะฐ ะบะพะถะฝะพะณะพ ะตะปะตะผะตะฝัั).
+
+#### Union (ะพะฑ'ัะดะฝะฐะฝะฝั)
+
+ะะธ ะผะพะถะตัะต ะพะณะพะปะพัะธัะธ, ัะพ ะทะผัะฝะฝะฐ ะผะพะถะต ะฑััะธ ะฑัะดั-ัะบะธะผ ัะท **ะบัะปัะบะพั
ัะธะฟัะฒ**, ะฝะฐะฟัะธะบะปะฐะด, `int` ะฐะฑะพ `str`.
+
+ะฃ Python 3.6 ั ะฒะธัะต (ะฒะบะปััะฐััะธ Python 3.10) ะฒะธ ะผะพะถะตัะต ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ัะธะฟ `Union` ะท `typing` ั ะฒััะฐะฒะปััะธ ะฒ ะบะฒะฐะดัะฐัะฝั ะดัะถะบะธ ะผะพะถะปะธะฒั ัะธะฟะธ, ัะบั ะผะพะถะฝะฐ ะฟัะธะนะฝััะธ.
+
+ะฃ Python 3.10 ัะฐะบะพะถ ั **ะฐะปััะตัะฝะฐัะธะฒะฝะธะน ัะธะฝัะฐะบัะธั**, ั ัะบะพะผั ะฒะธ ะผะพะถะตัะต ัะพะทะดัะปะธัะธ ะผะพะถะปะธะฒั ัะธะฟะธ ะทะฐ ะดะพะฟะพะผะพะณะพั ะฒะตััะธะบะฐะปัะฝะพั ัะผัะณะธ (`|`).
+
+=== "Python 3.8 ั ะฒะธัะต"
+
+ ```Python hl_lines="1 4"
+ {!> ../../../docs_src/python_types/tutorial008b.py!}
+ ```
+
+=== "Python 3.10 ั ะฒะธัะต"
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/python_types/tutorial008b_py310.py!}
+ ```
+
+ะ ะพะฑะพั
ะฒะธะฟะฐะดะบะฐั
ัะต ะพะทะฝะฐัะฐั, ัะพ `item` ะผะพะถะต ะฑััะธ `int` ะฐะฑะพ `str`.
+
+#### Possibly `None` (Optional)
+
+ะะธ ะผะพะถะตัะต ะพะณะพะปะพัะธัะธ, ัะพ ะทะฝะฐัะตะฝะฝั ะผะพะถะต ะผะฐัะธ ัะธะฟ, ะฝะฐะฟัะธะบะปะฐะด `str`, ะฐะปะต ัะฐะบะพะถ ะผะพะถะต ะฑััะธ `None`.
+
+ะฃ Python 3.6 ั ะฒะธัะต (ะฒะบะปััะฐััะธ Python 3.10) ะฒะธ ะผะพะถะตัะต ะพะณะพะปะพัะธัะธ ะนะพะณะพ, ัะผะฟะพัััะฒะฐะฒัะธ ัะฐ ะฒะธะบะพัะธััะพะฒัััะธ `Optional` ะท ะผะพะดัะปั `typing`.
+
+```Python hl_lines="1 4"
+{!../../../docs_src/python_types/tutorial009.py!}
+```
+
+ะะธะบะพัะธััะฐะฝะฝั `Optional[str]` ะทะฐะผัััั ะฟัะพััะพ `str` ะดะพะทะฒะพะปะธัั ัะตะดะฐะบัะพัั ะดะพะฟะพะผะพะณัะธ ะฒะฐะผ ะฒะธัะฒะธัะธ ะฟะพะผะธะปะบะธ, ะบะพะปะธ ะฒะธ ะผะพะณะปะธ ะฑ ะฒะฒะฐะถะฐัะธ, ัะพ ะทะฝะฐัะตะฝะฝัะผ ะทะฐะฒะถะดะธ ั `str`, ั
ะพัะฐ ะฝะฐัะฟัะฐะฒะดั ะฒะพะฝะพ ัะฐะบะพะถ ะผะพะถะต ะฑััะธ `None`.
+
+`Optional[Something]` ะฝะฐัะฟัะฐะฒะดั ั ัะบะพัะพัะตะฝะฝัะผ ะดะปั `Union[Something, None]`, ะฒะพะฝะธ ะตะบะฒัะฒะฐะปะตะฝัะฝั.
+
+ะฆะต ัะฐะบะพะถ ะพะทะฝะฐัะฐั, ัะพ ะฒ Python 3.10 ะฒะธ ะผะพะถะตัะต ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ `Something | None`:
+
+=== "Python 3.8 ั ะฒะธัะต"
+
+ ```Python hl_lines="1 4"
+ {!> ../../../docs_src/python_types/tutorial009.py!}
+ ```
+
+=== "Python 3.8 ั ะฒะธัะต - ะฐะปััะตัะฝะฐัะธะฒะฐ"
+
+ ```Python hl_lines="1 4"
+ {!> ../../../docs_src/python_types/tutorial009b.py!}
+ ```
+
+=== "Python 3.10 ั ะฒะธัะต"
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/python_types/tutorial009_py310.py!}
+ ```
+
+#### Generic ัะธะฟะธ
+
+ะฆั ัะธะฟะธ, ัะบั ะฟัะธะนะผะฐััั ะฟะฐัะฐะผะตััะธ ัะธะฟั ั ะบะฒะฐะดัะฐัะฝะธั
ะดัะถะบะฐั
, ะฝะฐะทะธะฒะฐััััั **Generic types** or **Generics**, ะฝะฐะฟัะธะบะปะฐะด:
+
+=== "Python 3.8 ั ะฒะธัะต"
+
+ * `List`
+ * `Tuple`
+ * `Set`
+ * `Dict`
+ * `Union`
+ * `Optional`
+ * ...ัะฐ ัะฝัั.
+
+=== "Python 3.9 ั ะฒะธัะต"
+
+ ะะธ ะผะพะถะตัะต ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ัั ัะฐะผั ะฒะฑัะดะพะฒะฐะฝั ัะธะฟะธ, ัะบ generic (ะท ะบะฒะฐะดัะฐัะฝะธะผะธ ะดัะถะบะฐะผะธ ัะฐ ัะธะฟะฐะผะธ ะฒัะตัะตะดะธะฝั):
+
+ * `list`
+ * `tuple`
+ * `set`
+ * `dict`
+
+ ะ ัะต ัะฐะผะต, ัะพ ะน ั Python 3.8, ัะท ะผะพะดัะปั `typing`:
+
+ * `Union`
+ * `Optional`
+ * ...ัะฐ ัะฝัั.
+
+=== "Python 3.10 ั ะฒะธัะต"
+
+ ะะธ ะผะพะถะตัะต ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ัั ัะฐะผั ะฒะฑัะดะพะฒะฐะฝั ัะธะฟะธ, ัะบ generic (ะท ะบะฒะฐะดัะฐัะฝะธะผะธ ะดัะถะบะฐะผะธ ัะฐ ัะธะฟะฐะผะธ ะฒัะตัะตะดะธะฝั):
+
+ * `list`
+ * `tuple`
+ * `set`
+ * `dict`
+
+ ะ ัะต ัะฐะผะต, ัะพ ะน ั Python 3.8, ัะท ะผะพะดัะปั `typing`:
+
+ * `Union`
+ * `Optional` (ัะฐะบ ัะฐะผะพ ัะบ ั Python 3.8)
+ * ...ัะฐ ัะฝัั.
+
+ ะฃ Python 3.10, ัะบ ะฐะปััะตัะฝะฐัะธะฒะฐ ะฒะธะบะพัะธััะฐะฝะฝั `Union` ัะฐ `Optional`, ะฒะธ ะผะพะถะตัะต ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ะฒะตััะธะบะฐะปัะฝั ัะผัะณั (`|`) ัะพะฑ ะพะณะพะปะพัะธัะธ ะพะฑ'ัะดะฝะฐะฝะฝั ัะธะฟัะฒ.
+
+### ะะปะฐัะธ ัะบ ัะธะฟะธ
+
+ะะธ ัะฐะบะพะถ ะผะพะถะตัะต ะพะณะพะปะพัะธัะธ ะบะปะฐั ัะบ ัะธะฟ ะทะผัะฝะฝะพั.
+
+ะกะบะฐะถัะผะพ, ั ะฒะฐั ั ะบะปะฐั `Person` ะท ัะผสผัะผ:
+
+```Python hl_lines="1-3"
+{!../../../docs_src/python_types/tutorial010.py!}
+```
+
+ะะพััะผ ะฒะธ ะผะพะถะตัะต ะพะณะพะปะพัะธัะธ ะทะผัะฝะฝั ัะธะฟั `Person`:
+
+```Python hl_lines="6"
+{!../../../docs_src/python_types/tutorial010.py!}
+```
+
+ะ ะทะฝะพะฒั ะถ ัะฐะบะธ, ะฒะธ ะพััะธะผัััะต ะฒัั ะฟัะดััะธะผะบั ัะตะดะฐะบัะพัะฐ:
+
+
+
+## Pydantic ะผะพะดะตะปั
+
+Pydantic ัะต ะฑัะฑะปัะพัะตะบะฐ Python ะดะปั ะฒะฐะปัะดะฐััั ะดะฐะฝะธั
.
+
+ะะธ ะพะณะพะปะพััััะต ยซัะพัะผัยป ะดะฐะฝะธั
ัะบ ะบะปะฐัะธ ะท ะฐััะธะฑััะฐะผะธ.
+
+ะ ะบะพะถะตะฝ ะฐััะธะฑัั ะผะฐั ัะธะฟ.
+
+ะะพััะผ ะฒะธ ััะฒะพััััะต ะตะบะทะตะผะฟะปัั ััะพะณะพ ะบะปะฐัั ะท ะดะตัะบะธะผะธ ะทะฝะฐัะตะฝะฝัะผะธ, ั ะฒัะฝ ะฟะตัะตะฒััะธัั ัั ะทะฝะฐัะตะฝะฝั, ะฟะตัะตัะฒะพัะธัั ัั
ั ะฒัะดะฟะพะฒัะดะฝะธะน ัะธะฟ (ัะบัะพ ั ะฟะพััะตะฑะฐ) ั ะฝะฐะดะฐััั ะฒะฐะผ ะพะฑโัะบั ะท ัััะผะฐ ะดะฐะฝะธะผะธ.
+
+ะ ะฒะธ ะพััะธะผัััะต ะฒัั ะฟัะดััะธะผะบั ัะตะดะฐะบัะพัะฐ ะท ัะธะผ ะพััะธะผะฐะฝะธะผ ะพะฑโัะบัะพะผ.
+
+ะัะธะบะปะฐะด ะท ะดะพะบัะผะตะฝัะฐััั Pydantic:
+
+=== "Python 3.8 ั ะฒะธัะต"
+
+ ```Python
+ {!> ../../../docs_src/python_types/tutorial011.py!}
+ ```
+
+=== "Python 3.9 ั ะฒะธัะต"
+
+ ```Python
+ {!> ../../../docs_src/python_types/tutorial011_py39.py!}
+ ```
+
+=== "Python 3.10 ั ะฒะธัะต"
+
+ ```Python
+ {!> ../../../docs_src/python_types/tutorial011_py310.py!}
+ ```
+
+!!! info
+ ะฉะพะฑ ะดัะทะฝะฐัะธัั ะฑัะปััะต ะฟัะพ Pydantic, ะฟะตัะตะณะปัะฝััะต ะนะพะณะพ ะดะพะบัะผะตะฝัะฐััั.
+
+**FastAPI** ะฟะพะฒะฝัััั ะฑะฐะทัััััั ะฝะฐ Pydantic.
+
+ะะธ ะฟะพะฑะฐัะธัะต ะฝะฐะฑะฐะณะฐัะพ ะฑัะปััะต ััะพะณะพ ะฒััะพะณะพ ะฝะฐ ะฟัะฐะบัะธัั ะฒ [Tutorial - User Guide](tutorial/index.md){.internal-link target=_blank}.
+
+## ะะฝะพัะฐััั ัะธะฟัะฒ ั **FastAPI**
+
+**FastAPI** ะฒะธะบะพัะธััะพะฒัั ัั ะฟัะดะบะฐะทะบะธ ะดะปั ะฒะธะบะพะฝะฐะฝะฝั ะบัะปัะบะพั
ัะตัะตะน.
+
+ะ **FastAPI** ะฒะธ ะพะณะพะปะพััััะต ะฟะฐัะฐะผะตััะธ ะท ะฟัะดะบะฐะทะบะฐะผะธ ัะธะฟั, ั ะพััะธะผัััะต:
+
+* **ะัะดััะธะผะบั ัะตะดะฐะบัะพัะฐ**.
+* **ะะตัะตะฒััะบั ัะธะฟัะฒ**.
+
+...ั **FastAPI** ะฒะธะบะพัะธััะพะฒัั ัั ัะฐะผั ะพะณะพะปะพัะตะฝะฝั ะดะปั:
+
+* **ะะธะทะฝะฐัะตะฝะฝั ะฒะธะผะพะณ**: ะท ะฟะฐัะฐะผะตัััะฒ ัะปัั
ั ะทะฐะฟะธัั, ะฟะฐัะฐะผะตัััะฒ ะทะฐะฟะธัั, ะทะฐะณะพะปะพะฒะบัะฒ, ััะป, ะทะฐะปะตะถะฝะพััะตะน ัะพัะพ.
+* **ะะตัะตัะฒะพัะตะฝะฝั ะดะฐะฝะธั
**: ัะท ะทะฐะฟะธัั ะฒ ะฝะตะพะฑั
ัะดะฝะธะน ัะธะฟ.
+* **ะะตัะตะฒััะบะฐ ะดะฐะฝะธั
**: ัะพ ะฝะฐะดั
ะพะดััั ะฒัะด ะบะพะถะฝะพะณะพ ะทะฐะฟะธัั:
+ * ะะตะฝะตััะฒะฐะฝะฝั **ะฐะฒัะพะผะฐัะธัะฝะธั
ะฟะพะผะธะปะพะบ**, ัะพ ะฟะพะฒะตััะฐััััั ะบะปััะฝัั, ะบะพะปะธ ะดะฐะฝั ะฝะตะดัะนัะฝั.
+* **ะะพะบัะผะตะฝััะฒะฐะฝะฝั** API ะทะฐ ะดะพะฟะพะผะพะณะพั OpenAPI:
+ * ัะบะธะน ะฟะพััะผ ะฒะธะบะพัะธััะพะฒัััััั ะดะปั ะฐะฒัะพะผะฐัะธัะฝะพั ัะฝัะตัะฐะบัะธะฒะฝะพั ะดะพะบัะผะตะฝัะฐััั ะบะพัะธัััะฒะฐะปัะฝะธััะบะธั
ัะฝัะตััะตะนััะฒ.
+
+ะัะต ัะต ะผะพะถะต ะทะดะฐัะธัั ะฐะฑัััะฐะบัะฝะธะผ. ะะต ั
ะฒะธะปัะนัะตัั. ะะธ ะฟะพะฑะฐัะธัะต ะฒัะต ัะต ะฒ ะดัั ะฒ [ะขััะพััะฐะป - ะะพััะฑะฝะธะบ ะบะพัะธัััะฒะฐัะฐ](tutorial/index.md){.internal-link target=_blank}.
+
+ะะฐะถะปะธะฒะพ ัะต, ัะพ ะทะฐ ะดะพะฟะพะผะพะณะพั ััะฐะฝะดะฐััะฝะธั
ัะธะฟัะฒ Python ะฒ ะพะดะฝะพะผั ะผัััั (ะทะฐะผัััั ัะพะณะพ, ัะพะฑ ะดะพะดะฐะฒะฐัะธ ะฑัะปััะต ะบะปะฐััะฒ, ะดะตะบะพัะฐัะพััะฒ ัะพัะพ), **FastAPI** ะทัะพะฑะธัั ะฑะฐะณะฐัะพ ัะพะฑะพัะธ ะทะฐ ะฒะฐั.
+
+!!! info
+ ะฏะบัะพ ะฒะธ ะฒะถะต ะฟัะพะนัะปะธ ะฒะตัั ะฝะฐะฒัะฐะปัะฝะธะน ะฟะพััะฑะฝะธะบ ั ะฟะพะฒะตัะฝัะปะธัั, ัะพะฑ ะดัะทะฝะฐัะธัั ะฑัะปััะต ะฟัะพ ัะธะฟะธ, ะพัั ั
ะพัะพัะธะน ัะตัััั "ัะฟะฐัะณะฐะปะบะฐ" ะฒัะด `mypy`.
diff --git a/docs/uk/docs/tutorial/body.md b/docs/uk/docs/tutorial/body.md
index e78c5de0e..9759e7f45 100644
--- a/docs/uk/docs/tutorial/body.md
+++ b/docs/uk/docs/tutorial/body.md
@@ -19,7 +19,7 @@
ะกะฟะพัะฐัะบั ะฒะฐะผ ะฟะพัััะฑะฝะพ ัะผะฟะพัััะฒะฐัะธ `BaseModel` ะท `pydantic`:
-=== "Python 3.6 ั ะฒะธัะต"
+=== "Python 3.8 ั ะฒะธัะต"
```Python hl_lines="4"
{!> ../../../docs_src/body/tutorial001.py!}
@@ -37,7 +37,7 @@
ะะธะบะพัะธััะพะฒัะนัะต ััะฐะฝะดะฐััะฝั ัะธะฟะธ Python ะดะปั ะฒััั
ะฐััะธะฑัััะฒ:
-=== "Python 3.6 ั ะฒะธัะต"
+=== "Python 3.8 ั ะฒะธัะต"
```Python hl_lines="7-11"
{!> ../../../docs_src/body/tutorial001.py!}
@@ -75,7 +75,7 @@
ะฉะพะฑ ะดะพะดะฐัะธ ะผะพะดะตะปั ะดะฐะฝะธั
ะดะพ ะฒะฐัะพั *ะพะฟะตัะฐััั ัะปัั
ั*, ะพะณะพะปะพัััั ัั ัะฐะบ ัะฐะผะพ, ัะบ ะฒะธ ะพะณะพะปะพัะธะปะธ ะฟะฐัะฐะผะตััะธ ัะปัั
ั ัะฐ ะทะฐะฟะธัั:
-=== "Python 3.6 ั ะฒะธัะต"
+=== "Python 3.8 ั ะฒะธัะต"
```Python hl_lines="18"
{!> ../../../docs_src/body/tutorial001.py!}
@@ -149,7 +149,7 @@
ะฃัะตัะตะดะธะฝั ััะฝะบััั ะฒะธ ะผะพะถะตัะต ะพััะธะผะฐัะธ ะฟััะผะธะน ะดะพัััะฟ ะดะพ ะฒััั
ะฐััะธะฑัััะฒ ะพะฑโัะบัะฐ ะผะพะดะตะปั:
-=== "Python 3.6 ั ะฒะธัะต"
+=== "Python 3.8 ั ะฒะธัะต"
```Python hl_lines="21"
{!> ../../../docs_src/body/tutorial002.py!}
@@ -167,7 +167,7 @@
**FastAPI** ัะพะทะฟัะทะฝะฐั, ัะพ ะฟะฐัะฐะผะตััะธ ััะฝะบััั, ัะบั ะฒัะดะฟะพะฒัะดะฐััั ะฟะฐัะฐะผะตััะฐะผ ัะปัั
ั, ะผะฐััั ะฑััะธ **ะฒะทััั ะท ัะปัั
ั**, ะฐ ะฟะฐัะฐะผะตััะธ ััะฝะบััั, ัะบั ะพะณะพะปะพััััััั ัะบ ะผะพะดะตะปั Pydantic, **ะฒะทััั ะท ััะปะฐ ะทะฐะฟะธัั**.
-=== "Python 3.6 ั ะฒะธัะต"
+=== "Python 3.8 ั ะฒะธัะต"
```Python hl_lines="17-18"
{!> ../../../docs_src/body/tutorial003.py!}
@@ -185,7 +185,7 @@
**FastAPI** ัะพะทะฟัะทะฝะฐั ะบะพะถะตะฝ ะท ะฝะธั
ั ะฒัะทัะผะต ะดะฐะฝั ะท ะฟะพัััะฑะฝะพะณะพ ะผัััั.
-=== "Python 3.6 ั ะฒะธัะต"
+=== "Python 3.8 ั ะฒะธัะต"
```Python hl_lines="18"
{!> ../../../docs_src/body/tutorial004.py!}
diff --git a/docs/uk/docs/tutorial/cookie-params.md b/docs/uk/docs/tutorial/cookie-params.md
index 2b0e8993c..199b93839 100644
--- a/docs/uk/docs/tutorial/cookie-params.md
+++ b/docs/uk/docs/tutorial/cookie-params.md
@@ -18,7 +18,7 @@
{!> ../../../docs_src/cookie_params/tutorial001_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="3"
{!> ../../../docs_src/cookie_params/tutorial001_an.py!}
@@ -33,7 +33,7 @@
{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
ะะฐะถะฐะฝะพ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ `Annotated` ะฒะตัััั, ัะบัะพ ัะต ะผะพะถะปะธะฒะพ.
@@ -60,7 +60,7 @@
{!> ../../../docs_src/cookie_params/tutorial001_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="10"
{!> ../../../docs_src/cookie_params/tutorial001_an.py!}
@@ -75,7 +75,7 @@
{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
ะะฐะถะฐะฝะพ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ `Annotated` ะฒะตัััั, ัะบัะพ ัะต ะผะพะถะปะธะฒะพ.
diff --git a/docs/uk/docs/tutorial/encoder.md b/docs/uk/docs/tutorial/encoder.md
new file mode 100644
index 000000000..b6583341f
--- /dev/null
+++ b/docs/uk/docs/tutorial/encoder.md
@@ -0,0 +1,42 @@
+# JSON Compatible Encoder
+
+ะัะฝัััั ะฒะธะฟะฐะดะบะธ, ะบะพะปะธ ะฒะฐะผ ะผะพะถะต ะทะฝะฐะดะพะฑะธัะธัั ะฟะตัะตัะฒะพัะธัะธ ัะธะฟ ะดะฐะฝะธั
(ะฝะฐะฟัะธะบะปะฐะด, ะผะพะดะตะปั Pydantic) ะฒ ัะพัั ััะผััะฝะต ะท JSON (ะฝะฐะฟัะธะบะปะฐะด, `dict`, `list`, ั ั. ะด.).
+
+ะะฐะฟัะธะบะปะฐะด, ัะบัะพ ะฒะฐะผ ะฟะพัััะฑะฝะพ ะทะฑะตัะตะณัะธ ัะต ะฒ ะฑะฐะทั ะดะฐะฝะธั
.
+
+ะะปั ััะพะณะพ, **FastAPI** ะฝะฐะดะฐั `jsonable_encoder()` ััะฝะบััั.
+
+## ะะธะบะพัะธััะฐะฝะฝั `jsonable_encoder`
+
+ะะฐะฒะฐะนัะต ััะฒะธะผะพ, ัะพ ั ะฒะฐั ั ะฑะฐะทะฐ ะดะฐะฝะธั
`fake_db`, ัะบะฐ ะฟัะธะนะผะฐั ะปะธัะต ะดะฐะฝั, ััะผััะฝั ะท JSON.
+
+ะะฐะฟัะธะบะปะฐะด, ะฒะพะฝะฐ ะฝะต ะฟัะธะนะผะฐั ะพะฑ'ัะบัะธ ัะธะฟั `datetime`, ะพัะบัะปัะบะธ ะฒะพะฝะธ ะฝะต ััะผััะฝั ะท JSON.
+
+ะัะถะต, ะพะฑ'ัะบั ัะธะฟั `datetime` ะฟะพัััะฑะฝะพ ะฟะตัะตัะฒะพัะธัะธ ะฒ ััะดะพะบ `str`, ัะบะธะน ะผัััะธัั ะดะฐะฝั ะฒ ISO ัะพัะผะฐัั.
+
+ะขะธะผ ัะฐะผะธะผ ัะฟะพัะพะฑะพะผ ัั ะฑะฐะทะฐ ะดะฐะฝะธั
ะฝะต ะฟัะธะนะผะฐัะธะผะต ะพะฑ'ัะบั ัะธะฟั Pydantic model (ะพะฑ'ัะบั ะท ะฐััะธะฑััะฐะผะธ), ะฐ ะปะธัะต `dict`.
+
+ะะธ ะผะพะถะตัะต ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ `jsonable_encoder` ะดะปั ััะพะณะพ.
+
+ะะพะฝะฐ ะฟัะธะนะผะฐั ะพะฑ'ัะบั, ัะฐะบะธะน ัะบ Pydantic model, ั ะฟะพะฒะตััะฐั ะนะพะณะพ ะฒะตัััั, ััะผััะฝั ะท JSON:
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="4 21"
+ {!> ../../../docs_src/encoder/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.8+"
+
+ ```Python hl_lines="5 22"
+ {!> ../../../docs_src/encoder/tutorial001.py!}
+ ```
+
+ะฃ ััะพะผั ะฟัะธะบะปะฐะดั ะฒะพะฝะฐ ะบะพะฝะฒะตัััั Pydantic model ั `dict`, ะฐ `datetime` ั `str`.
+
+ะ ะตะทัะปััะฐั ะฒะธะบะปะธะบั ัััั ััะฝะบััั - ัะต ัะพัั, ัะพ ะผะพะถะฝะฐ ะบะพะดัะฒะฐัะธ ะท ะฒะธะบะพัะธััะฐะฝะฝัะผ ััะฐะฝะดะฐััั Python `json.dumps()`.
+
+ะะพะฝะฐ ะฝะต ะฟะพะฒะตััะฐั ะฒะตะปะธะบั ัััะพะบั `str`, ัะบะฐ ะผัััะธัั ะดะฐะฝั ั ัะพัะผะฐัั JSON (ัะบ ัััะพะบะฐ). ะะพะฝะฐ ะฟะพะฒะตััะฐั ััะฐะฝะดะฐััะฝั ััััะบัััั ะดะฐะฝะธั
Python (ะฝะฐะฟัะธะบะปะฐะด `dict`) ัะท ะทะฝะฐัะตะฝะฝัะผะธ ัะฐ ะฟัะดะทะฝะฐัะตะฝะฝัะผะธ, ัะบั ั ััะผััะฝะธะผะธ ะท JSON.
+
+!!! ะัะธะผััะบะฐ
+ `jsonable_encoder` ัะฐะบัะธัะฝะพ ะฒะธะบะพัะธััะพะฒัััััั **FastAPI** ะฒะฝัััััะฝัะพ ะดะปั ะฟะตัะตัะฒะพัะตะฝะฝั ะดะฐะฝะธั
. ะัะพัะต ะฒะพะฝะฐ ะบะพัะธัะฝะฐ ะฒ ะฑะฐะณะฐััะพั
ัะฝัะธั
ััะตะฝะฐัััั
.
diff --git a/docs/uk/docs/tutorial/extra-data-types.md b/docs/uk/docs/tutorial/extra-data-types.md
new file mode 100644
index 000000000..ec5ec0d18
--- /dev/null
+++ b/docs/uk/docs/tutorial/extra-data-types.md
@@ -0,0 +1,130 @@
+# ะะพะดะฐัะบะพะฒั ัะธะฟะธ ะดะฐะฝะธั
+
+ะะพ ััะพะณะพ ัะฐัั, ะฒะธ ะฒะธะบะพัะธััะพะฒัะฒะฐะปะธ ะทะฐะณะฐะปัะฝะพะฟะพัะธัะตะฝั ัะธะฟะธ ะดะฐะฝะธั
, ัะฐะบั ัะบ:
+
+* `int`
+* `float`
+* `str`
+* `bool`
+
+ะะปะต ะผะพะถะฝะฐ ัะฐะบะพะถ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ะฑัะปัั ัะบะปะฐะดะฝั ัะธะฟะธ ะดะฐะฝะธั
.
+
+ะ ะฒะธ ะฒัะต ัะต ะผะฐัะธะผะตัะต ัั ะถ ะผะพะถะปะธะฒะพััั, ัะบั ะฑัะปะธ ะฟะพะบะฐะทะฐะฝั ะดะพ ััะพะณะพ:
+
+* ะงัะดะพะฒะฐ ะฟัะดััะธะผะบะฐ ัะตะดะฐะบัะพัะฐ.
+* ะะพะฝะฒะตััะฐััั ะดะฐะฝะธั
ะท ะฒั
ัะดะฝะธั
ะทะฐะฟะธััะฒ.
+* ะะพะฝะฒะตััะฐััั ะดะฐะฝะธั
ะดะปั ะฒัะดะฟะพะฒัะดั.
+* ะะฐะปัะดะฐััั ะดะฐะฝะธั
.
+* ะะฒัะพะผะฐัะธัะฝะฐ ะฐะฝะพัะฐััั ัะฐ ะดะพะบัะผะตะฝัะฐััั.
+
+## ะะฝัั ัะธะฟะธ ะดะฐะฝะธั
+
+ะัั ะดะพะดะฐัะบะพะฒั ัะธะฟะธ ะดะฐะฝะธั
ะดะปั ะฒะธะบะพัะธััะฐะฝะฝั:
+
+* `UUID`:
+ * ะกัะฐะฝะดะฐััะฝะธะน "ะฃะฝัะฒะตััะฐะปัะฝะธะน ะฃะฝัะบะฐะปัะฝะธะน ะะดะตะฝัะธััะบะฐัะพั", ัะบะธะน ัะฐััะพ ะฒะธะบะพัะธััะพะฒัััััั ัะบ ัะดะตะฝัะธััะบะฐัะพั ั ะฑะฐะณะฐััะพั
ะฑะฐะทะฐั
ะดะฐะฝะธั
ัะฐ ัะธััะตะผะฐั
.
+ * ะฃ ะทะฐะฟะธัะฐั
ัะฐ ะฒัะดะฟะพะฒัะดัั
ะฑัะดะต ะฟัะตะดััะฐะฒะปะตะฝะธะน ัะบ `str`.
+* `datetime.datetime`:
+ * ะะฐะนัะพะฝัะฒััะบะธะน `datetime.datetime`.
+ * ะฃ ะทะฐะฟะธัะฐั
ัะฐ ะฒัะดะฟะพะฒัะดัั
ะฑัะดะต ะฟัะตะดััะฐะฒะปะตะฝะธะน ัะบ `str` ะฒ ัะพัะผะฐัั ISO 8601, ัะบ: `2008-09-15T15:53:00+05:00`.
+* `datetime.date`:
+ * ะะฐะนัะพะฝัะฒััะบะธะน `datetime.date`.
+ * ะฃ ะทะฐะฟะธัะฐั
ัะฐ ะฒัะดะฟะพะฒัะดัั
ะฑัะดะต ะฟัะตะดััะฐะฒะปะตะฝะธะน ัะบ `str` ะฒ ัะพัะผะฐัั ISO 8601, ัะบ: `2008-09-15`.
+* `datetime.time`:
+ * ะะฐะนัะพะฝัะฒััะบะธะน `datetime.time`.
+ * ะฃ ะทะฐะฟะธัะฐั
ัะฐ ะฒัะดะฟะพะฒัะดัั
ะฑัะดะต ะฟัะตะดััะฐะฒะปะตะฝะธะน ัะบ `str` ะฒ ัะพัะผะฐัั ISO 8601, ัะบ: `14:23:55.003`.
+* `datetime.timedelta`:
+ * ะะฐะนัะพะฝัะฒััะบะธะน `datetime.timedelta`.
+ * ะฃ ะทะฐะฟะธัะฐั
ัะฐ ะฒัะดะฟะพะฒัะดัั
ะฑัะดะต ะฟัะตะดััะฐะฒะปะตะฝะธะน ัะบ `float` ะทะฐะณะฐะปัะฝะพั ะบัะปัะบะพััั ัะตะบัะฝะด.
+ * Pydantic ัะฐะบะพะถ ะดะพะทะฒะพะปัั ะฟัะตะดััะฐะฒะปััะธ ัะต ัะบ "ISO 8601 time diff encoding", ะฑัะปััะต ัะฝัะพัะผะฐััั ะดะธะฒะธัั ั ะดะพะบัะผะตะฝัะฐััั.
+* `frozenset`:
+ * ะฃ ะทะฐะฟะธัะฐั
ั ะฒัะดะฟะพะฒัะดัั
ัะต ะฑัะดะต ะพะฑัะพะฑะปะตะฝะพ ัะฐะบ ัะฐะผะพ, ัะบ ั `set`:
+ * ะฃ ะทะฐะฟะธัะฐั
ัะฟะธัะพะบ ะฑัะดะต ะทัะธัะฐะฝะพ, ะดัะฑะปัะบะฐัะธ ะฑัะดััั ะฒะธะดะฐะปะตะฝั ัะฐ ะฒัะฝ ะฑัะดะต ะฟะตัะตัะฒะพัะตะฝะธะน ะฝะฐ `set`.
+ * ะฃ ะฒัะดะฟะพะฒัะดัั
, `set` ะฑัะดะต ะฟะตัะตัะฒะพัะตะฝะธะน ะฝะฐ `list`.
+ * ะะณะตะฝะตัะพะฒะฐะฝะฐ ัั
ะตะผะฐ ะฑัะดะต ะฒะบะฐะทัะฒะฐัะธ, ัะพ ะทะฝะฐัะตะฝะฝั `set` ั ัะฝัะบะฐะปัะฝะธะผะธ (ะท ะฒะธะบะพัะธััะฐะฝะฝัะผ JSON Schema's `uniqueItems`).
+* `bytes`:
+ * ะกัะฐะฝะดะฐััะฝะธะน ะะฐะนัะพะฝัะฒััะบะธะน `bytes`.
+ * ะฃ ะทะฐะฟะธัะฐั
ั ะฒัะดะฟะพะฒัะดัั
ัะต ะฑัะดะต ะพะฑัะพะฑะปะตะฝะพ ัะบ `str`.
+ * ะะณะตะฝะตัะพะฒะฐะฝะฐ ัั
ะตะผะฐ ะฑัะดะต ะฒะบะฐะทัะฒะฐัะธ, ัะพ ัะต `str` ะท "ัะพัะผะฐัะพะผ" `binary`.
+* `Decimal`:
+ * ะกัะฐะฝะดะฐััะฝะธะน ะะฐะนัะพะฝัะฒััะบะธะน `Decimal`.
+ * ะฃ ะทะฐะฟะธัะฐั
ั ะฒัะดะฟะพะฒัะดัั
ัะต ะฑัะดะต ะพะฑัะพะฑะปะตะฝะพ ัะฐะบ ัะฐะผะพ, ัะบ ั `float`.
+* ะะธ ะผะพะถะตัะต ะฟะตัะตะฒััะธัะธ ะฒัั ะดัะนัะฝั ัะธะฟะธ ะดะฐะฝะธั
Pydantic ััั: ัะธะฟะธ ะดะฐะฝะธั
Pydantic.
+
+## ะัะธะบะปะฐะด
+
+ะัั ะฟัะธะบะปะฐะด *path operation* ะท ะฟะฐัะฐะผะตััะฐะผะธ, ะฒะธะบะพัะธััะพะฒัััะธ ะดะตัะบั ะท ะฒะธัะตะทะฐะทะฝะฐัะตะฝะธั
ัะธะฟัะฒ.
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="1 3 12-16"
+ {!> ../../../docs_src/extra_data_types/tutorial001_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="1 3 12-16"
+ {!> ../../../docs_src/extra_data_types/tutorial001_an_py39.py!}
+ ```
+
+=== "Python 3.8+"
+
+ ```Python hl_lines="1 3 13-17"
+ {!> ../../../docs_src/extra_data_types/tutorial001_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip
+ ะะฐะถะฐะฝะพ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ `Annotated` ะฒะตัััั, ัะบัะพ ัะต ะผะพะถะปะธะฒะพ.
+
+ ```Python hl_lines="1 2 11-15"
+ {!> ../../../docs_src/extra_data_types/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.8+ non-Annotated"
+
+ !!! tip
+ ะะฐะถะฐะฝะพ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ `Annotated` ะฒะตัััั, ัะบัะพ ัะต ะผะพะถะปะธะฒะพ.
+
+ ```Python hl_lines="1 2 12-16"
+ {!> ../../../docs_src/extra_data_types/tutorial001.py!}
+ ```
+
+ะะฒะตัะฝััั ัะฒะฐะณั, ัะพ ะฟะฐัะฐะผะตััะธ ะฒัะตัะตะดะธะฝั ััะฝะบััั ะผะฐััั ัะฒัะน ะทะฒะธัะฐะนะฝะธะน ัะธะฟ ะดะฐะฝะธั
, ั ะฒะธ ะผะพะถะตัะต, ะฝะฐะฟัะธะบะปะฐะด, ะฒะธะบะพะฝัะฒะฐัะธ ะทะฒะธัะฐะนะฝั ะผะฐะฝัะฟัะปัััั ะท ะดะฐัะฐะผะธ, ัะฐะบั ัะบ:
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="18-19"
+ {!> ../../../docs_src/extra_data_types/tutorial001_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="18-19"
+ {!> ../../../docs_src/extra_data_types/tutorial001_an_py39.py!}
+ ```
+
+=== "Python 3.8+"
+
+ ```Python hl_lines="19-20"
+ {!> ../../../docs_src/extra_data_types/tutorial001_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip
+ ะะฐะถะฐะฝะพ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ `Annotated` ะฒะตัััั, ัะบัะพ ัะต ะผะพะถะปะธะฒะพ.
+
+ ```Python hl_lines="17-18"
+ {!> ../../../docs_src/extra_data_types/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.8+ non-Annotated"
+
+ !!! tip
+ ะะฐะถะฐะฝะพ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ `Annotated` ะฒะตัััั, ัะบัะพ ัะต ะผะพะถะปะธะฒะพ.
+
+ ```Python hl_lines="18-19"
+ {!> ../../../docs_src/extra_data_types/tutorial001.py!}
+ ```
diff --git a/docs/uk/docs/tutorial/index.md b/docs/uk/docs/tutorial/index.md
new file mode 100644
index 000000000..e5bae74bc
--- /dev/null
+++ b/docs/uk/docs/tutorial/index.md
@@ -0,0 +1,80 @@
+# ะขััะพััะฐะป - ะะพััะฑะฝะธะบ ะบะพัะธัััะฒะฐัะฐ
+
+ะฃ ััะพะผั ะฟะพััะฑะฝะธะบั ะฟะพะบะฐะทะฐะฝะพ, ัะบ ะบะพัะธัััะฒะฐัะธัั **FastAPI** ะท ะฑัะปัััััั ะนะพะณะพ ััะฝะบััะน, ะบัะพะบ ะทะฐ ะบัะพะบะพะผ.
+
+ะะพะถะตะฝ ัะพะทะดัะป ะฟะพัััะฟะพะฒะพ ะฝะฐะดะฑัะดะพะฒัััััั ะฝะฐ ะฟะพะฟะตัะตะดะฝั, ะฐะปะต ะฒัะฝ ััััะบัััะพะฒะฐะฝะธะน ะฝะฐ ะพะบัะตะผั ัะตะผะธ, ัะพะฑ ะฒะธ ะผะพะณะปะธ ะฟะตัะตะนัะธ ะฑะตะทะฟะพัะตัะตะดะฝัะพ ะดะพ ะฑัะดั-ัะบะพั ะบะพะฝะบัะตัะฝะพั, ัะพะฑ ะฒะธัััะธัะธ ะฒะฐัั ะบะพะฝะบัะตัะฝั ะฟะพััะตะฑะธ API.
+
+ะัะฝ ัะฐะบะพะถ ััะฒะพัะตะฝะธะน ัะบ ะดะพะฒัะดะฝะธะบ ะดะปั ัะพะฑะพัะธ ั ะผะฐะนะฑััะฝัะพะผั.
+
+ะขะพะถ ะฒะธ ะผะพะถะตัะต ะฟะพะฒะตัะฝััะธัั ั ะฟะพะฑะฐัะธัะธ ัะฐะผะต ัะต, ัะพ ะฒะฐะผ ะฟะพัััะฑะฝะพ.
+
+## ะะฐะฟัััััั ะบะพะด
+
+ะฃัั ะฑะปะพะบะธ ะบะพะดั ะผะพะถะฝะฐ ัะบะพะฟััะฒะฐัะธ ัะฐ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ะฑะตะทะฟะพัะตัะตะดะฝัะพ (ัะต ัะฐะบัะธัะฝะพ ะฟะตัะตะฒััะตะฝั ัะฐะนะปะธ Python).
+
+ะฉะพะฑ ะทะฐะฟัััะธัะธ ะฑัะดั-ัะบะธะน ัะท ะฟัะธะบะปะฐะดัะฒ, ัะบะพะฟััะนัะต ะบะพะด ั ัะฐะนะป `main.py` ั ะทะฐะฟัััััั `uvicorn` ะทะฐ ะดะพะฟะพะผะพะณะพั:
+
+
+
+```console
+$ uvicorn main:app --reload
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+INFO: Started reloader process [28720]
+INFO: Started server process [28722]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+```
+
+
+
+**ะะฃะะ ัะฐะดะธะผะพ** ะฝะฐะฟะธัะฐัะธ ะฐะฑะพ ัะบะพะฟััะฒะฐัะธ ะบะพะด, ะฒัะดัะตะดะฐะณัะฒะฐัะธ ะนะพะณะพ ัะฐ ะทะฐะฟัััะธัะธ ะปะพะบะฐะปัะฝะพ.
+
+ะะธะบะพัะธััะฐะฝะฝั ะนะพะณะพ ั ัะฒะพัะผั ัะตะดะฐะบัะพัั โ ัะต ัะต, ัะพ ะดัะนัะฝะพ ะฟะพะบะฐะทัั ะฒะฐะผ ะฟะตัะตะฒะฐะณะธ FastAPI, ะฑะฐัะธัะต, ัะบ ะผะฐะปะพ ะบะพะดั ะฒะฐะผ ะฟะพัััะฑะฝะพ ะฝะฐะฟะธัะฐัะธ, ะฒัั ะฟะตัะตะฒััะบะธ ัะธะฟัะฒ, ะฐะฒัะพะทะฐะฟะพะฒะฝะตะฝะฝั ัะพัะพ.
+
+---
+
+## ะััะฐะฝะพะฒะปะตะฝะฝั FastAPI
+
+ะะตััะธะผ ะบัะพะบะพะผ ั ะฒััะฐะฝะพะฒะปะตะฝะฝั FastAPI.
+
+ะะปั ัััะพััะฐะปั ะฒะธ ะผะพะถะตัะต ะฒััะฐะฝะพะฒะธัะธ ะนะพะณะพ ะท ัััะผะฐ ะฝะตะพะฑะพะฒโัะทะบะพะฒะธะผะธ ะทะฐะปะตะถะฝะพัััะผะธ ัะฐ ััะฝะบัััะผะธ:
+
+
+
+```console
+$ pip install "fastapi[all]"
+
+---> 100%
+```
+
+
+
+...ัะบะธะน ัะฐะบะพะถ ะฒะบะปััะฐั `uvicorn`, ัะบะธะน ะฒะธ ะผะพะถะตัะต ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ัะบ ัะตัะฒะตั, ัะบะธะน ะทะฐะฟััะบะฐั ะฒะฐั ะบะพะด.
+
+!!! note
+ ะะธ ัะฐะบะพะถ ะผะพะถะตัะต ะฒััะฐะฝะพะฒะธัะธ ะนะพะณะพ ัะฐััะธะฝะฐ ะทะฐ ัะฐััะธะฝะพั.
+
+ ะฆะต ัะต, ัะพ ะฒะธ, ะนะผะพะฒััะฝะพ, ะทัะพะฑะธะปะธ ะฑ, ะบะพะปะธ ะทะฐั
ะพัะตัะต ัะพะทะณะพัะฝััะธ ัะฒะพั ะฟัะพะณัะฐะผั ั ะฒะธัะพะฑะฝะธัะพะผั ัะตัะตะดะพะฒะธัั:
+
+ ```
+ pip install fastapi
+ ```
+
+ ะขะฐะบะพะถ ะฒััะฐะฝะพะฒััั `uvicorn`, ัะพะฑ ะฒัะฝ ะฟัะฐััะฒะฐะฒ ัะบ ัะตัะฒะตั:
+
+ ```
+ pip install "uvicorn[standard]"
+ ```
+
+ ะ ัะต ัะฐะผะต ะดะปั ะบะพะถะฝะพั ะท ะพะฟััะพะฝะฐะปัะฝะธั
ะทะฐะปะตะถะฝะพััะตะน, ัะบั ะฒะธ ั
ะพัะตัะต ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ.
+
+## ะ ะพะทัะธัะตะฝะธะน ะฟะพััะฑะฝะธะบ ะบะพัะธัััะฒะฐัะฐ
+
+ะัะฝัั ัะฐะบะพะถ **ะ ะพะทัะธัะตะฝะธะน ะฟะพััะฑะฝะธะบ ะบะพัะธัััะฒะฐัะฐ**, ัะบะธะน ะฒะธ ะทะผะพะถะตัะต ะฟัะพัะธัะฐัะธ ะฟัะทะฝััะต ะฟััะปั ััะพะณะพ **ะขััะพััะฐะป - ะะพััะฑะฝะธะบ ะบะพัะธัััะฒะฐัะฐ**.
+
+**ะ ะพะทัะธัะตะฝะธะน ะฟะพััะฑะฝะธะบ ะบะพัะธัััะฒะฐัะฐ** ะทะฐัะฝะพะฒะฐะฝะพ ะฝะฐ ััะพะผั, ะฒะธะบะพัะธััะพะฒัั ัั ัะฐะผั ะบะพะฝัะตะฟััั ัะฐ ะฝะฐะฒัะฐั ะฒะฐั ะดะตัะบะธะผ ะดะพะดะฐัะบะพะฒะธะผ ััะฝะบัััะผ.
+
+ะะปะต ะฒะฐะผ ัะปัะด ัะฟะพัะฐัะบั ะฟัะพัะธัะฐัะธ **ะขััะพััะฐะป - ะะพััะฑะฝะธะบ ะบะพัะธัััะฒะฐัะฐ** (ัะต, ัะพ ะฒะธ ะทะฐัะฐะท ัะธัะฐััะต).
+
+ะัะฝ ัะพะทัะพะฑะปะตะฝะธะน ัะฐะบะธะผ ัะธะฝะพะผ, ัะพ ะฒะธ ะผะพะถะตัะต ััะฒะพัะธัะธ ะฟะพะฒะฝั ะฟัะพะณัะฐะผั ะปะธัะต ะทะฐ ะดะพะฟะพะผะพะณะพั **ะขััะพััะฐะป - ะะพััะฑะฝะธะบ ะบะพัะธัััะฒะฐัะฐ**, ะฐ ะฟะพััะผ ัะพะทัะธัะธัะธ ัั ััะทะฝะธะผะธ ัะฟะพัะพะฑะฐะผะธ, ะทะฐะปะตะถะฝะพ ะฒัะด ะฒะฐัะธั
ะฟะพััะตะฑ, ะฒะธะบะพัะธััะพะฒัััะธ ะดะตัะบั ะท ะดะพะดะฐัะบะพะฒะธั
ัะดะตะน ะท **ะ ะพะทัะธัะตะฝะพะณะพ ะฟะพััะฑะฝะธะบะฐ ะบะพัะธัััะฒะฐัะฐ** .
diff --git a/docs/vi/docs/features.md b/docs/vi/docs/features.md
index 0599530e8..306aeb359 100644
--- a/docs/vi/docs/features.md
+++ b/docs/vi/docs/features.md
@@ -26,7 +26,7 @@ Tร i liแปu tฦฐฦกng tรกc API vร web giao diแปn ngฦฐแปi dรนng. Lร mแปt frame
### Chแป cแบงn phiรชn bแบฃn Python hiแปn ฤแบกi
-Tแบฅt cแบฃ ฤฦฐแปฃc dแปฑa trรชn khai bรกo kiแปu dแปฏ liแปu chuแบฉn cแปงa **Python 3.6** (cแบฃm ฦกn Pydantic). Bแบกn khรดng cแบงn hแปc cรบ phรกp mแปi, chแป cแบงn biแบฟt chuแบฉn Python hiแปn ฤแบกi.
+Tแบฅt cแบฃ ฤฦฐแปฃc dแปฑa trรชn khai bรกo kiแปu dแปฏ liแปu chuแบฉn cแปงa **Python 3.8** (cแบฃm ฦกn Pydantic). Bแบกn khรดng cแบงn hแปc cรบ phรกp mแปi, chแป cแบงn biแบฟt chuแบฉn Python hiแปn ฤแบกi.
Nแบฟu bแบกn cแบงn 2 phรบt ฤแป lร m mแปi lแบกi cรกch sแปญ dแปฅng cรกc kiแปu dแปฏ liแปu mแปi cแปงa Python (thแบญm chรญ nแบฟu bแบกn khรดng sแปญ dแปฅng FastAPI), xem hฦฐแปng dแบซn ngแบฏn: [Kiแปu dแปฏ liแปu Python](python-types.md){.internal-link target=_blank}.
diff --git a/docs/vi/docs/index.md b/docs/vi/docs/index.md
index 0e773a011..3f416dbec 100644
--- a/docs/vi/docs/index.md
+++ b/docs/vi/docs/index.md
@@ -27,7 +27,7 @@
---
-FastAPI lร mแปt web framework hiแปn ฤแบกi, hiแปu nฤng cao ฤแป xรขy dแปฑng web APIs vแปi Python 3.7+ dแปฑa trรชn tiรชu chuแบฉn Python type hints.
+FastAPI lร mแปt web framework hiแปn ฤแบกi, hiแปu nฤng cao ฤแป xรขy dแปฑng web APIs vแปi Python 3.8+ dแปฑa trรชn tiรชu chuแบฉn Python type hints.
Nhแปฏng tรญnh nฤng nhฦฐ:
@@ -116,7 +116,7 @@ Nแบฟu bแบกn ฤang xรขy dแปฑng mแปt CLI
## Yรชu cแบงu
-Python 3.7+
+Python 3.8+
FastAPI ฤแปฉng trรชn vai nhแปฏng ngฦฐแปi khแปng lแป:
@@ -332,7 +332,7 @@ Bแบกn ฤแปnh nghฤฉa bแบฑng cรกch sแปญ dแปฅng cรกc kiแปu dแปฏ liแปu chuแบฉn c
Bแบกn khรดng phแบฃi hแปc mแปt cรบ phรกp mแปi, cรกc phฦฐฦกng thแปฉc vร class cแปงa mแปt thฦฐ viแปn cแปฅ thแป nร o.
-Chแป cแบงn sแปญ dแปฅng cรกc chuแบฉn cแปงa **Python 3.7+**.
+Chแป cแบงn sแปญ dแปฅng cรกc chuแบฉn cแปงa **Python 3.8+**.
Vรญ dแปฅ, vแปi mแปt tham sแป kiแปu `int`:
diff --git a/docs/vi/docs/python-types.md b/docs/vi/docs/python-types.md
index 7f4f51131..4999caac3 100644
--- a/docs/vi/docs/python-types.md
+++ b/docs/vi/docs/python-types.md
@@ -182,7 +182,7 @@ Vรญ dแปฅ, hรฃy ฤแปnh nghฤฉa mแปt biแบฟn lร `list` cรกc `str`.
{!> ../../../docs_src/python_types/tutorial006_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
Tแปซ `typing`, import `List` (vแปi chแปฏ cรกi `L` viแบฟt hoa):
@@ -230,7 +230,7 @@ Bแบกn sแบฝ lร m ฤiแปu tฦฐฦกng tแปฑ ฤแป khai bรกo cรกc `tuple` vร cรกc `set
{!> ../../../docs_src/python_types/tutorial007_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="1 4"
{!> ../../../docs_src/python_types/tutorial007.py!}
@@ -255,7 +255,7 @@ Tham sแป kiแปu dแปฏ liแปu thแปฉ hai dร nh cho giรก trแป cแปงa `dict`.
{!> ../../../docs_src/python_types/tutorial008_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="1 4"
{!> ../../../docs_src/python_types/tutorial008.py!}
@@ -284,7 +284,7 @@ Trong Python 3.10 cลฉng cรณ mแปt **cรบ phรกp mแปi** mร bแบกn cรณ thแป ฤแบทt
{!> ../../../docs_src/python_types/tutorial008b_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="1 4"
{!> ../../../docs_src/python_types/tutorial008b.py!}
@@ -314,13 +314,13 @@ Sแปญ dแปฅng `Optional[str]` thay cho `str` sแบฝ cho phรฉp trรฌnh soแบกn thแบฃo g
{!> ../../../docs_src/python_types/tutorial009_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="1 4"
{!> ../../../docs_src/python_types/tutorial009.py!}
```
-=== "Python 3.6+ alternative"
+=== "Python 3.8+ alternative"
```Python hl_lines="1 4"
{!> ../../../docs_src/python_types/tutorial009b.py!}
@@ -404,7 +404,7 @@ Nhแปฏng kiแปu dแปฏ liแปu nร y lแบฅy tham sแป kiแปu dแปฏ liแปu trong dแบฅu n
* `Optional`
* ...and others.
-=== "Python 3.6+"
+=== "Python 3.8+"
* `List`
* `Tuple`
@@ -464,7 +464,7 @@ Mแปt vรญ dแปฅ tแปซ tร i liแปu chรญnh thแปฉc cแปงa Pydantic:
{!> ../../../docs_src/python_types/tutorial011_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python
{!> ../../../docs_src/python_types/tutorial011.py!}
@@ -493,7 +493,7 @@ Python cลฉng cรณ mแปt tรญnh nฤng cho phรฉp ฤแบทt **metadata bแป sung** trong
{!> ../../../docs_src/python_types/tutorial013_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
แป phiรชn bแบฃn dฦฐแปi Python 3.9, bแบกn import `Annotated` tแปซ `typing_extensions`.
diff --git a/docs/vi/docs/tutorial/first-steps.md b/docs/vi/docs/tutorial/first-steps.md
new file mode 100644
index 000000000..712f00852
--- /dev/null
+++ b/docs/vi/docs/tutorial/first-steps.md
@@ -0,0 +1,333 @@
+# Nhแปฏng bฦฐแปc ฤแบงu tiรชn
+
+Tแปp tin FastAPI ฤฦกn giแบฃn nhแบฅt cรณ thแป trรดng nhฦฐ nร y:
+
+```Python
+{!../../../docs_src/first_steps/tutorial001.py!}
+```
+
+Sao chรฉp sang mแปt tแปp tin `main.py`.
+
+Chแบกy live server:
+
+
+
+```console
+$ uvicorn main:app --reload
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+INFO: Started reloader process [28720]
+INFO: Started server process [28722]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+```
+
+
+
+!!! note
+ Cรขu lแปnh `uvicorn main:app` ฤฦฐแปฃc giแบฃi thรญch nhฦฐ sau:
+
+ * `main`: tแปp tin `main.py` (mแปt Python "mรด ฤun").
+ * `app`: mแปt object ฤฦฐแปฃc tแบกo ra bรชn trong `main.py` vแปi dรฒng `app = FastAPI()`.
+ * `--reload`: lร m server khแปi ฤแปng lแบกi sau mแปi lแบงn thay ฤแปi. Chแป sแปญ dแปฅng trong mรดi trฦฐแปng phรกt triแปn.
+
+Trong output, cรณ mแปt dรฒng giแปng nhฦฐ:
+
+```hl_lines="4"
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+Dรฒng ฤรณ cho thแบฅy URL, nฦกi mร app cแปงa bแบกn ฤang ฤฦฐแปฃc chแบกy, trong mรกy local cแปงa bแบกn.
+
+### Kiแปm tra
+
+Mแป trรฌnh duyแปt cแปงa bแบกn tแบกi http://127.0.0.1:8000.
+
+Bแบกn sแบฝ thแบฅy mแปt JSON response nhฦฐ:
+
+```JSON
+{"message": "Hello World"}
+```
+
+### Tร i liแปu tฦฐฦกng tรกc API
+
+Bรขy giแป tแปi http://127.0.0.1:8000/docs.
+
+Bแบกn sแบฝ thแบฅy mแปt tร i liแปu tฦฐฦกng tรกc API (cung cแบฅp bแปi Swagger UI):
+
+
+
+### Phiรชn bแบฃn thay thแบฟ cแปงa tร i liแปu API
+
+Vร bรขy giแป tแปi http://127.0.0.1:8000/redoc.
+
+Bแบกn sแบฝ thแบฅy mแปt bแบฃn thay thแบฟ cแปงa tร i liแปu (cung cแบฅp bแปi ReDoc):
+
+
+
+### OpenAPI
+
+**FastAPI** sinh mแปt "schema" vแปi tแบฅt cแบฃ API cแปงa bแบกn sแปญ dแปฅng tiรชu chuแบฉn **OpenAPI** cho ฤแปnh nghฤฉa cรกc API.
+
+#### "Schema"
+
+Mแปt "schema" lร mแปt ฤแปnh nghฤฉa hoแบทc mรด tแบฃ thแปฉ gรฌ ฤรณ. Khรดng phแบฃi code triแปn khai cแปงa nรณ, nhฦฐng chแป lร mแปt bแบฃn mรด tแบฃ trแปซu tฦฐแปฃng.
+
+#### API "schema"
+
+Trong trฦฐแปng hแปฃp nร y, OpenAPI lร mแปt bแบฃn mรด tแบฃ bแบฏt buแปc cฦก chแบฟ ฤแปnh nghฤฉa API cแปงa bแบกn.
+
+ฤแปnh nghฤฉa cแบฅu trรบc nร y bao gแปm nhแปฏng ฤฦฐแปng dแบซn API cแปงa bแบกn, cรกc tham sแป cรณ thแป cรณ,...
+
+#### "Cแบฅu trรบc" dแปฏ liแปu
+
+Thuแบญt ngแปฏ "cแบฅu trรบc" (schema) cลฉng cรณ thแป ฤฦฐแปฃc coi nhฦฐ lร hรฌnh dแบกng cแปงa dแปฏ liแปu, tฦฐฦกng tแปฑ nhฦฐ mแปt JSON content.
+
+Trong trฦฐแปng hแปฃp ฤรณ, nรณ cรณ nghฤฉa lร cรกc thuแปc tรญnh JSON vร cรกc kiแปu dแปฏ liแปu hแป cรณ,...
+
+#### OpenAPI vร JSON Schema
+
+OpenAPI ฤแปnh nghฤฉa mแปt cแบฅu trรบc API cho API cแปงa bแบกn. Vร cแบฅu trรบc ฤรณ bao gแปm cรกc dแปnh nghฤฉa (or "schema") vแป dแปฏ liแปu ฤฦฐแปฃc gแปญi ฤi vร nhแบญn vแป bแปi API cแปงa bแบกn, sแปญ dแปฅng **JSON Schema**, mแปt tiรชu chuแบฉn cho cแบฅu trรบc dแปฏ liแปu JSON.
+
+#### Kiแปm tra `openapi.json`
+
+Nแบฟu bแบกn tรฒ mรฒ vแป viแปc cแบฅu trรบc OpenAPI nhรฌn nhฦฐ thแบฟ nร o thรฌ FastAPI tแปฑ ฤแปng sinh mแปt JSON (schema) vแปi cรกc mรด tแบฃ cho tแบฅt cแบฃ API cแปงa bแบกn.
+
+Bแบกn cรณ thแป thแบฅy nรณ trแปฑc tiแบฟp tแบกi: http://127.0.0.1:8000/openapi.json.
+
+Nรณ sแบฝ cho thแบฅy mแปt JSON bแบฏt ฤแบงu giแปng nhฦฐ:
+
+```JSON
+{
+ "openapi": "3.1.0",
+ "info": {
+ "title": "FastAPI",
+ "version": "0.1.0"
+ },
+ "paths": {
+ "/items/": {
+ "get": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+
+
+
+...
+```
+
+#### OpenAPI dรนng ฤแป lร m gรฌ?
+
+Cแบฅu trรบc OpenAPI lร sแปฉc mแบกnh cแปงa tร i liแปu tฦฐฦกng tรกc.
+
+Vร cรณ hร ng tรก cรกc bแบฃn thay thแบฟ, tแบฅt cแบฃ ฤแปu dแปฑa trรชn OpenAPI. Bแบกn cรณ thแป dแป
dร ng thรชm bแบฅt kรฌ bแบฃn thay thแบฟ bร o cho แปฉng dแปฅng cแปงa bแบกn ฤฦฐแปฃc xรขy dแปฑng vแปi **FastAPI**.
+
+Bแบกn cลฉng cรณ thแป sแปญ dแปฅng nรณ ฤแป sinh code tแปฑ ฤแปng, vแปi cรกc client giao viแบฟt qua API cแปงa bแบกn. Vรญ dแปฅ, frontend, mobile hoแบทc cรกc แปฉng dแปฅng IoT.
+
+## Tรณm lแบกi, tแปซng bฦฐแปc mแปt
+
+### Bฦฐแปc 1: import `FastAPI`
+
+```Python hl_lines="1"
+{!../../../docs_src/first_steps/tutorial001.py!}
+```
+
+`FastAPI` lร mแปt Python class cung cแบฅp tแบฅt cแบฃ chแปฉc nฤng cho API cแปงa bแบกn.
+
+!!! note "Chi tiแบฟt kฤฉ thuแบญt"
+ `FastAPI` lร mแปt class kแบฟ thแปซa trแปฑc tiแบฟp `Starlette`.
+
+ Bแบกn cลฉng cรณ thแป sแปญ dแปฅng tแบฅt cแบฃ Starlette chแปฉc nฤng vแปi `FastAPI`.
+
+### Bฦฐแปc 2: Tแบกo mแปt `FastAPI` "instance"
+
+```Python hl_lines="3"
+{!../../../docs_src/first_steps/tutorial001.py!}
+```
+
+Biแบฟn `app` nร y lร mแปt "instance" cแปงa class `FastAPI`.
+
+ฤรขy sแบฝ lร ฤiแปm cแปt lรตi ฤแป tแบกo ra tแบฅt cแบฃ API cแปงa bแบกn.
+
+`app` nร y chรญnh lร ฤiแปu ฤฦฐแปฃc nhแบฏc tแปi bแปi `uvicorn` trong cรขu lแปnh:
+
+
+
+```console
+$ uvicorn main:app --reload
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+Nแบฟu bแบกn tแบกo แปฉng dแปฅng cแปงa bแบกn giแปng nhฦฐ:
+
+```Python hl_lines="3"
+{!../../../docs_src/first_steps/tutorial002.py!}
+```
+
+Vร ฤแบทt nรณ trong mแปt tแปp tin `main.py`, sau ฤรณ bแบกn sแบฝ gแปi `uvicorn` giแปng nhฦฐ:
+
+
+
+```console
+$ uvicorn main:my_awesome_api --reload
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+### Bฦฐแปc 3: tแบกo mแปt *ฤฦฐแปng dแบซn toรกn tแปญ*
+
+#### ฤฦฐแปng dแบซn
+
+"ฤฦฐแปng dแบซn" แป ฤรขy ฤฦฐแปฃc nhแบฏc tแปi lร phแบงn cuแปi cรนng cแปงa URL bแบฏt ฤแบงu tแปซ `/`.
+
+Do ฤรณ, trong mแปt URL nhรฌn giแปng nhฦฐ:
+
+```
+https://example.com/items/foo
+```
+
+...ฤฦฐแปng dแบซn sแบฝ lร :
+
+```
+/items/foo
+```
+
+!!! info
+ Mแปt ฤฦฐแปng dแบซn cลฉng lร mแปt cรกch gแปi chung cho mแปt "endpoint" hoแบทc mแปt "route".
+
+Trong khi xรขy dแปฑng mแปt API, "ฤฦฐแปng dแบซn" lร cรกc chรญnh ฤแป phรขn tรกch "mแปi quan hแป" vร "tร i nguyรชn".
+
+#### Toรกn tแปญ (Operation)
+
+"Toรกn tแปญ" แป ฤรขy ฤฦฐแปฃc nhแบฏc tแปi lร mแปt trong cรกc "phฦฐฦกng thแปฉc" HTTP.
+
+Mแปt trong nhแปฏng:
+
+* `POST`
+* `GET`
+* `PUT`
+* `DELETE`
+
+...vร mแปt trong nhแปฏng cรกi cรฒn lแบกi:
+
+* `OPTIONS`
+* `HEAD`
+* `PATCH`
+* `TRACE`
+
+Trong giao thแปฉc HTTP, bแบกn cรณ thแป giao tiแบฟp trong mแปi ฤฦฐแปng dแบซn sแปญ dแปฅng mแปt (hoแบทc nhiแปu) trong cรกc "phฦฐฦกng thแปฉc nร y".
+
+---
+
+Khi xรขy dแปฑng cรกc API, bแบกn thฦฐแปng sแปญ dแปฅng cแปฅ thแป cรกc phฦฐฦกng thแปฉc HTTP nร y ฤแป thแปฑc hiแปn mแปt hร nh ฤแปng cแปฅ thแป.
+
+Thรดng thฦฐแปng, bแบกn sแปญ dแปฅng
+
+* `POST`: ฤแป tแบกo dแปฏ liแปu.
+* `GET`: ฤแป ฤแปc dแปฏ liแปu.
+* `PUT`: ฤแป cแบญp nhแบญt dแปฏ liแปu.
+* `DELETE`: ฤแป xรณa dแปฏ liแปu.
+
+Do ฤรณ, trong OpenAPI, mแปi phฦฐฦกng thแปฉc HTTP ฤฦฐแปฃc gแปi lร mแปt "toรกn tแปญ (operation)".
+
+Chรบng ta cลฉng sแบฝ gแปi chรบng lร "**cรกc toรกn tแปญ**".
+
+#### ฤแปnh nghฤฉa moojt *decorator cho ฤฦฐแปng dแบซn toรกn tแปญ*
+
+```Python hl_lines="6"
+{!../../../docs_src/first_steps/tutorial001.py!}
+```
+
+`@app.get("/")` nรณi **FastAPI** rแบฑng hร m bรชn dฦฐแปi cรณ trรกch nhiแปm xแปญ lรญ request tแปi:
+
+* ฤฦฐแปng dแบซn `/`
+* sแปญ dแปฅng mแปt toรกn tแปญget
+
+!!! info Thรดng tin vแป "`@decorator`"
+ Cรบ phรกp `@something` trong Python ฤฦฐแปฃc gแปi lร mแปt "decorator".
+
+ Bแบกn ฤแบทt nรณ trรชn mแปt hร m. Giแปng nhฦฐ mแปt chiแบฟc mลฉ xinh xแบฏn (Tรดi ddonas ฤรณ lร lรญ do mร thuแบญt ngแปฏ nร y ra ฤแปi).
+
+ Mแปt "decorator" lแบฅy mแปt hร m bรชn dฦฐแปi vร thแปฑc hiแปn mแปt vร i thแปฉ vแปi nรณ.
+
+ Trong trฦฐแปng hแปฃp cแปงa chรบng ta, decorator nร y nรณi **FastAPI** rแบฑng hร m bรชn dฦฐแปi แปฉng vแปi **ฤฦฐแปng dแบซn** `/` vร mแปt **toรกn tแปญ** `get`.
+
+ Nรณ lร mแปt "**decorator ฤฦฐแปng dแบซn toรกn tแปญ**".
+
+Bแบกn cลฉng cรณ thแป sแปญ dแปฅng vแปi cรกc toรกn tแปญ khรกc:
+
+* `@app.post()`
+* `@app.put()`
+* `@app.delete()`
+
+Vร nhiแปu hฦกn vแปi cรกc toรกn tแปญ cรฒn lแบกi:
+
+* `@app.options()`
+* `@app.head()`
+* `@app.patch()`
+* `@app.trace()`
+
+!!! tip
+ Bแบกn thoแบฃi mรกi sแปญ dแปฅng mแปi toรกn tแปญ (phฦฐฦกng thแปฉc HTTP) nhฦฐ bแบกn mฦก ฦฐแปc.
+
+ **FastAPI** khรดng bแบฏt buแปc bแบฅt kรฌ รฝ nghฤฉa cแปฅ thแป nร o.
+
+ Thรดng tin แป ฤรขy ฤฦฐแปฃc biแปu thแป nhฦฐ lร mแปt chแป dแบซn, khรดng phแบฃi lร mแปt yรชu cแบงu bแบฏt buแปc.
+
+ Vรญ dแปฅ, khi sแปญ dแปฅng GraphQL bแบกn thรดng thฦฐแปng thแปฑc hiแปn tแบฅt cแบฃ cรกc hร nh ฤแปng chแป bแบฑng viแปc sแปญ dแปฅng cรกc toรกn tแปญ `POST`.
+
+### Step 4: ฤแปnh nghฤฉa **hร m cho ฤฦฐแปng dแบซn toรกn tแปญ**
+
+ฤรขy lร "**hร m cho ฤฦฐแปng dแบซn toรกn tแปญ**":
+
+* **ฤฦฐแปng dแบซn**: lร `/`.
+* **toรกn tแปญ**: lร `get`.
+* **hร m**: lร hร m bรชn dฦฐแปi "decorator" (bรชn dฦฐแปi `@app.get("/")`).
+
+```Python hl_lines="7"
+{!../../../docs_src/first_steps/tutorial001.py!}
+```
+
+ฤรขy lร mแปt hร m Python.
+
+Nรณ sแบฝ ฤฦฐแปฃc gแปi bแปi **FastAPI** bแบฅt cแปฉ khi nร o nรณ nhแบญn mแปt request tแปi URL "`/`" sแปญ dแปฅng mแปt toรกn tแปญ `GET`.
+
+Trong trฦฐแปng hแปฃp nร y, nรณ lร mแปt hร m `async`.
+
+---
+
+Bแบกn cลฉng cรณ thแป ฤแปnh nghฤฉa nรณ nhฦฐ lร mแปt hร m thรดng thฦฐแปng thay cho `async def`:
+
+```Python hl_lines="7"
+{!../../../docs_src/first_steps/tutorial003.py!}
+```
+
+!!! note
+ Nแบฟu bแบกn khรดng biแบฟt sแปฑ khรกc nhau, kiแปm tra [Async: *"Trong khi vแปi vร ng?"*](../async.md#in-a-hurry){.internal-link target=_blank}.
+
+### Bฦฐแปc 5: Nแปi dung trแบฃ vแป
+
+```Python hl_lines="8"
+{!../../../docs_src/first_steps/tutorial001.py!}
+```
+
+Bแบกn cรณ thแป trแบฃ vแป mแปt `dict`, `list`, mแปt trong nhแปฏng giรก trแป ฤฦกn nhฦฐ `str`, `int`,...
+
+Bแบกn cลฉng cรณ thแป trแบฃ vแป Pydantic model (bแบกn sแบฝ thแบฅy nhiแปu hฦกn vแป nรณ sau).
+
+Cรณ nhiแปu object vร model khรกc nhau sแบฝ ฤฦฐแปฃc tแปฑ ฤแปng chuyแปn ฤแปi sang JSON (bao gแปm cแบฃ ORM,...). Thแปญ sแปญ dแปฅng loแบกi ฦฐa thรญch cแปงa bแบกn, nรณ cรณ khแบฃ nฤng cao ฤรฃ ฤฦฐแปฃc hแป trแปฃ.
+
+## Tรณm lแบกi
+
+* Import `FastAPI`.
+* Tแบกo mแปt `app` instance.
+* Viแบฟt mแปt **decorator cho ฤฦฐแปng dแบซn toรกn tแปญ** (giแปng nhฦฐ `@app.get("/")`).
+* Viแบฟt mแปt **hร m cho ฤฦฐแปng dแบซn toรกn tแปญ** (giแปng nhฦฐ `def root(): ...` แป trรชn).
+* Chแบกy server trong mรดi trฦฐแปng phรกt triแปn (giแปng nhฦฐ `uvicorn main:app --reload`).
diff --git a/docs/vi/docs/tutorial/index.md b/docs/vi/docs/tutorial/index.md
new file mode 100644
index 000000000..e8a93fe40
--- /dev/null
+++ b/docs/vi/docs/tutorial/index.md
@@ -0,0 +1,80 @@
+# Hฦฐแปng dแบซn sแปญ dแปฅng
+
+Hฦฐแปng dแบซn nร y cho bแบกn thแบฅy tแปซng bฦฐแปc cรกch sแปญ dแปฅng **FastAPI** ฤa sแป cรกc tรญnh nฤng cแปงa nรณ.
+
+Mแปi phแบงn ฤฦฐแปฃc xรขy dแปฑng tแปซ nhแปฏng phแบงn trฦฐแปc ฤรณ, nhฦฐng nรณ ฤฦฐแปฃc cแบฅu trรบc thร nh cรกc chแปง ฤแป riรชng biแปt, do ฤรณ bแบกn cรณ thแป xem trแปฑc tiแบฟp tแปซng phแบงn cแปฅ thแป bแบฅt kรฌ ฤแป giแบฃi quyแบฟt nhแปฏng API cแปฅ thแป mร bแบกn cแบงn.
+
+Nรณ cลฉng ฤฦฐแปฃc xรขy dแปฑng ฤแป lร m viแปc nhฦฐ mแปt tham chiแบฟu trong tฦฐฦกng lai.
+
+Do ฤรณ bแบกn cรณ thแป quay lแบกi vร tรฌm chรญnh xรกc nhแปฏng gรฌ bแบกn cแบงn.
+
+## Chแบกy mรฃ
+
+Tแบฅt cแบฃ cรกc code block cรณ thแป ฤฦฐแปฃc sao chรฉp vร sแปญ dแปฅng trแปฑc tiแบฟp (chรบng thแปฑc chแบฅt lร cรกc tแปp tin Python ฤรฃ ฤฦฐแปฃc kiแปm thแปญ).
+
+ฤแป chแบกy bแบฅt kรฌ vรญ dแปฅ nร o, sao chรฉp code tแปi tแปp tin `main.py`, vร bแบฏt ฤแบงu `uvicorn` vแปi:
+
+
+
+```console
+$ uvicorn main:app --reload
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+INFO: Started reloader process [28720]
+INFO: Started server process [28722]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+```
+
+
+
+**Khuyแบฟn khรญch** bแบกn viแบฟt hoแบทc sao chรฉp code, sแปญa vร chแบกy nรณ แป local.
+
+Sแปญ dแปฅng nรณ trong trรฌnh soแบกn thแบฃo cแปงa bแบกn thแปฑc sแปฑ cho bแบกn thแบฅy nhแปฏng lแปฃi รญch cแปงa FastAPI, thแบฅy ฤฦฐแปฃc cรกch bแบกn viแบฟt code รญt hฦกn, tแบฅt cแบฃ ฤแปu ฤฦฐแปฃc type check, autocompletion,...
+
+---
+
+## Cร i ฤแบทt FastAPI
+
+Bฦฐแปc ฤแบงu tiรชn lร cร i ฤแบทt FastAPI.
+
+Vแปi hฦฐแปng dแบซn nร y, bแบกn cรณ thแป muแปn cร i ฤแบทt nรณ vแปi tแบฅt cแบฃ cรกc phแปฅ thuแปc vร tรญnh nฤng tรนy chแปn:
+
+
+
+```console
+$ pip install "fastapi[all]"
+
+---> 100%
+```
+
+
+
+...dรณ cลฉng bao gแปm `uvicorn`, bแบกn cรณ thแป sแปญ dแปฅng nhฦฐ mแปt server ฤแป chแบกy code cแปงa bแบกn.
+
+!!! note
+ Bแบกn cลฉng cรณ thแป cร i ฤแบทt nรณ tแปซng phแบงn.
+
+ ฤรขy lร nhแปฏng gรฌ bแบกn cรณ thแป sแบฝ lร m mแปt lแบงn duy nhแบฅt bแบกn muแปn triแปn khai แปฉng dแปฅng cแปงa bแบกn lรชn production:
+
+ ```
+ pip install fastapi
+ ```
+
+ Cลฉng cร i ฤแบทt `uvicorn` ฤแป lร m viแปc nhฦฐ mแปt server:
+
+ ```
+ pip install "uvicorn[standard]"
+ ```
+
+ Vร tฦฐฦกng tแปฑ vแปi tแปซng phแปฅ thuแปc tรนy chแปn mร bแบกn muแปn sแปญ dแปฅng.
+
+## Hฦฐแปng dแบซn nรขng cao
+
+Cลฉng cรณ mแปt **Hฦฐแปng dแบซn nรขng cao** mร bแบกn cรณ thแป ฤแปc nรณ sau **Hฦฐแปng dแบซn sแปญ dแปฅng**.
+
+**Hฦฐแปng dแบซn sแปญ dแปฅng nรขng cao**, xรขy dแปฑng dแปฑa trรชn cรกi nร y, sแปญ dแปฅng cรกc khรกi niแปm tฦฐฦกng tแปฑ, vร dแบกy bแบกn nhแปฏng tรญnh nฤng mแป rแปng.
+
+Nhฦฐng bแบกn nรชn ฤแปc **Hฦฐแปng dแบซn sแปญ dแปฅng** ฤแบงu tiรชn (nhแปฏng gรฌ bแบกn ฤang ฤแปc).
+
+Nรณ ฤฦฐแปฃc thiแบฟt kแบฟ do ฤรณ bแบกn cรณ thแป xรขy dแปฑng mแปt แปฉng dแปฅng hoร n chแปnh chแป vแปi **Hฦฐแปng dแบซn sแปญ dแปฅng**, vร sau ฤรณ mแป rแปng nรณ theo cรกc cรกch khรกc nhau, phแปฅ thuแปc vร o nhแปฏng gรฌ bแบกn cแบงn, sแปญ dแปฅng mแปt vร i รฝ tฦฐแปng bแป sung tแปซ **Hฦฐแปng dแบซn sแปญ dแปฅng nรขng cao**.
diff --git a/docs/yo/docs/index.md b/docs/yo/docs/index.md
new file mode 100644
index 000000000..101e13b6b
--- /dev/null
+++ b/docs/yo/docs/index.md
@@ -0,0 +1,470 @@
+
+
+
+
+ รlร nร wแบนฬแบนฬbรน FastAPI, iแนฃแบนฬ gรญga, รณ rแปrรนn lรกti kแปฬ, o yรกra lรกti kรณรฒdรน, รณ sรฌ แนฃetรกn fรบn iแนฃelแปpแป nรญ lรญlo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+---
+
+**รkแปsรญlแบนฬ**: https://fastapi.tiangolo.com
+
+**Orisun Kรณรฒdรน**: https://github.com/tiangolo/fastapi
+
+---
+
+FastAPI jแบนฬ รฌgbร lรณdรฉ, tรญ รณ yรกra (iแนฃแบน-giga), รฌlร nร wแบนฬแบนฬbรน fรบn kikแป ร wแปn API pแบนฬlรบ Python 3.8+ รจyรญ tรญ รณ da lori ร wแปn รฌtแปฬkasรญ ร mรฌ irรบfแบนฬ Python.
+
+รwแปn แบนya pร tร kรฌ ni:
+
+* **ร yรกra**: Iแนฃแบน tรญ รณ ga pรบpแปฬ, tรญ รณ wa ni ibamu pแบนฬlรบ **NodeJS** ร ti **Go** (แปpแบน si Starlette ร ti Pydantic). [แปkan nรญnรบ ร wแปn รฌlร nร Python ti o yรกra jรนlแป ti o wa](#performance).
+* **ร yรกra lรกti kรณรฒdรน**: O mu iyara pแป si lรกti kแป ร wแปn แบนya tuntun kรณรฒdรน nipasแบน "Igba รฌdรก แปgแปฬrรนn-รบn" (i.e. 200%) si "แปฬแปฬdรบrรบn รฌdรก แปgแปฬrรนn-รบn" (i.e. 300%).
+* **รรฌtแปฬ kรฉkerรฉ**: O n din aแนฃiแนฃe ku bi แปgbon รฌdรก แปgแปฬrรนn-รบn (i.e. 40%) ti eda eniyan (oแนฃiแนฃแบน kรณรฒdรน) fa. *
+* **แปgbแปฬn ร ti รฌmแปฬ**: Atilแบนyin olootu nla. รparรญ nibi gbogbo. รkรณkรฒ dรญแบนฬ nipa wรญwรก ibi tรญ รฌแนฃรฒro kรณรฒdรน wร .
+* **Irแปrun**: A kแป kรญ รณ le rแปrun lรกti lo ร ti lรกti kแป แบนkแป nรญnรบ rรจ. ร mรกa fรบn แป nรญ ร kรณkรฒ dรญแบนฬ lรกtฤฑ ka ร kแปsรญlแบน.
+* **ร kรบkurรบ nรญ kikแป**: ร dรญn ร tรบnkแป ร ti ร tรบntรฒ kรณรฒdรน kรน. รkรฉde ร แนฃร yร n kแปฬแปฬkan nรญnรบ rแบนฬ nรญ แปฬpแปฬlแปpแปฬ ร wแปn รฌlรฒ. O แนฃe iranlแปwแป lรกti mรก แนฃe nรญ แปฬpแปฬlแปpแปฬ ร แนฃรฌแนฃe.
+* **ร lรกgbรกra**: ร ล แนฃe ร gbรฉjรกde kรณรฒdรน tรญ รณ แนฃetรกn fรบn รฌแนฃelแปฬpแปฬ. Pแบนฬlรบ ร kแปsรญlแบนฬ tรญ รณ mรกa แนฃร lร yรฉ ara rแบนฬ fรบn แบน nรญ รฌbรกแนฃepแปฬ alรกdร รกแนฃiแนฃแบนฬ pแบนฬlรบ rรจ.
+* **Ajohunลกe/รtแปฬkasรญ**: ร da lori (ร ti ibamu ni kikun pแบนฬlรบ) ร wแปn รฌmแป ajohunลกe/รฌtแปฬkasรญ fรบn ร wแปn API: OpenAPI (รจyรญ tรญ a mแป tแบนlแบน si Swagger) ร ti JSON Schema.
+
+* iแนฃiro yi da lori ร wแปn idanwo tรญ แบนgbแบน รฌdร gbร sรณkรจ FastAPI แนฃe, nรญgbร tรญ wแปn kแป ร wแปn ohun elo iแนฃelแปpแป kรณรฒdรน pแบนฬlรบ rแบน.
+
+## รwแปn onรญgbแปฬwแปฬ
+
+
+
+{% if sponsors %}
+{% for sponsor in sponsors.gold -%}
+
+{% endfor -%}
+{%- for sponsor in sponsors.silver -%}
+
+{% endfor %}
+{% endif %}
+
+
+
+รwแปn onรญgbแปฬwแปฬ mรญrร n
+
+## รwแปn ero ร ti รจsรฌ
+
+"_[...] Mรฒ ล lo **FastAPI** pรบpแปฬ nรญ lแบนฬnu ร รฌpแบนฬ yรฌรญ. [...] Mo n gbero lรกti lo o pแบนฬlรบ ร wแปn แบนgbแบน mi fรบn gbogbo iแนฃแบน **ML wa ni Microsoft**. Diแบน nรญnรบ wแปn ni afikun ti ifilelแบน ร wแปn แบนya ara ti แปja **Windows** wa pแบนฬlรบ ร wแปn ti **Office**._"
+
+Kabir Khan -
Microsoft (ref)
+
+---
+
+"_A gba ร wแปn ohun รจlรฒ รฌwรฉ afแปwแปkแป **FastAPI** tรญ kรฒ yรญ padร lรกti แนฃแบนฬdรก olรนpรญn **REST** tรญ a lรจ bรฉรจrรจ lแปฬwแปฬ rแบนฬ lรกti gba **ร sแปtแบนฬlแบนฬ**. [fรบn Ludwig]_"
+
+Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala -
Uber (ref)
+
+---
+
+"_**Netflix** ni inudidun lรกti kede itusilแบน orisun kรณรฒdรน ti รฌlร nร iแนฃแปkan **iแนฃakoso รแนฃรฒro** wa: **รfirรกnแนฃแบนฬ**! [a kแป pแบนฬlรบ **FastAPI**]_"
+
+Kevin Glisson, Marc Vilanova, Forest Monsen -
Netflix (ref)
+
+---
+
+"_Inรบ mi dรนn pรบpแปฬ nรญpa **FastAPI**. ร mรบ inรบ แบนnรฌ dรนn pรบpแปฬ!_"
+
+
+
+---
+
+"_Nรญ tรฒรณtแปฬ, ohun tรญ o kแป dรกra รณ sรฌ tรบn dรกn. Nรญ แปฬpแปฬlแปpแปฬ แปฬnร , ohun tรญ mo fแบนฬ kรญ **Hug** jแบนฬ nรฌyแบนn - รณ wรบni lรณrรญ gan-an lรกti rรญ แบนnรฌkan tรญ รณ kแปฬ nวนkan bรญ รจyรญ._"
+
+
+
+---
+
+"_Ti o ba n wa lรกti kแป แปkan **รฌlร nร igbalode** fรบn kikแป ร wแปn REST API, แนฃayแบนwo **FastAPI** [...] ร yรกra, รณ rแปrรนn lรกti lรฒ, รณ sรฌ rแปrรนn lรกti kแปฬ[...]_"
+
+"_A ti yipada si **FastAPI** fรบn **APIs** wa [...] Mo lรฉrรฒ pรฉ wร รก fแบนฬrร n rแบนฬ [...]_"
+
+
+
+---
+
+"_Ti แบนnikแบนni ba n wa lรกti kแป iแนฃelแปpแป API pแบนฬlรบ Python, รจmi yรณรฒ แนฃe'dรบrรณ fรบn **FastAPI**. ร jแบนฬ ohun tรญ **ร gbรฉkalแบนฬ rแบนฬ lแบนฬwร **, **รณ rแปrรนn lรกti lรฒ** ร ti wipe รณ ni **รฌwแปฬn gรญga**, o tรญ dรญ **bแปtini paati** nรญnรบ alakแปkแป API รฌdร gbร sรณkรจ kikแป fรบn wa, ร ti pe o ni ipa lori adaแนฃiแนฃแบน ร ti ร wแปn iแนฃแบน gแบนฬgแบนฬ bรญi Onรญmแปฬ-แบนฬrแป TAC tรญ รณrรญ รลtรกnแบนฬแบนฬtรฌ_"
+
+Deon Pillsbury -
Cisco (ref)
+
+---
+
+## **Typer**, FastAPI ti CLIs
+
+
+
+Ti o ba n kแป ohun รจlรฒ CLI lรกti แนฃeรฉ lแป nรญnรบ ohun รจlรฒ lori ebute kแปmputa dipo API, แนฃayแบนwo **Typer**.
+
+**Typer** jแบนฬ ร bรบrรฒ รฌyรก FastAPI kรฉkerรฉ. รti pรฉ wแปฬn kแปฬ lรกti jแบนฬ **FastAPI ti CLIs**. โจ๏ธ ๐
+
+## รrรฒjร
+
+Python 3.8+
+
+FastAPI dรบrรณ lรณrรญ ร wแปn รจjรฌkรก tรญ ร wแปn รฒmรญrร n:
+
+* Starlette fรบn ร wแปn แบนฬyร ayรฉlujรกra.
+* Pydantic fรบn ร wแปn แบนฬyร ร kรณjแปf'รกyแบนฬwรฒ.
+
+## Fifi sรณrรญ แบนrแป
+
+
+
+```console
+$ pip install fastapi
+
+---> 100%
+```
+
+
+Iwแป yรณรฒ tรบn nรญlรฒ olupin ASGI, fรบn iแนฃelแปpแป bii Uvicorn tabi Hypercorn.
+
+
+
+```console
+$ pip install "uvicorn[standard]"
+
+---> 100%
+```
+
+
+
+## รpแบนแบนrแบน
+
+### แนขแบนฬdรก rแบนฬ
+
+* แนขแบนฬdรก fรกรฌlรฌ `main.py (รจyรญ tรญรญ แนฃe, akแปkแป.py)` pแบนฬlรบ:
+
+```Python
+from typing import Union
+
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/")
+def read_root():
+ return {"Hello": "World"}
+
+
+@app.get("/items/{item_id}")
+def read_item(item_id: int, q: Union[str, None] = None):
+ return {"item_id": item_id, "q": q}
+```
+
+
+Tร bรญ lรฒ async def...
+
+Tรญ kรณรฒdรน rแบนฬ bรก ล lรฒ `async` / `await`, lรฒ `async def`:
+
+```Python hl_lines="9 14"
+from typing import Union
+
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/")
+async def read_root():
+ return {"Hello": "World"}
+
+
+@app.get("/items/{item_id}")
+async def read_item(item_id: int, q: Union[str, None] = None):
+ return {"item_id": item_id, "q": q}
+```
+
+**Akiyesi**:
+
+Tรญ o kรฒ bรก mแปฬ, แนฃร yแบนฬwรฒ ibi tรญ a ti nรญ _"In a hurry?"_ (i.e. _"Nรญ kรญรกkรญรก?"_) nรญpa `async` and `await` nรญnรบ ร kแปsรญlแบนฬ.
+
+
+
+### Mu แนฃiแนฃแบน
+
+Mรบ olupin แนฃiแนฃแบน pแบนฬlรบ:
+
+
+
+```console
+$ uvicorn main:app --reload
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+INFO: Started reloader process [28720]
+INFO: Started server process [28722]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+```
+
+
+
+
+Nipa aแนฃแบน kรณรฒdรน nรกร uvicorn main:app --reload...
+
+รแนฃแบน `uvicorn main:app` ล tแปฬka sรญ:
+
+* `main`: fรกรฌlรฌ nรกร 'main.py' (Python "module").
+* `app` jแบน object( i.e. nวนkan) tรญ a แนฃแบนฬdรก nรญnรบ `main.py` pแบนฬlรบ ilร `app = FastAPI()`.
+* `--reload`: รจyรญ yรณรฒ jแบนฬ ki olupin tรบn bแบนฬrแบนฬ lแบนฬhรฌn ร wแปn ร yรญpadร kรณรฒdรน. Jแปฬwแปฬ, แนฃe รจyรญ fรบn รฌdร gbร sรณkรจ kรณรฒdรน nรฌkan, mรก แนฃe รฉ แนฃe lori ร gbรฉjรกde kรณรฒdรน tabi fรบn iแนฃelแปpแป kรณรฒdรน.
+
+
+
+
+### แนขayแบนwo rแบน
+
+แนขii aแนฃร wรกkiri kแปฬวนpรบtร rแบน ni http://127.0.0.1:8000/items/5?q=somequery.
+
+รwแป yรณรฒ sรฌ rรญ รฌdรกhรนn JSON bรญi:
+
+```JSON
+{"item_id": 5, "q": "somequery"}
+```
+
+O tรญ แนฃแบนฬdรก API รจyรญ tรญ yรณรฒ:
+
+* Gbร ร wแปn รฌbรฉรจrรจ HTTP ni ร wแปn _ipa แปฬnร _ `/` ร ti `/items/{item_id}`.
+* รyรญ tรญ ร wแปn _ipa แปฬnร _ (i.e. _paths_) mรฉjรจรจjรฌ gbร ร wแปn iแนฃแบน `GET` (a tun mแป si _ร wแปn แปna_ HTTP).
+* รyรญ tรญ _ipa แปฬnร _ (i.e. _paths_) `/items/{item_id}` nรญ _ร wแปn ohun-ini ipa แปฬnร _ tรญ รณ yแบน kรญ รณ jแบนฬ `int` i.e. `รวธKร`.
+* รyรญ tรญ _ipa แปฬnร _ (i.e. _paths_) `/items/{item_id}` nรญ ร แนฃร yร n `str` _ร wแปn ohun-ini_ (i.e. _query parameter_) `q`.
+
+### รbรกแนฃepแปฬ ร kแปsรญlแบนฬ API
+
+Nรญ bรกyรฌรญ, lแป sรญ http://127.0.0.1:8000/docs.
+
+Lแบนฬyรฌn nรกร , iwแป yรณรฒ rรญ รฌdรกhรนn ร kแปsรญlแบนฬ API tรญ รณ jแบนฬ รฌbรกแนฃepแปฬ alaifแปwแปyi/alรกdร รกแนฃiแนฃแบนฬ (tรญ a pรจแนฃรจ nรญpaแนฃแบนฬ Swagger UI):
+
+
+
+### รdร kejรฌ ร kแปsรญlแบนฬ API
+
+Nรญ bรกyรฌรญ, lแป sรญ http://127.0.0.1:8000/redoc.
+
+Wร รก rรญ ร wแปn ร kแปsรญlแบนฬ alรกdร รกแนฃiแนฃแบนฬ mรฌรญrร n (tรญ a pese nipasแบน ReDoc):
+
+
+
+## รpแบนแบนrแบน รฌgbรฉsรณkรจ mรฌรญrร n
+
+Nรญ bรกyรฌรญ แนฃe ร tรบnแนฃe fรกรฌlรฌ `main.py` lรกti gba kรณkรณ รจsรฌ lรกti inรบ รฌbรฉรจrรจ `PUT`.
+
+Nรญ bรกyรฌรญ, แนฃe รฌkรฉde kรณkรณ รจsรฌ API nรญnรบ kรณรฒdรน rแบน nipa lรญlo ร wแปn รฌtแปฬkasรญ ร mรฌ irรบfแบนฬ Python, แปpแบนฬ pร tร kรฌsi sรญ Pydantic.
+
+```Python hl_lines="4 9-12 25-27"
+from typing import Union
+
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+ name: str
+ price: float
+ is_offer: Union[bool, None] = None
+
+
+@app.get("/")
+def read_root():
+ return {"Hello": "World"}
+
+
+@app.get("/items/{item_id}")
+def read_item(item_id: int, q: Union[str, None] = None):
+ return {"item_id": item_id, "q": q}
+
+
+@app.put("/items/{item_id}")
+def update_item(item_id: int, item: Item):
+ return {"item_name": item.name, "item_id": item_id}
+```
+
+Olupin yรณรฒ tรบn แนฃe ร tรบnแนฃe laifแปwแปyi/alรกdร รกแนฃiแนฃแบนฬ (nรญtorรญ wรญpรฉ รณ se ร fikรบn `-reload` si ร แนฃแบน kรณรฒdรน `uvicorn` lรณkรจ).
+
+### รbรกแนฃepแปฬ รฌgbรฉsรณkรจ ร kแปsรญlแบนฬ API
+
+Nรญ bรกyรฌรญ, lแป sรญ http://127.0.0.1:8000/docs.
+
+* รbรกแนฃepแปฬ ร kแปsรญlแบนฬ API yรณรฒ แนฃe imudojuiwแปn ร kแปsรญlแบนฬ API laifแปwแปyi, pแบนฬlรบ kรณkรณ รจsรฌ รฌdรกhรนn API tuntun:
+
+
+
+* Tแบน bแปtini "Gbiyanju rแบน" i.e. "Try it out", yรณรฒ gbร แปฬ lรกร yรจ lรกti jแบนฬ kรญ รณ tแบนฬ ร lร yรฉ tรญ รณ nรญlรฒ kรญ รณ le sแปฬrแปฬ tร ร rร pแบนฬlรบ API:
+
+
+
+* Lแบนhinna tแบน bแปtini "แนขiแนฃe" i.e. "Execute", olรนmรบlรฒ (i.e. user interface) yรณรฒ sแปrแป pแบนฬlรบ API rแบน, yรณรฒ แนฃe afiranแนฃแบน ร wแปn รจrรฒjร , pร รกpร รก jรนlแป yรณรฒ gba ร wแปn ร bรกjรกde yรณรฒ si แนฃafihan wแปn loju รฌbรฒjรบ:
+
+
+
+### รdร kejรฌ รฌgbรฉsรณkรจ ร kแปsรญlแบนฬ API
+
+Nรญ bรกyรฌรญ, lแป sรญ http://127.0.0.1:8000/redoc.
+
+* รdร kejรฌ ร kแปsรญlแบนฬ API yรณรฒ แนฃ'afihan รฌbรฉรจrรจ รจrรฒjร /pร rรกmรญtร tuntun ร ti kรณkรณ รจsรฌ ti API:
+
+
+
+### รtรบnyแบนฬwรฒ
+
+Ni akopแป, รฌwแป yรณรฒ kรฉde ni **kete** ร wแปn iru รจrรฒjร /pร rรกmรญtร , kรณkรณ รจsรฌ API, abbl (i.e. ร ti bแบนbแบน lแป), bi ร wแปn รจrรฒjร iแนฃแบน.
+
+O แนฃe รฌyแบนn pแบนฬlรบ irรบfแบนฬ ร mรฌ รฌtแปฬkasรญ รฌgbร lรณdรฉ Python.
+
+O รฒ nรญlรฒ lรกti kแปฬ sรญลtรกร sรฌ tuntun, รฌlร nร tร bรญ แปฬwแปฬ kรญlรกร sรฌ kan pร tรณ, abbl (i.e. ร ti bแบนbแบน lแป).
+
+รtแปฬkasรญ **Python 3.8+**
+
+Fรบn ร pแบนแบนrแบน, fรบn `int`:
+
+```Python
+item_id: int
+```
+
+tร bรญ fรบn ร wรฒแนฃe `Item` tรญ รณ nira dรญแบนฬ sรญi:
+
+```Python
+item: Item
+```
+
+... ร ti pแบนฬlรบ รฌkรฉde kan แนฃoแนฃo yแบนn รฌwแป yรณรฒ gbร :
+
+* Atilแบนyin olootu, pแบนฬlรบ:
+ * Pipari.
+ * รyแบนฬwรฒ irรบfแบนฬ ร mรฌ รฌtแปฬkasรญ.
+* รfแปwแปฬsรญ ร kรณjแปf'รกyแบนฬwรฒ (i.e. data):
+ * Aแนฃiแนฃe alaifแปwแปyi/alรกdร รกแนฃiแนฃแบนฬ ร ti aแนฃiแนฃe ti รณ hร n kedere nรญgbร tรญ ร wแปn ร kรณjแปf'รกyแบนฬwรฒ (i.e. data) kรฒ wulo tabi tรญ kรฒ fแบนsแบนฬ mรบlแบนฬ.
+ * รfแปwแปฬsรญ fรบn ohun elo JSON tรญ รณ jรฌn gan-an.
+* รyรญpadร tรญ input ร kรณjแปf'รกyแบนฬwรฒ: tรญ รณ wร lรกti nแบนtiwแปแปki si ร kรณjแปf'รกyแบนฬwรฒ ร ti irรบfแบนฬ ร mรฌ รฌtแปฬkasรญ Python. ร ล ka lรกti:
+ * JSON.
+ * รจrรฒjร แปฬnร tรญ รฒ gbรฉ gbร .
+ * รจrรฒjร รฌbรฉรจrรจ.
+ * รwแปn Kรบkรฌ
+ * รwแปn รkแปlรฉ
+ * รwแปn Fแปแปmu
+ * รwแปn Fรกรฌlรฌ
+* รyรญpadร รจsรฌ ร kรณjแปf'รกyแบนฬwรฒ: yรญyรญpadร lรกti ร kรณjแปf'รกyแบนฬwรฒ ร ti irรบfแบนฬ ร mรฌ รฌtแปฬkasรญ Python si nแบนtiwแปแปki (gแบนฬgแบนฬ bรญ JSON):
+ * Yรญ irรบfแบนฬ ร mรฌ รฌtแปฬkasรญ padร (`str`, `int`, `float`, `bool`, `list`, abbl i.e. ร ti bรจbรจ lรณ).
+ * รwแปn ohun รจlรฒ `datetime`.
+ * รwแปn ohun รจlรฒ `UUID`.
+ * รwแปn awoแนฃแบนฬ ibi รฌpamแปฬ ร kรณjแปf'รกyแบนฬwรฒ.
+ * ...ร ti แปฬpแปฬlแปpแปฬ dรญแบนฬ sรญi.
+* รbรกแนฃepแปฬ ร kแปsรญlแบนฬ API alรกdร รกแนฃiแนฃแบนฬ, pแบนฬlรบ รฌdร kejรฌ ร gbรฉkalแบนฬ-ร wแปn-olรนmรบlรฒ (i.e user interfaces) mรฉjรฌ:
+ * รgbรฉkalแบนฬ-olรนmรบlรฒ Swagger.
+ * ReDoc.
+
+---
+
+Nisinsin yi, tรญ รณ padร sรญ ร pแบนแบนrแบน ti tแบนฬlแบนฬ, **FastAPI** yรณรฒ:
+
+* Fแปwแปฬ sรญ i pรฉ `item_id` wร nรญnรบ แปฬnร รฌbรฉรจrรจ HTTP fรบn `GET` ร ti `PUT`.
+* Fแปwแปฬ sรญ i pรฉ `item_id` jแบนฬ irรบfแบนฬ ร mรฌ รฌtแปฬkasรญ `int` fรบn รฌbรฉรจrรจ HTTP `GET` ร ti `PUT`.
+ * Tรญ kรฌรญ bรก แนฃe bแบน, onรญbร รกrร yรณรฒ rรญi ร แนฃรฌแนฃe tรญ รณ wรบlรฒ, kedere.
+* แนขร yแบนฬwรฒ bรณyรก รฌbรฉรจrรจ ร แนฃร yร n pร rรกmรญtร kan wร tรญ orรบkแป rแบนฬ ล jแบนฬ `q` (gแบนฬgแบนฬ bรญi `http://127.0.0.1:8000/items/foo?q=somequery`) fรบn รฌbรฉรจrรจ HTTP `GET`.
+ * Bรญ wแปฬn แนฃe kรฉde pร rรกmรญtร `q` pแบนฬlรบ `= None`, รณ jแบนฬ ร แนฃร yร n (i.e optional).
+ * Lรกรฌsรญ `None` yรณรฒ nรญlรฒ (gแบนฬgแบนฬ bรญ kรณkรณ รจsรฌ รฌbรฉรจrรจ HTTP แนฃe wร pแบนฬlรบ `PUT`).
+* Fรบn ร wแปn รฌbรฉรจrรจ HTTP `PUT` sรญ `/items/{item_id}`, kร kรณkรณ รจsรฌ รฌbรฉรจrรจ HTTP gแบนฬgแบนฬ bรญ JSON:
+ * แนขร yแบนฬwรฒ pรฉ รณ nรญ ร bรนdรก tรญ รณ nรญlรฒ รจyรญ tรญรญ แนฃe `name` i.e. `orรบkแป` tรญ รณ yแบน kรญ รณ jแบนฬ `str`.
+ * แนขร yแบนฬwรฒ pรฉ รณ nรญ ร bรนdรก tรญ รณ nรญlรฒ รจyรญ tรญรญ แนฃe `price` i.e. `iye` tรญ รณ gbแปฬdแปฬ jแบนฬ `float`.
+ * แนขร yแบนฬwรฒ pรฉ รณ nรญ ร bรนdรก ร แนฃร yร n `is_offer`, tรญ รณ yแบน kรญ รณ jแบนฬ `bool`, tรญ รณ bรก wร nรญbแบนฬ.
+ * Gbogbo รจyรญ yรณรฒ tรบn แนฃiแนฃแบนฬ fรบn ร wแปn ohun รจlรฒ JSON tรญ รณ jรฌn gidi gan-an.
+* Yรฌรญ padร lรกti ร ti sรญ JSON lai fi แปwแปฬ yi.
+* แนขe ร kแปsรญlแบนฬ ohun gbogbo pแบนฬlรบ OpenAPI, รจyรญ tรญ yรณรฒ wร nรญ lรญlo nรญpaแนฃแบนฬ:
+ * รwแปn รจtรฒ ร kแปsรญlแบนฬ รฌbรกแนฃepแปฬ.
+ * Alรกdร รกแนฃiแนฃแบนฬ onรญbรกrร รจlรจtรฒ tรญรญ แนฃแบนฬdรก kรณรฒdรน, fรบn แปฬpแปฬlแปpแปฬ ร wแปn รจdรจ.
+* Pese ร kแปsรญlแบนฬ รฒnรญ รฌbรกแนฃepแปฬ ti ร wแปn ร gbรฉkalแบนฬ ayรฉlujรกra mรฉjรฌ tร ร rร .
+
+---
+
+A ล แนฃแบนฬแนฃแบนฬ ล mรบ แบนyแบน bแปฬ lร pรฒ nรญ, แนฃรนgbแปฬn รณ ti ni รฒye bรญ gbogbo rแบนฬ แนฃe ล แนฃiแนฃแบนฬ.
+
+Gbiyanju lรกti yรญ รฌlร padร pแบนฬlรบ:
+
+```Python
+ return {"item_name": item.name, "item_id": item_id}
+```
+
+...lรกti:
+
+```Python
+ ... "item_name": item.name ...
+```
+
+...แนฃรญ:
+
+```Python
+ ... "item_price": item.price ...
+```
+
+.. kรญ o sรฌ wo bรญ olรณรฒtรบ rแบน yรณรฒ แนฃe parรญ ร wแปn ร bรนdรก nรกร fรบnra rแบนฬ, yรณรฒ sรฌ mแป irรบfแบนฬ wแปn:
+
+
+
+Fรบn ร pแบนแบนrแบน pรญpรฉ sรญi pแบนฬlรบ ร wแปn ร bรนdรก mรฌรญrร n, wo รdรกnilแบนฬkแปฬแปฬ - รtแปฬsแปฬnร Olรนmรบlรฒ.
+
+**Itaniji gแบนฬgแบนฬ bรญ isแป'ye**: รฌdรกnilแบนฬkแปฬแปฬ - itแปsแปna olรนmรบlรฒ pแบนฬlรบ:
+
+* รkรฉde ร แนฃร yร n **pร rรกmรญtร ** lรกti ร wแปn oriแนฃiriแนฃi ibรฒmรญrร n gแบนฬgแบนฬ bรญi: ร wแปn **ร kแปlรฉ รจsรฌ API**, **kรบkรฌ**, **ร ร yรจ fแปแปmu**, ร ti **fรกรฌlรฌ**.
+* Bรญi รณ แนฃe lรฉ แนฃรจtรฒ **ร wแปn รฌdรญwแปฬ รฌfแปwแปฬsรญ** bรญ `maximum_length` tร bรญ `regex`.
+* ร lรกgbรกra pรบpแปฬ รณ sรฌ rแปrรนn lรกti lo รจtรฒ **รfikรบn รgbแบนฬkแบนฬlรฉ Kรณรฒdรน**.
+* รร bรฒ ร ti รฌfแปwแปฬsowแปฬpแปฬ, pแบนฬlรบ ร tรฌlแบนฬyรฌn fรบn **OAuth2** pแบนฬlรบ **ร mรฌ JWT** ร ti **HTTP Ipilแบน รฌfแปwแปฬsowแปฬpแปฬ**.
+* รwแปn รฌlร nร รฌlแปsรญwรกjรบ (แนฃรนgbแปฬn tรญ รณ rแปrรนn bรกkan nรกร ) fรบn รฌkรฉde **ร wแปn ร wรฒแนฃe JSON tรณ jinlแบนฬ** (แปpแบนฬ pร tร kรฌsi sรญ Pydantic).
+* Iแนฃแปpแป **GraphQL** pแบนฬlรบ Strawberry ร ti ร wแปn ohun รจlรฒ รฌwรฉ kรณรฒdรน afแปwแปkแป mรฌรญrร n tรญ kรฒ yรญ padร .
+* แปpแปlแปpแป ร wแปn ร fikรบn ร wแปn แบนฬyร (แปpแบนฬ pร tร kรฌsi sรญ Starlette) bรญ:
+ * **WebSockets**
+ * ร wแปn รฌdรกnwรฒ tรญ รณ rแปrรนn pรบpแปฬ lรณrรญ HTTPX ร ti `pytest`
+ * **CORS**
+ * **Cookie Sessions**
+ * ...ร ti sรญwรกjรบ sรญi.
+
+## รแนฃesรญ
+
+รwแปn ร lรก TechEmpower fi hร n pรฉ **FastAPI** ล แนฃiแนฃแบนฬ lรกbแบนฬ Uvicorn gแบนฬgแบนฬ bรญ แปฬkan lรกra ร wแปn รฌlร nร Python tรญ รณ yรกra jรนlแป tรญ รณ wร , nรญ รฌsร lแบนฬ Starlette ร ti Uvicorn fรบnra wแปn (tรญ FastAPI ล lรฒ fรบnra rแบนฬ). (*)
+
+Lรกti nรญ รฒye sรญi nรญpa rแบนฬ, wo abala ร wแปn รlรก.
+
+## รแนฃร yร n รwแปn รfikรบn รgbแบนฬkแบนฬlรฉ Kรณรฒdรน
+
+รyรญ tรญ Pydantic ล lรฒ:
+
+* email_validator - fรบn ifแปwแปsi รญmeรจlรฌ.
+* pydantic-settings - fรบn รจtรฒ รฌsร kรณso.
+* pydantic-extra-types - fรบn ร fikรบn orรญแนฃi lรกti lแป pแบนฬlรบ Pydantic.
+
+รyรญ tรญ Starlette ล lรฒ:
+
+* httpx - Nรญlรฒ tรญ รณ bรก fแบนฬ lรกti lแป `TestClient`.
+* jinja2 - Nรญlรฒ tรญ รณ bรก fแบนฬ lรกti lแป iแนฃeto awoแนฃe aiyipada.
+* python-multipart - Nรญlรฒ tรญ รณ bรก fแบนฬ lรกti แนฃe ร tรฌlแบนฬyรฌn fรบn "ร yแบนฬwรฒ" fแปแปmu, pแบนฬlรบ `request.form()`.
+* itsdangerous - Nรญlรฒ fรบn ร tรฌlแบนฬyรฌn `SessionMiddleware`.
+* pyyaml - Nรญlรฒ fรบn ร tรฌlแบนฬyรฌn Starlette's `SchemaGenerator` (รณ แนฃe แนฃe kรญ รณ mรก nรญlรฒ rแบนฬ fรบn FastAPI).
+* ujson - Nรญlรฒ tรญ รณ bรก fแบนฬ lรกti lแป `UJSONResponse`.
+
+รyรญ tรญ FastAPI / Starlette ล lรฒ:
+
+* uvicorn - Fรบn olupin tรญ yรณรฒ sแบนฬ ร mรบyแบน ร ti tรญ yรณรฒ แนฃe รฌpรจsรจ fรบn iแนฃแบนฬ rแบน tร bรญ ohun รจlรฒ rแบน.
+* orjson - Nรญlรฒ tรญ รณ bรก fแบนฬ lรกti lแป `ORJSONResponse`.
+
+ร lรจ fi gbogbo ร wแปn wแปฬnyรญ sรณrรญ แบนrแป pแบนฬlรบ `pip install "fastapi[all]"`.
+
+## Iwe-aแนฃแบน
+
+Iแนฃแบนฬ yรฌรญ ni iwe-aแนฃแบน lรกbแบนฬ ร wแปn รฒfin tรญ iwe-aแนฃแบน MIT.
diff --git a/docs/yo/mkdocs.yml b/docs/yo/mkdocs.yml
new file mode 100644
index 000000000..de18856f4
--- /dev/null
+++ b/docs/yo/mkdocs.yml
@@ -0,0 +1 @@
+INHERIT: ../en/mkdocs.yml
diff --git a/docs/zh/docs/advanced/generate-clients.md b/docs/zh/docs/advanced/generate-clients.md
new file mode 100644
index 000000000..e222e479c
--- /dev/null
+++ b/docs/zh/docs/advanced/generate-clients.md
@@ -0,0 +1,266 @@
+# ็ๆๅฎขๆท็ซฏ
+
+ๅ ไธบ **FastAPI** ๆฏๅบไบOpenAPI่ง่็๏ผ่ช็ถๆจๅฏไปฅไฝฟ็จ่ฎธๅค็ธๅน้
็ๅทฅๅ
ท๏ผๅ
ๆฌ่ชๅจ็ๆAPIๆๆกฃ (็ฑ Swagger UI ๆไพ)ใ
+
+ไธไธชไธๅคชๆๆพ่ๅ็นๅซ็ไผๅฟๆฏ๏ผไฝ ๅฏไปฅไธบไฝ ็API้ๅฏนไธๅ็**็ผ็จ่ฏญ่จ**ๆฅ**็ๆๅฎขๆท็ซฏ**(ๆๆถๅ่ขซๅซๅ **SDKs** )ใ
+
+## OpenAPI ๅฎขๆท็ซฏ็ๆ
+
+ๆ่ฎธๅคๅทฅๅ
ทๅฏไปฅไป**OpenAPI**็ๆๅฎขๆท็ซฏใ
+
+ไธไธชๅธธ่ง็ๅทฅๅ
ทๆฏ OpenAPI Generatorใ
+
+ๅฆๆๆจๆญฃๅจๅผๅ**ๅ็ซฏ**๏ผไธไธช้ๅธธๆ่ถฃ็ๆฟไปฃๆนๆกๆฏ openapi-typescript-codegenใ
+
+## ็ๆไธไธช TypeScript ๅ็ซฏๅฎขๆท็ซฏ
+
+่ฎฉๆไปฌไปไธไธช็ฎๅ็ FastAPI ๅบ็จๅผๅง๏ผ
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="7-9 12-13 16-17 21"
+ {!> ../../../docs_src/generate_clients/tutorial001_py39.py!}
+ ```
+
+=== "Python 3.8+"
+
+ ```Python hl_lines="9-11 14-15 18 19 23"
+ {!> ../../../docs_src/generate_clients/tutorial001.py!}
+ ```
+
+่ฏทๆณจๆ๏ผ*่ทฏๅพๆไฝ* ๅฎไนไบไปไปฌๆ็จไบ่ฏทๆฑๆฐๆฎๅๅๅบๆฐๆฎ็ๆจกๅ๏ผๆไฝฟ็จ็ๆจกๅๆฏ`Item` ๅ `ResponseMessage`ใ
+
+### API ๆๆกฃ
+
+ๅฆๆๆจ่ฎฟ้ฎAPIๆๆกฃ๏ผๆจๅฐ็ๅฐๅฎๅ
ทๆๅจ่ฏทๆฑไธญๅ้ๅๅจๅๅบไธญๆฅๆถๆฐๆฎ็**ๆจกๅผ(schemas)**๏ผ
+
+
+
+ๆจๅฏไปฅ็ๅฐ่ฟไบๆจกๅผ๏ผๅ ไธบๅฎไปฌๆฏ็จ็จๅบไธญ็ๆจกๅๅฃฐๆ็ใ
+
+้ฃไบไฟกๆฏๅฏไปฅๅจๅบ็จ็ **OpenAPIๆจกๅผ** ่ขซๆพๅฐ๏ผ็ถๅๆพ็คบๅจAPIๆๆกฃไธญ๏ผ้่ฟSwagger UI๏ผใ
+
+OpenAPIไธญๆๅ
ๅซ็ๆจกๅ้ๆ็ธๅ็ไฟกๆฏๅฏไปฅ็จไบ **็ๆๅฎขๆท็ซฏไปฃ็ **ใ
+
+### ็ๆไธไธชTypeScript ๅฎขๆท็ซฏ
+
+็ฐๅจๆไปฌๆไบๅธฆๆๆจกๅ็ๅบ็จ๏ผๆไปฌๅฏไปฅไธบๅ็ซฏ็ๆๅฎขๆท็ซฏไปฃ็ ใ
+
+#### ๅฎ่ฃ
`openapi-typescript-codegen`
+
+ๆจๅฏไปฅไฝฟ็จไปฅไธๅทฅๅ
ทๅจๅ็ซฏไปฃ็ ไธญๅฎ่ฃ
`openapi-typescript-codegen`:
+
+
+
+```console
+$ npm install openapi-typescript-codegen --save-dev
+
+---> 100%
+```
+
+
+
+#### ็ๆๅฎขๆท็ซฏไปฃ็
+
+่ฆ็ๆๅฎขๆท็ซฏไปฃ็ ๏ผๆจๅฏไปฅไฝฟ็จ็ฐๅจๅฐ่ฆๅฎ่ฃ
็ๅฝไปค่กๅบ็จ็จๅบ `openapi`ใ
+
+ๅ ไธบๅฎๅฎ่ฃ
ๅจๆฌๅฐ้กน็ฎไธญ๏ผๆไปฅๆจๅฏ่ฝๆ ๆณ็ดๆฅไฝฟ็จๆญคๅฝไปค๏ผไฝๆจๅฏไปฅๅฐๅ
ถๆพๅจ `package.json` ๆไปถไธญใ
+
+ๅฎๅฏ่ฝ็่ตทๆฅๆฏ่ฟๆ ท็:
+
+```JSON hl_lines="7"
+{
+ "name": "frontend-app",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "generate-client": "openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios"
+ },
+ "author": "",
+ "license": "",
+ "devDependencies": {
+ "openapi-typescript-codegen": "^0.20.1",
+ "typescript": "^4.6.2"
+ }
+}
+```
+
+ๅจ่ฟ้ๆทปๅ NPM `generate-client` ่ๆฌๅ๏ผๆจๅฏไปฅไฝฟ็จไปฅไธๅฝไปค่ฟ่กๅฎ:
+
+
+
+```console
+$ npm run generate-client
+
+frontend-app@1.0.0 generate-client /home/user/code/frontend-app
+> openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios
+```
+
+
+
+ๆญคๅฝไปคๅฐๅจ `./src/client` ไธญ็ๆไปฃ็ ๏ผๅนถๅฐๅจๅ
ถๅ
้จไฝฟ็จ `axios`๏ผๅ็ซฏHTTPๅบ๏ผใ
+
+### ๅฐ่ฏๅฎขๆท็ซฏไปฃ็
+
+็ฐๅจๆจๅฏไปฅๅฏผๅ
ฅๅนถไฝฟ็จๅฎขๆท็ซฏไปฃ็ ๏ผๅฎๅฏ่ฝ็่ตทๆฅๅ่ฟๆ ท๏ผ่ฏทๆณจๆ๏ผๆจๅฏไปฅไธบ่ฟไบๆนๆณไฝฟ็จ่ชๅจ่กฅๅ
จ๏ผ
+
+
+
+ๆจ่ฟๅฐ่ชๅจ่กฅๅ
จ่ฆๅ้็ๆฐๆฎ๏ผ
+
+
+
+!!! tip
+ ่ฏทๆณจๆ๏ผ `name` ๅ `price` ็่ชๅจ่กฅๅ
จ๏ผๆฏ้่ฟๅ
ถๅจ`Item`ๆจกๅ(FastAPI)ไธญ็ๅฎไนๅฎ็ฐ็ใ
+
+ๅฆๆๅ้็ๆฐๆฎๅญๆฎตไธ็ฌฆ๏ผไฝ ไนไผ็ๅฐ็ผ่พๅจ็้่ฏฏๆ็คบ:
+
+
+
+ๅๅบ(response)ๅฏน่ฑกไนๆฅๆ่ชๅจ่กฅๅ
จ:
+
+
+
+## ๅธฆๆๆ ็ญพ็ FastAPI ๅบ็จ
+
+ๅจ่ฎธๅคๆ
ๅตไธ๏ผไฝ ็FastAPIๅบ็จ็จๅบไผๆดๅคๆ๏ผไฝ ๅฏ่ฝไผไฝฟ็จๆ ็ญพๆฅๅ้ไธๅ็ป็*่ทฏๅพๆไฝ(path operations)*ใ
+
+ไพๅฆ๏ผๆจๅฏไปฅๆไธไธช็จ `items` ็้จๅๅๅฆไธไธช็จไบ `users` ็้จๅ๏ผๅฎไปฌๅฏไปฅ็จๆ ็ญพๆฅๅ้๏ผ
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="21 26 34"
+ {!> ../../../docs_src/generate_clients/tutorial002_py39.py!}
+ ```
+
+=== "Python 3.8+"
+
+ ```Python hl_lines="23 28 36"
+ {!> ../../../docs_src/generate_clients/tutorial002.py!}
+ ```
+
+### ็ๆๅธฆๆๆ ็ญพ็ TypeScript ๅฎขๆท็ซฏ
+
+ๅฆๆๆจไฝฟ็จๆ ็ญพไธบFastAPIๅบ็จ็ๆๅฎขๆท็ซฏ๏ผๅฎ้ๅธธไนไผๆ นๆฎๆ ็ญพๅๅฒๅฎขๆท็ซฏไปฃ็ ใ
+
+้่ฟ่ฟ็งๆนๅผ๏ผๆจๅฐ่ฝๅคไธบๅฎขๆท็ซฏไปฃ็ ่ฟ่กๆญฃ็กฎๅฐๆๅบๅๅ็ป๏ผ
+
+
+
+ๅจ่ฟไธชๆกไพไธญ๏ผๆจๆ๏ผ
+
+* `ItemsService`
+* `UsersService`
+
+### ๅฎขๆท็ซฏๆนๆณๅ็งฐ
+
+็ฐๅจ็ๆ็ๆนๆณๅๅ `createItemItemsPost` ็่ตทๆฅไธๅคช็ฎๆด:
+
+```TypeScript
+ItemsService.createItemItemsPost({name: "Plumbus", price: 5})
+```
+
+...่ฟๆฏๅ ไธบๅฎขๆท็ซฏ็ๆๅจไธบๆฏไธช *่ทฏๅพๆไฝ* ไฝฟ็จOpenAPI็ๅ
้จ **ๆไฝ ID(operation ID)**ใ
+
+OpenAPI่ฆๆฑๆฏไธชๆไฝ ID ๅจๆๆ *่ทฏๅพๆไฝ* ไธญ้ฝๆฏๅฏไธ็๏ผๅ ๆญค FastAPI ไฝฟ็จ**ๅฝๆฐๅ**ใ**่ทฏๅพ**ๅ**HTTPๆนๆณ/ๆไฝ**ๆฅ็ๆๆญคๆไฝID๏ผๅ ไธบ่ฟๆ ทๅฏไปฅ็กฎไฟ่ฟไบๆไฝ ID ๆฏๅฏไธ็ใ
+
+ไฝๆฅไธๆฅๆไผๅ่ฏไฝ ๅฆไฝๆน่ฟใ ๐ค
+
+## ่ชๅฎไนๆไฝIDๅๆดๅฅฝ็ๆนๆณๅ
+
+ๆจๅฏไปฅ**ไฟฎๆน**่ฟไบๆไฝID็**็ๆ**ๆนๅผ๏ผไปฅไฝฟๅ
ถๆด็ฎๆด๏ผๅนถๅจๅฎขๆท็ซฏไธญๅ
ทๆ**ๆด็ฎๆด็ๆนๆณๅ็งฐ**ใ
+
+ๅจ่ฟ็งๆ
ๅตไธ๏ผๆจๅฟ
้กป็กฎไฟๆฏไธชๆไฝIDๅจๅ
ถไปๆน้ขๆฏ**ๅฏไธ**็ใ
+
+ไพๅฆ๏ผๆจๅฏไปฅ็กฎไฟๆฏไธช*่ทฏๅพๆไฝ*้ฝๆไธไธชๆ ็ญพ๏ผ็ถๅๆ นๆฎ**ๆ ็ญพ**ๅ*่ทฏๅพๆไฝ***ๅ็งฐ**๏ผๅฝๆฐๅ๏ผๆฅ็ๆๆไฝIDใ
+
+### ่ชๅฎไน็ๆๅฏไธIDๅฝๆฐ
+
+FastAPIไธบๆฏไธช*่ทฏๅพๆไฝ*ไฝฟ็จไธไธช**ๅฏไธID**๏ผๅฎ็จไบ**ๆไฝID**๏ผไน็จไบไปปไฝๆ้่ชๅฎไนๆจกๅ็ๅ็งฐ๏ผ็จไบ่ฏทๆฑๆๅๅบใ
+
+ไฝ ๅฏไปฅ่ชๅฎไน่ฏฅๅฝๆฐใๅฎๆฅๅไธไธช `APIRoute` ๅฏน่ฑกไฝไธบ่พๅ
ฅ๏ผๅนถ่พๅบไธไธชๅญ็ฌฆไธฒใ
+
+ไพๅฆ๏ผไปฅไธๆฏไธไธช็คบไพ๏ผๅฎไฝฟ็จ็ฌฌไธไธชๆ ็ญพ๏ผไฝ ๅฏ่ฝๅชๆไธไธชๆ ็ญพ๏ผๅ*่ทฏๅพๆไฝ*ๅ็งฐ๏ผๅฝๆฐๅ๏ผใ
+
+็ถๅ๏ผไฝ ๅฏไปฅๅฐ่ฟไธช่ชๅฎไนๅฝๆฐไฝไธบ `generate_unique_id_function` ๅๆฐไผ ้็ป **FastAPI**:
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="6-7 10"
+ {!> ../../../docs_src/generate_clients/tutorial003_py39.py!}
+ ```
+
+=== "Python 3.8+"
+
+ ```Python hl_lines="8-9 12"
+ {!> ../../../docs_src/generate_clients/tutorial003.py!}
+ ```
+
+### ไฝฟ็จ่ชๅฎไนๆไฝID็ๆTypeScriptๅฎขๆท็ซฏ
+
+็ฐๅจ๏ผๅฆๆไฝ ๅๆฌก็ๆๅฎขๆท็ซฏ๏ผไฝ ไผๅ็ฐๅฎๅ
ทๆๆนๅ็ๆนๆณๅ็งฐ๏ผ
+
+
+
+ๆญฃๅฆไฝ ๆ่ง๏ผ็ฐๅจๆนๆณๅ็งฐไธญๅชๅ
ๅซๆ ็ญพๅๅฝๆฐๅ๏ผไธๅๅ
ๅซURL่ทฏๅพๅHTTPๆไฝ็ไฟกๆฏใ
+
+### ้ขๅค็็จไบๅฎขๆท็ซฏ็ๆๅจ็OpenAPI่ง่
+
+็ๆ็ไปฃ็ ไป็ถๅญๅจไธไบ**้ๅค็ไฟกๆฏ**ใ
+
+ๆไปฌๅทฒ็ป็ฅ้่ฏฅๆนๆณไธ **items** ็ธๅ
ณ๏ผๅ ไธบๅฎๅจ `ItemsService` ไธญ๏ผไปๆ ็ญพไธญ่ทๅ๏ผ๏ผไฝๆนๆณๅไธญไป็ถๆๆ ็ญพๅไฝไธบๅ็ผใ๐
+
+ไธ่ฌๆ
ๅตไธๅฏนไบOpenAPI๏ผๆไปฌๅฏ่ฝไป็ถๅธๆไฟ็ๅฎ๏ผๅ ไธบ่ฟๅฐ็กฎไฟๆไฝIDๆฏ**ๅฏไธ็**ใ
+
+ไฝๅฏนไบ็ๆ็ๅฎขๆท็ซฏ๏ผๆไปฌๅฏไปฅๅจ็ๆๅฎขๆท็ซฏไนๅ**ไฟฎๆน** OpenAPI ๆไฝID๏ผไปฅไฝฟๆนๆณๅ็งฐๆดๅ ็พ่งๅ**็ฎๆด**ใ
+
+ๆไปฌๅฏไปฅๅฐ OpenAPI JSON ไธ่ฝฝๅฐไธไธชๅไธบ`openapi.json`็ๆไปถไธญ๏ผ็ถๅไฝฟ็จไปฅไธ่ๆฌ**ๅ ้คๆญคๅ็ผ็ๆ ็ญพ**๏ผ
+
+```Python
+{!../../../docs_src/generate_clients/tutorial004.py!}
+```
+
+้่ฟ่ฟๆ ทๅ๏ผๆไฝIDๅฐไป็ฑปไผผไบ `items-get_items` ็ๅ็งฐ้ๅฝๅไธบ `get_items` ๏ผ่ฟๆ ทๅฎขๆท็ซฏ็ๆๅจๅฐฑๅฏไปฅ็ๆๆด็ฎๆด็ๆนๆณๅ็งฐใ
+
+### ไฝฟ็จ้ขๅค็็OpenAPI็ๆTypeScriptๅฎขๆท็ซฏ
+
+็ฐๅจ๏ผ็ฑไบๆ็ป็ปๆไฟๅญๅจๆไปถopenapi.jsonไธญ๏ผไฝ ๅฏไปฅไฟฎๆน package.json ๆไปถไปฅไฝฟ็จๆญคๆฌๅฐๆไปถ๏ผไพๅฆ๏ผ
+
+```JSON hl_lines="7"
+{
+ "name": "frontend-app",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "generate-client": "openapi --input ./openapi.json --output ./src/client --client axios"
+ },
+ "author": "",
+ "license": "",
+ "devDependencies": {
+ "openapi-typescript-codegen": "^0.20.1",
+ "typescript": "^4.6.2"
+ }
+}
+```
+
+็ๆๆฐ็ๅฎขๆท็ซฏไนๅ๏ผไฝ ็ฐๅจๅฐๆฅๆ**ๆธ
ๆฐ็ๆนๆณๅ็งฐ**๏ผๅ
ทๅค**่ชๅจ่กฅๅ
จ**ใ**้่ฏฏๆ็คบ**็ญๅ่ฝ๏ผ
+
+
+
+## ไผ็น
+
+ๅฝไฝฟ็จ่ชๅจ็ๆ็ๅฎขๆท็ซฏๆถ๏ผไฝ ๅฐ่ทๅพไปฅไธ็่ชๅจ่กฅๅ
จๅ่ฝ๏ผ
+
+* ๆนๆณใ
+* ่ฏทๆฑไฝไธญ็ๆฐๆฎใๆฅ่ฏขๅๆฐ็ญใ
+* ๅๅบๆฐๆฎใ
+
+ไฝ ่ฟๅฐ่ทๅพ้ๅฏนๆๆๅ
ๅฎน็้่ฏฏๆ็คบใ
+
+ๆฏๅฝไฝ ๆดๆฐๅ็ซฏไปฃ็ ๅนถ**้ๆฐ็ๆ**ๅ็ซฏไปฃ็ ๆถ๏ผๆฐ็*่ทฏๅพๆไฝ*ๅฐไฝไธบๆนๆณๅฏ็จ๏ผๆง็ๆนๆณๅฐ่ขซๅ ้ค๏ผๅนถไธๅ
ถไปไปปไฝๆดๆนๅฐๅๆ ๅจ็ๆ็ไปฃ็ ไธญใ ๐ค
+
+่ฟไนๆๅณ็ๅฆๆๆไปปไฝๆดๆน๏ผๅฎๅฐ่ชๅจ**ๅๆ **ๅจๅฎขๆท็ซฏไปฃ็ ไธญใๅฆๆไฝ **ๆๅปบ**ๅฎขๆท็ซฏ๏ผๅจไฝฟ็จ็ๆฐๆฎไธๅญๅจ**ไธๅน้
**ๆถ๏ผๅฎๅฐๆฅ้ใ
+
+ๅ ๆญค๏ผไฝ ๅฐๅจๅผๅๅจๆ็ๆฉๆ**ๆฃๆตๅฐ่ฎธๅค้่ฏฏ**๏ผ่ไธๅฟ
็ญๅพ
้่ฏฏๅจ็ไบง็ฏๅขไธญๅๆ็ป็จๆทๅฑ็คบ๏ผ็ถๅๅฐ่ฏ่ฐ่ฏ้ฎ้ขๆๅจใ โจ
diff --git a/docs/zh/docs/advanced/settings.md b/docs/zh/docs/advanced/settings.md
index 597e99a77..76070fb7f 100644
--- a/docs/zh/docs/advanced/settings.md
+++ b/docs/zh/docs/advanced/settings.md
@@ -223,13 +223,13 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp"uvicorn main:app
{!> ../../../docs_src/settings/app02_an_py39/main.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="6 12-13"
{!> ../../../docs_src/settings/app02_an/main.py!}
```
-=== "Python 3.6+ ้ๆณจ่งฃ็ๆฌ"
+=== "Python 3.8+ ้ๆณจ่งฃ็ๆฌ"
!!! tip
ๅฆๆๅฏ่ฝ๏ผ่ฏทๅฐฝ้ไฝฟ็จ `Annotated` ็ๆฌใ
@@ -239,7 +239,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp"uvicorn main:app
```
!!! tip
- ๆไปฌ็จๅไผ่ฎจ่ฎบ `@lru_cache()`ใ
+ ๆไปฌ็จๅไผ่ฎจ่ฎบ `@lru_cache`ใ
็ฎๅ๏ผๆจๅฏไปฅๅฐ `get_settings()` ่งไธบๆฎ้ๅฝๆฐใ
@@ -251,13 +251,13 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp"uvicorn main:app
{!> ../../../docs_src/settings/app02_an_py39/main.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="17 19-21"
{!> ../../../docs_src/settings/app02_an/main.py!}
```
-=== "Python 3.6+ ้ๆณจ่งฃ็ๆฌ"
+=== "Python 3.8+ ้ๆณจ่งฃ็ๆฌ"
!!! tip
ๅฆๆๅฏ่ฝ๏ผ่ฏทๅฐฝ้ไฝฟ็จ `Annotated` ็ๆฌใ
@@ -289,7 +289,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp"uvicorn main:app
ไฝๆฏ๏ผdotenv ๆไปถๅฎ้
ไธไธไธๅฎ่ฆๅ
ทๆ็กฎๅ็ๆไปถๅใ
-Pydantic ๆฏๆไฝฟ็จๅค้จๅบไป่ฟไบ็ฑปๅ็ๆไปถไธญ่ฏปๅใๆจๅฏไปฅๅจPydantic ่ฎพ็ฝฎ: Dotenv (.env) ๆฏๆไธญ้
่ฏปๆดๅค็ธๅ
ณไฟกๆฏใ
+Pydantic ๆฏๆไฝฟ็จๅค้จๅบไป่ฟไบ็ฑปๅ็ๆไปถไธญ่ฏปๅใๆจๅฏไปฅๅจPydantic ่ฎพ็ฝฎ: Dotenv (.env) ๆฏๆไธญ้
่ฏปๆดๅค็ธๅ
ณไฟกๆฏใ
!!! tip
่ฆไฝฟๅ
ถๅทฅไฝ๏ผๆจ้่ฆๆง่ก `pip install python-dotenv`ใ
@@ -337,7 +337,7 @@ def get_settings():
ๆไปฌๅฐไธบๆฏไธช่ฏทๆฑๅๅปบ่ฏฅๅฏน่ฑก๏ผๅนถไธๅฐๅจๆฏไธช่ฏทๆฑไธญ่ฏปๅ `.env` ๆไปถใ โ ๏ธ
-ไฝๆฏ๏ผ็ฑไบๆไปฌๅจ้กถ้จไฝฟ็จไบ `@lru_cache()` ่ฃ
้ฅฐๅจ๏ผๅ ๆญคๅชๆๅจ็ฌฌไธๆฌก่ฐ็จๅฎๆถ๏ผๆไผๅๅปบ `Settings` ๅฏน่ฑกไธๆฌกใ โ๏ธ
+ไฝๆฏ๏ผ็ฑไบๆไปฌๅจ้กถ้จไฝฟ็จไบ `@lru_cache` ่ฃ
้ฅฐๅจ๏ผๅ ๆญคๅชๆๅจ็ฌฌไธๆฌก่ฐ็จๅฎๆถ๏ผๆไผๅๅปบ `Settings` ๅฏน่ฑกไธๆฌกใ โ๏ธ
=== "Python 3.9+"
@@ -345,13 +345,13 @@ def get_settings():
{!> ../../../docs_src/settings/app03_an_py39/main.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="1 11"
{!> ../../../docs_src/settings/app03_an/main.py!}
```
-=== "Python 3.6+ ้ๆณจ่งฃ็ๆฌ"
+=== "Python 3.8+ ้ๆณจ่งฃ็ๆฌ"
!!! tip
ๅฆๆๅฏ่ฝ๏ผ่ฏทๅฐฝ้ไฝฟ็จ `Annotated` ็ๆฌใ
@@ -364,13 +364,13 @@ def get_settings():
#### `lru_cache` ๆๆฏ็ป่
-`@lru_cache()` ไฟฎๆนไบๅฎๆ่ฃ
้ฅฐ็ๅฝๆฐ๏ผไปฅ่ฟๅ็ฌฌไธๆฌก่ฟๅ็็ธๅๅผ๏ผ่ไธๆฏๅๆฌก่ฎก็ฎๅฎ๏ผๆฏๆฌก้ฝๆง่กๅฝๆฐ็ไปฃ็ ใ
+`@lru_cache` ไฟฎๆนไบๅฎๆ่ฃ
้ฅฐ็ๅฝๆฐ๏ผไปฅ่ฟๅ็ฌฌไธๆฌก่ฟๅ็็ธๅๅผ๏ผ่ไธๆฏๅๆฌก่ฎก็ฎๅฎ๏ผๆฏๆฌก้ฝๆง่กๅฝๆฐ็ไปฃ็ ใ
ๅ ๆญค๏ผไธ้ข็ๅฝๆฐๅฐๅฏนๆฏไธชๅๆฐ็ปๅๆง่กไธๆฌกใ็ถๅ๏ผๆฏไธชๅๆฐ็ปๅ่ฟๅ็ๅผๅฐๅจไฝฟ็จๅฎๅ
จ็ธๅ็ๅๆฐ็ปๅ่ฐ็จๅฝๆฐๆถๅๆฌกไฝฟ็จใ
ไพๅฆ๏ผๅฆๆๆจๆไธไธชๅฝๆฐ๏ผ
```Python
-@lru_cache()
+@lru_cache
def say_hi(name: str, salutation: str = "Ms."):
return f"Hello {salutation} {name}"
```
@@ -422,7 +422,7 @@ participant execute as Execute function
่ฟๆ ท๏ผๅฎ็่กไธบๅ ไนๅฐฑๅๆฏไธไธชๅ
จๅฑๅ้ใไฝๆฏ็ฑไบๅฎไฝฟ็จไบไพ่ต้กนๅฝๆฐ๏ผๅ ๆญคๆไปฌๅฏไปฅ่ฝปๆพๅฐ่ฟ่กๆต่ฏๆถ็่ฆ็ใ
-`@lru_cache()` ๆฏ `functools` ็ไธ้จๅ๏ผๅฎๆฏ Python ๆ ๅๅบ็ไธ้จๅ๏ผๆจๅฏไปฅๅจPython ๆๆกฃไธญไบ่งฃๆๅ
ณ `@lru_cache()` ็ๆดๅคไฟกๆฏใ
+`@lru_cache` ๆฏ `functools` ็ไธ้จๅ๏ผๅฎๆฏ Python ๆ ๅๅบ็ไธ้จๅ๏ผๆจๅฏไปฅๅจPython ๆๆกฃไธญไบ่งฃๆๅ
ณ `@lru_cache` ็ๆดๅคไฟกๆฏใ
## ๅฐ็ป
@@ -430,4 +430,4 @@ participant execute as Execute function
* ้่ฟไฝฟ็จไพ่ต้กน๏ผๆจๅฏไปฅ็ฎๅๆต่ฏใ
* ๆจๅฏไปฅไฝฟ็จ `.env` ๆไปถใ
-* ไฝฟ็จ `@lru_cache()` ๅฏไปฅ้ฟๅ
ไธบๆฏไธช่ฏทๆฑ้ๅค่ฏปๅ dotenv ๆไปถ๏ผๅๆถๅ
่ฎธๆจๅจๆต่ฏๆถ่ฟ่ก่ฆ็ใ
+* ไฝฟ็จ `@lru_cache` ๅฏไปฅ้ฟๅ
ไธบๆฏไธช่ฏทๆฑ้ๅค่ฏปๅ dotenv ๆไปถ๏ผๅๆถๅ
่ฎธๆจๅจๆต่ฏๆถ่ฟ่ก่ฆ็ใ
diff --git a/docs/zh/docs/advanced/websockets.md b/docs/zh/docs/advanced/websockets.md
index a723487fd..a5cbdd965 100644
--- a/docs/zh/docs/advanced/websockets.md
+++ b/docs/zh/docs/advanced/websockets.md
@@ -118,7 +118,7 @@ $ uvicorn main:app --reload
{!> ../../../docs_src/websockets/tutorial002_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="69-70 83"
{!> ../../../docs_src/websockets/tutorial002_an.py!}
@@ -133,7 +133,7 @@ $ uvicorn main:app --reload
{!> ../../../docs_src/websockets/tutorial002_py310.py!}
```
-=== "Python 3.6+ ้ๅธฆๆณจ่งฃ็ๆฌ"
+=== "Python 3.8+ ้ๅธฆๆณจ่งฃ็ๆฌ"
!!! tip
ๅฆๆๅฏ่ฝ๏ผ่ฏทๅฐฝ้ไฝฟ็จ `Annotated` ็ๆฌใ
@@ -181,7 +181,7 @@ $ uvicorn main:app --reload
{!> ../../../docs_src/websockets/tutorial003_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="81-83"
{!> ../../../docs_src/websockets/tutorial003.py!}
diff --git a/docs/zh/docs/async.md b/docs/zh/docs/async.md
new file mode 100644
index 000000000..59eebd049
--- /dev/null
+++ b/docs/zh/docs/async.md
@@ -0,0 +1,430 @@
+# ๅนถๅ async / await
+
+ๆๅ
ณ่ทฏๅพๆไฝๅฝๆฐ็ `async def` ่ฏญๆณไปฅๅๅผๆญฅไปฃ็ ใๅนถๅๅๅนถ่ก็ไธไบ่ๆฏ็ฅ่ฏใ
+
+## ่ตถๆถ้ดๅ๏ผ
+
+TL;DR:
+
+ๅฆๆไฝ ๆญฃๅจไฝฟ็จ็ฌฌไธๆนๅบ๏ผๅฎไปฌไผๅ่ฏไฝ ไฝฟ็จ `await` ๅ
ณ้ฎๅญๆฅ่ฐ็จๅฎไปฌ๏ผๅฐฑๅ่ฟๆ ท๏ผ
+
+```Python
+results = await some_library()
+```
+
+็ถๅ๏ผ้่ฟ `async def` ๅฃฐๆไฝ ็ *่ทฏๅพๆไฝๅฝๆฐ*๏ผ
+
+```Python hl_lines="2"
+@app.get('/')
+async def read_results():
+ results = await some_library()
+ return results
+```
+
+!!! note
+ ไฝ ๅช่ฝๅจ่ขซ `async def` ๅๅปบ็ๅฝๆฐๅ
ไฝฟ็จ `await`
+
+---
+
+ๅฆๆไฝ ๆญฃๅจไฝฟ็จไธไธช็ฌฌไธๆนๅบๅๆไบ็ปไปถ๏ผๆฏๅฆ๏ผๆฐๆฎๅบใAPIใๆไปถ็ณป็ป...๏ผ่ฟ่ก้ไฟก๏ผ็ฌฌไธๆนๅบๅไธๆฏๆไฝฟ็จ `await` ๏ผ็ฎๅๅคงๅคๆฐๆฐๆฎๅบไธๆนๅบ้ฝๆฏ่ฟๆ ท๏ผ๏ผ่ฟ็งๆ
ๅตไฝ ๅฏไปฅๅๅนณๅธธ้ฃๆ ทไฝฟ็จ `def` ๅฃฐๆไธไธช่ทฏๅพๆไฝๅฝๆฐ๏ผๅฐฑๅ่ฟๆ ท๏ผ
+
+```Python hl_lines="2"
+@app.get('/')
+def results():
+ results = some_library()
+ return results
+```
+
+---
+
+ๅฆๆไฝ ็ๅบ็จ็จๅบไธ้่ฆไธๅ
ถไปไปปไฝไธ่ฅฟ้ไฟก่็ญๅพ
ๅ
ถๅๅบ๏ผ่ฏทไฝฟ็จ `async def`ใ
+
+---
+
+ๅฆๆไฝ ไธๆธ
ๆฅ๏ผไฝฟ็จ `def` ๅฐฑๅฅฝ.
+
+---
+
+**ๆณจๆ**๏ผไฝ ๅฏไปฅๆ นๆฎ้่ฆๅจ่ทฏๅพๆไฝๅฝๆฐไธญๆททๅไฝฟ็จ `def` ๅ `async def`๏ผๅนถไฝฟ็จๆ้ๅไฝ ็ๆนๅผๅปๅฎไนๆฏไธชๅฝๆฐใFastAPI ๅฐไธบไปไปฌๅๆญฃ็กฎ็ไบๆ
ใ
+
+ๆ ่ฎบๅฆไฝ๏ผๅจไธ่ฟฐไปปไฝๆ
ๅตไธ๏ผFastAPI ไปๅฐๅผๆญฅๅทฅไฝ๏ผ้ๅบฆไน้ๅธธๅฟซใ
+
+ไฝๆฏ๏ผ้่ฟ้ตๅพชไธ่ฟฐๆญฅ้ชค๏ผๅฎๅฐ่ฝๅค่ฟ่กไธไบๆง่ฝไผๅใ
+
+## ๆๆฏ็ป่
+
+Python ็็ฐไปฃ็ๆฌๆฏๆ้่ฟไธ็งๅซ**"ๅ็จ"**โโไฝฟ็จ `async` ๅ `await` ่ฏญๆณ็ไธ่ฅฟๆฅๅ**โๅผๆญฅไปฃ็ โ**ใ
+
+่ฎฉๆไปฌๅจไธ้ข็้จๅไธญ้ไธไป็ป๏ผ
+
+* **ๅผๆญฅไปฃ็ **
+* **`async` ๅ `await`**
+* **ๅ็จ**
+
+## ๅผๆญฅไปฃ็
+
+ๅผๆญฅไปฃ็ ไป
ไป
ๆๅณ็็ผ็จ่ฏญ่จ ๐ฌ ๆๅๆณๅ่ฏ่ฎก็ฎๆบ/็จๅบ ๐ค ๅจไปฃ็ ไธญ็ๆไธช็น๏ผๅฎ ๐ค ๅฐไธๅพไธ็ญๅพ
ๅจๆไบๅฐๆนๅฎๆไธไบไบๆ
ใ่ฎฉๆไปฌๅ่ฎพไธไบไบๆ
่ขซ็งฐไธบ "ๆ
ขๆไปถ"๐.
+
+ๆไปฅ๏ผๅจ็ญๅพ
"ๆ
ขๆไปถ"๐ๅฎๆ็่ฟๆฎตๆถ้ด๏ผ่ฎก็ฎๆบๅฏไปฅๅไธไบๅ
ถไปๅทฅไฝใ
+
+็ถๅ่ฎก็ฎๆบ/็จๅบ ๐ค ๆฏๆฌกๆๆบไผ้ฝไผๅๆฅ๏ผๅ ไธบๅฎๅๅจ็ญๅพ
๏ผๆ่
ๅฎ ๐ค ๅฎๆไบๅฝๅๆๆ็ๅทฅไฝใ่ไธๅฎ ๐ค ๅฐๆฅ็ๅฎ็ญๅพ
็ๆๆไปปๅกไธญๆฏๅฆๆๅทฒ็ปๅฎๆ็๏ผๅๅฎๅฟ
้กปๅ็ไปปไฝไบๆ
ใ
+
+ๆฅไธๆฅ๏ผๅฎ ๐ค ๅฎๆ็ฌฌไธไธชไปปๅก๏ผๆฏๅฆๆฏๆไปฌ็"ๆ
ขๆไปถ"๐) ๅนถ็ปง็ปญไธไน็ธๅ
ณ็ไธๅใ
+
+่ฟไธช"็ญๅพ
ๅ
ถไปไบๆ
"้ๅธธๆ็ๆฏไธไบ็ธๅฏน่พๆ
ข๏ผไธๅค็ๅจๅ RAM ๅญๅจๅจ็้ๅบฆ็ธๆฏ๏ผ็ I/O ๆไฝ๏ผๆฏๅฆ่ฏด๏ผ
+
+* ้่ฟ็ฝ็ปๅ้ๆฅ่ชๅฎขๆท็ซฏ็ๆฐๆฎ
+* ๅฎขๆท็ซฏๆฅๆถๆฅ่ช็ฝ็ปไธญ็ๆฐๆฎ
+* ็ฃ็ไธญ่ฆ็ฑ็ณป็ป่ฏปๅๅนถๆไพ็ป็จๅบ็ๆไปถ็ๅ
ๅฎน
+* ็จๅบๆไพ็ป็ณป็ป็่ฆๅๅ
ฅ็ฃ็็ๅ
ๅฎน
+* ไธไธช API ็่ฟ็จ่ฐ็จ
+* ไธไธชๆฐๆฎๅบๆไฝ๏ผ็ดๅฐๅฎๆ
+* ไธไธชๆฐๆฎๅบๆฅ่ฏข๏ผ็ดๅฐ่ฟๅ็ปๆ
+* ็ญ็ญ.
+
+่ฟไธชๆง่ก็ๆถ้ดๅคงๅคๆฏๅจ็ญๅพ
I/O ๆไฝ๏ผๅ ๆญคๅฎไปฌ่ขซๅซๅ "I/O ๅฏ้ๅ" ๆไฝใ
+
+ๅฎ่ขซ็งฐไธบ"ๅผๆญฅ"็ๅๅ ๆฏๅ ไธบ่ฎก็ฎๆบ/็จๅบไธๅฟ
ไธๆ
ขไปปๅก"ๅๆญฅ"๏ผๅป็ญๅพ
ไปปๅกๅฎๆ็็กฎๅๆถๅป๏ผ่ๅจๆญคๆ้ดไธๅไปปไฝไบๆ
็ดๅฐ่ฝๅค่ทๅไปปๅก็ปๆๆ็ปง็ปญๅทฅไฝใ
+
+็ธๅ๏ผไฝไธบไธไธช"ๅผๆญฅ"็ณป็ป๏ผไธๆฆๅฎๆ๏ผไปปๅกๅฐฑๅฏไปฅๆ้็ญๅพ
ไธๆฎตๆถ้ด๏ผๅ ๅพฎ็ง๏ผ๏ผ็ญๅพ
่ฎก็ฎๆบ็จๅบๅฎๆๅฎ่ฆๅ็ไปปไฝไบๆ
๏ผ็ถๅๅๆฅ่ทๅ็ปๆๅนถ็ปง็ปญๅค็ๅฎไปฌใ
+
+ๅฏนไบ"ๅๆญฅ"๏ผไธ"ๅผๆญฅ"็ธๅ๏ผ๏ผไปไปฌ้ๅธธไนไฝฟ็จ"้กบๅบ"ไธ่ฏ๏ผๅ ไธบ่ฎก็ฎๆบ็จๅบๅจๅๆขๅฐๅฆไธไธชไปปๅกไนๅๆฏๆ้กบๅบๆง่กๆๆๆญฅ้ชค๏ผๅณไฝฟ่ฟไบๆญฅ้ชคๆถๅๅฐ็ญๅพ
ใ
+
+### ๅนถๅไธๆฑๅ ก
+
+ไธ่ฟฐๅผๆญฅไปฃ็ ็ๆๆณๆๆถไน่ขซ็งฐไธบโๅนถๅโ๏ผๅฎไธๅไบโๅนถ่กโใ
+
+ๅนถๅๅๅนถ่ก้ฝไธโไธๅ็ไบๆ
ๆๅคๆๅฐๅๆถๅ็โๆๅ
ณใ
+
+ไฝๆฏๅนถๅๅๅนถ่กไน้ด็็ป่ๆฏๅฎๅ
จไธๅ็ใ
+
+่ฆไบ่งฃๅทฎๅผ๏ผ่ฏทๆณ่ฑกไปฅไธๅ
ณไบๆฑๅ ก็ๆ
ไบ๏ผ
+
+### ๅนถๅๆฑๅ ก
+
+ไฝ ๅไฝ ็ๆไบบไธ่ตทๅปๅฟซ้คๅบ๏ผไฝ ๆ้ๅจๅ้ข๏ผๆถ้ถๅไปไฝ ๅ้ข็ไบบๆฅๅใ๐
+
+
+
+็ถๅ่ฝฎๅฐไฝ ไบ๏ผไฝ ไธบไฝ ็ๆไบบๅไฝ ้ไบไธคไธช้ๅธธ่ฑชๅ็ๆฑๅ กใ๐๐
+
+
+
+ๆถ้ถๅๅฏนๅจๆฟ้็ๅจๅธ่ฏดไบไธไบ่ฏ๏ผ่ฎฉไปไปฌ็ฅ้ไปไปฌๅฟ
้กปไธบไฝ ๅๅคๆฑๅ ก๏ผๅฐฝ็ฎกไปไปฌ็ฎๅๆญฃๅจไธบไนๅ็้กพๅฎขๅๅคๆฑๅ ก๏ผใ
+
+
+
+ไฝ ไป้ฑไบใ ๐ธ
+
+ๆถ้ถๅ็ปไฝ ่ฝฎๅฐ็ๅท็ ใ
+
+
+
+ๅฝไฝ ๅจ็ญๅพ
็ๆถๅ๏ผไฝ ๅไฝ ็ๆไบบไธ่ตทๅปๆ้ไธๅผ ๆกๅญ๏ผ็ถๅไฝ ไปฌๅไธๆฅ่ไบๅพ้ฟๆถ้ด๏ผๅ ไธบๆฑๅ กๅพ่ฑชๅ๏ผ้่ฆไธไบๆถ้ดๆฅๅๅค๏ผใ
+
+ๅฝไฝ ๅไฝ ็ๆไบบๅๅจๆกๅญๆ๏ผ็ญๅพ
ๆฑๅ ก็ๆถๅ๏ผไฝ ๅฏไปฅ็จ่ฟๆฎตๆถ้ดๆฅๆฌฃ่ตไฝ ็ๆไบบๆฏๅคไน็ๆฃใๅฏ็ฑๅ่ชๆโจ๐โจใ
+
+
+
+ๅจ็ญๅพ
ไธญๅไฝ ็ๆไบบไบค่ฐๆถ๏ผไฝ ไผไธๆถๅฐๆฅ็ๆๅฐไธๆพ็คบ็ๅท็ ๏ผ็็ๆฏๅฆๅทฒ็ป่ฝฎๅฐไฝ ไบใ
+
+็ถๅๅจๆไธชๆถๅป๏ผ็ปไบ่ฝฎๅฐไฝ ไบใไฝ ๅปๆๅฐๆฟๆฑๅ ก็ถๅๅๅฐๆกๅญไธใ
+
+
+
+ไฝ ไปฌไบซ็จไบๆฑๅ ก๏ผๆดไธช่ฟ็จ้ฝๅพๅผๅฟใโจ
+
+
+
+!!! info
+ ๆผไบฎ็ๆ็ปๆฅ่ช Ketrina Thompson. ๐จ
+
+---
+
+ๅจ้ฃไธชๆ
ไบ้๏ผๅ่ฎพไฝ ๆฏ่ฎก็ฎๆบ็จๅบ ๐ค ใ
+
+ๅฝไฝ ๅจๆ้ๆถ๏ผไฝ ๅชๆฏ้ฒ็๐ด๏ผ ่ฝฎๅฐไฝ ๅไธๅไปปไฝไบๆ
๏ผไป
ๆ้๏ผใไฝๆ้ๅพๅฟซ๏ผๅ ไธบๆถ้ถๅๅชๆฅ่ฎขๅ๏ผไธๅๅค่ฎขๅ๏ผ๏ผๆไปฅ่ฟไธๅ้ฝ่ฟๅฅฝใ
+
+็ถๅ๏ผๅฝ่ฝฎๅฐไฝ ๆถ๏ผ้่ฆไฝ ๅไธไบๅฎ้
ๆง็ๅทฅไฝ๏ผๆฏๅฆๆฅ็่ๅ๏ผๅณๅฎไฝ ๆณ่ฆไปไน๏ผ่ฎฉไฝ ็ๆไบบ้ๆฉ๏ผๆฏไป๏ผๆฃๆฅไฝ ๆฏๅฆๆไพไบๆญฃ็กฎ็่ดฆๅๆๅก๏ผๆฃๆฅไฝ ็ๆถ่ดนๆฏๅฆๆญฃ็กฎ๏ผๆฃๆฅ่ฎขๅๆฏๅฆๆๆญฃ็กฎ็้กน็ฎ๏ผ็ญ็ญใ
+
+ๆญคๆถ๏ผๅณไฝฟไฝ ไป็ถๆฒกๆๆฑๅ ก๏ผไฝ ๅๆถ้ถๅ็ๅทฅไฝไน"ๆๅ"ไบโธ๏ผ ๅ ไธบไฝ ๅฟ
้กป็ญๅพ
ไธๆฎตๆถ้ด ๐ ่ฎฉไฝ ็ๆฑๅ กๅๅฅฝใ
+
+ไฝๆฏ๏ผๅฝไฝ ็ฆปๅผๆๅฐๅนถๅๅจๆกๅญๆ๏ผๅจ่ฝฎๅฐไฝ ็ๅท็ ๅ็่ฟๆฎตๆถ้ด๏ผไฝ ๅฏไปฅๅฐ็ฆ็นๅๆขๅฐ ๐ ไฝ ็ๆไบบไธ๏ผๅนถๅไธไบ"ๅทฅไฝ"โฏ ๐คใไฝ ๅฏไปฅๅไธไบ้ๅธธ"ๆๆๆ"็ไบๆ
๏ผๆฏๅฆๅไฝ ็ๆไบบ่ฐๆ
๐.
+
+ไนๅ๏ผๆถ้ถๅ ๐ ๆๅท็ ๆพ็คบๅจๆพ็คบๅฑไธ๏ผๅนถ่ฏดๅฐ "ๆฑๅ กๅๅฅฝไบ"๏ผ่ๅฝๆพ็คบ็ๅท็ ๆฏไฝ ็ๅท็ ๆถ๏ผไฝ ไธไผ็ซๅป็ฏ็ๅฐ่ทณ่ตทๆฅใๅ ไธบไฝ ็ฅ้ๆฒกๆไบบไผๅทไฝ ็ๆฑๅ ก๏ผๅ ไธบไฝ ๆไฝ ็ๅท็ ๏ผ่ๅ
ถไปไบบๅๆไปไปฌ่ชๅทฑ็ๅท็ ใ
+
+ๆไปฅไฝ ่ฆ็ญๅพ
ไฝ ็ๆไบบๅฎๆๆ
ไบ๏ผๅฎๆๅฝๅ็ๅทฅไฝโฏ /ๆญฃๅจๅ็ไบ๐ค)๏ผ ่ฝป่ฝปๅพฎ็ฌ๏ผ่ฏดไฝ ่ฆๅๆฑๅ กโธ.
+
+็ถๅไฝ ๅปๆๅฐ๐๏ผ ๅฐ็ฐๅจๅๅงไปปๅกๅทฒ็ปๅฎๆโฏ๏ผ ๆฟ่ตทๆฑๅ ก๏ผ่ฏดๅฃฐ่ฐข่ฐข๏ผ็ถๅๆๅฎไปฌ้ๅฐๆกไธใ่ฟๅฐฑๅฎๆไบไธ่ฎกๆฐๅจไบคไบ็ๆญฅ้ชค/ไปปๅกโน. ่ฟๅ่ฟๆฅๅไบง็ไบไธ้กนๆฐไปปๅก๏ผๅณ"ๅๆฑๅ ก"๐ โฏ๏ผ ไธไธไธช"ๆฟๆฑๅ ก"็ไปปๅกๅทฒ็ป็ปๆไบโน.
+
+### ๅนถ่กๆฑๅ ก
+
+็ฐๅจ่ฎฉๆไปฌๅ่ฎพไธๆฏ"ๅนถๅๆฑๅ ก"๏ผ่ๆฏ"ๅนถ่กๆฑๅ ก"ใ
+
+ไฝ ๅไฝ ็ๆไบบไธ่ตทๅปๅๅนถ่กๅฟซ้คใ
+
+ไฝ ็ซๅจ้ไผไธญ๏ผๅๆถๆฏๅจๅธ็ๅ ไธชๆถ้ถๅ๏ผๆฏๆน่ฏด8ไธช๏ผไปๅ้ข็ไบบ้ฃ้ๆฅๅใ
+
+ไฝ ไนๅ็ๆฏไธชไบบ้ฝๅจ็ญๅพ
ไปไปฌ็ๆฑๅ กๅๅคๅฅฝๅๆ็ฆปๅผๆๅฐ๏ผๅ ไธบ8ๅๆถ้ถๅ้ฝไผๅจไธไธไปฝ่ฎขๅๅ้ฉฌไธๅๅคๅฅฝๆฑๅ กใ
+
+
+
+็ถๅ๏ผ็ปไบ่ฝฎๅฐไฝ ไบ๏ผไฝ ไธบไฝ ็ๆไบบๅไฝ ่ฎข่ดญไบไธคไธช้ๅธธ็ฒพ็พ็ๆฑๅ กใ
+
+ไฝ ไป้ฑไบ ๐ธใ
+
+
+
+ๆถ้ถๅๅปๅจๆฟใ
+
+ไฝ ็ซๅจๆๅฐๅ ๐็ญๅพ
็๏ผ่ฟๆ ทๅฐฑไธไผๆไบบๅจไฝ ไนๅๆข่ตฐไฝ ็ๆฑๅ ก๏ผๅ ไธบๆฒกๆ่ฝฎๆต็ๅท็ ใ
+
+
+
+ๅฝไฝ ๅไฝ ็ๆไบบๅฟไบไธ่ฎฉไปปไฝไบบๅบ็ฐๅจไฝ ้ขๅ๏ผๅนถไธๅจไปไปฌๅฐๆฅ็ๆถๅๆฟ่ตฐไฝ ็ๆฑๅ กๆถ๏ผไฝ ๆ ๆณๅ
ณๆณจๅฐไฝ ็ๆไบบใ๐
+
+่ฟๆฏ"ๅๆญฅ"็ๅทฅไฝ๏ผไฝ ่ขซ่ฟซไธๆๅกๅ/ๅจๅธ ๐จโ๐ณ"ๅๆญฅ"ใไฝ ๅจๆญคๅฟ
้กป็ญๅพ
๐ ๏ผๅจๆถ้ถๅ/ๅจๅธ ๐จโ๐ณ ๅฎๆๆฑๅ กๅนถๅฐๅฎไปฌไบค็ปไฝ ็็กฎๅๆถ้ดๅฐ่พพไนๅไธ็ด็ญๅพ
๏ผๅฆๅๅ
ถไปไบบๅฏ่ฝไผๆฟ่ตฐๅฎไปฌใ
+
+
+
+ไฝ ็ป่ฟ้ฟๆถ้ด็็ญๅพ
๐ ๏ผๆถ้ถๅ/ๅจๅธ ๐จโ๐ณ็ปไบๅธฆ็ๆฑๅ กๅๅฐไบๆๅฐใ
+
+
+
+ไฝ ๆฟ็ๆฑๅ ก๏ผๅไฝ ็ๆ
ไบบไธ่ตทไธๆกใ
+
+ไฝ ไปฌไป
ไป
ๆฏๅไบๅฎไปฌ๏ผๅฐฑ็ปๆไบใโน
+
+
+
+ๆฒกๆๅคชๅค็ไบค่ฐๆ่ฐๆ
๏ผๅ ไธบๅคง้จๅๆถ้ด ๐ ้ฝๅจๆๅฐๅ็ญๅพ
๐ใ
+
+!!! info
+ ๆผไบฎ็ๆ็ปๆฅ่ช Ketrina Thompson. ๐จ
+
+---
+
+ๅจ่ฟไธชๅนถ่กๆฑๅ ก็ๅบๆฏไธญ๏ผไฝ ๆฏไธไธช่ฎก็ฎๆบ็จๅบ ๐ค ไธๆไธคไธชๅค็ๅจ๏ผไฝ ๅไฝ ็ๆไบบ๏ผ๏ผ้ฝๅจ็ญๅพ
๐ ๏ผๅนถๆๅ
ฅไปไปฌ็ๆณจๆๅ โฏ ๅจๆๅฐไธ็ญๅพ
ไบๅพ้ฟไธๆฎตๆถ้ดใ
+
+่ฟๅฎถๅฟซ้คๅบๆ 8 ไธชๅค็ๅจ๏ผๆถ้ถๅ/ๅจๅธ๏ผใ่ๅนถๅๆฑๅ กๅบๅฏ่ฝๅชๆ 2 ไธช๏ผไธไธชๆถ้ถๅๅไธไธชๅจๅธ๏ผใ
+
+ไฝๆ็ป็ไฝ้ชไป็ถไธๆฏๆๅฅฝ็ใ๐
+
+---
+
+่ฟๅฐๆฏไธๆฑๅ ก็็ฑปไผผๆ
ไบใ๐
+
+ไธ็งๆด"่ดด่ฟ็ๆดป"็ไพๅญ๏ผๆณ่ฑกไธๅฎถ้ถ่กใ
+
+็ดๅฐๆ่ฟ๏ผๅคงๅคๆฐ้ถ่ก้ฝๆๅคไธชๅบ็บณๅ ๐จโ๐ผ๐จโ๐ผ๐จโ๐ผ๐จโ๐ผ ่ฟๆไธๆก้ฟ้ฟๆ้้ไผ๐๐๐๐๐๐๐๐ใ
+
+ๆๆๆถ้ถๅ้ฝๆฏไธไธชๆฅไธไธช็ๅจๅฎขๆท้ขๅๅๅฎๆๆ็ๅทฅไฝ๐จโ๐ผโฏ.
+
+ไฝ ๅฟ
้กป็ป่ฟ ๐ ่พ้ฟๆถ้ดๆ้๏ผๅฆๅไฝ ๅฐฑๆฒกๆบไผไบใ
+
+ไฝ ๅฏไธไผๆณๅธฆไฝ ็ๆไบบ ๐ ๅไฝ ไธ่ตทๅป้ถ่กๅไบ๐ฆ.
+
+### ๆฑๅ ก็ป่ฎบ
+
+ๅจ"ไฝ ไธๆไบบไธ่ตทๅๆฑๅ ก"็่ฟไธชๅบๆฏไธญ๏ผๅ ไธบๆๅพๅคไบบๅจ็ญๅพ
๐๏ผ ไฝฟ็จๅนถๅ็ณป็ปๆดๆๆไนโธ๐โฏ.
+
+ๅคงๅคๆฐ Web ๅบ็จ้ฝๆฏ่ฟๆ ท็ใ
+
+ไฝ ็ๆๅกๅจๆญฃๅจ็ญๅพ
ๅพๅคๅพๅค็จๆท้่ฟไปไปฌไธๅคชๅฅฝ็็ฝ็ปๅ้ๆฅ็่ฏทๆฑใ
+
+็ถๅๅๆฌก็ญๅพ
๐ ๅๅบๅๆฅใ
+
+่ฟไธช"็ญๅพ
" ๐ ๆฏไปฅๅพฎ็งไธบๅไฝๆต้็๏ผไฝๆป็ๆฅ่ฏด๏ผๆๅ่ฟๆฏ็ญๅพ
ๅพไน
ใ
+
+่ฟๅฐฑๆฏไธบไปไนไฝฟ็จๅผๆญฅๅฏนไบ Web API ๅพๆๆไน็ๅๅ โธ๐โฏใ
+
+่ฟ็งๅผๆญฅๆบๅถๆญฃๆฏ NodeJS ๅๅฐๆฌข่ฟ็ๅๅ ๏ผๅฐฝ็ฎก NodeJS ไธๆฏๅนถ่ก็๏ผ๏ผไปฅๅ Go ไฝไธบ็ผ็จ่ฏญ่จ็ไผๅฟๆๅจใ
+
+่ฟไธ **FastAPI** ็ๆง่ฝๆฐดๅนณ็ธๅใ
+
+ๆจๅฏไปฅๅๆถๆฅๆๅนถ่กๆงๅๅผๆญฅๆง๏ผๆจๅฏไปฅ่ทๅพๆฏๅคงๅคๆฐ็ป่ฟๆต่ฏ็ NodeJS ๆกๆถๆด้ซ็ๆง่ฝ๏ผๅนถไธไธ Go ไธ็ธไธไธ๏ผ Go ๆฏไธ็งๆดๆฅ่ฟไบ C ็็ผ่ฏ่ฏญ่จ๏ผๅ
จ้จๅฝๅไบ Starlette๏ผใ
+
+### ๅนถๅๆฏๅนถ่กๅฅฝๅ๏ผ
+
+ไธ๏ผ่ฟไธๆฏๆ
ไบ็ๆฌๆใ
+
+ๅนถๅไธๅไบๅนถ่กใ่ๆฏๅจ้่ฆๅคง้็ญๅพ
็็นๅฎๅบๆฏไธๆๆๆดๅฅฝใๅ ๆญค๏ผๅจ Web ๅบ็จ็จๅบๅผๅไธญ๏ผๅฎ้ๅธธๆฏๅนถ่ก่ฆๅฅฝๅพๅค๏ผไฝ่ฟๅนถไธๆๅณ็ๅ
จ้จใ
+
+ๅ ๆญค๏ผไธบไบๅนณ่กก่ฟไธ็น๏ผๆณ่ฑกไธไธไธ้ข็็ญ็ฏๆ
ไบ๏ผ
+
+> ไฝ ๅฟ
้กปๆๆซไธไธชๅๅคงๅ่็ๆฟๅญใ
+
+*ๆฏ็๏ผ่ฟๅฐฑๆฏๅฎๆด็ๆ
ไบใ*
+
+---
+
+ๅจไปปไฝๅฐๆน๏ผ ้ฝไธ้่ฆ็ญๅพ
๐ ๏ผๅช้่ฆๅจๆฟๅญ็ๅคไธชๅฐๆนๅ็ๅพๅคๅทฅไฝใ
+
+ไฝ ๅฏไปฅๅๆฑๅ ก็ไพๅญ้ฃๆ ท่ฝฎๆตๆง่ก๏ผๅ
ๆฏๅฎขๅ
๏ผ็ถๅๆฏๅจๆฟ๏ผไฝๅ ไธบไฝ ไธ้่ฆ็ญๅพ
๐ ๏ผๅฏนไบไปปไฝไบๆ
้ฝๆฏๆธ
ๆด๏ผๆธ
ๆด๏ผ่ฟๆฏๆธ
ๆด๏ผ่ฝฎๆตไธไผๅฝฑๅไปปไฝไบๆ
ใ
+
+ๆ ่ฎบๆฏๅฆ่ฝฎๆตๆง่ก๏ผๅนถๅ๏ผ๏ผ้ฝ้่ฆ็ธๅ็ๆถ้ดๆฅๅฎๆ๏ผ่ไฝ ไนไผๅฎๆ็ธๅ็ๅทฅไฝ้ใ
+
+ไฝๅจ่ฟ็งๆ
ๅตไธ๏ผๅฆๆไฝ ่ฝๅธฆไธ 8 ๅๅๆถ้ถๅ/ๅจๅธ๏ผ็ฐๅจๆฏๆธ
ๆดๅทฅไธ่ตทๆธ
ๆซ๏ผไปไปฌไธญ็ๆฏไธไธชไบบ๏ผๅ ไธไฝ ๏ผ้ฝ่ฝๅ ๆฎๆฟๅญ็ไธไธชๅบๅๆฅๆธ
ๆซ๏ผไฝ ๅฐฑๅฏไปฅๅจ้ขๅค็ๅธฎๅฉไธๅนถ่ก็ๆดๅฟซๅฐๅฎๆๆๆๅทฅไฝใ
+
+ๅจ่ฟไธชๅบๆฏไธญ๏ผๆฏไธชๆธ
ๆดๅทฅ๏ผๅ
ๆฌๆจ๏ผ้ฝๅฐๆฏไธไธชๅค็ๅจ๏ผๅฎๆ่ฟไธชๅทฅไฝ็ไธ้จๅใ
+
+็ฑไบๅคงๅคๆฐๆง่กๆถ้ดๆฏ็ฑๅฎ้
ๅทฅไฝ๏ผ่ไธๆฏ็ญๅพ
๏ผๅ ็จ็๏ผๅนถไธ่ฎก็ฎๆบไธญ็ๅทฅไฝๆฏ็ฑ CPU ๅฎๆ็๏ผๆไปฅไปไปฌ็งฐ่ฟไบ้ฎ้ขไธบ"CPU ๅฏ้ๅ"ใ
+
+---
+
+CPU ๅฏ้ๅๆไฝ็ๅธธ่ง็คบไพๆฏ้่ฆๅคๆ็ๆฐๅญฆๅค็ใ
+
+ไพๅฆ๏ผ
+
+* **้ณ้ข**ๆ**ๅพๅ**ๅค็๏ผ
+* **่ฎก็ฎๆบ่ง่ง**: ไธๅน
ๅพๅ็ฑๆฐ็พไธๅ็ด ็ปๆ๏ผๆฏไธชๅ็ด ๆ3็ง้ข่ฒๅผ๏ผๅค็้ๅธธ้่ฆๅๆถๅฏน่ฟไบๅ็ด ่ฟ่ก่ฎก็ฎ๏ผ
+* **ๆบๅจๅญฆไน **: ๅฎ้ๅธธ้่ฆๅคง้็"็ฉ้ต"ๅ"ๅ้"ไนๆณใๆณ่ฑกไธไธชๅ
ๅซๆฐๅญ็ๅทจๅคง็ตๅญ่กจๆ ผ๏ผๅนถๅๆถๅฐๆๆๆฐๅญ็ธไน๏ผ
+* **ๆทฑๅบฆๅญฆไน **: ่ฟๆฏๆบๅจๅญฆไน ็ไธไธชๅญ้ขๅ๏ผๅๆ ท้็จใๅชๆฏๆฒกๆไธไธชๆฐๅญ็็ตๅญ่กจๆ ผๅฏไปฅ็ธไน๏ผ่ๆฏไธไธชๅบๅคง็ๆฐๅญ้ๅ๏ผๅจๅพๅคๆ
ๅตไธ๏ผไฝ ้่ฆไฝฟ็จไธไธช็นๆฎ็ๅค็ๅจๆฅๆๅปบๅไฝฟ็จ่ฟไบๆจกๅใ
+
+### ๅนถๅ + ๅนถ่ก: Web + ๆบๅจๅญฆไน
+
+ไฝฟ็จ **FastAPI**๏ผๆจๅฏไปฅๅฉ็จ Web ๅผๅไธญๅธธ่ง็ๅนถๅๆบๅถ็ไผๅฟ๏ผNodeJS ็ไธป่ฆๅธๅผๅ๏ผใ
+
+ๅนถไธ๏ผๆจไนๅฏไปฅๅฉ็จๅนถ่กๅๅค่ฟ็จ๏ผ่ฎฉๅคไธช่ฟ็จๅนถ่ก่ฟ่ก๏ผ็ไผ็นๆฅๅค็ไธๆบๅจๅญฆไน ็ณป็ปไธญ็ฑปไผผ็ **CPU ๅฏ้ๅ** ๅทฅไฝใ
+
+่ฟไธ็น๏ผๅๅ ไธ Python ๆฏ**ๆฐๆฎ็งๅญฆ**ใๆบๅจๅญฆไน ๏ผๅฐคๅ
ถๆฏๆทฑๅบฆๅญฆไน ๏ผ็ไธป่ฆ่ฏญ่จ่ฟไธ็ฎๅไบๅฎ๏ผไฝฟๅพ **FastAPI** ไธๆฐๆฎ็งๅญฆ/ๆบๅจๅญฆไน Web API ๅๅบ็จ็จๅบ๏ผไปฅๅๅ
ถไป่ฎธๅคๅบ็จ็จๅบ๏ผ้ๅธธๅน้
ใ
+
+ไบ่งฃๅฆไฝๅจ็ไบง็ฏๅขไธญๅฎ็ฐ่ฟ็งๅนถ่กๆง๏ผๅฏๆฅ็ๆญคๆ [Deployment](deployment/index.md){.internal-link target=_blank}ใ
+
+## `async` ๅ `await`
+
+็ฐไปฃ็ๆฌ็ Python ๆไธ็ง้ๅธธ็ด่ง็ๆนๅผๆฅๅฎไนๅผๆญฅไปฃ็ ใ่ฟไฝฟๅฎ็่ตทๆฅๅฐฑๅๆญฃๅธธ็"้กบๅบ"ไปฃ็ ๏ผๅนถๅจ้ๅฝ็ๆถๅ"็ญๅพ
"ใ
+
+ๅฝๆไธไธชๆไฝ้่ฆ็ญๅพ
ๆ่ฝ็ปๅบ็ปๆ๏ผไธๆฏๆ่ฟไธชๆฐ็ Python ็นๆงๆถ๏ผๆจๅฏไปฅ็ผๅๅฆไธไปฃ็ ๏ผ
+
+```Python
+burgers = await get_burgers(2)
+```
+
+่ฟ้็ๅ
ณ้ฎๆฏ `await`ใๅฎๅ่ฏ Python ๅฎๅฟ
้กป็ญๅพ
โธ `get_burgers(2)` ๅฎๆๅฎ็ๅทฅไฝ ๐ ๏ผ็ถๅๅฐ็ปๆๅญๅจๅจ `burgers` ไธญใ่ฟๆ ท๏ผPython ๅฐฑไผ็ฅ้ๆญคๆถๅฎๅฏไปฅๅปๅๅ
ถไปไบๆ
๐ โฏ ๏ผๆฏๅฆๆฅๆถๅฆไธไธช่ฏทๆฑ๏ผใ
+
+่ฆไฝฟ `await` ๅทฅไฝ๏ผๅฎๅฟ
้กปไฝไบๆฏๆ่ฟ็งๅผๆญฅๆบๅถ็ๅฝๆฐๅ
ใๅ ๆญค๏ผๅช้ไฝฟ็จ `async def` ๅฃฐๆๅฎ๏ผ
+
+```Python hl_lines="1"
+async def get_burgers(number: int):
+ # Do some asynchronous stuff to create the burgers
+ return burgers
+```
+
+...่ไธๆฏ `def`:
+
+```Python hl_lines="2"
+# This is not asynchronous
+def get_sequential_burgers(number: int):
+ # Do some sequential stuff to create the burgers
+ return burgers
+```
+
+ไฝฟ็จ `async def`๏ผPython ๅฐฑ็ฅ้ๅจ่ฏฅๅฝๆฐไธญ๏ผๅฎๅฐ้ไธ `await`๏ผๅนถไธๅฎๅฏไปฅ"ๆๅ" โธ ๆง่ก่ฏฅๅฝๆฐ๏ผ็ด่ณๆง่กๅ
ถไปๆไฝ ๐ ๅๅๆฅใ
+
+ๅฝไฝ ๆณ่ฐ็จไธไธช `async def` ๅฝๆฐๆถ๏ผไฝ ๅฟ
้กป"็ญๅพ
"ๅฎใๅ ๆญค๏ผ่ฟไธไผ่ตทไฝ็จ๏ผ
+
+```Python
+# This won't work, because get_burgers was defined with: async def
+burgers = get_burgers(2)
+```
+
+---
+
+ๅ ๆญค๏ผๅฆๆๆจไฝฟ็จ็ๅบๅ่ฏๆจๅฏไปฅไฝฟ็จ `await` ่ฐ็จๅฎ๏ผๅ้่ฆไฝฟ็จ `async def` ๅๅปบ่ทฏๅพๆไฝๅฝๆฐ ๏ผๅฆ๏ผ
+
+```Python hl_lines="2-3"
+@app.get('/burgers')
+async def read_burgers():
+ burgers = await get_burgers(2)
+ return burgers
+```
+
+### ๆดๅคๆๆฏ็ป่
+
+ๆจๅฏ่ฝๅทฒ็ปๆณจๆๅฐ๏ผ`await` ๅช่ฝๅจ `async def` ๅฎไน็ๅฝๆฐๅ
้จไฝฟ็จใ
+
+ไฝไธๆญคๅๆถ๏ผๅฟ
้กป"็ญๅพ
"้่ฟ `async def` ๅฎไน็ๅฝๆฐใๅ ๆญค๏ผๅธฆ `async def` ็ๅฝๆฐไนๅช่ฝๅจ `async def` ๅฎไน็ๅฝๆฐๅ
้จ่ฐ็จใ
+
+้ฃไน๏ผ่ฟๅ
ณไบๅ
ๆ้ธก่ฟๆฏๅ
ๆ่็้ฎ้ข๏ผๅฆไฝ่ฐ็จ็ฌฌไธไธช `async` ๅฝๆฐ๏ผ
+
+ๅฆๆๆจไฝฟ็จ **FastAPI**๏ผไฝ ไธๅฟ
ๆ
ๅฟ่ฟไธ็น๏ผๅ ไธบ"็ฌฌไธไธช"ๅฝๆฐๅฐๆฏไฝ ็่ทฏๅพๆไฝๅฝๆฐ๏ผFastAPI ๅฐ็ฅ้ๅฆไฝๅๆญฃ็กฎ็ไบๆ
ใ
+
+ไฝๅฆๆๆจๆณๅจๆฒกๆ FastAPI ็ๆ
ๅตไธไฝฟ็จ `async` / `await`๏ผๅๅฏไปฅ่ฟๆ ทๅใ
+
+### ็ผๅ่ชๅทฑ็ๅผๆญฅไปฃ็
+
+Starlette ๏ผๅ **FastAPI**๏ผ ๆฏๅบไบ AnyIO ๅฎ็ฐ็๏ผ่ฟไฝฟๅพๅฎไปฌๅฏไปฅๅ
ผๅฎน Python ็ๆ ๅๅบ asyncio ๅ Trioใ
+
+็นๅซๆฏ๏ผไฝ ๅฏไปฅ็ดๆฅไฝฟ็จ AnyIO ๆฅๅค็้ซ็บง็ๅนถๅ็จไพ๏ผ่ฟไบ็จไพ้่ฆๅจ่ชๅทฑ็ไปฃ็ ไธญไฝฟ็จๆด้ซ็บง็ๆจกๅผใ
+
+ๅณไฝฟๆจๆฒกๆไฝฟ็จ **FastAPI**๏ผๆจไนๅฏไปฅไฝฟ็จ AnyIO ็ผๅ่ชๅทฑ็ๅผๆญฅ็จๅบ๏ผไฝฟๅ
ถๆฅๆ่พ้ซ็ๅ
ผๅฎนๆงๅนถ่ทๅพไธไบๅฅฝๅค๏ผไพๅฆ๏ผ ็ปๆๅๅนถๅ๏ผใ
+
+### ๅ
ถไปๅฝขๅผ็ๅผๆญฅไปฃ็
+
+่ฟ็งไฝฟ็จ `async` ๅ `await` ็้ฃๆ ผๅจ่ฏญ่จไธญ็ธๅฏน่พๆฐใ
+
+ไฝๅฎไฝฟๅค็ๅผๆญฅไปฃ็ ๅๅพๅฎนๆๅพๅคใ
+
+่ฟ็ง็ธๅ็่ฏญๆณ๏ผๆๅ ไน็ธๅ๏ผๆ่ฟไนๅ
ๅซๅจ็ฐไปฃ็ๆฌ็ JavaScript ไธญ๏ผๅจๆต่งๅจๅ NodeJS ไธญ๏ผใ
+
+ไฝๅจๆญคไนๅ๏ผๅค็ๅผๆญฅไปฃ็ ้ๅธธๅคๆๅๅฐ้พใ
+
+ๅจไปฅๅ็ๆฌ็ Python๏ผไฝ ๅฏไปฅไฝฟ็จๅค็บฟ็จๆ่
Geventใไฝไปฃ็ ็็่งฃใ่ฐ่ฏๅๆ่้ฝ่ฆๅคๆ่ฎธๅคใ
+
+ๅจไปฅๅ็ๆฌ็ NodeJS / ๆต่งๅจ JavaScript ไธญ๏ผไฝ ไผไฝฟ็จ"ๅ่ฐ"๏ผๅ ๆญคไนๅฏ่ฝๅฏผ่ดๅ่ฐๅฐ็ฑใ
+
+## ๅ็จ
+
+**ๅ็จ**ๅชๆฏ `async def` ๅฝๆฐ่ฟๅ็ไธไธช้ๅธธๅฅ็น็ไธ่ฅฟ็็งฐๅผใPython ็ฅ้ๅฎๆ็นๅไธไธชๅฝๆฐ๏ผๅฎๅฏไปฅๅฏๅจ๏ผไนไผๅจๆไธชๆถๅป็ปๆ๏ผ่ไธๅฎๅฏ่ฝไผๅจๅ
้จๆๅ โธ ๏ผๅช่ฆๅ
้จๆไธไธช `await`ใ
+
+้่ฟไฝฟ็จ `async` ๅ `await` ็ๅผๆญฅไปฃ็ ็ๆๆๅ่ฝๅคงๅคๆฐ่ขซๆฆๆฌไธบ"ๅ็จ"ใๅฎๅฏไปฅไธ Go ็ไธป่ฆๅ
ณ้ฎ็นๆง "Goroutines" ็ธๅชฒ็พใ
+
+## ็ป่ฎบ
+
+่ฎฉๆไปฌๅๆฅๅ้กพไธไธๆๆ่ฏด็๏ผ
+
+> Python ็็ฐไปฃ็ๆฌๅฏไปฅ้่ฟไฝฟ็จ `async` ๅ `await` ่ฏญๆณๅๅปบ**ๅ็จ**๏ผๅนถ็จไบๆฏๆ**ๅผๆญฅไปฃ็ **ใ
+
+็ฐๅจๅบ่ฏฅ่ฝๆ็ฝๅ
ถๅซไนไบใโจ
+
+ๆๆ่ฟไบไฝฟๅพ FastAPI๏ผ้่ฟ Starlette๏ผๅฆๆญคๅผบๅคง๏ผไนๆฏๅฎๆฅๆๅฆๆญคไปคไบบๅฐ่ฑกๆทฑๅป็ๆง่ฝ็ๅๅ ใ
+
+## ้ๅธธๆๆฏๆง็็ป่
+
+!!! warning
+ ไฝ ๅฏไปฅ่ทณ่ฟ่ฟ้ใ
+
+ ่ฟไบ้ฝๆฏ FastAPI ๅฆไฝๅจๅ
้จๅทฅไฝ็ๆๆฏ็ป่ใ
+
+ ๅฆๆๆจๆ็ธๅฝๅค็ๆๆฏ็ฅ่ฏ๏ผๅ็จใ็บฟ็จใ้ปๅก็ญ๏ผ๏ผๅนถไธๅฏน FastAPI ๅฆไฝๅค็ `async def` ไธๅธธ่ง `def` ๆๅฐๅฅฝๅฅ๏ผ่ฏท็ปง็ปญใ
+
+### ่ทฏๅพๆไฝๅฝๆฐ
+
+ๅฝไฝ ไฝฟ็จ `def` ่ไธๆฏ `async def` ๆฅๅฃฐๆไธไธช*่ทฏๅพๆไฝๅฝๆฐ*ๆถ๏ผๅฎ่ฟ่กๅจๅค้จ็็บฟ็จๆฑ ไธญๅนถ็ญๅพ
ๅ
ถ็ปๆ๏ผ่ไธๆฏ็ดๆฅ่ฐ็จ๏ผๅ ไธบๅฎไผ้ปๅกๆๅกๅจ๏ผใ
+
+ๅฆๆๆจไฝฟ็จ่ฟๅฆไธไธชไธไปฅไธ่ฟฐๆนๅผๅทฅไฝ็ๅผๆญฅๆกๆถ๏ผๅนถไธๆจไน ๆฏไบ็จๆฎ้็ `def` ๅฎไนๆฎ้็ไป
่ฎก็ฎ่ทฏๅพๆไฝๅฝๆฐ๏ผไปฅ่ทๅพๅพฎๅฐ็ๆง่ฝๅข็๏ผๅคง็บฆ100็บณ็ง๏ผ๏ผ่ฏทๆณจๆ๏ผๅจ FastAPI ไธญ๏ผๆๆๅฐๅฎๅ
จ็ธๅใๅจ่ฟไบๆ
ๅตไธ๏ผๆๅฅฝไฝฟ็จ `async def`๏ผ้ค้่ทฏๅพๆไฝๅฝๆฐๅ
ไฝฟ็จๆง่ก้ปๅก I/O ็ไปฃ็ ใ
+
+ๅจ่ฟไธค็งๆ
ๅตไธ๏ผไธๆจไนๅ็ๆกๆถ็ธๆฏ๏ผ**FastAPI** ๅฏ่ฝ[ไป็ถๅพๅฟซ](/#performance){.internal-link target=_blank}ใ
+
+### ไพ่ต
+
+่ฟๅๆ ท้็จไบ[ไพ่ต](./tutorial/dependencies/index.md){.internal-link target=_blank}ใๅฆๆไธไธชไพ่ตๆฏๆ ๅ็ `def` ๅฝๆฐ่ไธๆฏ `async def`๏ผๅฎๅฐ่ขซ่ฟ่กๅจๅค้จ็บฟ็จๆฑ ไธญใ
+
+### ๅญไพ่ต
+
+ไฝ ๅฏไปฅๆฅๆๅคไธช็ธไบไพ่ต็ไพ่ตไปฅๅ[ๅญไพ่ต](./tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank} ๏ผไฝไธบๅฝๆฐ็ๅๆฐ๏ผ๏ผๅฎไปฌไธญ็ไธไบๅฏ่ฝๆฏ้่ฟ `async def` ๅฃฐๆ๏ผไนๅฏ่ฝๆฏ้่ฟ `def` ๅฃฐๆใๅฎไปฌไป็ถๅฏไปฅๆญฃๅธธๅทฅไฝ๏ผ่ฟไบ้่ฟ `def` ๅฃฐๆ็ๅฝๆฐๅฐไผๅจๅค้จ็บฟ็จไธญ่ฐ็จ๏ผๆฅ่ช็บฟ็จๆฑ ๏ผ๏ผ่ไธๆฏ"่ขซ็ญๅพ
"ใ
+
+### ๅ
ถไปๅฝๆฐ
+
+ๆจๅฏ็ดๆฅ่ฐ็จ้่ฟ `def` ๆ `async def` ๅๅปบ็ไปปไฝๅ
ถไปๅฝๆฐ๏ผFastAPI ไธไผๅฝฑๅๆจ่ฐ็จๅฎไปฌ็ๆนๅผใ
+
+่ฟไธ FastAPI ไธบๆจ่ฐ็จ*่ทฏๅพๆไฝๅฝๆฐ*ๅไพ่ต้กน็้ป่พ็ธๅใ
+
+ๅฆๆไฝ ็ๅฝๆฐๆฏ้่ฟ `def` ๅฃฐๆ็๏ผๅฎๅฐ่ขซ็ดๆฅ่ฐ็จ๏ผๅจไปฃ็ ไธญ็ผๅ็ๅฐๆน๏ผ๏ผ่ไธไผๅจ็บฟ็จๆฑ ไธญ๏ผๅฆๆ่ฟไธชๅฝๆฐ้่ฟ `async def` ๅฃฐๆ๏ผๅฝๅจไปฃ็ ไธญ่ฐ็จๆถ๏ผไฝ ๅฐฑๅบ่ฏฅไฝฟ็จ `await` ็ญๅพ
ๅฝๆฐ็็ปๆใ
+
+---
+
+ๅๆฌกๆ้๏ผ่ฟไบๆฏ้ๅธธๆๆฏๆง็็ป่๏ผๅฆๆไฝ ๆฅๆ็ดขๅฎๅฏ่ฝๅฏนไฝ ๆ็จใ
+
+ๅฆๅ๏ผๆจๆๅฅฝๅบ่ฏฅ้ตๅฎ็ๆๅฏผๅๅ่ตถๆถ้ดๅ๏ผ.
diff --git a/docs/zh/docs/deployment/versions.md b/docs/zh/docs/deployment/versions.md
new file mode 100644
index 000000000..75b870139
--- /dev/null
+++ b/docs/zh/docs/deployment/versions.md
@@ -0,0 +1,87 @@
+# ๅ
ณไบ FastAPI ็ๆฌ
+
+**FastAPI** ๅทฒๅจ่ฎธๅคๅบ็จ็จๅบๅ็ณป็ป็็ไบง็ฏๅขไธญไฝฟ็จใ ๅนถไธๆต่ฏ่ฆ็็ไฟๆๅจ100%ใ ไฝๅ
ถๅผๅ่ฟๅบฆไปๅจๅฟซ้ๆจ่ฟใ
+
+็ปๅธธๆทปๅ ๆฐๅ่ฝ๏ผๅฎๆไฟฎๅค้่ฏฏ๏ผๅนถไธไปฃ็ ไปๅจๆ็ปญๆน่ฟใ
+
+่ฟๅฐฑๆฏไธบไปไนๅฝๅ็ๆฌไป็ถๆฏ`0.x.x`๏ผ่ฟๅๆ ๅบๆฏไธช็ๆฌ้ฝๅฏ่ฝๆBreaking changesใ ่ฟ้ตๅพช่ฏญไน็ๆฌๆงๅถ็็บฆๅฎใ
+
+ไฝ ็ฐๅจๅฐฑๅฏไปฅไฝฟ็จ **FastAPI** ๅๅปบ็ไบง็ฏๅขๅบ็จ็จๅบ๏ผไฝ ๅฏ่ฝๅทฒ็ป่ฟๆ ทๅไบไธๆฎตๆถ้ด๏ผ๏ผไฝ ๅช้็กฎไฟไฝฟ็จ็็ๆฌๅฏไปฅไธๅ
ถไฝไปฃ็ ๆญฃ็กฎ้
ๅๅณๅฏใ
+
+## ๅบๅฎไฝ ็ `fastapi` ็ๆฌ
+
+ไฝ ๅบ่ฏฅๅ็็ฌฌไธไปถไบๆฏๅฐไฝ ๆญฃๅจไฝฟ็จ็ **FastAPI** ็ๆฌโๅบๅฎโๅฐไฝ ็ฅ้้็จไบไฝ ็ๅบ็จ็จๅบ็็นๅฎๆๆฐ็ๆฌใ
+
+ไพๅฆ๏ผๅ่ฎพไฝ ๅจๅบ็จ็จๅบไธญไฝฟ็จ็ๆฌ`0.45.0`ใ
+
+ๅฆๆไฝ ไฝฟ็จ`requirements.txt`ๆไปถ๏ผไฝ ๅฏไปฅไฝฟ็จไปฅไธๅฝไปคๆๅฎ็ๆฌ๏ผ
+
+````txt
+fastapi==0.45.0
+````
+
+่ฟๆๅณ็ไฝ ๅฐไฝฟ็จ็ๆฌ`0.45.0`ใ
+
+ๆ่
ไฝ ไนๅฏไปฅๅฐๅ
ถๅบๅฎไธบ๏ผ
+
+````txt
+fastapi>=0.45.0,<0.46.0
+````
+
+่ฟๆๅณ็ไฝ ๅฐไฝฟ็จ`0.45.0`ๆๆด้ซ็ๆฌ๏ผไฝไฝไบ`0.46.0`๏ผไพๅฆ๏ผ็ๆฌ`0.45.2`ไปไผ่ขซๆฅๅใ
+
+ๅฆๆไฝ ไฝฟ็จไปปไฝๅ
ถไปๅทฅๅ
ทๆฅ็ฎก็ไฝ ็ๅฎ่ฃ
๏ผไพๅฆ PoetryใPipenv ๆๅ
ถไปๅทฅๅ
ท๏ผๅฎไปฌ้ฝๆไธ็งๅฎไนๅ
็็นๅฎ็ๆฌ็ๆนๆณใ
+
+## ๅฏ็จ็ๆฌ
+
+ไฝ ๅฏไปฅๅจ[ๅ่ก่ฏดๆ](../release-notes.md){.internal-link target=_blank}ไธญๆฅ็ๅฏ็จ็ๆฌ๏ผไพๅฆๆฅ็ๅฝๅๆๆฐ็ๆฌ๏ผใ
+
+## ๅ
ณไบ็ๆฌ
+
+้ตๅพช่ฏญไน็ๆฌๆงๅถ็บฆๅฎ๏ผไปปไฝไฝไบ`1.0.0`็็ๆฌ้ฝๅฏ่ฝไผๆทปๅ breaking changesใ
+
+FastAPI ่ฟ้ตๅพช่ฟๆ ท็็บฆๅฎ๏ผไปปไฝ`PATCH`็ๆฌๆดๆน้ฝๆฏไธบไบbugไฟฎๅคๅnon-breaking changesใ
+
+!!! tip
+ "PATCH"ๆฏๆๅไธไธชๆฐๅญ๏ผไพๅฆ๏ผๅจ`0.2.3`ไธญ๏ผPATCH็ๆฌๆฏ`3`ใ
+
+ๅ ๆญค๏ผไฝ ๅบ่ฏฅ่ฝๅคๅบๅฎๅฐๅฆไธ็ๆฌ๏ผ
+
+```txt
+fastapi>=0.45.0,<0.46.0
+```
+
+"MINOR"็ๆฌไธญไผๆทปๅ breaking changesๅๆฐๅ่ฝใ
+
+!!! tip
+ "MINOR"ๆฏไธญ้ด็ๆฐๅญ๏ผไพๅฆ๏ผๅจ`0.2.3`ไธญ๏ผMINOR็ๆฌๆฏ`2`ใ
+
+## ๅ็บงFastAPI็ๆฌ
+
+ไฝ ๅบ่ฏฅไธบไฝ ็ๅบ็จ็จๅบๆทปๅ ๆต่ฏใ
+
+ไฝฟ็จ **FastAPI** ็ผๅๆต่ฏ้ๅธธ็ฎๅ๏ผๆ่ฐข Starlette๏ผ๏ผ่ฏทๅ่ๆๆกฃ๏ผ[ๆต่ฏ](../tutorial/testing.md){.internal-link target=_blank}
+
+ๆทปๅ ๆต่ฏๅ๏ผไฝ ๅฏไปฅๅฐ **FastAPI** ็ๆฌๅ็บงๅฐๆดๆฐ็ๆฌ๏ผๅนถ้่ฟ่ฟ่กๆต่ฏๆฅ็กฎไฟๆๆไปฃ็ ้ฝ่ฝๆญฃๅธธๅทฅไฝใ
+
+ๅฆๆไธๅๆญฃๅธธ๏ผๆ่
ๅจ่ฟ่กๅฟ
่ฆ็ๆดๆนไนๅ๏ผๅนถไธๆๆๆต่ฏ้ฝ้่ฟไบ๏ผ้ฃไนไฝ ๅฏไปฅๅฐ`fastapi`ๅบๅฎๅฐๆฐ็็ๆฌใ
+
+## ๅ
ณไบStarlette
+
+ไฝ ไธๅบ่ฏฅๅบๅฎ`starlette`็็ๆฌใ
+
+ไธๅ็ๆฌ็ **FastAPI** ๅฐไฝฟ็จ็นๅฎ็่พๆฐ็ๆฌ็ Starletteใ
+
+ๅ ๆญค๏ผ**FastAPI** ่ชๅทฑๅฏไปฅไฝฟ็จๆญฃ็กฎ็ Starlette ็ๆฌใ
+
+## ๅ
ณไบ Pydantic
+
+Pydantic ๅ
ๅซ้ๅฏน **FastAPI** ็ๆต่ฏๅๅ
ถ่ชๅทฑ็ๆต่ฏ๏ผๅ ๆญค Pydantic ็ๆฐ็ๆฌ๏ผ`1.0.0`ไปฅไธ๏ผๅง็ปไธ FastAPI ๅ
ผๅฎนใ
+
+ไฝ ๅฏไปฅๅฐ Pydantic ๅบๅฎๅฐ้ๅไฝ ็`1.0.0`ไปฅไธๅ`2.0.0`ไปฅไธ็ไปปไฝ็ๆฌใ
+
+ไพๅฆ๏ผ
+
+````txt
+pydantic>=1.2.0,<2.0.0
+````
diff --git a/docs/zh/docs/help-fastapi.md b/docs/zh/docs/help-fastapi.md
index 2a99950e3..9b70d115a 100644
--- a/docs/zh/docs/help-fastapi.md
+++ b/docs/zh/docs/help-fastapi.md
@@ -114,8 +114,6 @@
่ๅคฉๅฎคไป
ไพ้ฒ่ใ
-ๆไปฌไนๅ่ฟไฝฟ็จ่ฟ Gitter chat๏ผไฝๅฎไธๆฏๆ้ข้็ญ้ซ็บงๅ่ฝ๏ผ่ๅคฉไนๆฏ่พ้บป็ฆ๏ผๆไปฅ็ฐๅจๆจ่ไฝฟ็จ Discordใ
-
### ๅซๅจ่ๅคฉๅฎค้ๆ้ฎ
ๆณจๆ๏ผ่ๅคฉๅฎคๆดๅพๅไบโ้ฒ่โ๏ผ็ปๅธธๆไบบไผๆๅบไธไบ็ฌผ็ปๅพ่ฎฉไบบ้พไปฅๅ็ญ็้ฎ้ข๏ผๆไปฅๅจ่ฟ้ๆ้ฎไธ่ฌๆฒกไบบๅ็ญใ
diff --git a/docs/zh/docs/index.md b/docs/zh/docs/index.md
index 1de2a8d36..d776e5813 100644
--- a/docs/zh/docs/index.md
+++ b/docs/zh/docs/index.md
@@ -24,7 +24,7 @@
---
-FastAPI ๆฏไธไธช็จไบๆๅปบ API ็็ฐไปฃใๅฟซ้๏ผ้ซๆง่ฝ๏ผ็ web ๆกๆถ๏ผไฝฟ็จ Python 3.6+ ๅนถๅบไบๆ ๅ็ Python ็ฑปๅๆ็คบใ
+FastAPI ๆฏไธไธช็จไบๆๅปบ API ็็ฐไปฃใๅฟซ้๏ผ้ซๆง่ฝ๏ผ็ web ๆกๆถ๏ผไฝฟ็จ Python 3.8+ ๅนถๅบไบๆ ๅ็ Python ็ฑปๅๆ็คบใ
ๅ
ณ้ฎ็นๆง:
@@ -107,7 +107,7 @@ FastAPI ๆฏไธไธช็จไบๆๅปบ API ็็ฐไปฃใๅฟซ้๏ผ้ซๆง่ฝ๏ผ็ web ๆก
## ไพ่ต
-Python 3.6 ๅๆด้ซ็ๆฌ
+Python 3.8 ๅๆด้ซ็ๆฌ
FastAPI ็ซๅจไปฅไธๅทจไบบ็่ฉ่ไนไธ๏ผ
@@ -323,7 +323,7 @@ def update_item(item_id: int, item: Item):
ไฝ ไธ้่ฆๅปๅญฆไน ๆฐ็่ฏญๆณใไบ่งฃ็นๅฎๅบ็ๆนๆณๆ็ฑป๏ผ็ญ็ญใ
-ๅช้่ฆไฝฟ็จๆ ๅ็ **Python 3.6 ๅๆด้ซ็ๆฌ**ใ
+ๅช้่ฆไฝฟ็จๆ ๅ็ **Python 3.8 ๅๆด้ซ็ๆฌ**ใ
ไธพไธชไพๅญ๏ผๆฏๅฆๅฃฐๆ `int` ็ฑปๅ๏ผ
diff --git a/docs/zh/docs/tutorial/background-tasks.md b/docs/zh/docs/tutorial/background-tasks.md
index c8568298b..94b75d4fd 100644
--- a/docs/zh/docs/tutorial/background-tasks.md
+++ b/docs/zh/docs/tutorial/background-tasks.md
@@ -69,7 +69,7 @@
{!> ../../../docs_src/background_tasks/tutorial002_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="14 16 23 26"
{!> ../../../docs_src/background_tasks/tutorial002_an.py!}
@@ -84,7 +84,7 @@
{!> ../../../docs_src/background_tasks/tutorial002_py310.py!}
```
-=== "Python 3.6+ ๆฒกAnnotated"
+=== "Python 3.8+ ๆฒกAnnotated"
!!! tip
ๅฐฝๅฏ่ฝ้ๆฉไฝฟ็จ `Annotated` ็็ๆฌใ
diff --git a/docs/zh/docs/tutorial/body-fields.md b/docs/zh/docs/tutorial/body-fields.md
index c153784dc..fb6c6d9b6 100644
--- a/docs/zh/docs/tutorial/body-fields.md
+++ b/docs/zh/docs/tutorial/body-fields.md
@@ -18,7 +18,7 @@
{!> ../../../docs_src/body_fields/tutorial001_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="4"
{!> ../../../docs_src/body_fields/tutorial001_an.py!}
@@ -33,7 +33,7 @@
{!> ../../../docs_src/body_fields/tutorial001_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
ๅฐฝๅฏ่ฝ้ๆฉไฝฟ็จ `Annotated` ็็ๆฌใ
@@ -61,7 +61,7 @@
{!> ../../../docs_src/body_fields/tutorial001_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="12-15"
{!> ../../../docs_src/body_fields/tutorial001_an.py!}
@@ -76,7 +76,7 @@
{!> ../../../docs_src/body_fields/tutorial001_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
Prefer to use the `Annotated` version if possible.
diff --git a/docs/zh/docs/tutorial/body-multiple-params.md b/docs/zh/docs/tutorial/body-multiple-params.md
index ee2cba6df..c93ef2f5c 100644
--- a/docs/zh/docs/tutorial/body-multiple-params.md
+++ b/docs/zh/docs/tutorial/body-multiple-params.md
@@ -20,7 +20,7 @@
{!> ../../../docs_src/body_multiple_params/tutorial001_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="19-21"
{!> ../../../docs_src/body_multiple_params/tutorial001_an.py!}
@@ -35,7 +35,7 @@
{!> ../../../docs_src/body_multiple_params/tutorial001_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
ๅฐฝๅฏ่ฝ้ๆฉไฝฟ็จ `Annotated` ็็ๆฌใ
@@ -68,7 +68,7 @@
{!> ../../../docs_src/body_multiple_params/tutorial002_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="22"
{!> ../../../docs_src/body_multiple_params/tutorial002.py!}
@@ -124,7 +124,7 @@
{!> ../../../docs_src/body_multiple_params/tutorial003_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="24"
{!> ../../../docs_src/body_multiple_params/tutorial003_an.py!}
@@ -139,7 +139,7 @@
{!> ../../../docs_src/body_multiple_params/tutorial003_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
ๅฐฝๅฏ่ฝ้ๆฉไฝฟ็จ `Annotated` ็็ๆฌใ
@@ -193,7 +193,7 @@ q: str = None
{!> ../../../docs_src/body_multiple_params/tutorial004_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="28"
{!> ../../../docs_src/body_multiple_params/tutorial004_an.py!}
@@ -208,7 +208,7 @@ q: str = None
{!> ../../../docs_src/body_multiple_params/tutorial004_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
ๅฐฝๅฏ่ฝ้ๆฉไฝฟ็จ `Annotated` ็็ๆฌใ
@@ -247,7 +247,7 @@ item: Item = Body(embed=True)
{!> ../../../docs_src/body_multiple_params/tutorial005_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="18"
{!> ../../../docs_src/body_multiple_params/tutorial005_an.py!}
@@ -262,7 +262,7 @@ item: Item = Body(embed=True)
{!> ../../../docs_src/body_multiple_params/tutorial005_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
ๅฐฝๅฏ่ฝ้ๆฉไฝฟ็จ `Annotated` ็็ๆฌใ
diff --git a/docs/zh/docs/tutorial/body-nested-models.md b/docs/zh/docs/tutorial/body-nested-models.md
index 7704d2624..c65308bef 100644
--- a/docs/zh/docs/tutorial/body-nested-models.md
+++ b/docs/zh/docs/tutorial/body-nested-models.md
@@ -12,7 +12,7 @@
{!> ../../../docs_src/body_nested_models/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="14"
{!> ../../../docs_src/body_nested_models/tutorial001.py!}
@@ -63,7 +63,7 @@ my_list: List[str]
{!> ../../../docs_src/body_nested_models/tutorial002_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="14"
{!> ../../../docs_src/body_nested_models/tutorial002.py!}
@@ -89,7 +89,7 @@ Python ๅ
ทๆไธ็ง็นๆฎ็ๆฐๆฎ็ฑปๅๆฅไฟๅญไธ็ปๅฏไธ็ๅ
็ด ๏ผๅณ `se
{!> ../../../docs_src/body_nested_models/tutorial003_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="1 14"
{!> ../../../docs_src/body_nested_models/tutorial003.py!}
@@ -127,7 +127,7 @@ Pydantic ๆจกๅ็ๆฏไธชๅฑๆง้ฝๅ
ทๆ็ฑปๅใ
{!> ../../../docs_src/body_nested_models/tutorial004_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9-11"
{!> ../../../docs_src/body_nested_models/tutorial004.py!}
@@ -149,7 +149,7 @@ Pydantic ๆจกๅ็ๆฏไธชๅฑๆง้ฝๅ
ทๆ็ฑปๅใ
{!> ../../../docs_src/body_nested_models/tutorial004_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="20"
{!> ../../../docs_src/body_nested_models/tutorial004.py!}
@@ -198,7 +198,7 @@ Pydantic ๆจกๅ็ๆฏไธชๅฑๆง้ฝๅ
ทๆ็ฑปๅใ
{!> ../../../docs_src/body_nested_models/tutorial005_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="4 10"
{!> ../../../docs_src/body_nested_models/tutorial005.py!}
@@ -222,7 +222,7 @@ Pydantic ๆจกๅ็ๆฏไธชๅฑๆง้ฝๅ
ทๆ็ฑปๅใ
{!> ../../../docs_src/body_nested_models/tutorial006_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="20"
{!> ../../../docs_src/body_nested_models/tutorial006.py!}
@@ -273,7 +273,7 @@ Pydantic ๆจกๅ็ๆฏไธชๅฑๆง้ฝๅ
ทๆ็ฑปๅใ
{!> ../../../docs_src/body_nested_models/tutorial007_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9 14 20 23 27"
{!> ../../../docs_src/body_nested_models/tutorial007.py!}
@@ -298,7 +298,7 @@ images: List[Image]
{!> ../../../docs_src/body_nested_models/tutorial008_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="15"
{!> ../../../docs_src/body_nested_models/tutorial008.py!}
@@ -338,7 +338,7 @@ images: List[Image]
{!> ../../../docs_src/body_nested_models/tutorial009_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9"
{!> ../../../docs_src/body_nested_models/tutorial009.py!}
diff --git a/docs/zh/docs/tutorial/body.md b/docs/zh/docs/tutorial/body.md
index d00c96dc3..5cf53c0c2 100644
--- a/docs/zh/docs/tutorial/body.md
+++ b/docs/zh/docs/tutorial/body.md
@@ -23,7 +23,7 @@
{!> ../../../docs_src/body/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="4"
{!> ../../../docs_src/body/tutorial001.py!}
@@ -41,7 +41,7 @@
{!> ../../../docs_src/body/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="7-11"
{!> ../../../docs_src/body/tutorial001.py!}
@@ -79,7 +79,7 @@
{!> ../../../docs_src/body/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="18"
{!> ../../../docs_src/body/tutorial001.py!}
@@ -142,7 +142,7 @@ Pydantic ๆฌ่บซ็่ณไน่ฟ่กไบไธไบๆดๆนไปฅๆฏๆๆญคๅ่ฝใ
{!> ../../../docs_src/body/tutorial002_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="21"
{!> ../../../docs_src/body/tutorial002.py!}
@@ -160,7 +160,7 @@ Pydantic ๆฌ่บซ็่ณไน่ฟ่กไบไธไบๆดๆนไปฅๆฏๆๆญคๅ่ฝใ
{!> ../../../docs_src/body/tutorial003_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="17-18"
{!> ../../../docs_src/body/tutorial003.py!}
@@ -178,7 +178,7 @@ Pydantic ๆฌ่บซ็่ณไน่ฟ่กไบไธไบๆดๆนไปฅๆฏๆๆญคๅ่ฝใ
{!> ../../../docs_src/body/tutorial004_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="18"
{!> ../../../docs_src/body/tutorial004.py!}
diff --git a/docs/zh/docs/tutorial/cookie-params.md b/docs/zh/docs/tutorial/cookie-params.md
index 470fd8e82..f115f9677 100644
--- a/docs/zh/docs/tutorial/cookie-params.md
+++ b/docs/zh/docs/tutorial/cookie-params.md
@@ -18,7 +18,7 @@
{!> ../../../docs_src/cookie_params/tutorial001_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="3"
{!> ../../../docs_src/cookie_params/tutorial001_an.py!}
@@ -33,7 +33,7 @@
{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
ๅฐฝๅฏ่ฝ้ๆฉไฝฟ็จ `Annotated` ็็ๆฌใ
@@ -61,7 +61,7 @@
{!> ../../../docs_src/cookie_params/tutorial001_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="10"
{!> ../../../docs_src/cookie_params/tutorial001_an.py!}
@@ -76,7 +76,7 @@
{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
ๅฐฝๅฏ่ฝ้ๆฉไฝฟ็จ `Annotated` ็็ๆฌใ
diff --git a/docs/zh/docs/tutorial/dependencies/classes-as-dependencies.md b/docs/zh/docs/tutorial/dependencies/classes-as-dependencies.md
index f404820df..1866da298 100644
--- a/docs/zh/docs/tutorial/dependencies/classes-as-dependencies.md
+++ b/docs/zh/docs/tutorial/dependencies/classes-as-dependencies.md
@@ -12,7 +12,7 @@
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9"
{!> ../../../docs_src/dependencies/tutorial001.py!}
@@ -85,7 +85,7 @@ fluffy = Cat(name="Mr Fluffy")
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="11-15"
{!> ../../../docs_src/dependencies/tutorial002.py!}
diff --git a/docs/zh/docs/tutorial/encoder.md b/docs/zh/docs/tutorial/encoder.md
index 76ed846ce..859ebc2e8 100644
--- a/docs/zh/docs/tutorial/encoder.md
+++ b/docs/zh/docs/tutorial/encoder.md
@@ -26,7 +26,7 @@
{!> ../../../docs_src/encoder/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="5 22"
{!> ../../../docs_src/encoder/tutorial001.py!}
diff --git a/docs/zh/docs/tutorial/extra-data-types.md b/docs/zh/docs/tutorial/extra-data-types.md
index 76d606903..a74efa61b 100644
--- a/docs/zh/docs/tutorial/extra-data-types.md
+++ b/docs/zh/docs/tutorial/extra-data-types.md
@@ -67,7 +67,7 @@
{!> ../../../docs_src/extra_data_types/tutorial001_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="1 3 13-17"
{!> ../../../docs_src/extra_data_types/tutorial001_an.py!}
@@ -82,7 +82,7 @@
{!> ../../../docs_src/extra_data_types/tutorial001_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
ๅฐฝๅฏ่ฝ้ๆฉไฝฟ็จ `Annotated` ็็ๆฌใ
@@ -105,7 +105,7 @@
{!> ../../../docs_src/extra_data_types/tutorial001_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="19-20"
{!> ../../../docs_src/extra_data_types/tutorial001_an.py!}
@@ -120,7 +120,7 @@
{!> ../../../docs_src/extra_data_types/tutorial001_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
ๅฐฝๅฏ่ฝ้ๆฉไฝฟ็จ `Annotated` ็็ๆฌใ
diff --git a/docs/zh/docs/tutorial/extra-models.md b/docs/zh/docs/tutorial/extra-models.md
index 32f8f9df1..06427a73d 100644
--- a/docs/zh/docs/tutorial/extra-models.md
+++ b/docs/zh/docs/tutorial/extra-models.md
@@ -23,7 +23,7 @@
{!> ../../../docs_src/extra_models/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9 11 16 22 24 29-30 33-35 40-41"
{!> ../../../docs_src/extra_models/tutorial001.py!}
@@ -164,7 +164,7 @@ UserInDB(
{!> ../../../docs_src/extra_models/tutorial002_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9 15-16 19-20 23-24"
{!> ../../../docs_src/extra_models/tutorial002.py!}
@@ -188,7 +188,7 @@ UserInDB(
{!> ../../../docs_src/extra_models/tutorial003_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="1 14-15 18-20 33"
{!> ../../../docs_src/extra_models/tutorial003.py!}
@@ -206,7 +206,7 @@ UserInDB(
{!> ../../../docs_src/extra_models/tutorial004_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="1 20"
{!> ../../../docs_src/extra_models/tutorial004.py!}
@@ -226,7 +226,7 @@ UserInDB(
{!> ../../../docs_src/extra_models/tutorial005_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="1 8"
{!> ../../../docs_src/extra_models/tutorial005.py!}
diff --git a/docs/zh/docs/tutorial/header-params.md b/docs/zh/docs/tutorial/header-params.md
index 22ff6dc27..2701167b3 100644
--- a/docs/zh/docs/tutorial/header-params.md
+++ b/docs/zh/docs/tutorial/header-params.md
@@ -18,7 +18,7 @@
{!> ../../../docs_src/header_params/tutorial001_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="3"
{!> ../../../docs_src/header_params/tutorial001_an.py!}
@@ -33,7 +33,7 @@
{!> ../../../docs_src/header_params/tutorial001_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
ๅฐฝๅฏ่ฝ้ๆฉไฝฟ็จ `Annotated` ็็ๆฌใ
@@ -60,7 +60,7 @@
{!> ../../../docs_src/header_params/tutorial001_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="10"
{!> ../../../docs_src/header_params/tutorial001_an.py!}
@@ -75,7 +75,7 @@
{!> ../../../docs_src/header_params/tutorial001_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
ๅฐฝๅฏ่ฝ้ๆฉไฝฟ็จ `Annotated` ็็ๆฌใ
@@ -120,7 +120,7 @@
{!> ../../../docs_src/header_params/tutorial002_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="12"
{!> ../../../docs_src/header_params/tutorial002_an.py!}
@@ -135,7 +135,7 @@
{!> ../../../docs_src/header_params/tutorial002_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
ๅฐฝๅฏ่ฝ้ๆฉไฝฟ็จ `Annotated` ็็ๆฌใ
@@ -170,7 +170,7 @@
{!> ../../../docs_src/header_params/tutorial003_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="10"
{!> ../../../docs_src/header_params/tutorial003_an.py!}
@@ -194,7 +194,7 @@
{!> ../../../docs_src/header_params/tutorial003_py39.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
ๅฐฝๅฏ่ฝ้ๆฉไฝฟ็จ `Annotated` ็็ๆฌใ
diff --git a/docs/zh/docs/tutorial/path-params-numeric-validations.md b/docs/zh/docs/tutorial/path-params-numeric-validations.md
index 78fa922b4..9b41ad7cf 100644
--- a/docs/zh/docs/tutorial/path-params-numeric-validations.md
+++ b/docs/zh/docs/tutorial/path-params-numeric-validations.md
@@ -18,7 +18,7 @@
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="3-4"
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
@@ -33,7 +33,7 @@
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
ๅฐฝๅฏ่ฝ้ๆฉไฝฟ็จ `Annotated` ็็ๆฌใ
@@ -60,7 +60,7 @@
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="11"
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
@@ -75,7 +75,7 @@
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
ๅฐฝๅฏ่ฝ้ๆฉไฝฟ็จ `Annotated` ็็ๆฌใ
@@ -107,7 +107,7 @@
ๅ ๆญค๏ผไฝ ๅฏไปฅๅฐๅฝๆฐๅฃฐๆไธบ๏ผ
-=== "Python 3.6 non-Annotated"
+=== "Python 3.8 non-Annotated"
!!! tip
ๅฐฝๅฏ่ฝ้ๆฉไฝฟ็จ `Annotated` ็็ๆฌใ
diff --git a/docs/zh/docs/tutorial/query-params-str-validations.md b/docs/zh/docs/tutorial/query-params-str-validations.md
index 7244aeade..39253eb0d 100644
--- a/docs/zh/docs/tutorial/query-params-str-validations.md
+++ b/docs/zh/docs/tutorial/query-params-str-validations.md
@@ -10,7 +10,7 @@
{!> ../../../docs_src/query_params_str_validations/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9"
{!> ../../../docs_src/query_params_str_validations/tutorial001.py!}
diff --git a/docs/zh/docs/tutorial/request-files.md b/docs/zh/docs/tutorial/request-files.md
index 03474907e..2c48f33ca 100644
--- a/docs/zh/docs/tutorial/request-files.md
+++ b/docs/zh/docs/tutorial/request-files.md
@@ -130,7 +130,7 @@ contents = myfile.file.read()
{!> ../../../docs_src/request_files/tutorial001_02_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9 17"
{!> ../../../docs_src/request_files/tutorial001_02.py!}
@@ -158,7 +158,7 @@ FastAPI ๆฏๆๅๆถไธไผ ๅคไธชๆไปถใ
{!> ../../../docs_src/request_files/tutorial002_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="10 15"
{!> ../../../docs_src/request_files/tutorial002.py!}
@@ -183,7 +183,7 @@ FastAPI ๆฏๆๅๆถไธไผ ๅคไธชๆไปถใ
{!> ../../../docs_src/request_files/tutorial003_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="18"
{!> ../../../docs_src/request_files/tutorial003.py!}
diff --git a/docs/zh/docs/tutorial/response-model.md b/docs/zh/docs/tutorial/response-model.md
index f529cb0d8..e731b6989 100644
--- a/docs/zh/docs/tutorial/response-model.md
+++ b/docs/zh/docs/tutorial/response-model.md
@@ -20,7 +20,7 @@
{!> ../../../docs_src/response_model/tutorial001_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="17 22 24-27"
{!> ../../../docs_src/response_model/tutorial001.py!}
@@ -78,7 +78,7 @@ FastAPI ๅฐไฝฟ็จๆญค `response_model` ๆฅ๏ผ
{!> ../../../docs_src/response_model/tutorial003_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9 11 16"
{!> ../../../docs_src/response_model/tutorial003.py!}
@@ -92,7 +92,7 @@ FastAPI ๅฐไฝฟ็จๆญค `response_model` ๆฅ๏ผ
{!> ../../../docs_src/response_model/tutorial003_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="24"
{!> ../../../docs_src/response_model/tutorial003.py!}
@@ -106,7 +106,7 @@ FastAPI ๅฐไฝฟ็จๆญค `response_model` ๆฅ๏ผ
{!> ../../../docs_src/response_model/tutorial003_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="22"
{!> ../../../docs_src/response_model/tutorial003.py!}
diff --git a/docs/zh/docs/tutorial/schema-extra-example.md b/docs/zh/docs/tutorial/schema-extra-example.md
index 816e8f68e..ebc04da8b 100644
--- a/docs/zh/docs/tutorial/schema-extra-example.md
+++ b/docs/zh/docs/tutorial/schema-extra-example.md
@@ -16,7 +16,7 @@
{!> ../../../docs_src/schema_extra_example/tutorial001_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="15-23"
{!> ../../../docs_src/schema_extra_example/tutorial001.py!}
@@ -34,7 +34,7 @@
{!> ../../../docs_src/schema_extra_example/tutorial002_py310.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="4 10-13"
{!> ../../../docs_src/schema_extra_example/tutorial002.py!}
@@ -61,7 +61,7 @@
{!> ../../../docs_src/schema_extra_example/tutorial003_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="23-28"
{!> ../../../docs_src/schema_extra_example/tutorial003_an.py!}
@@ -76,7 +76,7 @@
{!> ../../../docs_src/schema_extra_example/tutorial003_py310.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
ๅฐฝๅฏ่ฝ้ๆฉไฝฟ็จ `Annotated` ็็ๆฌใ
diff --git a/docs/zh/docs/tutorial/security/first-steps.md b/docs/zh/docs/tutorial/security/first-steps.md
index 7b1052e12..dda956417 100644
--- a/docs/zh/docs/tutorial/security/first-steps.md
+++ b/docs/zh/docs/tutorial/security/first-steps.md
@@ -26,13 +26,13 @@
{!> ../../../docs_src/security/tutorial001_an_py39.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python
{!> ../../../docs_src/security/tutorial001_an.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
ๅฐฝๅฏ่ฝ้ๆฉไฝฟ็จ `Annotated` ็็ๆฌใ
diff --git a/docs/zh/docs/tutorial/security/simple-oauth2.md b/docs/zh/docs/tutorial/security/simple-oauth2.md
index 276f3d63b..c7f46177f 100644
--- a/docs/zh/docs/tutorial/security/simple-oauth2.md
+++ b/docs/zh/docs/tutorial/security/simple-oauth2.md
@@ -1,94 +1,98 @@
-# ไฝฟ็จๅฏ็ ๅ Bearer ็็ฎๅ OAuth2
+# OAuth2 ๅฎ็ฐ็ฎๅ็ Password ๅ Bearer ้ช่ฏ
-็ฐๅจ่ฎฉๆไปฌๆฅ็ไธไธ็ซ ็ปง็ปญๅผๅ๏ผๅนถๆทปๅ ็ผบๅฐ็้จๅไปฅๅฎ็ฐไธไธชๅฎๆด็ๅฎๅ
จๆงๆต็จใ
+ๆฌ็ซ ๆทปๅ ไธไธ็ซ ็คบไพไธญๆฌ ็ผบ็้จๅ๏ผๅฎ็ฐๅฎๆด็ๅฎๅ
จๆตใ
## ่ทๅ `username` ๅ `password`
-ๆไปฌๅฐไฝฟ็จ **FastAPI** ็ๅฎๅ
จๆงๅฎ็จๅทฅๅ
ทๆฅ่ทๅ `username` ๅ `password`ใ
+้ฆๅ
๏ผไฝฟ็จ **FastAPI** ๅฎๅ
จๅทฅๅ
ท่ทๅ `username` ๅ `password`ใ
-OAuth2 ่งๅฎๅจไฝฟ็จ๏ผๆไปฌๆ็ฎ็จ็๏ผใpassword ๆต็จใๆถ๏ผๅฎขๆท็ซฏ/็จๆทๅฟ
้กปๅฐ `username` ๅ `password` ๅญๆฎตไฝไธบ่กจๅๆฐๆฎๅ้ใ
+OAuth2 ่ง่่ฆๆฑไฝฟ็จ**ๅฏ็ ๆต**ๆถ๏ผๅฎขๆท็ซฏๆ็จๆทๅฟ
้กปไปฅ่กจๅๆฐๆฎๅฝขๅผๅ้ `username` ๅ `password` ๅญๆฎตใ
-่ไธ่ง่ๆ็กฎไบๅญๆฎตๅฟ
้กป่ฟๆ ทๅฝๅใๅ ๆญค `user-name` ๆ `email` ๆฏ่กไธ้็ใ
+ๅนถไธ๏ผ่ฟไธคไธชๅญๆฎตๅฟ
้กปๅฝๅไธบ `username` ๅ `password` ๏ผไธ่ฝไฝฟ็จ `user-name` ๆ `email` ็ญๅ
ถๅฎๅ็งฐใ
-ไธ่ฟไธ็จๆ
ๅฟ๏ผไฝ ๅฏไปฅๅจๅ็ซฏๆ็
งไฝ ็ๆณๆณๅฐๅฎๅฑ็คบ็ปๆ็ป็จๆทใ
+ไธ่ฟไนไธ็จๆ
ๅฟ๏ผๅ็ซฏไปๅฏไปฅๆพ็คบ็ป็ซฏ็จๆทๆ้็ๅ็งฐใ
-่ไธไฝ ็ๆฐๆฎๅบๆจกๅไนๅฏไปฅไฝฟ็จไฝ ๆณ็จ็ไปปไฝๅ
ถไปๅ็งฐใ
+ๆฐๆฎๅบๆจกๅไนๅฏไปฅไฝฟ็จๆ้็ๅ็งฐใ
-ไฝๆฏๅฏนไบ็ปๅฝ*่ทฏๅพๆไฝ*๏ผๆไปฌ้่ฆไฝฟ็จ่ฟไบๅ็งฐๆฅไธ่ง่ๅ
ผๅฎน๏ผไปฅๅ
ทๅคไพๅฆไฝฟ็จ้ๆ็ API ๆๆกฃ็ณป็ป็่ฝๅ๏ผใ
+ไฝๅฏนไบ็ปๅฝ*่ทฏๅพๆไฝ*๏ผๅ่ฆไฝฟ็จๅ
ผๅฎน่ง่็ `username` ๅ `password`๏ผ๏ผไพๅฆ๏ผๅฎ็ฐไธ API ๆๆกฃ้ๆ๏ผใ
-่ง่่ฟๅๆไบ `username` ๅ `password` ๅฟ
้กปไฝไธบ่กจๅๆฐๆฎๅ้๏ผๅ ๆญค๏ผๆญคๅคไธ่ฝไฝฟ็จ JSON๏ผใ
+่ฏฅ่ง่่ฆๆฑๅฟ
้กปไปฅ่กจๅๆฐๆฎๅฝขๅผๅ้ `username` ๅ `password`๏ผๅ ๆญค๏ผไธ่ฝไฝฟ็จ JSON ๅฏน่ฑกใ
-### `scope`
+### `Scope`๏ผไฝ็จๅ๏ผ
-่ง่่ฟๆๅฐๅฎขๆท็ซฏๅฏไปฅๅ้ๅฆไธไธช่กจๅๅญๆฎตใ`scope`ใใ
+OAuth2 ่ฟๆฏๆๅฎขๆท็ซฏๅ้**`scope`**่กจๅๅญๆฎตใ
-่ฟไธช่กจๅๅญๆฎต็ๅ็งฐไธบ `scope`๏ผๅๆฐๅฝขๅผ๏ผ๏ผไฝๅฎ้
ไธๅฎๆฏไธไธช็ฑ็ฉบๆ ผๅ้็ใไฝ็จๅใ็ปๆ็้ฟๅญ็ฌฆไธฒใ
+่ฝ็ถ่กจๅๅญๆฎต็ๅ็งฐๆฏ `scope`๏ผๅๆฐ๏ผ๏ผไฝๅฎ้
ไธ๏ผๅฎๆฏไปฅ็ฉบๆ ผๅ้็๏ผ็ฑๅคไธช**scope**็ปๆ็้ฟๅญ็ฌฆไธฒใ
-ๆฏไธชใไฝ็จๅใๅชๆฏไธไธชๅญ็ฌฆไธฒ๏ผไธญ้ดๆฒกๆ็ฉบๆ ผ๏ผใ
+**ไฝ็จๅ**ๅชๆฏไธๅธฆ็ฉบๆ ผ็ๅญ็ฌฆไธฒใ
-ๅฎไปฌ้ๅธธ็จไบๅฃฐๆ็นๅฎ็ๅฎๅ
จๆ้๏ผไพๅฆ๏ผ
+ๅธธ็จไบๅฃฐๆๆๅฎๅฎๅ
จๆ้๏ผไพๅฆ๏ผ
-* `users:read` ๆ่
`users:write` ๆฏๅธธ่ง็ไพๅญใ
-* Facebook / Instagram ไฝฟ็จ `instagram_basic`ใ
-* Google ไฝฟ็จไบ `https://www.googleapis.com/auth/drive` ใ
+* ๅธธ่ง็จไพไธบ๏ผ`users:read` ๆ `users:write`
+* ่ธไนฆๅ Instagram ไฝฟ็จ `instagram_basic`
+* ่ฐทๆญไฝฟ็จ `https://www.googleapis.com/auth/drive`
-!!! info
- ๅจ OAuth2 ไธญใไฝ็จๅใๅชๆฏไธไธชๅฃฐๆๆ้็นๅฎๆ้็ๅญ็ฌฆไธฒใ
+!!! info "่ฏดๆ"
- ๅฎๆๆฒกๆ `:` ่ฟๆ ท็ๅ
ถไปๅญ็ฌฆๆ่
ๆฏไธๆฏ URL ้ฝๆฒกๆๅ
ณ็ณปใ
+ OAuth2 ไธญ๏ผ**ไฝ็จๅ**ๅชๆฏๅฃฐๆๆๅฎๆ้็ๅญ็ฌฆไธฒใ
- ่ฟไบ็ป่ๆฏๅ
ทไฝ็ๅฎ็ฐใ
+ ๆฏๅฆไฝฟ็จๅๅท `:` ็ญ็ฌฆๅท๏ผๆๆฏไธๆฏ URL ๅนถไธ้่ฆใ
- ๅฏน OAuth2 ๆฅ่ฏดๅฎไปฌๅฐฑๅชๆฏๅญ็ฌฆไธฒ่ๅทฒใ
+ ่ฟไบ็ป่ๅชๆฏ็นๅฎ็ๅฎ็ฐๆนๅผใ
+
+ ๅฏน OAuth2 ๆฅ่ฏด๏ผ้ฝๅชๆฏๅญ็ฌฆไธฒ่ๅทฒใ
## ่ทๅ `username` ๅ `password` ็ไปฃ็
-็ฐๅจ๏ผ่ฎฉๆไปฌไฝฟ็จ **FastAPI** ๆไพ็ๅฎ็จๅทฅๅ
ทๆฅๅค็ๆญค้ฎ้ขใ
+ๆฅไธๆฅ๏ผไฝฟ็จ **FastAPI** ๅทฅๅ
ท่ทๅ็จๆทๅไธๅฏ็ ใ
### `OAuth2PasswordRequestForm`
-้ฆๅ
๏ผๅฏผๅ
ฅ `OAuth2PasswordRequestForm`๏ผ็ถๅๅจ `token` ็*่ทฏๅพๆไฝ*ไธญ้่ฟ `Depends` ๅฐๅ
ถไฝไธบไพ่ต้กนไฝฟ็จใ
+้ฆๅ
๏ผๅฏผๅ
ฅ `OAuth2PasswordRequestForm`๏ผ็ถๅ๏ผๅจ `/token` *่ทฏๅพๆไฝ* ไธญ๏ผ็จ `Depends` ๆ่ฏฅ็ฑปไฝไธบไพ่ต้กนใ
```Python hl_lines="4 76"
{!../../../docs_src/security/tutorial003.py!}
```
-`OAuth2PasswordRequestForm` ๆฏไธไธช็ฑปไพ่ต้กน๏ผๅฃฐๆไบๅฆไธ็่ฏทๆฑ่กจๅ๏ผ
+`OAuth2PasswordRequestForm` ๆฏ็จไปฅไธๅ ้กนๅ
ๅฎนๅฃฐๆ่กจๅ่ฏทๆฑไฝ็็ฑปไพ่ต้กน๏ผ
-* `username`ใ
-* `password`ใ
-* ไธไธชๅฏ้็ `scope` ๅญๆฎต๏ผๆฏไธไธช็ฑ็ฉบๆ ผๅ้็ๅญ็ฌฆไธฒ็ปๆ็ๅคงๅญ็ฌฆไธฒใ
-* ไธไธชๅฏ้็ `grant_type`.
+* `username`
+* `password`
+* ๅฏ้็ `scope` ๅญๆฎต๏ผ็ฑๅคไธช็ฉบๆ ผๅ้็ๅญ็ฌฆไธฒ็ปๆ็้ฟๅญ็ฌฆไธฒ
+* ๅฏ้็ `grant_type`
-!!! tip
- OAuth2 ่ง่ๅฎ้
ไธ*่ฆๆฑ* `grant_type` ๅญๆฎตไฝฟ็จไธไธชๅบๅฎ็ๅผ `password`๏ผไฝๆฏ `OAuth2PasswordRequestForm` ๆฒกๆไฝๅผบๅถ็บฆๆใ
+!!! tip "ๆ็คบ"
- ๅฆๆไฝ ้่ฆๅผบๅถ่ฆๆฑ่ฟไธ็น๏ผ่ฏทไฝฟ็จ `OAuth2PasswordRequestFormStrict` ่ไธๆฏ `OAuth2PasswordRequestForm`ใ
+ ๅฎ้
ไธ๏ผOAuth2 ่ง่*่ฆๆฑ* `grant_type` ๅญๆฎตไฝฟ็จๅบๅฎๅผ `password`๏ผไฝ `OAuth2PasswordRequestForm` ๆฒกๆไฝๅผบๅถ็บฆๆใ
-* ไธไธชๅฏ้็ `client_id`๏ผๆไปฌ็็คบไพไธ้่ฆๅฎ๏ผใ
-* ไธไธชๅฏ้็ `client_secret`๏ผๆไปฌ็็คบไพไธ้่ฆๅฎ๏ผใ
+ ๅฆ้ๅผบๅถไฝฟ็จๅบๅฎๅผ `password`๏ผๅไธ่ฆ็จ `OAuth2PasswordRequestForm`๏ผ่ๆฏ็จ `OAuth2PasswordRequestFormStrict`ใ
-!!! info
- `OAuth2PasswordRequestForm` ๅนถไธๅ `OAuth2PasswordBearer` ไธๆ ทๆฏ FastAPI ็ไธไธช็นๆฎ็็ฑปใ
+* ๅฏ้็ `client_id`๏ผๆฌไพๆชไฝฟ็จ๏ผ
+* ๅฏ้็ `client_secret`๏ผๆฌไพๆชไฝฟ็จ๏ผ
- `OAuth2PasswordBearer` ไฝฟๅพ **FastAPI** ๆ็ฝๅฎๆฏไธไธชๅฎๅ
จๆนๆกใๆไปฅๅฎๅพไปฅ้่ฟ่ฟ็งๆนๅผๆทปๅ ๅฐ OpenAPI ไธญใ
+!!! info "่ฏดๆ"
- ไฝ `OAuth2PasswordRequestForm` ๅชๆฏไธไธชไฝ ๅฏไปฅ่ชๅทฑ็ผๅ็็ฑปไพ่ต้กน๏ผๆ่
ไฝ ไนๅฏไปฅ็ดๆฅๅฃฐๆ `Form` ๅๆฐใ
+ `OAuth2PasswordRequestForm` ไธ `OAuth2PasswordBearer` ไธๆ ท๏ผ้ฝไธๆฏ FastAPI ็็นๆฎ็ฑปใ
- ไฝๆฏ็ฑไบ่ฟๆฏไธ็งๅธธ่ง็ไฝฟ็จๅบๆฏ๏ผๅ ๆญค FastAPI ๅบไบ็ฎไพฟ็ดๆฅๆไพไบๅฎใ
+ **FastAPI** ๆ `OAuth2PasswordBearer` ่ฏๅซไธบๅฎๅ
จๆนๆกใๅ ๆญค๏ผๅฏไปฅ้่ฟ่ฟ็งๆนๅผๆๅฎๆทปๅ ่ณ OpenAPIใ
+
+ ไฝ `OAuth2PasswordRequestForm` ๅชๆฏๅฏไปฅ่ช่ก็ผๅ็็ฑปไพ่ต้กน๏ผไนๅฏไปฅ็ดๆฅๅฃฐๆ `Form` ๅๆฐใ
+
+ ไฝ็ฑไบ่ฟ็ง็จไพๅพๅธธ่ง๏ผFastAPI ไธบไบ็ฎไพฟ๏ผๅฐฑ็ดๆฅๆไพไบๅฏนๅฎ็ๆฏๆใ
### ไฝฟ็จ่กจๅๆฐๆฎ
-!!! tip
- ็ฑปไพ่ต้กน `OAuth2PasswordRequestForm` ็ๅฎไพไธไผๆ็จ็ฉบๆ ผๅ้็้ฟๅญ็ฌฆไธฒๅฑๆง `scope`๏ผ่ๆฏๅ
ทๆไธไธช `scopes` ๅฑๆง๏ผ่ฏฅๅฑๆงๅฐๅ
ๅซๅฎ้
่ขซๅ้็ๆฏไธชไฝ็จๅๅญ็ฌฆไธฒ็ปๆ็ๅ่กจใ
+!!! tip "ๆ็คบ"
- ๅจๆญค็คบไพไธญๆไปฌๆฒกๆไฝฟ็จ `scopes`๏ผไฝๅฆๆไฝ ้่ฆ็่ฏๅฏไปฅไฝฟ็จ่ฏฅๅ่ฝใ
+ `OAuth2PasswordRequestForm` ็ฑปไพ่ต้กน็ๅฎไพๆฒกๆไปฅ็ฉบๆ ผๅ้็้ฟๅญ็ฌฆไธฒๅฑๆง `scope`๏ผไฝๅฎๆฏๆ `scopes` ๅฑๆง๏ผ็ฑๅทฒๅ้็ scope ๅญ็ฌฆไธฒๅ่กจ็ปๆใ
-็ฐๅจ๏ผไฝฟ็จ่กจๅๅญๆฎตไธญ็ `username` ไป๏ผไผช๏ผๆฐๆฎๅบไธญ่ทๅ็จๆทๆฐๆฎใ
+ ๆฌไพๆฒกๆไฝฟ็จ `scopes`๏ผไฝๅผๅ่
ไนๅฏไปฅๆ นๆฎ้่ฆไฝฟ็จ่ฏฅๅฑๆงใ
-ๅฆๆๆฒกๆ่ฟไธช็จๆท๏ผๆไปฌๅฐ่ฟๅไธไธช้่ฏฏๆถๆฏ๏ผๆ็คบใ็จๆทๅๆๅฏ็ ้่ฏฏใใ
+็ฐๅจ๏ผๅณๅฏไฝฟ็จ่กจๅๅญๆฎต `username`๏ผไป๏ผไผช๏ผๆฐๆฎๅบไธญ่ทๅ็จๆทๆฐๆฎใ
-ๅฏนไบ่ฟไธช้่ฏฏ๏ผๆไปฌไฝฟ็จ `HTTPException` ๅผๅธธ๏ผ
+ๅฆๆไธๅญๅจๆๅฎ็จๆท๏ผๅ่ฟๅ้่ฏฏๆถๆฏ๏ผๆ็คบ**็จๆทๅๆๅฏ็ ้่ฏฏ**ใ
+
+ๆฌไพไฝฟ็จ `HTTPException` ๅผๅธธๆพ็คบๆญค้่ฏฏ๏ผ
```Python hl_lines="3 77-79"
{!../../../docs_src/security/tutorial003.py!}
@@ -96,27 +100,27 @@ OAuth2 ่งๅฎๅจไฝฟ็จ๏ผๆไปฌๆ็ฎ็จ็๏ผใpassword ๆต็จใๆถ๏ผๅฎขๆท
### ๆ ก้ชๅฏ็
-็ฎๅๆไปฌๅทฒ็ปไปๆฐๆฎๅบไธญ่ทๅไบ็จๆทๆฐๆฎ๏ผไฝๅฐๆชๆ ก้ชๅฏ็ ใ
+่ณๆญค๏ผๆไปฌๅทฒ็ปไปๆฐๆฎๅบไธญ่ทๅไบ็จๆทๆฐๆฎ๏ผไฝๅฐๆชๆ ก้ชๅฏ็ ใ
-่ฎฉๆไปฌ้ฆๅ
ๅฐ่ฟไบๆฐๆฎๆพๅ
ฅ Pydantic `UserInDB` ๆจกๅไธญใ
+ๆฅไธๆฅ๏ผ้ฆๅ
ๅฐๆฐๆฎๆพๅ
ฅ Pydantic ็ `UserInDB` ๆจกๅใ
-ๆฐธ่ฟไธ่ฆไฟๅญๆๆๅฏ็ ๏ผๅ ๆญค๏ผๆไปฌๅฐไฝฟ็จ๏ผไผช๏ผๅๅธๅฏ็ ็ณป็ปใ
+ๆณจๆ๏ผๆฐธ่ฟไธ่ฆไฟๅญๆๆๅฏ็ ๏ผๆฌไพๆๆถๅ
ไฝฟ็จ๏ผไผช๏ผๅๅธๅฏ็ ็ณป็ปใ
-ๅฆๆๅฏ็ ไธๅน้
๏ผๆไปฌๅฐ่ฟๅๅไธไธช้่ฏฏใ
+ๅฆๆๅฏ็ ไธๅน้
๏ผๅ่ฟๅไธไธ้ข็ธๅ็้่ฏฏใ
-#### ๅๅธๅฏ็
+#### ๅฏ็ ๅๅธ
-ใๅๅธใ็ๆๆๆฏ๏ผๅฐๆไบๅ
ๅฎน๏ผๅจๆฌไพไธญไธบๅฏ็ ๏ผ่ฝฌๆขไธบ็่ตทๆฅๅไนฑ็ ็ๅญ่ๅบๅ๏ผๅชๆฏไธไธชๅญ็ฌฆไธฒ๏ผใ
+**ๅๅธ**ๆฏๆ๏ผๅฐๆๅฎๅ
ๅฎน๏ผๆฌไพไธญไธบๅฏ็ ๏ผ่ฝฌๆขไธบๅฝขไผผไนฑ็ ็ๅญ่ๅบๅ๏ผๅ
ถๅฎๅฐฑๆฏๅญ็ฌฆไธฒ๏ผใ
-ๆฏๆฌกไฝ ไผ ๅ
ฅๅฎๅ
จ็ธๅ็ๅ
ๅฎน๏ผๅฎๅ
จ็ธๅ็ๅฏ็ ๏ผๆถ๏ผไฝ ้ฝไผๅพๅฐๅฎๅ
จ็ธๅ็ไนฑ็ ใ
+ๆฏๆฌกไผ ๅ
ฅๅฎๅ
จ็ธๅ็ๅ
ๅฎน๏ผๆฏๅฆ๏ผๅฎๅ
จ็ธๅ็ๅฏ็ ๏ผๆถ๏ผๅพๅฐ็้ฝๆฏๅฎๅ
จ็ธๅ็ไนฑ็ ใ
-ไฝๆฏไฝ ไธ่ฝไปไนฑ็ ่ฝฌๆขๅๅฏ็ ใ
+ไฝ่ฟไธชไนฑ็ ๆ ๆณ่ฝฌๆขๅไผ ๅ
ฅ็ๅฏ็ ใ
-##### ไธบไปไนไฝฟ็จๅๅธๅฏ็
+##### ไธบไปไนไฝฟ็จๅฏ็ ๅๅธ
-ๅฆๆไฝ ็ๆฐๆฎๅบ่ขซ็๏ผๅฐๅทๅฐๆ ๆณ่ทๅพ็จๆท็ๆๆๅฏ็ ๏ผๅชๆๅๅธๅผใ
+ๅๅ ๅพ็ฎๅ๏ผๅๅฆๆฐๆฎๅบ่ขซ็๏ผ็ช่ดผๆ ๆณ่ทๅ็จๆท็ๆๆๅฏ็ ๏ผๅพๅฐ็ๅชๆฏๅๅธๅผใ
-ๅ ๆญค๏ผๅฐๅทๅฐๆ ๆณๅฐ่ฏๅจๅฆไธไธช็ณป็ปไธญไฝฟ็จ่ฟไบ็ธๅ็ๅฏ็ ๏ผ็ฑไบ่ฎธๅค็จๆทๅจไปปไฝๅฐๆน้ฝไฝฟ็จ็ธๅ็ๅฏ็ ๏ผๅ ๆญค่ฟๅพๅฑ้ฉ๏ผใ
+่ฟๆ ทไธๆฅ๏ผ็ช่ดผๅฐฑๆ ๆณๅจๅ
ถๅฎๅบ็จไธญไฝฟ็จ็ชๅ็ๅฏ็ ๏ผ่ฆ็ฅ้๏ผๅพๅค็จๆทๅจๆๆ็ณป็ปไธญ้ฝไฝฟ็จ็ธๅ็ๅฏ็ ๏ผ้ฃ้ฉ่ถ
ๅคงใ
```Python hl_lines="80-83"
{!../../../docs_src/security/tutorial003.py!}
@@ -124,9 +128,9 @@ OAuth2 ่งๅฎๅจไฝฟ็จ๏ผๆไปฌๆ็ฎ็จ็๏ผใpassword ๆต็จใๆถ๏ผๅฎขๆท
#### ๅ
ณไบ `**user_dict`
-`UserInDB(**user_dict)` ่กจ็คบ๏ผ
+`UserInDB(**user_dict)` ๆฏๆ๏ผ
-*็ดๆฅๅฐ `user_dict` ็้ฎๅๅผไฝไธบๅ
ณ้ฎๅญๅๆฐไผ ้๏ผ็ญๅไบ๏ผ*
+*็ดๆฅๆ `user_dict` ็้ฎไธๅผๅฝไฝๅ
ณ้ฎๅญๅๆฐไผ ้๏ผ็ญๆไบ๏ผ*
```Python
UserInDB(
@@ -138,75 +142,79 @@ UserInDB(
)
```
-!!! info
- ๆๅ
ณ `user_dict` ็ๆดๅฎๆด่ฏดๆ๏ผ่ฏทๅ้
[**้ขๅค็ๆจกๅ**ๆๆกฃ](../extra-models.md#about-user_indict){.internal-link target=_blank}ใ
+!!! info "่ฏดๆ"
-## ่ฟๅไปค็
+ `user_dict` ็่ฏดๆ๏ผ่ฏฆ่ง[**ๆดๅคๆจกๅ**ไธ็ซ ](../extra-models.md#about-user_indict){.internal-link target=_blank}ใ
-`token` ็ซฏ็น็ๅๅบๅฟ
้กปๆฏไธไธช JSON ๅฏน่ฑกใ
+## ่ฟๅ Token
-ๅฎๅบ่ฏฅๆไธไธช `token_type`ใๅจๆไปฌ็ไพๅญไธญ๏ผ็ฑไบๆไปฌไฝฟ็จ็ๆฏใBearerใไปค็๏ผๅ ๆญคไปค็็ฑปๅๅบไธบใ`bearer`ใใ
+`token` ็ซฏ็น็ๅๅบๅฟ
้กปๆฏ JSON ๅฏน่ฑกใ
-ๅนถไธ่ฟๅบ่ฏฅๆไธไธช `access_token` ๅญๆฎต๏ผๅฎๆฏไธไธชๅ
ๅซๆไปฌ็่ฎฟ้ฎไปค็็ๅญ็ฌฆไธฒใ
+ๅๅบ่ฟๅ็ๅ
ๅฎนๅบ่ฏฅๅ
ๅซ `token_type`ใๆฌไพไธญ็จ็ๆฏ**Bearer**Token๏ผๅ ๆญค๏ผ Token ็ฑปๅๅบไธบ**`bearer`**ใ
-ๅฏนไบ่ฟไธช็ฎๅ็็คบไพ๏ผๆไปฌๅฐๆๅ
ถไธๅฎๅ
จๅฐ่ฟๅ็ธๅ็ `username` ไฝไธบไปค็ใ
+่ฟๅๅ
ๅฎน่ฟๅบๅ
ๅซ `access_token` ๅญๆฎต๏ผๅฎๆฏๅ
ๅซๆ้ Token ็ๅญ็ฌฆไธฒใ
-!!! tip
- ๅจไธไธ็ซ ไธญ๏ผไฝ ๅฐ็ๅฐไธไธช็ๅฎ็ๅฎๅ
จๅฎ็ฐ๏ผไฝฟ็จไบๅๅธๅฏ็ ๅ JWT ไปค็ใ
+ๆฌไพๅชๆฏ็ฎๅ็ๆผ็คบ๏ผ่ฟๅ็ Token ๅฐฑๆฏ `username`๏ผไฝ่ฟ็งๆนๅผๆไธๅฎๅ
จใ
- ไฝ็ฐๅจ๏ผ่ฎฉๆไปฌไป
ๅ
ณๆณจๆไปฌ้่ฆ็็นๅฎ็ป่ใ
+!!! tip "ๆ็คบ"
+
+ ไธไธ็ซ ไป็ปไฝฟ็จๅๅธๅฏ็ ๅ JWT Token ็็ๆญฃๅฎๅ
จๆบๅถใ
+
+ ไฝ็ฐๅจ๏ผไป
ๅ
ณๆณจๆ้็็นๅฎ็ป่ใ
```Python hl_lines="85"
{!../../../docs_src/security/tutorial003.py!}
```
-!!! tip
- ๆ นๆฎ่ง่๏ผไฝ ๅบ่ฏฅๅๆฌ็คบไพไธๆ ท๏ผ่ฟๅไธไธชๅธฆๆ `access_token` ๅ `token_type` ็ JSONใ
+!!! tip "ๆ็คบ"
- ่ฟๆฏไฝ ๅฟ
้กปๅจไปฃ็ ไธญ่ช่กๅฎๆ็ๅทฅไฝ๏ผๅนถไธ่ฆ็กฎไฟไฝฟ็จไบ่ฟไบ JSON ๅญๆฎตใ
+ ๆ่ง่็่ฆๆฑ๏ผๅบๅๆฌ็คบไพไธๆ ท๏ผ่ฟๅๅธฆๆ `access_token` ๅ `token_type` ็ JSON ๅฏน่ฑกใ
- ่ฟๅ ไนๆฏๅฏไธ็ไฝ ้่ฆ่ชๅทฑ่ฎฐไฝๅนถๆญฃ็กฎๅฐๆง่กไปฅ็ฌฆๅ่ง่็ไบๆ
ใ
+ ่ฟๆฏๅผๅ่
ๅฟ
้กปๅจไปฃ็ ไธญ่ช่กๅฎๆ็ๅทฅไฝ๏ผๅนถไธ่ฆ็กฎไฟไฝฟ็จ่ฟไบ JSON ็้ฎใ
- ๅ
ถไฝ็๏ผ**FastAPI** ้ฝไผไธบไฝ ๅค็ใ
+ ่ฟๅ ไนๆฏๅฏไธ้่ฆๅผๅ่
็ข่ฎฐๅจๅฟ๏ผๅนถๆ่ง่่ฆๆฑๆญฃ็กฎๆง่ก็ไบใ
+
+ **FastAPI** ๅ่ด่ดฃๅค็ๅ
ถๅฎ็ๅทฅไฝใ
## ๆดๆฐไพ่ต้กน
-็ฐๅจๆไปฌๅฐๆดๆฐๆไปฌ็ไพ่ต้กนใ
+ๆฅไธๆฅ๏ผๆดๆฐไพ่ต้กนใ
-ๆไปฌๆณ่ฆไป
ๅฝๆญค็จๆทๅคไบๅฏ็จ็ถๆๆถๆ่ฝ่ทๅ `current_user`ใ
+ไฝฟไนไป
ๅจๅฝๅ็จๆทไธบๆฟๆดป็ถๆๆถ๏ผๆ่ฝ่ทๅ `current_user`ใ
-ๅ ๆญค๏ผๆไปฌๅๅปบไบไธไธช้ขๅค็ไพ่ต้กน `get_current_active_user`๏ผ่่ฏฅไพ่ต้กนๅไปฅ `get_current_user` ไฝไธบไพ่ต้กนใ
+ไธบๆญค๏ผ่ฆๅๅๅปบไธไธชไพ่ต้กน `get_current_active_user`๏ผๆญคไพ่ต้กนไปฅ `get_current_user` ไพ่ต้กนไธบๅบ็กใ
-ๅฆๆ็จๆทไธๅญๅจๆๅคไบๆชๅฏ็จ็ถๆ๏ผๅ่ฟไธคไธชไพ่ต้กน้ฝๅฐไป
่ฟๅ HTTP ้่ฏฏใ
+ๅฆๆ็จๆทไธๅญๅจ๏ผๆ็ถๆไธบๆชๆฟๆดป๏ผ่ฟไธคไธชไพ่ต้กน้ฝไผ่ฟๅ HTTP ้่ฏฏใ
-ๅ ๆญค๏ผๅจๆไปฌ็็ซฏ็นไธญ๏ผๅชๆๅฝ็จๆทๅญๅจ๏ผ่บซไปฝ่ฎค่ฏ้่ฟไธๅคไบๅฏ็จ็ถๆๆถ๏ผๆไปฌๆ่ฝ่ทๅพ่ฏฅ็จๆท๏ผ
+ๅ ๆญค๏ผๅจ็ซฏ็นไธญ๏ผๅชๆๅฝ็จๆทๅญๅจใ้่ฟ่บซไปฝ้ช่ฏใไธ็ถๆไธบๆฟๆดปๆถ๏ผๆ่ฝ่ทๅพ่ฏฅ็จๆท๏ผ
```Python hl_lines="58-67 69-72 90"
{!../../../docs_src/security/tutorial003.py!}
```
-!!! info
- ๆไปฌๅจๆญคๅค่ฟๅ็ๅผไธบ `Bearer` ็้ขๅคๅๅบๅคด `WWW-Authenticate` ไนๆฏ่ง่็ไธ้จๅใ
+!!! info "่ฏดๆ"
- ไปปไฝ็ 401ใๆช่ฎค่ฏใHTTP๏ผ้่ฏฏ๏ผ็ถๆ็ ้ฝๅบ่ฏฅ่ฟๅ `WWW-Authenticate` ๅๅบๅคดใ
+ ๆญคๅค่ฟๅๅผไธบ `Bearer` ็ๅๅบๅคด `WWW-Authenticate` ไนๆฏ่ง่็ไธ้จๅใ
- ๅฏนไบ bearer ไปค็๏ผๆไปฌ็ไพๅญ๏ผ๏ผ่ฏฅๅๅบๅคด็ๅผๅบไธบ `Bearer`ใ
+ ไปปไฝ 401**UNAUTHORIZED**HTTP๏ผ้่ฏฏ๏ผ็ถๆ็ ้ฝๅบ่ฟๅ `WWW-Authenticate` ๅๅบๅคดใ
- ๅฎ้
ไธไฝ ๅฏไปฅๅฟฝ็ฅ่ฟไธช้ขๅค็ๅๅบๅคด๏ผไธไผๆไปไน้ฎ้ขใ
+ ๆฌไพไธญ๏ผๅ ไธบไฝฟ็จ็ๆฏ Bearer Token๏ผ่ฏฅๅๅบๅคด็ๅผๅบไธบ `Bearer`ใ
- ไฝๆญคๅคๆไพไบๅฎไปฅ็ฌฆๅ่ง่ใ
+ ๅฎ้
ไธ๏ผๅฟฝ็ฅ่ฟไธช้ๅ ๅๅบๅคด๏ผไนไธไผๆไปไน้ฎ้ขใ
- ่ไธ๏ผ๏ผ็ฐๅจๆๅฐๆฅ๏ผๅฏ่ฝไผๆๅทฅๅ
ทๆๆๅพๅฐๅนถไฝฟ็จๅฎ๏ผ็ถๅๅฏนไฝ ๆไฝ ็็จๆทๆ็จๅคใ
+ ไนๆไปฅๅจๆญคๆไพ่ฟไธช้ๅ ๅๅบๅคด๏ผๆฏไธบไบ็ฌฆๅ่ง่็่ฆๆฑใ
- ่ฟๅฐฑๆฏ้ตๅพชๆ ๅ็ๅฅฝๅค...
+ ่ฏดไธๅฎไปไนๆถๅ๏ผๅฐฑๆๅทฅๅ
ท็จๅพไธๅฎ๏ผ่ไธ๏ผๅผๅ่
ๆ็จๆทไนๅฏ่ฝ็จๅพไธใ
+
+ ่ฟๅฐฑๆฏ้ตๅพชๆ ๅ็ๅฅฝๅคโฆโฆ
## ๅฎ้
ๆๆ
-ๆๅผไบคไบๅผๆๆกฃ๏ผhttp://127.0.0.1:8000/docsใ
+ๆๅผ API ๆๆกฃ๏ผhttp://127.0.0.1:8000/docsใ
-### ่บซไปฝ่ฎค่ฏ
+### ่บซไปฝ้ช่ฏ
-็นๅปใAuthorizeใๆ้ฎใ
+็นๅป**Authorize**ๆ้ฎใ
ไฝฟ็จไปฅไธๅญ่ฏ๏ผ
@@ -216,15 +224,15 @@ UserInDB(
-ๅจ็ณป็ปไธญ่ฟ่ก่บซไปฝ่ฎค่ฏๅ๏ผไฝ ๅฐ็ๅฐ๏ผ
+้่ฟ่บซไปฝ้ช่ฏๅ๏ผๆพ็คบไธๅพๆ็คบ็ๅ
ๅฎน๏ผ
-### ่ทๅๆฌไบบ็็จๆทๆฐๆฎ
+### ่ทๅๅฝๅ็จๆทๆฐๆฎ
-็ฐๅจๆง่ก `/users/me` ่ทฏๅพ็ `GET` ๆไฝใ
+ไฝฟ็จ `/users/me` ่ทฏๅพ็ `GET` ๆไฝใ
-ไฝ ๅฐ่ทๅพไฝ ็็จๆทๆฐๆฎ๏ผๅฆ๏ผ
+ๅฏไปฅๆๅๅฆไธๅฝๅ็จๆทๆฐๆฎ๏ผ
```JSON
{
@@ -238,7 +246,7 @@ UserInDB(
-ๅฆๆไฝ ็นๅป้ๅฎๅพๆ ๅนถๆณจ้๏ผ็ถๅๅๆฌกๅฐ่ฏๅไธๆไฝ๏ผๅไผๅพๅฐ HTTP 401 ้่ฏฏ๏ผ
+็นๅปๅฐ้ๅพๆ ๏ผๆณจ้ๅ๏ผๅๆง่กๅๆ ท็ๆไฝ๏ผๅไผๅพๅฐ HTTP 401 ้่ฏฏ๏ผ
```JSON
{
@@ -246,17 +254,17 @@ UserInDB(
}
```
-### ๆชๅฏ็จ็็จๆท
+### ๆชๆฟๆดป็จๆท
-็ฐๅจๅฐ่ฏไฝฟ็จๆชๅฏ็จ็็จๆท๏ผๅนถ้่ฟไปฅไธๆนๅผ่ฟ่ก่บซไปฝ่ฎค่ฏ๏ผ
+ๆต่ฏๆชๆฟๆดป็จๆท๏ผ่พๅ
ฅไปฅไธไฟกๆฏ๏ผ่ฟ่ก่บซไปฝ้ช่ฏ๏ผ
็จๆทๅ๏ผ`alice`
ๅฏ็ ๏ผ`secret2`
-็ถๅๅฐ่ฏๆง่ก `/users/me` ่ทฏๅพ็ `GET` ๆไฝใ
+็ถๅ๏ผๆง่ก `/users/me` ่ทฏๅพ็ `GET` ๆไฝใ
-ไฝ ๅฐๅพๅฐไธไธชใๆชๅฏ็จ็็จๆทใ้่ฏฏ๏ผๅฆ๏ผ
+ๆพ็คบไธๅ**ๆชๆฟๆดป็จๆท**้่ฏฏไฟกๆฏ๏ผ
```JSON
{
@@ -264,12 +272,12 @@ UserInDB(
}
```
-## ๆป็ป
+## ๅฐ็ป
-็ฐๅจไฝ ๆๆกไบไธบไฝ ็ API ๅฎ็ฐไธไธชๅบไบ `username` ๅ `password` ็ๅฎๆดๅฎๅ
จ็ณป็ป็ๅทฅๅ
ทใ
+ไฝฟ็จๆฌ็ซ ็ๅทฅๅ
ทๅฎ็ฐๅบไบ `username` ๅ `password` ็ๅฎๆด API ๅฎๅ
จ็ณป็ปใ
-ไฝฟ็จ่ฟไบๅทฅๅ
ท๏ผไฝ ๅฏไปฅไฝฟๅฎๅ
จ็ณป็ปไธไปปไฝๆฐๆฎๅบไปฅๅไปปไฝ็จๆทๆๆฐๆฎๆจกๅๅ
ผๅฎนใ
+่ฟไบๅทฅๅ
ท่ฎฉๅฎๅ
จ็ณป็ปๅ
ผๅฎนไปปไฝๆฐๆฎๅบใ็จๆทๅๆฐๆฎๆจกๅใ
-ๅฏไธ็ผบๅฐ็็ป่ๆฏๅฎๅฎ้
ไธ่ฟๅนถไธใๅฎๅ
จใใ
+ๅฏไธๆฌ ็ผบ็ๆฏ๏ผๅฎไป็ถไธๆฏ็็**ๅฎๅ
จ**ใ
-ๅจไธไธ็ซ ไธญ๏ผไฝ ๅฐ็ๅฐๅฆไฝไฝฟ็จไธไธชๅฎๅ
จ็ๅๅธๅฏ็ ๅบๅ JWT ไปค็ใ
+ไธไธ็ซ ๏ผไป็ปไฝฟ็จๅฏ็ ๅๅธๆฏๆๅบไธ JWT ไปค็ๅฎ็ฐ็ๆญฃ็ๅฎๅ
จๆบๅถใ
diff --git a/docs/zh/docs/tutorial/sql-databases.md b/docs/zh/docs/tutorial/sql-databases.md
index 482588f94..8b09dc677 100644
--- a/docs/zh/docs/tutorial/sql-databases.md
+++ b/docs/zh/docs/tutorial/sql-databases.md
@@ -258,7 +258,7 @@ connect_args={"check_same_thread": False}
{!> ../../../docs_src/sql_databases/sql_app_py39/schemas.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="3 6-8 11-12 23-24 27-28"
{!> ../../../docs_src/sql_databases/sql_app/schemas.py!}
@@ -302,7 +302,7 @@ name: str
{!> ../../../docs_src/sql_databases/sql_app_py39/schemas.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="15-17 31-34"
{!> ../../../docs_src/sql_databases/sql_app/schemas.py!}
@@ -331,7 +331,7 @@ name: str
{!> ../../../docs_src/sql_databases/sql_app_py39/schemas.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="15 19-20 31 36-37"
{!> ../../../docs_src/sql_databases/sql_app/schemas.py!}
@@ -471,7 +471,7 @@ current_user.items
{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="9"
{!> ../../../docs_src/sql_databases/sql_app/main.py!}
@@ -505,7 +505,7 @@ current_user.items
{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="15-20"
{!> ../../../docs_src/sql_databases/sql_app/main.py!}
@@ -530,7 +530,7 @@ current_user.items
{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="24 32 38 47 53"
{!> ../../../docs_src/sql_databases/sql_app/main.py!}
@@ -551,7 +551,7 @@ current_user.items
{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="23-28 31-34 37-42 45-49 52-55"
{!> ../../../docs_src/sql_databases/sql_app/main.py!}
@@ -650,7 +650,7 @@ def read_user(user_id: int, db: Session = Depends(get_db)):
{!> ../../../docs_src/sql_databases/sql_app_py39/schemas.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python
{!> ../../../docs_src/sql_databases/sql_app/schemas.py!}
@@ -670,7 +670,7 @@ def read_user(user_id: int, db: Session = Depends(get_db)):
{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python
{!> ../../../docs_src/sql_databases/sql_app/main.py!}
@@ -729,7 +729,7 @@ $ uvicorn sql_app.main:app --reload
{!> ../../../docs_src/sql_databases/sql_app_py39/alt_main.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python hl_lines="14-22"
{!> ../../../docs_src/sql_databases/sql_app/alt_main.py!}
diff --git a/docs/zh/docs/tutorial/testing.md b/docs/zh/docs/tutorial/testing.md
index 41f01f8d8..77fff7596 100644
--- a/docs/zh/docs/tutorial/testing.md
+++ b/docs/zh/docs/tutorial/testing.md
@@ -122,7 +122,7 @@
{!> ../../../docs_src/app_testing/app_b_an_py39/main.py!}
```
-=== "Python 3.6+"
+=== "Python 3.8+"
```Python
{!> ../../../docs_src/app_testing/app_b_an/main.py!}
@@ -137,7 +137,7 @@
{!> ../../../docs_src/app_testing/app_b_py310/main.py!}
```
-=== "Python 3.6+ non-Annotated"
+=== "Python 3.8+ non-Annotated"
!!! tip
Prefer to use the `Annotated` version if possible.
diff --git a/docs_src/extending_openapi/tutorial003.py b/docs_src/configure_swagger_ui/tutorial001.py
similarity index 100%
rename from docs_src/extending_openapi/tutorial003.py
rename to docs_src/configure_swagger_ui/tutorial001.py
diff --git a/docs_src/extending_openapi/tutorial004.py b/docs_src/configure_swagger_ui/tutorial002.py
similarity index 100%
rename from docs_src/extending_openapi/tutorial004.py
rename to docs_src/configure_swagger_ui/tutorial002.py
diff --git a/docs_src/extending_openapi/tutorial005.py b/docs_src/configure_swagger_ui/tutorial003.py
similarity index 100%
rename from docs_src/extending_openapi/tutorial005.py
rename to docs_src/configure_swagger_ui/tutorial003.py
diff --git a/docs_src/custom_docs_ui/tutorial001.py b/docs_src/custom_docs_ui/tutorial001.py
new file mode 100644
index 000000000..4384433e3
--- /dev/null
+++ b/docs_src/custom_docs_ui/tutorial001.py
@@ -0,0 +1,38 @@
+from fastapi import FastAPI
+from fastapi.openapi.docs import (
+ get_redoc_html,
+ get_swagger_ui_html,
+ get_swagger_ui_oauth2_redirect_html,
+)
+
+app = FastAPI(docs_url=None, redoc_url=None)
+
+
+@app.get("/docs", include_in_schema=False)
+async def custom_swagger_ui_html():
+ return get_swagger_ui_html(
+ openapi_url=app.openapi_url,
+ title=app.title + " - Swagger UI",
+ oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
+ swagger_js_url="https://unpkg.com/swagger-ui-dist@5.9.0/swagger-ui-bundle.js",
+ swagger_css_url="https://unpkg.com/swagger-ui-dist@5.9.0/swagger-ui.css",
+ )
+
+
+@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
+async def swagger_ui_redirect():
+ return get_swagger_ui_oauth2_redirect_html()
+
+
+@app.get("/redoc", include_in_schema=False)
+async def redoc_html():
+ return get_redoc_html(
+ openapi_url=app.openapi_url,
+ title=app.title + " - ReDoc",
+ redoc_js_url="https://unpkg.com/redoc@next/bundles/redoc.standalone.js",
+ )
+
+
+@app.get("/users/{username}")
+async def read_user(username: str):
+ return {"message": f"Hello {username}"}
diff --git a/docs_src/extending_openapi/tutorial002.py b/docs_src/custom_docs_ui/tutorial002.py
similarity index 100%
rename from docs_src/extending_openapi/tutorial002.py
rename to docs_src/custom_docs_ui/tutorial002.py
diff --git a/docs_src/header_params/tutorial002_an.py b/docs_src/header_params/tutorial002_an.py
index 65d972d46..82fe49ba2 100644
--- a/docs_src/header_params/tutorial002_an.py
+++ b/docs_src/header_params/tutorial002_an.py
@@ -10,6 +10,6 @@ app = FastAPI()
async def read_items(
strange_header: Annotated[
Union[str, None], Header(convert_underscores=False)
- ] = None
+ ] = None,
):
return {"strange_header": strange_header}
diff --git a/docs_src/header_params/tutorial002_an_py39.py b/docs_src/header_params/tutorial002_an_py39.py
index 7f6a99f9c..008e4b6e1 100644
--- a/docs_src/header_params/tutorial002_an_py39.py
+++ b/docs_src/header_params/tutorial002_an_py39.py
@@ -9,6 +9,6 @@ app = FastAPI()
async def read_items(
strange_header: Annotated[
Union[str, None], Header(convert_underscores=False)
- ] = None
+ ] = None,
):
return {"strange_header": strange_header}
diff --git a/docs_src/openapi_webhooks/tutorial001.py b/docs_src/openapi_webhooks/tutorial001.py
index 5016f5b00..55822bb48 100644
--- a/docs_src/openapi_webhooks/tutorial001.py
+++ b/docs_src/openapi_webhooks/tutorial001.py
@@ -8,7 +8,7 @@ app = FastAPI()
class Subscription(BaseModel):
username: str
- montly_fee: float
+ monthly_fee: float
start_date: datetime
diff --git a/docs_src/python_types/tutorial011.py b/docs_src/python_types/tutorial011.py
index c8634cbff..297a84db6 100644
--- a/docs_src/python_types/tutorial011.py
+++ b/docs_src/python_types/tutorial011.py
@@ -6,7 +6,7 @@ from pydantic import BaseModel
class User(BaseModel):
id: int
- name = "John Doe"
+ name: str = "John Doe"
signup_ts: Union[datetime, None] = None
friends: List[int] = []
diff --git a/docs_src/python_types/tutorial011_py310.py b/docs_src/python_types/tutorial011_py310.py
index 7f173880f..842760c60 100644
--- a/docs_src/python_types/tutorial011_py310.py
+++ b/docs_src/python_types/tutorial011_py310.py
@@ -5,7 +5,7 @@ from pydantic import BaseModel
class User(BaseModel):
id: int
- name = "John Doe"
+ name: str = "John Doe"
signup_ts: datetime | None = None
friends: list[int] = []
diff --git a/docs_src/python_types/tutorial011_py39.py b/docs_src/python_types/tutorial011_py39.py
index 468496f51..4eb40b405 100644
--- a/docs_src/python_types/tutorial011_py39.py
+++ b/docs_src/python_types/tutorial011_py39.py
@@ -6,7 +6,7 @@ from pydantic import BaseModel
class User(BaseModel):
id: int
- name = "John Doe"
+ name: str = "John Doe"
signup_ts: Union[datetime, None] = None
friends: list[int] = []
diff --git a/docs_src/query_params_str_validations/tutorial004.py b/docs_src/query_params_str_validations/tutorial004.py
index 3639b6c38..64a647a16 100644
--- a/docs_src/query_params_str_validations/tutorial004.py
+++ b/docs_src/query_params_str_validations/tutorial004.py
@@ -9,7 +9,7 @@ app = FastAPI()
async def read_items(
q: Union[str, None] = Query(
default=None, min_length=3, max_length=50, pattern="^fixedquery$"
- )
+ ),
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
diff --git a/docs_src/query_params_str_validations/tutorial004_an.py b/docs_src/query_params_str_validations/tutorial004_an.py
index 24698c7b3..c75d45d63 100644
--- a/docs_src/query_params_str_validations/tutorial004_an.py
+++ b/docs_src/query_params_str_validations/tutorial004_an.py
@@ -10,7 +10,7 @@ app = FastAPI()
async def read_items(
q: Annotated[
Union[str, None], Query(min_length=3, max_length=50, pattern="^fixedquery$")
- ] = None
+ ] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
diff --git a/docs_src/query_params_str_validations/tutorial004_an_py310.py b/docs_src/query_params_str_validations/tutorial004_an_py310.py
index b7b629ee8..20cf1988f 100644
--- a/docs_src/query_params_str_validations/tutorial004_an_py310.py
+++ b/docs_src/query_params_str_validations/tutorial004_an_py310.py
@@ -9,7 +9,7 @@ app = FastAPI()
async def read_items(
q: Annotated[
str | None, Query(min_length=3, max_length=50, pattern="^fixedquery$")
- ] = None
+ ] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
diff --git a/docs_src/query_params_str_validations/tutorial004_an_py310_regex.py b/docs_src/query_params_str_validations/tutorial004_an_py310_regex.py
index 8fd375b3d..21e0d3eb8 100644
--- a/docs_src/query_params_str_validations/tutorial004_an_py310_regex.py
+++ b/docs_src/query_params_str_validations/tutorial004_an_py310_regex.py
@@ -9,7 +9,7 @@ app = FastAPI()
async def read_items(
q: Annotated[
str | None, Query(min_length=3, max_length=50, regex="^fixedquery$")
- ] = None
+ ] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
diff --git a/docs_src/query_params_str_validations/tutorial004_an_py39.py b/docs_src/query_params_str_validations/tutorial004_an_py39.py
index 8e9a6fc32..de27097b3 100644
--- a/docs_src/query_params_str_validations/tutorial004_an_py39.py
+++ b/docs_src/query_params_str_validations/tutorial004_an_py39.py
@@ -9,7 +9,7 @@ app = FastAPI()
async def read_items(
q: Annotated[
Union[str, None], Query(min_length=3, max_length=50, pattern="^fixedquery$")
- ] = None
+ ] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
diff --git a/docs_src/query_params_str_validations/tutorial004_py310.py b/docs_src/query_params_str_validations/tutorial004_py310.py
index f80798bcb..7801e7500 100644
--- a/docs_src/query_params_str_validations/tutorial004_py310.py
+++ b/docs_src/query_params_str_validations/tutorial004_py310.py
@@ -5,8 +5,9 @@ app = FastAPI()
@app.get("/items/")
async def read_items(
- q: str
- | None = Query(default=None, min_length=3, max_length=50, pattern="^fixedquery$")
+ q: str | None = Query(
+ default=None, min_length=3, max_length=50, pattern="^fixedquery$"
+ ),
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
diff --git a/docs_src/query_params_str_validations/tutorial008.py b/docs_src/query_params_str_validations/tutorial008.py
index d112a9ab8..e3e0b50aa 100644
--- a/docs_src/query_params_str_validations/tutorial008.py
+++ b/docs_src/query_params_str_validations/tutorial008.py
@@ -12,7 +12,7 @@ async def read_items(
title="Query string",
description="Query string for the items to search in the database that have a good match",
min_length=3,
- )
+ ),
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
diff --git a/docs_src/query_params_str_validations/tutorial008_an.py b/docs_src/query_params_str_validations/tutorial008_an.py
index 5699f1e88..01606a920 100644
--- a/docs_src/query_params_str_validations/tutorial008_an.py
+++ b/docs_src/query_params_str_validations/tutorial008_an.py
@@ -15,7 +15,7 @@ async def read_items(
description="Query string for the items to search in the database that have a good match",
min_length=3,
),
- ] = None
+ ] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
diff --git a/docs_src/query_params_str_validations/tutorial008_an_py310.py b/docs_src/query_params_str_validations/tutorial008_an_py310.py
index 4aaadf8b4..44b3082b6 100644
--- a/docs_src/query_params_str_validations/tutorial008_an_py310.py
+++ b/docs_src/query_params_str_validations/tutorial008_an_py310.py
@@ -14,7 +14,7 @@ async def read_items(
description="Query string for the items to search in the database that have a good match",
min_length=3,
),
- ] = None
+ ] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
diff --git a/docs_src/query_params_str_validations/tutorial008_an_py39.py b/docs_src/query_params_str_validations/tutorial008_an_py39.py
index 1c3b36176..f3f2f2c0e 100644
--- a/docs_src/query_params_str_validations/tutorial008_an_py39.py
+++ b/docs_src/query_params_str_validations/tutorial008_an_py39.py
@@ -14,7 +14,7 @@ async def read_items(
description="Query string for the items to search in the database that have a good match",
min_length=3,
),
- ] = None
+ ] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
diff --git a/docs_src/query_params_str_validations/tutorial008_py310.py b/docs_src/query_params_str_validations/tutorial008_py310.py
index 489f631d5..574385272 100644
--- a/docs_src/query_params_str_validations/tutorial008_py310.py
+++ b/docs_src/query_params_str_validations/tutorial008_py310.py
@@ -5,13 +5,12 @@ app = FastAPI()
@app.get("/items/")
async def read_items(
- q: str
- | None = Query(
+ q: str | None = Query(
default=None,
title="Query string",
description="Query string for the items to search in the database that have a good match",
min_length=3,
- )
+ ),
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
diff --git a/docs_src/query_params_str_validations/tutorial010.py b/docs_src/query_params_str_validations/tutorial010.py
index 3314f8b6d..ff29176fe 100644
--- a/docs_src/query_params_str_validations/tutorial010.py
+++ b/docs_src/query_params_str_validations/tutorial010.py
@@ -16,7 +16,7 @@ async def read_items(
max_length=50,
pattern="^fixedquery$",
deprecated=True,
- )
+ ),
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
diff --git a/docs_src/query_params_str_validations/tutorial010_an.py b/docs_src/query_params_str_validations/tutorial010_an.py
index c5df00897..ed343230f 100644
--- a/docs_src/query_params_str_validations/tutorial010_an.py
+++ b/docs_src/query_params_str_validations/tutorial010_an.py
@@ -19,7 +19,7 @@ async def read_items(
pattern="^fixedquery$",
deprecated=True,
),
- ] = None
+ ] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
diff --git a/docs_src/query_params_str_validations/tutorial010_an_py310.py b/docs_src/query_params_str_validations/tutorial010_an_py310.py
index a8e8c099b..775095bda 100644
--- a/docs_src/query_params_str_validations/tutorial010_an_py310.py
+++ b/docs_src/query_params_str_validations/tutorial010_an_py310.py
@@ -18,7 +18,7 @@ async def read_items(
pattern="^fixedquery$",
deprecated=True,
),
- ] = None
+ ] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
diff --git a/docs_src/query_params_str_validations/tutorial010_an_py39.py b/docs_src/query_params_str_validations/tutorial010_an_py39.py
index 955880dd6..b126c116f 100644
--- a/docs_src/query_params_str_validations/tutorial010_an_py39.py
+++ b/docs_src/query_params_str_validations/tutorial010_an_py39.py
@@ -18,7 +18,7 @@ async def read_items(
pattern="^fixedquery$",
deprecated=True,
),
- ] = None
+ ] = None,
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
diff --git a/docs_src/query_params_str_validations/tutorial010_py310.py b/docs_src/query_params_str_validations/tutorial010_py310.py
index 9ea7b3c49..530e6cf5b 100644
--- a/docs_src/query_params_str_validations/tutorial010_py310.py
+++ b/docs_src/query_params_str_validations/tutorial010_py310.py
@@ -5,8 +5,7 @@ app = FastAPI()
@app.get("/items/")
async def read_items(
- q: str
- | None = Query(
+ q: str | None = Query(
default=None,
alias="item-query",
title="Query string",
@@ -15,7 +14,7 @@ async def read_items(
max_length=50,
pattern="^fixedquery$",
deprecated=True,
- )
+ ),
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
diff --git a/docs_src/schema_extra_example/tutorial005.py b/docs_src/schema_extra_example/tutorial005.py
new file mode 100644
index 000000000..b8217c27e
--- /dev/null
+++ b/docs_src/schema_extra_example/tutorial005.py
@@ -0,0 +1,51 @@
+from typing import Union
+
+from fastapi import Body, FastAPI
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+ name: str
+ description: Union[str, None] = None
+ price: float
+ tax: Union[float, None] = None
+
+
+@app.put("/items/{item_id}")
+async def update_item(
+ *,
+ item_id: int,
+ item: Item = Body(
+ openapi_examples={
+ "normal": {
+ "summary": "A normal example",
+ "description": "A **normal** item works correctly.",
+ "value": {
+ "name": "Foo",
+ "description": "A very nice Item",
+ "price": 35.4,
+ "tax": 3.2,
+ },
+ },
+ "converted": {
+ "summary": "An example with converted data",
+ "description": "FastAPI can convert price `strings` to actual `numbers` automatically",
+ "value": {
+ "name": "Bar",
+ "price": "35.4",
+ },
+ },
+ "invalid": {
+ "summary": "Invalid data is rejected with an error",
+ "value": {
+ "name": "Baz",
+ "price": "thirty five point four",
+ },
+ },
+ },
+ ),
+):
+ results = {"item_id": item_id, "item": item}
+ return results
diff --git a/docs_src/schema_extra_example/tutorial005_an.py b/docs_src/schema_extra_example/tutorial005_an.py
new file mode 100644
index 000000000..4b2d9c662
--- /dev/null
+++ b/docs_src/schema_extra_example/tutorial005_an.py
@@ -0,0 +1,55 @@
+from typing import Union
+
+from fastapi import Body, FastAPI
+from pydantic import BaseModel
+from typing_extensions import Annotated
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+ name: str
+ description: Union[str, None] = None
+ price: float
+ tax: Union[float, None] = None
+
+
+@app.put("/items/{item_id}")
+async def update_item(
+ *,
+ item_id: int,
+ item: Annotated[
+ Item,
+ Body(
+ openapi_examples={
+ "normal": {
+ "summary": "A normal example",
+ "description": "A **normal** item works correctly.",
+ "value": {
+ "name": "Foo",
+ "description": "A very nice Item",
+ "price": 35.4,
+ "tax": 3.2,
+ },
+ },
+ "converted": {
+ "summary": "An example with converted data",
+ "description": "FastAPI can convert price `strings` to actual `numbers` automatically",
+ "value": {
+ "name": "Bar",
+ "price": "35.4",
+ },
+ },
+ "invalid": {
+ "summary": "Invalid data is rejected with an error",
+ "value": {
+ "name": "Baz",
+ "price": "thirty five point four",
+ },
+ },
+ },
+ ),
+ ],
+):
+ results = {"item_id": item_id, "item": item}
+ return results
diff --git a/docs_src/schema_extra_example/tutorial005_an_py310.py b/docs_src/schema_extra_example/tutorial005_an_py310.py
new file mode 100644
index 000000000..64dc2cf90
--- /dev/null
+++ b/docs_src/schema_extra_example/tutorial005_an_py310.py
@@ -0,0 +1,54 @@
+from typing import Annotated
+
+from fastapi import Body, FastAPI
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+ name: str
+ description: str | None = None
+ price: float
+ tax: float | None = None
+
+
+@app.put("/items/{item_id}")
+async def update_item(
+ *,
+ item_id: int,
+ item: Annotated[
+ Item,
+ Body(
+ openapi_examples={
+ "normal": {
+ "summary": "A normal example",
+ "description": "A **normal** item works correctly.",
+ "value": {
+ "name": "Foo",
+ "description": "A very nice Item",
+ "price": 35.4,
+ "tax": 3.2,
+ },
+ },
+ "converted": {
+ "summary": "An example with converted data",
+ "description": "FastAPI can convert price `strings` to actual `numbers` automatically",
+ "value": {
+ "name": "Bar",
+ "price": "35.4",
+ },
+ },
+ "invalid": {
+ "summary": "Invalid data is rejected with an error",
+ "value": {
+ "name": "Baz",
+ "price": "thirty five point four",
+ },
+ },
+ },
+ ),
+ ],
+):
+ results = {"item_id": item_id, "item": item}
+ return results
diff --git a/docs_src/schema_extra_example/tutorial005_an_py39.py b/docs_src/schema_extra_example/tutorial005_an_py39.py
new file mode 100644
index 000000000..edeb1affc
--- /dev/null
+++ b/docs_src/schema_extra_example/tutorial005_an_py39.py
@@ -0,0 +1,54 @@
+from typing import Annotated, Union
+
+from fastapi import Body, FastAPI
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+ name: str
+ description: Union[str, None] = None
+ price: float
+ tax: Union[float, None] = None
+
+
+@app.put("/items/{item_id}")
+async def update_item(
+ *,
+ item_id: int,
+ item: Annotated[
+ Item,
+ Body(
+ openapi_examples={
+ "normal": {
+ "summary": "A normal example",
+ "description": "A **normal** item works correctly.",
+ "value": {
+ "name": "Foo",
+ "description": "A very nice Item",
+ "price": 35.4,
+ "tax": 3.2,
+ },
+ },
+ "converted": {
+ "summary": "An example with converted data",
+ "description": "FastAPI can convert price `strings` to actual `numbers` automatically",
+ "value": {
+ "name": "Bar",
+ "price": "35.4",
+ },
+ },
+ "invalid": {
+ "summary": "Invalid data is rejected with an error",
+ "value": {
+ "name": "Baz",
+ "price": "thirty five point four",
+ },
+ },
+ },
+ ),
+ ],
+):
+ results = {"item_id": item_id, "item": item}
+ return results
diff --git a/docs_src/schema_extra_example/tutorial005_py310.py b/docs_src/schema_extra_example/tutorial005_py310.py
new file mode 100644
index 000000000..eef973343
--- /dev/null
+++ b/docs_src/schema_extra_example/tutorial005_py310.py
@@ -0,0 +1,49 @@
+from fastapi import Body, FastAPI
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+ name: str
+ description: str | None = None
+ price: float
+ tax: float | None = None
+
+
+@app.put("/items/{item_id}")
+async def update_item(
+ *,
+ item_id: int,
+ item: Item = Body(
+ openapi_examples={
+ "normal": {
+ "summary": "A normal example",
+ "description": "A **normal** item works correctly.",
+ "value": {
+ "name": "Foo",
+ "description": "A very nice Item",
+ "price": 35.4,
+ "tax": 3.2,
+ },
+ },
+ "converted": {
+ "summary": "An example with converted data",
+ "description": "FastAPI can convert price `strings` to actual `numbers` automatically",
+ "value": {
+ "name": "Bar",
+ "price": "35.4",
+ },
+ },
+ "invalid": {
+ "summary": "Invalid data is rejected with an error",
+ "value": {
+ "name": "Baz",
+ "price": "thirty five point four",
+ },
+ },
+ },
+ ),
+):
+ results = {"item_id": item_id, "item": item}
+ return results
diff --git a/docs_src/separate_openapi_schemas/tutorial001.py b/docs_src/separate_openapi_schemas/tutorial001.py
new file mode 100644
index 000000000..415eef8e2
--- /dev/null
+++ b/docs_src/separate_openapi_schemas/tutorial001.py
@@ -0,0 +1,28 @@
+from typing import List, Union
+
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+
+class Item(BaseModel):
+ name: str
+ description: Union[str, None] = None
+
+
+app = FastAPI()
+
+
+@app.post("/items/")
+def create_item(item: Item):
+ return item
+
+
+@app.get("/items/")
+def read_items() -> List[Item]:
+ return [
+ Item(
+ name="Portal Gun",
+ description="Device to travel through the multi-rick-verse",
+ ),
+ Item(name="Plumbus"),
+ ]
diff --git a/docs_src/separate_openapi_schemas/tutorial001_py310.py b/docs_src/separate_openapi_schemas/tutorial001_py310.py
new file mode 100644
index 000000000..289cb54ed
--- /dev/null
+++ b/docs_src/separate_openapi_schemas/tutorial001_py310.py
@@ -0,0 +1,26 @@
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+
+class Item(BaseModel):
+ name: str
+ description: str | None = None
+
+
+app = FastAPI()
+
+
+@app.post("/items/")
+def create_item(item: Item):
+ return item
+
+
+@app.get("/items/")
+def read_items() -> list[Item]:
+ return [
+ Item(
+ name="Portal Gun",
+ description="Device to travel through the multi-rick-verse",
+ ),
+ Item(name="Plumbus"),
+ ]
diff --git a/docs_src/separate_openapi_schemas/tutorial001_py39.py b/docs_src/separate_openapi_schemas/tutorial001_py39.py
new file mode 100644
index 000000000..63cffd1e3
--- /dev/null
+++ b/docs_src/separate_openapi_schemas/tutorial001_py39.py
@@ -0,0 +1,28 @@
+from typing import Optional
+
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+
+class Item(BaseModel):
+ name: str
+ description: Optional[str] = None
+
+
+app = FastAPI()
+
+
+@app.post("/items/")
+def create_item(item: Item):
+ return item
+
+
+@app.get("/items/")
+def read_items() -> list[Item]:
+ return [
+ Item(
+ name="Portal Gun",
+ description="Device to travel through the multi-rick-verse",
+ ),
+ Item(name="Plumbus"),
+ ]
diff --git a/docs_src/separate_openapi_schemas/tutorial002.py b/docs_src/separate_openapi_schemas/tutorial002.py
new file mode 100644
index 000000000..7df93783b
--- /dev/null
+++ b/docs_src/separate_openapi_schemas/tutorial002.py
@@ -0,0 +1,28 @@
+from typing import List, Union
+
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+
+class Item(BaseModel):
+ name: str
+ description: Union[str, None] = None
+
+
+app = FastAPI(separate_input_output_schemas=False)
+
+
+@app.post("/items/")
+def create_item(item: Item):
+ return item
+
+
+@app.get("/items/")
+def read_items() -> List[Item]:
+ return [
+ Item(
+ name="Portal Gun",
+ description="Device to travel through the multi-rick-verse",
+ ),
+ Item(name="Plumbus"),
+ ]
diff --git a/docs_src/separate_openapi_schemas/tutorial002_py310.py b/docs_src/separate_openapi_schemas/tutorial002_py310.py
new file mode 100644
index 000000000..5db210872
--- /dev/null
+++ b/docs_src/separate_openapi_schemas/tutorial002_py310.py
@@ -0,0 +1,26 @@
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+
+class Item(BaseModel):
+ name: str
+ description: str | None = None
+
+
+app = FastAPI(separate_input_output_schemas=False)
+
+
+@app.post("/items/")
+def create_item(item: Item):
+ return item
+
+
+@app.get("/items/")
+def read_items() -> list[Item]:
+ return [
+ Item(
+ name="Portal Gun",
+ description="Device to travel through the multi-rick-verse",
+ ),
+ Item(name="Plumbus"),
+ ]
diff --git a/docs_src/separate_openapi_schemas/tutorial002_py39.py b/docs_src/separate_openapi_schemas/tutorial002_py39.py
new file mode 100644
index 000000000..50d997d92
--- /dev/null
+++ b/docs_src/separate_openapi_schemas/tutorial002_py39.py
@@ -0,0 +1,28 @@
+from typing import Optional
+
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+
+class Item(BaseModel):
+ name: str
+ description: Optional[str] = None
+
+
+app = FastAPI(separate_input_output_schemas=False)
+
+
+@app.post("/items/")
+def create_item(item: Item):
+ return item
+
+
+@app.get("/items/")
+def read_items() -> list[Item]:
+ return [
+ Item(
+ name="Portal Gun",
+ description="Device to travel through the multi-rick-verse",
+ ),
+ Item(name="Plumbus"),
+ ]
diff --git a/docs_src/settings/app02/main.py b/docs_src/settings/app02/main.py
index 163aa2614..941f82e6b 100644
--- a/docs_src/settings/app02/main.py
+++ b/docs_src/settings/app02/main.py
@@ -7,7 +7,7 @@ from .config import Settings
app = FastAPI()
-@lru_cache()
+@lru_cache
def get_settings():
return Settings()
diff --git a/docs_src/settings/app02_an/main.py b/docs_src/settings/app02_an/main.py
index cb679202d..3a578cc33 100644
--- a/docs_src/settings/app02_an/main.py
+++ b/docs_src/settings/app02_an/main.py
@@ -8,7 +8,7 @@ from .config import Settings
app = FastAPI()
-@lru_cache()
+@lru_cache
def get_settings():
return Settings()
diff --git a/docs_src/settings/app02_an_py39/main.py b/docs_src/settings/app02_an_py39/main.py
index 61be74fcb..6d5db12a8 100644
--- a/docs_src/settings/app02_an_py39/main.py
+++ b/docs_src/settings/app02_an_py39/main.py
@@ -8,7 +8,7 @@ from .config import Settings
app = FastAPI()
-@lru_cache()
+@lru_cache
def get_settings():
return Settings()
diff --git a/docs_src/settings/app03/main.py b/docs_src/settings/app03/main.py
index 69bc8c6e0..ea64a5709 100644
--- a/docs_src/settings/app03/main.py
+++ b/docs_src/settings/app03/main.py
@@ -7,7 +7,7 @@ from . import config
app = FastAPI()
-@lru_cache()
+@lru_cache
def get_settings():
return config.Settings()
diff --git a/docs_src/settings/app03_an/main.py b/docs_src/settings/app03_an/main.py
index c33b98f47..2f64b9cd1 100644
--- a/docs_src/settings/app03_an/main.py
+++ b/docs_src/settings/app03_an/main.py
@@ -8,7 +8,7 @@ from . import config
app = FastAPI()
-@lru_cache()
+@lru_cache
def get_settings():
return config.Settings()
diff --git a/docs_src/settings/app03_an_py39/main.py b/docs_src/settings/app03_an_py39/main.py
index b89c6b6cf..62f347639 100644
--- a/docs_src/settings/app03_an_py39/main.py
+++ b/docs_src/settings/app03_an_py39/main.py
@@ -8,7 +8,7 @@ from . import config
app = FastAPI()
-@lru_cache()
+@lru_cache
def get_settings():
return config.Settings()
diff --git a/fastapi/__init__.py b/fastapi/__init__.py
index d8abf2103..dd16ea34d 100644
--- a/fastapi/__init__.py
+++ b/fastapi/__init__.py
@@ -1,6 +1,6 @@
"""FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
-__version__ = "0.101.1"
+__version__ = "0.105.0"
from starlette import status as status
diff --git a/fastapi/_compat.py b/fastapi/_compat.py
index 9ffcaf409..35d4a8723 100644
--- a/fastapi/_compat.py
+++ b/fastapi/_compat.py
@@ -58,9 +58,15 @@ if PYDANTIC_V2:
from pydantic_core import CoreSchema as CoreSchema
from pydantic_core import PydanticUndefined, PydanticUndefinedType
from pydantic_core import Url as Url
- from pydantic_core.core_schema import (
- general_plain_validator_function as general_plain_validator_function,
- )
+
+ try:
+ from pydantic_core.core_schema import (
+ with_info_plain_validator_function as with_info_plain_validator_function,
+ )
+ except ImportError: # pragma: no cover
+ from pydantic_core.core_schema import (
+ general_plain_validator_function as with_info_plain_validator_function, # noqa: F401
+ )
Required = PydanticUndefined
Undefined = PydanticUndefined
@@ -181,15 +187,19 @@ if PYDANTIC_V2:
field_mapping: Dict[
Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
],
+ separate_input_output_schemas: bool = True,
) -> Dict[str, Any]:
+ override_mode: Union[Literal["validation"], None] = (
+ None if separate_input_output_schemas else "validation"
+ )
# This expects that GenerateJsonSchema was already used to generate the definitions
- json_schema = field_mapping[(field, field.mode)]
+ json_schema = field_mapping[(field, override_mode or field.mode)]
if "$ref" not in json_schema:
# TODO remove when deprecating Pydantic v1
# Ref: https://github.com/pydantic/pydantic/blob/d61792cc42c80b13b23e3ffa74bc37ec7c77f7d1/pydantic/schema.py#L207
- json_schema[
- "title"
- ] = field.field_info.title or field.alias.title().replace("_", " ")
+ json_schema["title"] = (
+ field.field_info.title or field.alias.title().replace("_", " ")
+ )
return json_schema
def get_compat_model_name_map(fields: List[ModelField]) -> ModelNameMap:
@@ -200,14 +210,19 @@ if PYDANTIC_V2:
fields: List[ModelField],
schema_generator: GenerateJsonSchema,
model_name_map: ModelNameMap,
+ separate_input_output_schemas: bool = True,
) -> Tuple[
Dict[
Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
],
Dict[str, Dict[str, Any]],
]:
+ override_mode: Union[Literal["validation"], None] = (
+ None if separate_input_output_schemas else "validation"
+ )
inputs = [
- (field, field.mode, field._type_adapter.core_schema) for field in fields
+ (field, override_mode or field.mode, field._type_adapter.core_schema)
+ for field in fields
]
field_mapping, definitions = schema_generator.generate_definitions(
inputs=inputs
@@ -234,7 +249,12 @@ if PYDANTIC_V2:
return is_bytes_sequence_annotation(field.type_)
def copy_field_info(*, field_info: FieldInfo, annotation: Any) -> FieldInfo:
- return type(field_info).from_annotation(annotation)
+ cls = type(field_info)
+ merged_field_info = cls.from_annotation(annotation)
+ new_field_info = copy(field_info)
+ new_field_info.metadata = merged_field_info.metadata
+ new_field_info.annotation = merged_field_info.annotation
+ return new_field_info
def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:
origin_type = (
@@ -336,7 +356,7 @@ else:
class PydanticSchemaGenerationError(Exception): # type: ignore[no-redef]
pass
- def general_plain_validator_function( # type: ignore[misc]
+ def with_info_plain_validator_function( # type: ignore[misc]
function: Callable[..., Any],
*,
ref: Union[str, None] = None,
@@ -429,6 +449,7 @@ else:
field_mapping: Dict[
Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
],
+ separate_input_output_schemas: bool = True,
) -> Dict[str, Any]:
# This expects that GenerateJsonSchema was already used to generate the definitions
return field_schema( # type: ignore[no-any-return]
@@ -444,6 +465,7 @@ else:
fields: List[ModelField],
schema_generator: GenerateJsonSchema,
model_name_map: ModelNameMap,
+ separate_input_output_schemas: bool = True,
) -> Tuple[
Dict[
Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
diff --git a/fastapi/applications.py b/fastapi/applications.py
index e32cfa03d..3021d7593 100644
--- a/fastapi/applications.py
+++ b/fastapi/applications.py
@@ -43,56 +43,785 @@ from starlette.requests import Request
from starlette.responses import HTMLResponse, JSONResponse, Response
from starlette.routing import BaseRoute
from starlette.types import ASGIApp, Lifespan, Receive, Scope, Send
+from typing_extensions import Annotated, Doc, deprecated # type: ignore [attr-defined]
AppType = TypeVar("AppType", bound="FastAPI")
class FastAPI(Starlette):
+ """
+ `FastAPI` app class, the main entrypoint to use FastAPI.
+
+ Read more in the
+ [FastAPI docs for First Steps](https://fastapi.tiangolo.com/tutorial/first-steps/).
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI()
+ ```
+ """
+
def __init__(
self: AppType,
*,
- debug: bool = False,
- routes: Optional[List[BaseRoute]] = None,
- title: str = "FastAPI",
- summary: Optional[str] = None,
- description: str = "",
- version: str = "0.1.0",
- openapi_url: Optional[str] = "/openapi.json",
- openapi_tags: Optional[List[Dict[str, Any]]] = None,
- servers: Optional[List[Dict[str, Union[str, Any]]]] = None,
- dependencies: Optional[Sequence[Depends]] = None,
- default_response_class: Type[Response] = Default(JSONResponse),
- redirect_slashes: bool = True,
- docs_url: Optional[str] = "/docs",
- redoc_url: Optional[str] = "/redoc",
- swagger_ui_oauth2_redirect_url: Optional[str] = "/docs/oauth2-redirect",
- swagger_ui_init_oauth: Optional[Dict[str, Any]] = None,
- middleware: Optional[Sequence[Middleware]] = None,
- exception_handlers: Optional[
- Dict[
- Union[int, Type[Exception]],
- Callable[[Request, Any], Coroutine[Any, Any, Response]],
- ]
+ debug: Annotated[
+ bool,
+ Doc(
+ """
+ Boolean indicating if debug tracebacks should be returned on server
+ errors.
+
+ Read more in the
+ [Starlette docs for Applications](https://www.starlette.io/applications/#instantiating-the-application).
+ """
+ ),
+ ] = False,
+ routes: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ **Note**: you probably shouldn't use this parameter, it is inherited
+ from Starlette and supported for compatibility.
+
+ ---
+
+ A list of routes to serve incoming HTTP and WebSocket requests.
+ """
+ ),
+ deprecated(
+ """
+ You normally wouldn't use this parameter with FastAPI, it is inherited
+ from Starlette and supported for compatibility.
+
+ In FastAPI, you normally would use the *path operation methods*,
+ like `app.get()`, `app.post()`, etc.
+ """
+ ),
] = None,
- on_startup: Optional[Sequence[Callable[[], Any]]] = None,
- on_shutdown: Optional[Sequence[Callable[[], Any]]] = None,
- lifespan: Optional[Lifespan[AppType]] = None,
- terms_of_service: Optional[str] = None,
- contact: Optional[Dict[str, Union[str, Any]]] = None,
- license_info: Optional[Dict[str, Union[str, Any]]] = None,
- openapi_prefix: str = "",
- root_path: str = "",
- root_path_in_servers: bool = True,
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- webhooks: Optional[routing.APIRouter] = None,
- deprecated: Optional[bool] = None,
- include_in_schema: bool = True,
- swagger_ui_parameters: Optional[Dict[str, Any]] = None,
- generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
- generate_unique_id
- ),
- **extra: Any,
+ title: Annotated[
+ str,
+ Doc(
+ """
+ The title of the API.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more in the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(title="ChimichangApp")
+ ```
+ """
+ ),
+ ] = "FastAPI",
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A short summary of the API.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more in the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(summary="Deadpond's favorite app. Nuff said.")
+ ```
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ str,
+ Doc(
+ '''
+ A description of the API. Supports Markdown (using
+ [CommonMark syntax](https://commonmark.org/)).
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more in the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(
+ description="""
+ ChimichangApp API helps you do awesome stuff. ๐
+
+ ## Items
+
+ You can **read items**.
+
+ ## Users
+
+ You will be able to:
+
+ * **Create users** (_not implemented_).
+ * **Read users** (_not implemented_).
+
+ """
+ )
+ ```
+ '''
+ ),
+ ] = "",
+ version: Annotated[
+ str,
+ Doc(
+ """
+ The version of the API.
+
+ **Note** This is the version of your application, not the version of
+ the OpenAPI specification nor the version of FastAPI being used.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more in the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(version="0.0.1")
+ ```
+ """
+ ),
+ ] = "0.1.0",
+ openapi_url: Annotated[
+ Optional[str],
+ Doc(
+ """
+ The URL where the OpenAPI schema will be served from.
+
+ If you set it to `None`, no OpenAPI schema will be served publicly, and
+ the default automatic endpoints `/docs` and `/redoc` will also be
+ disabled.
+
+ Read more in the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#openapi-url).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(openapi_url="/api/v1/openapi.json")
+ ```
+ """
+ ),
+ ] = "/openapi.json",
+ openapi_tags: Annotated[
+ Optional[List[Dict[str, Any]]],
+ Doc(
+ """
+ A list of tags used by OpenAPI, these are the same `tags` you can set
+ in the *path operations*, like:
+
+ * `@app.get("/users/", tags=["users"])`
+ * `@app.get("/items/", tags=["items"])`
+
+ The order of the tags can be used to specify the order shown in
+ tools like Swagger UI, used in the automatic path `/docs`.
+
+ It's not required to specify all the tags used.
+
+ The tags that are not declared MAY be organized randomly or based
+ on the tools' logic. Each tag name in the list MUST be unique.
+
+ The value of each item is a `dict` containing:
+
+ * `name`: The name of the tag.
+ * `description`: A short description of the tag.
+ [CommonMark syntax](https://commonmark.org/) MAY be used for rich
+ text representation.
+ * `externalDocs`: Additional external documentation for this tag. If
+ provided, it would contain a `dict` with:
+ * `description`: A short description of the target documentation.
+ [CommonMark syntax](https://commonmark.org/) MAY be used for
+ rich text representation.
+ * `url`: The URL for the target documentation. Value MUST be in
+ the form of a URL.
+
+ Read more in the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-tags).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ tags_metadata = [
+ {
+ "name": "users",
+ "description": "Operations with users. The **login** logic is also here.",
+ },
+ {
+ "name": "items",
+ "description": "Manage items. So _fancy_ they have their own docs.",
+ "externalDocs": {
+ "description": "Items external docs",
+ "url": "https://fastapi.tiangolo.com/",
+ },
+ },
+ ]
+
+ app = FastAPI(openapi_tags=tags_metadata)
+ ```
+ """
+ ),
+ ] = None,
+ servers: Annotated[
+ Optional[List[Dict[str, Union[str, Any]]]],
+ Doc(
+ """
+ A `list` of `dict`s with connectivity information to a target server.
+
+ You would use it, for example, if your application is served from
+ different domains and you want to use the same Swagger UI in the
+ browser to interact with each of them (instead of having multiple
+ browser tabs open). Or if you want to leave fixed the possible URLs.
+
+ If the servers `list` is not provided, or is an empty `list`, the
+ default value would be a a `dict` with a `url` value of `/`.
+
+ Each item in the `list` is a `dict` containing:
+
+ * `url`: A URL to the target host. This URL supports Server Variables
+ and MAY be relative, to indicate that the host location is relative
+ to the location where the OpenAPI document is being served. Variable
+ substitutions will be made when a variable is named in `{`brackets`}`.
+ * `description`: An optional string describing the host designated by
+ the URL. [CommonMark syntax](https://commonmark.org/) MAY be used for
+ rich text representation.
+ * `variables`: A `dict` between a variable name and its value. The value
+ is used for substitution in the server's URL template.
+
+ Read more in the
+ [FastAPI docs for Behind a Proxy](https://fastapi.tiangolo.com/advanced/behind-a-proxy/#additional-servers).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(
+ servers=[
+ {"url": "https://stag.example.com", "description": "Staging environment"},
+ {"url": "https://prod.example.com", "description": "Production environment"},
+ ]
+ )
+ ```
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of global dependencies, they will be applied to each
+ *path operation*, including in sub-routers.
+
+ Read more about it in the
+ [FastAPI docs for Global Dependencies](https://fastapi.tiangolo.com/tutorial/dependencies/global-dependencies/).
+
+ **Example**
+
+ ```python
+ from fastapi import Depends, FastAPI
+
+ from .dependencies import func_dep_1, func_dep_2
+
+ app = FastAPI(dependencies=[Depends(func_dep_1), Depends(func_dep_2)])
+ ```
+ """
+ ),
+ ] = None,
+ default_response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ The default response class to be used.
+
+ Read more in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+ from fastapi.responses import ORJSONResponse
+
+ app = FastAPI(default_response_class=ORJSONResponse)
+ ```
+ """
+ ),
+ ] = Default(JSONResponse),
+ redirect_slashes: Annotated[
+ bool,
+ Doc(
+ """
+ Whether to detect and redirect slashes in URLs when the client doesn't
+ use the same format.
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(redirect_slashes=True) # the default
+
+ @app.get("/items/")
+ async def read_items():
+ return [{"item_id": "Foo"}]
+ ```
+
+ With this app, if a client goes to `/items` (without a trailing slash),
+ they will be automatically redirected with an HTTP status code of 307
+ to `/items/`.
+ """
+ ),
+ ] = True,
+ docs_url: Annotated[
+ Optional[str],
+ Doc(
+ """
+ The path to the automatic interactive API documentation.
+ It is handled in the browser by Swagger UI.
+
+ The default URL is `/docs`. You can disable it by setting it to `None`.
+
+ If `openapi_url` is set to `None`, this will be automatically disabled.
+
+ Read more in the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#docs-urls).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(docs_url="/documentation", redoc_url=None)
+ ```
+ """
+ ),
+ ] = "/docs",
+ redoc_url: Annotated[
+ Optional[str],
+ Doc(
+ """
+ The path to the alternative automatic interactive API documentation
+ provided by ReDoc.
+
+ The default URL is `/redoc`. You can disable it by setting it to `None`.
+
+ If `openapi_url` is set to `None`, this will be automatically disabled.
+
+ Read more in the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#docs-urls).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(docs_url="/documentation", redoc_url="redocumentation")
+ ```
+ """
+ ),
+ ] = "/redoc",
+ swagger_ui_oauth2_redirect_url: Annotated[
+ Optional[str],
+ Doc(
+ """
+ The OAuth2 redirect endpoint for the Swagger UI.
+
+ By default it is `/docs/oauth2-redirect`.
+
+ This is only used if you use OAuth2 (with the "Authorize" button)
+ with Swagger UI.
+ """
+ ),
+ ] = "/docs/oauth2-redirect",
+ swagger_ui_init_oauth: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ OAuth2 configuration for the Swagger UI, by default shown at `/docs`.
+
+ Read more about the available configuration options in the
+ [Swagger UI docs](https://swagger.io/docs/open-source-tools/swagger-ui/usage/oauth2/).
+ """
+ ),
+ ] = None,
+ middleware: Annotated[
+ Optional[Sequence[Middleware]],
+ Doc(
+ """
+ List of middleware to be added when creating the application.
+
+ In FastAPI you would normally do this with `app.add_middleware()`
+ instead.
+
+ Read more in the
+ [FastAPI docs for Middleware](https://fastapi.tiangolo.com/tutorial/middleware/).
+ """
+ ),
+ ] = None,
+ exception_handlers: Annotated[
+ Optional[
+ Dict[
+ Union[int, Type[Exception]],
+ Callable[[Request, Any], Coroutine[Any, Any, Response]],
+ ]
+ ],
+ Doc(
+ """
+ A dictionary with handlers for exceptions.
+
+ In FastAPI, you would normally use the decorator
+ `@app.exception_handler()`.
+
+ Read more in the
+ [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/).
+ """
+ ),
+ ] = None,
+ on_startup: Annotated[
+ Optional[Sequence[Callable[[], Any]]],
+ Doc(
+ """
+ A list of startup event handler functions.
+
+ You should instead use the `lifespan` handlers.
+
+ Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/).
+ """
+ ),
+ ] = None,
+ on_shutdown: Annotated[
+ Optional[Sequence[Callable[[], Any]]],
+ Doc(
+ """
+ A list of shutdown event handler functions.
+
+ You should instead use the `lifespan` handlers.
+
+ Read more in the
+ [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/).
+ """
+ ),
+ ] = None,
+ lifespan: Annotated[
+ Optional[Lifespan[AppType]],
+ Doc(
+ """
+ A `Lifespan` context manager handler. This replaces `startup` and
+ `shutdown` functions with a single context manager.
+
+ Read more in the
+ [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/).
+ """
+ ),
+ ] = None,
+ terms_of_service: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A URL to the Terms of Service for your API.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more at the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+ **Example**
+
+ ```python
+ app = FastAPI(terms_of_service="http://example.com/terms/")
+ ```
+ """
+ ),
+ ] = None,
+ contact: Annotated[
+ Optional[Dict[str, Union[str, Any]]],
+ Doc(
+ """
+ A dictionary with the contact information for the exposed API.
+
+ It can contain several fields.
+
+ * `name`: (`str`) The name of the contact person/organization.
+ * `url`: (`str`) A URL pointing to the contact information. MUST be in
+ the format of a URL.
+ * `email`: (`str`) The email address of the contact person/organization.
+ MUST be in the format of an email address.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more at the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+ **Example**
+
+ ```python
+ app = FastAPI(
+ contact={
+ "name": "Deadpoolio the Amazing",
+ "url": "http://x-force.example.com/contact/",
+ "email": "dp@x-force.example.com",
+ }
+ )
+ ```
+ """
+ ),
+ ] = None,
+ license_info: Annotated[
+ Optional[Dict[str, Union[str, Any]]],
+ Doc(
+ """
+ A dictionary with the license information for the exposed API.
+
+ It can contain several fields.
+
+ * `name`: (`str`) **REQUIRED** (if a `license_info` is set). The
+ license name used for the API.
+ * `identifier`: (`str`) An [SPDX](https://spdx.dev/) license expression
+ for the API. The `identifier` field is mutually exclusive of the `url`
+ field. Available since OpenAPI 3.1.0, FastAPI 0.99.0.
+ * `url`: (`str`) A URL to the license used for the API. This MUST be
+ the format of a URL.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more at the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+ **Example**
+
+ ```python
+ app = FastAPI(
+ license_info={
+ "name": "Apache 2.0",
+ "url": "https://www.apache.org/licenses/LICENSE-2.0.html",
+ }
+ )
+ ```
+ """
+ ),
+ ] = None,
+ openapi_prefix: Annotated[
+ str,
+ Doc(
+ """
+ A URL prefix for the OpenAPI URL.
+ """
+ ),
+ deprecated(
+ """
+ "openapi_prefix" has been deprecated in favor of "root_path", which
+ follows more closely the ASGI standard, is simpler, and more
+ automatic.
+ """
+ ),
+ ] = "",
+ root_path: Annotated[
+ str,
+ Doc(
+ """
+ A path prefix handled by a proxy that is not seen by the application
+ but is seen by external clients, which affects things like Swagger UI.
+
+ Read more about it at the
+ [FastAPI docs for Behind a Proxy](https://fastapi.tiangolo.com/advanced/behind-a-proxy/).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(root_path="/api/v1")
+ ```
+ """
+ ),
+ ] = "",
+ root_path_in_servers: Annotated[
+ bool,
+ Doc(
+ """
+ To disable automatically generating the URLs in the `servers` field
+ in the autogenerated OpenAPI using the `root_path`.
+
+ Read more about it in the
+ [FastAPI docs for Behind a Proxy](https://fastapi.tiangolo.com/advanced/behind-a-proxy/#disable-automatic-server-from-root_path).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(root_path_in_servers=False)
+ ```
+ """
+ ),
+ ] = True,
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses to be shown in OpenAPI.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Additional Responses in OpenAPI](https://fastapi.tiangolo.com/advanced/additional-responses/).
+
+ And in the
+ [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ OpenAPI callbacks that should apply to all *path operations*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ webhooks: Annotated[
+ Optional[routing.APIRouter],
+ Doc(
+ """
+ Add OpenAPI webhooks. This is similar to `callbacks` but it doesn't
+ depend on specific *path operations*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ **Note**: This is available since OpenAPI 3.1.0, FastAPI 0.99.0.
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Webhooks](https://fastapi.tiangolo.com/advanced/openapi-webhooks/).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark all *path operations* as deprecated. You probably don't need it,
+ but it's available.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ To include (or not) all the *path operations* in the generated OpenAPI.
+ You probably don't need it, but it's available.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+ """
+ ),
+ ] = True,
+ swagger_ui_parameters: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Parameters to configure Swagger UI, the autogenerated interactive API
+ documentation (by default at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs about how to Configure Swagger UI](https://fastapi.tiangolo.com/how-to/configure-swagger-ui/).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ separate_input_output_schemas: Annotated[
+ bool,
+ Doc(
+ """
+ Whether to generate separate OpenAPI schemas for request body and
+ response body when the results would be more precise.
+
+ This is particularly useful when automatically generating clients.
+
+ For example, if you have a model like:
+
+ ```python
+ from pydantic import BaseModel
+
+ class Item(BaseModel):
+ name: str
+ tags: list[str] = []
+ ```
+
+ When `Item` is used for input, a request body, `tags` is not required,
+ the client doesn't have to provide it.
+
+ But when using `Item` for output, for a response body, `tags` is always
+ available because it has a default value, even if it's just an empty
+ list. So, the client should be able to always expect it.
+
+ In this case, there would be two different schemas, one for input and
+ another one for output.
+ """
+ ),
+ ] = True,
+ **extra: Annotated[
+ Any,
+ Doc(
+ """
+ Extra keyword arguments to be stored in the app, not used by FastAPI
+ anywhere.
+ """
+ ),
+ ],
) -> None:
self.debug = debug
self.title = title
@@ -111,8 +840,39 @@ class FastAPI(Starlette):
self.swagger_ui_init_oauth = swagger_ui_init_oauth
self.swagger_ui_parameters = swagger_ui_parameters
self.servers = servers or []
+ self.separate_input_output_schemas = separate_input_output_schemas
self.extra = extra
- self.openapi_version = "3.1.0"
+ self.openapi_version: Annotated[
+ str,
+ Doc(
+ """
+ The version string of OpenAPI.
+
+ FastAPI will generate OpenAPI version 3.1.0, and will output that as
+ the OpenAPI version. But some tools, even though they might be
+ compatible with OpenAPI 3.1.0, might not recognize it as a valid.
+
+ So you could override this value to trick those tools into using
+ the generated OpenAPI. Have in mind that this is a hack. But if you
+ avoid using features added in OpenAPI 3.1.0, it might work for your
+ use case.
+
+ This is not passed as a parameter to the `FastAPI` class to avoid
+ giving the false idea that FastAPI would generate a different OpenAPI
+ schema. It is only available as an attribute.
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI()
+
+ app.openapi_version = "3.0.2"
+ ```
+ """
+ ),
+ ] = "3.1.0"
self.openapi_schema: Optional[Dict[str, Any]] = None
if self.openapi_url:
assert self.title, "A title must be provided for OpenAPI, e.g.: 'My API'"
@@ -125,10 +885,53 @@ class FastAPI(Starlette):
"automatic. Check the docs at "
"https://fastapi.tiangolo.com/advanced/sub-applications/"
)
- self.webhooks = webhooks or routing.APIRouter()
+ self.webhooks: Annotated[
+ routing.APIRouter,
+ Doc(
+ """
+ The `app.webhooks` attribute is an `APIRouter` with the *path
+ operations* that will be used just for documentation of webhooks.
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Webhooks](https://fastapi.tiangolo.com/advanced/openapi-webhooks/).
+ """
+ ),
+ ] = webhooks or routing.APIRouter()
self.root_path = root_path or openapi_prefix
- self.state: State = State()
- self.dependency_overrides: Dict[Callable[..., Any], Callable[..., Any]] = {}
+ self.state: Annotated[
+ State,
+ Doc(
+ """
+ A state object for the application. This is the same object for the
+ entire application, it doesn't change from request to request.
+
+ You normally woudln't use this in FastAPI, for most of the cases you
+ would instead use FastAPI dependencies.
+
+ This is simply inherited from Starlette.
+
+ Read more about it in the
+ [Starlette docs for Applications](https://www.starlette.io/applications/#storing-state-on-the-app-instance).
+ """
+ ),
+ ] = State()
+ self.dependency_overrides: Annotated[
+ Dict[Callable[..., Any], Callable[..., Any]],
+ Doc(
+ """
+ A dictionary with overrides for the dependencies.
+
+ Each key is the original dependency callable, and the value is the
+ actual dependency that should be called.
+
+ This is for testing, to replace expensive dependencies with testing
+ versions.
+
+ Read more about it in the
+ [FastAPI docs for Testing Dependencies with Overrides](https://fastapi.tiangolo.com/advanced/testing-dependencies/).
+ """
+ ),
+ ] = {}
self.router: routing.APIRouter = routing.APIRouter(
routes=routes,
redirect_slashes=redirect_slashes,
@@ -146,7 +949,7 @@ class FastAPI(Starlette):
)
self.exception_handlers: Dict[
Any, Callable[[Request, Any], Union[Response, Awaitable[Response]]]
- ] = ({} if exception_handlers is None else dict(exception_handlers))
+ ] = {} if exception_handlers is None else dict(exception_handlers)
self.exception_handlers.setdefault(HTTPException, http_exception_handler)
self.exception_handlers.setdefault(
RequestValidationError, request_validation_exception_handler
@@ -187,20 +990,20 @@ class FastAPI(Starlette):
# contextvars.
# This needs to happen after user middlewares because those create a
# new contextvars context copy by using a new AnyIO task group.
- # The initial part of dependencies with yield is executed in the
- # FastAPI code, inside all the middlewares, but the teardown part
- # (after yield) is executed in the AsyncExitStack in this middleware,
- # if the AsyncExitStack lived outside of the custom middlewares and
- # contextvars were set in a dependency with yield in that internal
+ # The initial part of dependencies with 'yield' is executed in the
+ # FastAPI code, inside all the middlewares. However, the teardown part
+ # (after 'yield') is executed in the AsyncExitStack in this middleware.
+ # If the AsyncExitStack lived outside of the custom middlewares and
+ # contextvars were set in a dependency with 'yield' in that internal
# contextvars context, the values would not be available in the
- # outside context of the AsyncExitStack.
- # By putting the middleware and the AsyncExitStack here, inside all
- # user middlewares, the code before and after yield in dependencies
- # with yield is executed in the same contextvars context, so all values
- # set in contextvars before yield is still available after yield as
- # would be expected.
+ # outer context of the AsyncExitStack.
+ # By placing the middleware and the AsyncExitStack here, inside all
+ # user middlewares, the code before and after 'yield' in dependencies
+ # with 'yield' is executed in the same contextvars context. Thus, all values
+ # set in contextvars before 'yield' are still available after 'yield,' as
+ # expected.
# Additionally, by having this AsyncExitStack here, after the
- # ExceptionMiddleware, now dependencies can catch handled exceptions,
+ # ExceptionMiddleware, dependencies can now catch handled exceptions,
# e.g. HTTPException, to customize the teardown code (e.g. DB session
# rollback).
Middleware(AsyncExitStackMiddleware),
@@ -213,6 +1016,19 @@ class FastAPI(Starlette):
return app
def openapi(self) -> Dict[str, Any]:
+ """
+ Generate the OpenAPI schema of the application. This is called by FastAPI
+ internally.
+
+ The first time it is called it stores the result in the attribute
+ `app.openapi_schema`, and next times it is called, it just returns that same
+ result. To avoid the cost of generating the schema every time.
+
+ If you need to modify the generated OpenAPI schema, you could modify it.
+
+ Read more in the
+ [FastAPI docs for OpenAPI](https://fastapi.tiangolo.com/how-to/extending-openapi/).
+ """
if not self.openapi_schema:
self.openapi_schema = get_openapi(
title=self.title,
@@ -227,6 +1043,7 @@ class FastAPI(Starlette):
webhooks=self.webhooks.routes,
tags=self.openapi_tags,
servers=self.servers,
+ separate_input_output_schemas=self.separate_input_output_schemas,
)
return self.openapi_schema
@@ -424,11 +1241,58 @@ class FastAPI(Starlette):
def websocket(
self,
- path: str,
- name: Optional[str] = None,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ WebSocket path.
+ """
+ ),
+ ],
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A name for the WebSocket. Only used internally.
+ """
+ ),
+ ] = None,
*,
- dependencies: Optional[Sequence[Depends]] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be used for this
+ WebSocket.
+
+ Read more about it in the
+ [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/).
+ """
+ ),
+ ] = None,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Decorate a WebSocket function.
+
+ Read more about it in the
+ [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI, WebSocket
+
+ app = FastAPI()
+
+ @app.websocket("/ws")
+ async def websocket_endpoint(websocket: WebSocket):
+ await websocket.accept()
+ while True:
+ data = await websocket.receive_text()
+ await websocket.send_text(f"Message text was: {data}")
+ ```
+ """
+
def decorator(func: DecoratedCallable) -> DecoratedCallable:
self.add_api_websocket_route(
path,
@@ -442,20 +1306,196 @@ class FastAPI(Starlette):
def include_router(
self,
- router: routing.APIRouter,
+ router: Annotated[routing.APIRouter, Doc("The `APIRouter` to include.")],
*,
- prefix: str = "",
- tags: Optional[List[Union[str, Enum]]] = None,
- dependencies: Optional[Sequence[Depends]] = None,
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- deprecated: Optional[bool] = None,
- include_in_schema: bool = True,
- default_response_class: Type[Response] = Default(JSONResponse),
- callbacks: Optional[List[BaseRoute]] = None,
- generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
- generate_unique_id
- ),
+ prefix: Annotated[str, Doc("An optional path prefix for the router.")] = "",
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to all the *path operations* in this
+ router.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to all the
+ *path operations* in this router.
+
+ Read more about it in the
+ [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+
+ **Example**
+
+ ```python
+ from fastapi import Depends, FastAPI
+
+ from .dependencies import get_token_header
+ from .internal import admin
+
+ app = FastAPI()
+
+ app.include_router(
+ admin.router,
+ dependencies=[Depends(get_token_header)],
+ )
+ ```
+ """
+ ),
+ ] = None,
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses to be shown in OpenAPI.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Additional Responses in OpenAPI](https://fastapi.tiangolo.com/advanced/additional-responses/).
+
+ And in the
+ [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark all the *path operations* in this router as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ from .internal import old_api
+
+ app = FastAPI()
+
+ app.include_router(
+ old_api.router,
+ deprecated=True,
+ )
+ ```
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include (or not) all the *path operations* in this router in the
+ generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ from .internal import old_api
+
+ app = FastAPI()
+
+ app.include_router(
+ old_api.router,
+ include_in_schema=False,
+ )
+ ```
+ """
+ ),
+ ] = True,
+ default_response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Default response class to be used for the *path operations* in this
+ router.
+
+ Read more in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+ from fastapi.responses import ORJSONResponse
+
+ from .internal import old_api
+
+ app = FastAPI()
+
+ app.include_router(
+ old_api.router,
+ default_response_class=ORJSONResponse,
+ )
+ ```
+ """
+ ),
+ ] = Default(JSONResponse),
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
) -> None:
+ """
+ Include an `APIRouter` in the same app.
+
+ Read more about it in the
+ [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/).
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI
+
+ from .users import users_router
+
+ app = FastAPI()
+
+ app.include_router(users_router)
+ ```
+ """
self.router.include_router(
router,
prefix=prefix,
@@ -471,33 +1511,351 @@ class FastAPI(Starlette):
def get(
self,
- path: str,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
*,
- response_model: Any = Default(None),
- status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
- dependencies: Optional[Sequence[Depends]] = None,
- summary: Optional[str] = None,
- description: Optional[str] = None,
- response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- deprecated: Optional[bool] = None,
- operation_id: Optional[str] = None,
- response_model_include: Optional[IncEx] = None,
- response_model_exclude: Optional[IncEx] = None,
- response_model_by_alias: bool = True,
- response_model_exclude_unset: bool = False,
- response_model_exclude_defaults: bool = False,
- response_model_exclude_none: bool = False,
- include_in_schema: bool = True,
- response_class: Type[Response] = Default(JSONResponse),
- name: Optional[str] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
- generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
- generate_unique_id
- ),
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP GET operation.
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI()
+
+ @app.get("/items/")
+ def read_items():
+ return [{"name": "Empanada"}, {"name": "Arepa"}]
+ ```
+ """
return self.router.get(
path,
response_model=response_model,
@@ -526,33 +1884,356 @@ class FastAPI(Starlette):
def put(
self,
- path: str,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
*,
- response_model: Any = Default(None),
- status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
- dependencies: Optional[Sequence[Depends]] = None,
- summary: Optional[str] = None,
- description: Optional[str] = None,
- response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- deprecated: Optional[bool] = None,
- operation_id: Optional[str] = None,
- response_model_include: Optional[IncEx] = None,
- response_model_exclude: Optional[IncEx] = None,
- response_model_by_alias: bool = True,
- response_model_exclude_unset: bool = False,
- response_model_exclude_defaults: bool = False,
- response_model_exclude_none: bool = False,
- include_in_schema: bool = True,
- response_class: Type[Response] = Default(JSONResponse),
- name: Optional[str] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
- generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
- generate_unique_id
- ),
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP PUT operation.
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI
+ from pydantic import BaseModel
+
+ class Item(BaseModel):
+ name: str
+ description: str | None = None
+
+ app = FastAPI()
+
+ @app.put("/items/{item_id}")
+ def replace_item(item_id: str, item: Item):
+ return {"message": "Item replaced", "id": item_id}
+ ```
+ """
return self.router.put(
path,
response_model=response_model,
@@ -581,33 +2262,356 @@ class FastAPI(Starlette):
def post(
self,
- path: str,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
*,
- response_model: Any = Default(None),
- status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
- dependencies: Optional[Sequence[Depends]] = None,
- summary: Optional[str] = None,
- description: Optional[str] = None,
- response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- deprecated: Optional[bool] = None,
- operation_id: Optional[str] = None,
- response_model_include: Optional[IncEx] = None,
- response_model_exclude: Optional[IncEx] = None,
- response_model_by_alias: bool = True,
- response_model_exclude_unset: bool = False,
- response_model_exclude_defaults: bool = False,
- response_model_exclude_none: bool = False,
- include_in_schema: bool = True,
- response_class: Type[Response] = Default(JSONResponse),
- name: Optional[str] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
- generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
- generate_unique_id
- ),
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP POST operation.
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI
+ from pydantic import BaseModel
+
+ class Item(BaseModel):
+ name: str
+ description: str | None = None
+
+ app = FastAPI()
+
+ @app.post("/items/")
+ def create_item(item: Item):
+ return {"message": "Item created"}
+ ```
+ """
return self.router.post(
path,
response_model=response_model,
@@ -636,33 +2640,351 @@ class FastAPI(Starlette):
def delete(
self,
- path: str,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
*,
- response_model: Any = Default(None),
- status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
- dependencies: Optional[Sequence[Depends]] = None,
- summary: Optional[str] = None,
- description: Optional[str] = None,
- response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- deprecated: Optional[bool] = None,
- operation_id: Optional[str] = None,
- response_model_include: Optional[IncEx] = None,
- response_model_exclude: Optional[IncEx] = None,
- response_model_by_alias: bool = True,
- response_model_exclude_unset: bool = False,
- response_model_exclude_defaults: bool = False,
- response_model_exclude_none: bool = False,
- include_in_schema: bool = True,
- response_class: Type[Response] = Default(JSONResponse),
- name: Optional[str] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
- generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
- generate_unique_id
- ),
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP DELETE operation.
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI()
+
+ @app.delete("/items/{item_id}")
+ def delete_item(item_id: str):
+ return {"message": "Item deleted"}
+ ```
+ """
return self.router.delete(
path,
response_model=response_model,
@@ -691,33 +3013,351 @@ class FastAPI(Starlette):
def options(
self,
- path: str,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
*,
- response_model: Any = Default(None),
- status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
- dependencies: Optional[Sequence[Depends]] = None,
- summary: Optional[str] = None,
- description: Optional[str] = None,
- response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- deprecated: Optional[bool] = None,
- operation_id: Optional[str] = None,
- response_model_include: Optional[IncEx] = None,
- response_model_exclude: Optional[IncEx] = None,
- response_model_by_alias: bool = True,
- response_model_exclude_unset: bool = False,
- response_model_exclude_defaults: bool = False,
- response_model_exclude_none: bool = False,
- include_in_schema: bool = True,
- response_class: Type[Response] = Default(JSONResponse),
- name: Optional[str] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
- generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
- generate_unique_id
- ),
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP OPTIONS operation.
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI()
+
+ @app.options("/items/")
+ def get_item_options():
+ return {"additions": ["Aji", "Guacamole"]}
+ ```
+ """
return self.router.options(
path,
response_model=response_model,
@@ -746,33 +3386,351 @@ class FastAPI(Starlette):
def head(
self,
- path: str,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
*,
- response_model: Any = Default(None),
- status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
- dependencies: Optional[Sequence[Depends]] = None,
- summary: Optional[str] = None,
- description: Optional[str] = None,
- response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- deprecated: Optional[bool] = None,
- operation_id: Optional[str] = None,
- response_model_include: Optional[IncEx] = None,
- response_model_exclude: Optional[IncEx] = None,
- response_model_by_alias: bool = True,
- response_model_exclude_unset: bool = False,
- response_model_exclude_defaults: bool = False,
- response_model_exclude_none: bool = False,
- include_in_schema: bool = True,
- response_class: Type[Response] = Default(JSONResponse),
- name: Optional[str] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
- generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
- generate_unique_id
- ),
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP HEAD operation.
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI, Response
+
+ app = FastAPI()
+
+ @app.head("/items/", status_code=204)
+ def get_items_headers(response: Response):
+ response.headers["X-Cat-Dog"] = "Alone in the world"
+ ```
+ """
return self.router.head(
path,
response_model=response_model,
@@ -801,33 +3759,356 @@ class FastAPI(Starlette):
def patch(
self,
- path: str,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
*,
- response_model: Any = Default(None),
- status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
- dependencies: Optional[Sequence[Depends]] = None,
- summary: Optional[str] = None,
- description: Optional[str] = None,
- response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- deprecated: Optional[bool] = None,
- operation_id: Optional[str] = None,
- response_model_include: Optional[IncEx] = None,
- response_model_exclude: Optional[IncEx] = None,
- response_model_by_alias: bool = True,
- response_model_exclude_unset: bool = False,
- response_model_exclude_defaults: bool = False,
- response_model_exclude_none: bool = False,
- include_in_schema: bool = True,
- response_class: Type[Response] = Default(JSONResponse),
- name: Optional[str] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
- generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
- generate_unique_id
- ),
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP PATCH operation.
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI
+ from pydantic import BaseModel
+
+ class Item(BaseModel):
+ name: str
+ description: str | None = None
+
+ app = FastAPI()
+
+ @app.patch("/items/")
+ def update_item(item: Item):
+ return {"message": "Item updated in place"}
+ ```
+ """
return self.router.patch(
path,
response_model=response_model,
@@ -856,33 +4137,351 @@ class FastAPI(Starlette):
def trace(
self,
- path: str,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
*,
- response_model: Any = Default(None),
- status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
- dependencies: Optional[Sequence[Depends]] = None,
- summary: Optional[str] = None,
- description: Optional[str] = None,
- response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- deprecated: Optional[bool] = None,
- operation_id: Optional[str] = None,
- response_model_include: Optional[IncEx] = None,
- response_model_exclude: Optional[IncEx] = None,
- response_model_by_alias: bool = True,
- response_model_exclude_unset: bool = False,
- response_model_exclude_defaults: bool = False,
- response_model_exclude_none: bool = False,
- include_in_schema: bool = True,
- response_class: Type[Response] = Default(JSONResponse),
- name: Optional[str] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
- generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
- generate_unique_id
- ),
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP TRACE operation.
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI()
+
+ @app.put("/items/{item_id}")
+ def trace_item(item_id: str):
+ return None
+ ```
+ """
return self.router.trace(
path,
response_model=response_model,
@@ -918,14 +4517,72 @@ class FastAPI(Starlette):
return decorator
+ @deprecated(
+ """
+ on_event is deprecated, use lifespan event handlers instead.
+
+ Read more about it in the
+ [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/).
+ """
+ )
def on_event(
- self, event_type: str
+ self,
+ event_type: Annotated[
+ str,
+ Doc(
+ """
+ The type of event. `startup` or `shutdown`.
+ """
+ ),
+ ],
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add an event handler for the application.
+
+ `on_event` is deprecated, use `lifespan` event handlers instead.
+
+ Read more about it in the
+ [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/#alternative-events-deprecated).
+ """
return self.router.on_event(event_type)
def middleware(
- self, middleware_type: str
+ self,
+ middleware_type: Annotated[
+ str,
+ Doc(
+ """
+ The type of middleware. Currently only supports `http`.
+ """
+ ),
+ ],
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a middleware to the application.
+
+ Read more about it in the
+ [FastAPI docs for Middleware](https://fastapi.tiangolo.com/tutorial/middleware/).
+
+ ## Example
+
+ ```python
+ import time
+
+ from fastapi import FastAPI, Request
+
+ app = FastAPI()
+
+
+ @app.middleware("http")
+ async def add_process_time_header(request: Request, call_next):
+ start_time = time.time()
+ response = await call_next(request)
+ process_time = time.time() - start_time
+ response.headers["X-Process-Time"] = str(process_time)
+ return response
+ ```
+ """
+
def decorator(func: DecoratedCallable) -> DecoratedCallable:
self.add_middleware(BaseHTTPMiddleware, dispatch=func)
return func
@@ -933,8 +4590,46 @@ class FastAPI(Starlette):
return decorator
def exception_handler(
- self, exc_class_or_status_code: Union[int, Type[Exception]]
+ self,
+ exc_class_or_status_code: Annotated[
+ Union[int, Type[Exception]],
+ Doc(
+ """
+ The Exception class this would handle, or a status code.
+ """
+ ),
+ ],
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add an exception handler to the app.
+
+ Read more about it in the
+ [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/).
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI, Request
+ from fastapi.responses import JSONResponse
+
+
+ class UnicornException(Exception):
+ def __init__(self, name: str):
+ self.name = name
+
+
+ app = FastAPI()
+
+
+ @app.exception_handler(UnicornException)
+ async def unicorn_exception_handler(request: Request, exc: UnicornException):
+ return JSONResponse(
+ status_code=418,
+ content={"message": f"Oops! {exc.name} did something. There goes a rainbow..."},
+ )
+ ```
+ """
+
def decorator(func: DecoratedCallable) -> DecoratedCallable:
self.add_exception_handler(exc_class_or_status_code, func)
return func
diff --git a/fastapi/background.py b/fastapi/background.py
index dd3bbe249..35ab1b227 100644
--- a/fastapi/background.py
+++ b/fastapi/background.py
@@ -1 +1,59 @@
-from starlette.background import BackgroundTasks as BackgroundTasks # noqa
+from typing import Any, Callable
+
+from starlette.background import BackgroundTasks as StarletteBackgroundTasks
+from typing_extensions import Annotated, Doc, ParamSpec # type: ignore [attr-defined]
+
+P = ParamSpec("P")
+
+
+class BackgroundTasks(StarletteBackgroundTasks):
+ """
+ A collection of background tasks that will be called after a response has been
+ sent to the client.
+
+ Read more about it in the
+ [FastAPI docs for Background Tasks](https://fastapi.tiangolo.com/tutorial/background-tasks/).
+
+ ## Example
+
+ ```python
+ from fastapi import BackgroundTasks, FastAPI
+
+ app = FastAPI()
+
+
+ def write_notification(email: str, message=""):
+ with open("log.txt", mode="w") as email_file:
+ content = f"notification for {email}: {message}"
+ email_file.write(content)
+
+
+ @app.post("/send-notification/{email}")
+ async def send_notification(email: str, background_tasks: BackgroundTasks):
+ background_tasks.add_task(write_notification, email, message="some notification")
+ return {"message": "Notification sent in the background"}
+ ```
+ """
+
+ def add_task(
+ self,
+ func: Annotated[
+ Callable[P, Any],
+ Doc(
+ """
+ The function to call after the response is sent.
+
+ It can be a regular `def` function or an `async def` function.
+ """
+ ),
+ ],
+ *args: P.args,
+ **kwargs: P.kwargs,
+ ) -> None:
+ """
+ Add a function to be called in the background after the response is sent.
+
+ Read more about it in the
+ [FastAPI docs for Background Tasks](https://fastapi.tiangolo.com/tutorial/background-tasks/).
+ """
+ return super().add_task(func, *args, **kwargs)
diff --git a/fastapi/datastructures.py b/fastapi/datastructures.py
index 3c96c56c7..ce03e3ce4 100644
--- a/fastapi/datastructures.py
+++ b/fastapi/datastructures.py
@@ -1,11 +1,21 @@
-from typing import Any, Callable, Dict, Iterable, Type, TypeVar, cast
+from typing import (
+ Any,
+ BinaryIO,
+ Callable,
+ Dict,
+ Iterable,
+ Optional,
+ Type,
+ TypeVar,
+ cast,
+)
from fastapi._compat import (
PYDANTIC_V2,
CoreSchema,
GetJsonSchemaHandler,
JsonSchemaValue,
- general_plain_validator_function,
+ with_info_plain_validator_function,
)
from starlette.datastructures import URL as URL # noqa: F401
from starlette.datastructures import Address as Address # noqa: F401
@@ -14,9 +24,120 @@ from starlette.datastructures import Headers as Headers # noqa: F401
from starlette.datastructures import QueryParams as QueryParams # noqa: F401
from starlette.datastructures import State as State # noqa: F401
from starlette.datastructures import UploadFile as StarletteUploadFile
+from typing_extensions import Annotated, Doc # type: ignore [attr-defined]
class UploadFile(StarletteUploadFile):
+ """
+ A file uploaded in a request.
+
+ Define it as a *path operation function* (or dependency) parameter.
+
+ If you are using a regular `def` function, you can use the `upload_file.file`
+ attribute to access the raw standard Python file (blocking, not async), useful and
+ needed for non-async code.
+
+ Read more about it in the
+ [FastAPI docs for Request Files](https://fastapi.tiangolo.com/tutorial/request-files/).
+
+ ## Example
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import FastAPI, File, UploadFile
+
+ app = FastAPI()
+
+
+ @app.post("/files/")
+ async def create_file(file: Annotated[bytes, File()]):
+ return {"file_size": len(file)}
+
+
+ @app.post("/uploadfile/")
+ async def create_upload_file(file: UploadFile):
+ return {"filename": file.filename}
+ ```
+ """
+
+ file: Annotated[
+ BinaryIO,
+ Doc("The standard Python file object (non-async)."),
+ ]
+ filename: Annotated[Optional[str], Doc("The original file name.")]
+ size: Annotated[Optional[int], Doc("The size of the file in bytes.")]
+ headers: Annotated[Headers, Doc("The headers of the request.")]
+ content_type: Annotated[
+ Optional[str], Doc("The content type of the request, from the headers.")
+ ]
+
+ async def write(
+ self,
+ data: Annotated[
+ bytes,
+ Doc(
+ """
+ The bytes to write to the file.
+ """
+ ),
+ ],
+ ) -> None:
+ """
+ Write some bytes to the file.
+
+ You normally wouldn't use this from a file you read in a request.
+
+ To be awaitable, compatible with async, this is run in threadpool.
+ """
+ return await super().write(data)
+
+ async def read(
+ self,
+ size: Annotated[
+ int,
+ Doc(
+ """
+ The number of bytes to read from the file.
+ """
+ ),
+ ] = -1,
+ ) -> bytes:
+ """
+ Read some bytes from the file.
+
+ To be awaitable, compatible with async, this is run in threadpool.
+ """
+ return await super().read(size)
+
+ async def seek(
+ self,
+ offset: Annotated[
+ int,
+ Doc(
+ """
+ The position in bytes to seek to in the file.
+ """
+ ),
+ ],
+ ) -> None:
+ """
+ Move to a position in the file.
+
+ Any next read or write will be done from that position.
+
+ To be awaitable, compatible with async, this is run in threadpool.
+ """
+ return await super().seek(offset)
+
+ async def close(self) -> None:
+ """
+ Close the file.
+
+ To be awaitable, compatible with async, this is run in threadpool.
+ """
+ return await super().close()
+
@classmethod
def __get_validators__(cls: Type["UploadFile"]) -> Iterable[Callable[..., Any]]:
yield cls.validate
@@ -49,7 +170,7 @@ class UploadFile(StarletteUploadFile):
def __get_pydantic_core_schema__(
cls, source: Type[Any], handler: Callable[[Any], CoreSchema]
) -> CoreSchema:
- return general_plain_validator_function(cls._validate)
+ return with_info_plain_validator_function(cls._validate)
class DefaultPlaceholder:
diff --git a/fastapi/dependencies/utils.py b/fastapi/dependencies/utils.py
index e2915268c..4e88410a5 100644
--- a/fastapi/dependencies/utils.py
+++ b/fastapi/dependencies/utils.py
@@ -44,6 +44,7 @@ from fastapi._compat import (
serialize_sequence_value,
value_is_sequence,
)
+from fastapi.background import BackgroundTasks
from fastapi.concurrency import (
AsyncExitStack,
asynccontextmanager,
@@ -56,7 +57,7 @@ from fastapi.security.oauth2 import OAuth2, SecurityScopes
from fastapi.security.open_id_connect_url import OpenIdConnect
from fastapi.utils import create_response_field, get_path_param_names
from pydantic.fields import FieldInfo
-from starlette.background import BackgroundTasks
+from starlette.background import BackgroundTasks as StarletteBackgroundTasks
from starlette.concurrency import run_in_threadpool
from starlette.datastructures import FormData, Headers, QueryParams, UploadFile
from starlette.requests import HTTPConnection, Request
@@ -305,7 +306,7 @@ def add_non_field_param_to_dependency(
elif lenient_issubclass(type_annotation, Response):
dependant.response_param_name = param_name
return True
- elif lenient_issubclass(type_annotation, BackgroundTasks):
+ elif lenient_issubclass(type_annotation, StarletteBackgroundTasks):
dependant.background_tasks_param_name = param_name
return True
elif lenient_issubclass(type_annotation, SecurityScopes):
@@ -324,10 +325,11 @@ def analyze_param(
field_info = None
depends = None
type_annotation: Any = Any
- if (
- annotation is not inspect.Signature.empty
- and get_origin(annotation) is Annotated
- ):
+ use_annotation: Any = Any
+ if annotation is not inspect.Signature.empty:
+ use_annotation = annotation
+ type_annotation = annotation
+ if get_origin(use_annotation) is Annotated:
annotated_args = get_args(annotation)
type_annotation = annotated_args[0]
fastapi_annotations = [
@@ -335,14 +337,21 @@ def analyze_param(
for arg in annotated_args[1:]
if isinstance(arg, (FieldInfo, params.Depends))
]
- assert (
- len(fastapi_annotations) <= 1
- ), f"Cannot specify multiple `Annotated` FastAPI arguments for {param_name!r}"
- fastapi_annotation = next(iter(fastapi_annotations), None)
+ fastapi_specific_annotations = [
+ arg
+ for arg in fastapi_annotations
+ if isinstance(arg, (params.Param, params.Body, params.Depends))
+ ]
+ if fastapi_specific_annotations:
+ fastapi_annotation: Union[
+ FieldInfo, params.Depends, None
+ ] = fastapi_specific_annotations[-1]
+ else:
+ fastapi_annotation = None
if isinstance(fastapi_annotation, FieldInfo):
# Copy `field_info` because we mutate `field_info.default` below.
field_info = copy_field_info(
- field_info=fastapi_annotation, annotation=annotation
+ field_info=fastapi_annotation, annotation=use_annotation
)
assert field_info.default is Undefined or field_info.default is Required, (
f"`{field_info.__class__.__name__}` default value cannot be set in"
@@ -355,8 +364,6 @@ def analyze_param(
field_info.default = Required
elif isinstance(fastapi_annotation, params.Depends):
depends = fastapi_annotation
- elif annotation is not inspect.Signature.empty:
- type_annotation = annotation
if isinstance(value, params.Depends):
assert depends is None, (
@@ -382,7 +389,14 @@ def analyze_param(
if lenient_issubclass(
type_annotation,
- (Request, WebSocket, HTTPConnection, Response, BackgroundTasks, SecurityScopes),
+ (
+ Request,
+ WebSocket,
+ HTTPConnection,
+ Response,
+ StarletteBackgroundTasks,
+ SecurityScopes,
+ ),
):
assert depends is None, f"Cannot specify `Depends` for type {type_annotation!r}"
assert (
@@ -394,15 +408,15 @@ def analyze_param(
# We might check here that `default_value is Required`, but the fact is that the same
# parameter might sometimes be a path parameter and sometimes not. See
# `tests/test_infer_param_optionality.py` for an example.
- field_info = params.Path(annotation=type_annotation)
+ field_info = params.Path(annotation=use_annotation)
elif is_uploadfile_or_nonable_uploadfile_annotation(
type_annotation
) or is_uploadfile_sequence_annotation(type_annotation):
- field_info = params.File(annotation=type_annotation, default=default_value)
+ field_info = params.File(annotation=use_annotation, default=default_value)
elif not field_annotation_is_scalar(annotation=type_annotation):
- field_info = params.Body(annotation=type_annotation, default=default_value)
+ field_info = params.Body(annotation=use_annotation, default=default_value)
else:
- field_info = params.Query(annotation=type_annotation, default=default_value)
+ field_info = params.Query(annotation=use_annotation, default=default_value)
field = None
if field_info is not None:
@@ -416,8 +430,8 @@ def analyze_param(
and getattr(field_info, "in_", None) is None
):
field_info.in_ = params.ParamTypes.query
- use_annotation = get_annotation_from_field_info(
- type_annotation,
+ use_annotation_from_field_info = get_annotation_from_field_info(
+ use_annotation,
field_info,
param_name,
)
@@ -428,7 +442,7 @@ def analyze_param(
field_info.alias = alias
field = create_response_field(
name=param_name,
- type_=use_annotation,
+ type_=use_annotation_from_field_info,
default=field_info.default,
alias=alias,
required=field_info.default in (Required, Undefined),
@@ -458,16 +472,17 @@ def is_body_param(*, param_field: ModelField, is_path_param: bool) -> bool:
def add_param_to_fields(*, field: ModelField, dependant: Dependant) -> None:
- field_info = cast(params.Param, field.field_info)
- if field_info.in_ == params.ParamTypes.path:
+ field_info = field.field_info
+ field_info_in = getattr(field_info, "in_", None)
+ if field_info_in == params.ParamTypes.path:
dependant.path_params.append(field)
- elif field_info.in_ == params.ParamTypes.query:
+ elif field_info_in == params.ParamTypes.query:
dependant.query_params.append(field)
- elif field_info.in_ == params.ParamTypes.header:
+ elif field_info_in == params.ParamTypes.header:
dependant.header_params.append(field)
else:
assert (
- field_info.in_ == params.ParamTypes.cookie
+ field_info_in == params.ParamTypes.cookie
), f"non-body parameters must be in path, query, header or cookie: {field.name}"
dependant.cookie_params.append(field)
@@ -510,14 +525,14 @@ async def solve_dependencies(
request: Union[Request, WebSocket],
dependant: Dependant,
body: Optional[Union[Dict[str, Any], FormData]] = None,
- background_tasks: Optional[BackgroundTasks] = None,
+ background_tasks: Optional[StarletteBackgroundTasks] = None,
response: Optional[Response] = None,
dependency_overrides_provider: Optional[Any] = None,
dependency_cache: Optional[Dict[Tuple[Callable[..., Any], Tuple[str]], Any]] = None,
) -> Tuple[
Dict[str, Any],
List[Any],
- Optional[BackgroundTasks],
+ Optional[StarletteBackgroundTasks],
Response,
Dict[Tuple[Callable[..., Any], Tuple[str]], Any],
]:
diff --git a/fastapi/encoders.py b/fastapi/encoders.py
index 30493697e..e50171393 100644
--- a/fastapi/encoders.py
+++ b/fastapi/encoders.py
@@ -22,6 +22,7 @@ from pydantic import BaseModel
from pydantic.color import Color
from pydantic.networks import AnyUrl, NameEmail
from pydantic.types import SecretBytes, SecretStr
+from typing_extensions import Annotated, Doc # type: ignore [attr-defined]
from ._compat import PYDANTIC_V2, Url, _model_dump
@@ -99,16 +100,107 @@ encoders_by_class_tuples = generate_encoders_by_class_tuples(ENCODERS_BY_TYPE)
def jsonable_encoder(
- obj: Any,
- include: Optional[IncEx] = None,
- exclude: Optional[IncEx] = None,
- by_alias: bool = True,
- exclude_unset: bool = False,
- exclude_defaults: bool = False,
- exclude_none: bool = False,
- custom_encoder: Optional[Dict[Any, Callable[[Any], Any]]] = None,
- sqlalchemy_safe: bool = True,
+ obj: Annotated[
+ Any,
+ Doc(
+ """
+ The input object to convert to JSON.
+ """
+ ),
+ ],
+ include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Pydantic's `include` parameter, passed to Pydantic models to set the
+ fields to include.
+ """
+ ),
+ ] = None,
+ exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Pydantic's `exclude` parameter, passed to Pydantic models to set the
+ fields to exclude.
+ """
+ ),
+ ] = None,
+ by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Pydantic's `by_alias` parameter, passed to Pydantic models to define if
+ the output should use the alias names (when provided) or the Python
+ attribute names. In an API, if you set an alias, it's probably because you
+ want to use it in the result, so you probably want to leave this set to
+ `True`.
+ """
+ ),
+ ] = True,
+ exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Pydantic's `exclude_unset` parameter, passed to Pydantic models to define
+ if it should exclude from the output the fields that were not explicitly
+ set (and that only had their default values).
+ """
+ ),
+ ] = False,
+ exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Pydantic's `exclude_defaults` parameter, passed to Pydantic models to define
+ if it should exclude from the output the fields that had the same default
+ value, even when they were explicitly set.
+ """
+ ),
+ ] = False,
+ exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Pydantic's `exclude_none` parameter, passed to Pydantic models to define
+ if it should exclude from the output any fields that have a `None` value.
+ """
+ ),
+ ] = False,
+ custom_encoder: Annotated[
+ Optional[Dict[Any, Callable[[Any], Any]]],
+ Doc(
+ """
+ Pydantic's `custom_encoder` parameter, passed to Pydantic models to define
+ a custom encoder.
+ """
+ ),
+ ] = None,
+ sqlalchemy_safe: Annotated[
+ bool,
+ Doc(
+ """
+ Exclude from the output any fields that start with the name `_sa`.
+
+ This is mainly a hack for compatibility with SQLAlchemy objects, they
+ store internal SQLAlchemy-specific state in attributes named with `_sa`,
+ and those objects can't (and shouldn't be) serialized to JSON.
+ """
+ ),
+ ] = True,
) -> Any:
+ """
+ Convert any object to something that can be encoded in JSON.
+
+ This is used internally by FastAPI to make sure anything you return can be
+ encoded as JSON before it is sent to the client.
+
+ You can also use it yourself, for example to convert objects before saving them
+ in a database that supports only JSON.
+
+ Read more about it in the
+ [FastAPI docs for JSON Compatible Encoder](https://fastapi.tiangolo.com/tutorial/encoder/).
+ """
custom_encoder = custom_encoder or {}
if custom_encoder:
if type(obj) in custom_encoder:
diff --git a/fastapi/exceptions.py b/fastapi/exceptions.py
index 42f4709fb..680d288e4 100644
--- a/fastapi/exceptions.py
+++ b/fastapi/exceptions.py
@@ -1,20 +1,141 @@
-from typing import Any, Dict, Optional, Sequence, Type
+from typing import Any, Dict, Optional, Sequence, Type, Union
from pydantic import BaseModel, create_model
from starlette.exceptions import HTTPException as StarletteHTTPException
-from starlette.exceptions import WebSocketException as WebSocketException # noqa: F401
+from starlette.exceptions import WebSocketException as StarletteWebSocketException
+from typing_extensions import Annotated, Doc # type: ignore [attr-defined]
class HTTPException(StarletteHTTPException):
+ """
+ An HTTP exception you can raise in your own code to show errors to the client.
+
+ This is for client errors, invalid authentication, invalid data, etc. Not for server
+ errors in your code.
+
+ Read more about it in the
+ [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/).
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI, HTTPException
+
+ app = FastAPI()
+
+ items = {"foo": "The Foo Wrestlers"}
+
+
+ @app.get("/items/{item_id}")
+ async def read_item(item_id: str):
+ if item_id not in items:
+ raise HTTPException(status_code=404, detail="Item not found")
+ return {"item": items[item_id]}
+ ```
+ """
+
def __init__(
self,
- status_code: int,
- detail: Any = None,
- headers: Optional[Dict[str, str]] = None,
+ status_code: Annotated[
+ int,
+ Doc(
+ """
+ HTTP status code to send to the client.
+ """
+ ),
+ ],
+ detail: Annotated[
+ Any,
+ Doc(
+ """
+ Any data to be sent to the client in the `detail` key of the JSON
+ response.
+ """
+ ),
+ ] = None,
+ headers: Annotated[
+ Optional[Dict[str, str]],
+ Doc(
+ """
+ Any headers to send to the client in the response.
+ """
+ ),
+ ] = None,
) -> None:
super().__init__(status_code=status_code, detail=detail, headers=headers)
+class WebSocketException(StarletteWebSocketException):
+ """
+ A WebSocket exception you can raise in your own code to show errors to the client.
+
+ This is for client errors, invalid authentication, invalid data, etc. Not for server
+ errors in your code.
+
+ Read more about it in the
+ [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/).
+
+ ## Example
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import (
+ Cookie,
+ FastAPI,
+ WebSocket,
+ WebSocketException,
+ status,
+ )
+
+ app = FastAPI()
+
+ @app.websocket("/items/{item_id}/ws")
+ async def websocket_endpoint(
+ *,
+ websocket: WebSocket,
+ session: Annotated[str | None, Cookie()] = None,
+ item_id: str,
+ ):
+ if session is None:
+ raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION)
+ await websocket.accept()
+ while True:
+ data = await websocket.receive_text()
+ await websocket.send_text(f"Session cookie is: {session}")
+ await websocket.send_text(f"Message text was: {data}, for item ID: {item_id}")
+ ```
+ """
+
+ def __init__(
+ self,
+ code: Annotated[
+ int,
+ Doc(
+ """
+ A closing code from the
+ [valid codes defined in the specification](https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1).
+ """
+ ),
+ ],
+ reason: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ The reason to close the WebSocket connection.
+
+ It is UTF-8-encoded data. The interpretation of the reason is up to the
+ application, it is not specified by the WebSocket specification.
+
+ It could contain text that could be human-readable or interpretable
+ by the client code, etc.
+ """
+ ),
+ ] = None,
+ ) -> None:
+ super().__init__(code=code, reason=reason)
+
+
RequestErrorModel: Type[BaseModel] = create_model("Request")
WebSocketErrorModel: Type[BaseModel] = create_model("WebSocket")
diff --git a/fastapi/openapi/docs.py b/fastapi/openapi/docs.py
index 81f67dcc5..69473d19c 100644
--- a/fastapi/openapi/docs.py
+++ b/fastapi/openapi/docs.py
@@ -3,8 +3,18 @@ from typing import Any, Dict, Optional
from fastapi.encoders import jsonable_encoder
from starlette.responses import HTMLResponse
+from typing_extensions import Annotated, Doc # type: ignore [attr-defined]
-swagger_ui_default_parameters = {
+swagger_ui_default_parameters: Annotated[
+ Dict[str, Any],
+ Doc(
+ """
+ Default configurations for Swagger UI.
+
+ You can use it as a template to add any other configurations needed.
+ """
+ ),
+] = {
"dom_id": "#swagger-ui",
"layout": "BaseLayout",
"deepLinking": True,
@@ -15,15 +25,91 @@ swagger_ui_default_parameters = {
def get_swagger_ui_html(
*,
- openapi_url: str,
- title: str,
- swagger_js_url: str = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js",
- swagger_css_url: str = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css",
- swagger_favicon_url: str = "https://fastapi.tiangolo.com/img/favicon.png",
- oauth2_redirect_url: Optional[str] = None,
- init_oauth: Optional[Dict[str, Any]] = None,
- swagger_ui_parameters: Optional[Dict[str, Any]] = None,
+ openapi_url: Annotated[
+ str,
+ Doc(
+ """
+ The OpenAPI URL that Swagger UI should load and use.
+
+ This is normally done automatically by FastAPI using the default URL
+ `/openapi.json`.
+ """
+ ),
+ ],
+ title: Annotated[
+ str,
+ Doc(
+ """
+ The HTML `` content, normally shown in the browser tab.
+ """
+ ),
+ ],
+ swagger_js_url: Annotated[
+ str,
+ Doc(
+ """
+ The URL to use to load the Swagger UI JavaScript.
+
+ It is normally set to a CDN URL.
+ """
+ ),
+ ] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5.9.0/swagger-ui-bundle.js",
+ swagger_css_url: Annotated[
+ str,
+ Doc(
+ """
+ The URL to use to load the Swagger UI CSS.
+
+ It is normally set to a CDN URL.
+ """
+ ),
+ ] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5.9.0/swagger-ui.css",
+ swagger_favicon_url: Annotated[
+ str,
+ Doc(
+ """
+ The URL of the favicon to use. It is normally shown in the browser tab.
+ """
+ ),
+ ] = "https://fastapi.tiangolo.com/img/favicon.png",
+ oauth2_redirect_url: Annotated[
+ Optional[str],
+ Doc(
+ """
+ The OAuth2 redirect URL, it is normally automatically handled by FastAPI.
+ """
+ ),
+ ] = None,
+ init_oauth: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ A dictionary with Swagger UI OAuth2 initialization configurations.
+ """
+ ),
+ ] = None,
+ swagger_ui_parameters: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Configuration parameters for Swagger UI.
+
+ It defaults to [swagger_ui_default_parameters][fastapi.openapi.docs.swagger_ui_default_parameters].
+ """
+ ),
+ ] = None,
) -> HTMLResponse:
+ """
+ Generate and return the HTML that loads Swagger UI for the interactive
+ API docs (normally served at `/docs`).
+
+ You would only call this function yourself if you needed to override some parts,
+ for example the URLs to use to load Swagger UI's JavaScript and CSS.
+
+ Read more about it in the
+ [FastAPI docs for Configure Swagger UI](https://fastapi.tiangolo.com/how-to/configure-swagger-ui/)
+ and the [FastAPI docs for Custom Docs UI Static Assets (Self-Hosting)](https://fastapi.tiangolo.com/how-to/custom-docs-ui-assets/).
+ """
current_swagger_ui_parameters = swagger_ui_default_parameters.copy()
if swagger_ui_parameters:
current_swagger_ui_parameters.update(swagger_ui_parameters)
@@ -74,12 +160,62 @@ def get_swagger_ui_html(
def get_redoc_html(
*,
- openapi_url: str,
- title: str,
- redoc_js_url: str = "https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js",
- redoc_favicon_url: str = "https://fastapi.tiangolo.com/img/favicon.png",
- with_google_fonts: bool = True,
+ openapi_url: Annotated[
+ str,
+ Doc(
+ """
+ The OpenAPI URL that ReDoc should load and use.
+
+ This is normally done automatically by FastAPI using the default URL
+ `/openapi.json`.
+ """
+ ),
+ ],
+ title: Annotated[
+ str,
+ Doc(
+ """
+ The HTML `` content, normally shown in the browser tab.
+ """
+ ),
+ ],
+ redoc_js_url: Annotated[
+ str,
+ Doc(
+ """
+ The URL to use to load the ReDoc JavaScript.
+
+ It is normally set to a CDN URL.
+ """
+ ),
+ ] = "https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js",
+ redoc_favicon_url: Annotated[
+ str,
+ Doc(
+ """
+ The URL of the favicon to use. It is normally shown in the browser tab.
+ """
+ ),
+ ] = "https://fastapi.tiangolo.com/img/favicon.png",
+ with_google_fonts: Annotated[
+ bool,
+ Doc(
+ """
+ Load and use Google Fonts.
+ """
+ ),
+ ] = True,
) -> HTMLResponse:
+ """
+ Generate and return the HTML response that loads ReDoc for the alternative
+ API docs (normally served at `/redoc`).
+
+ You would only call this function yourself if you needed to override some parts,
+ for example the URLs to use to load ReDoc's JavaScript and CSS.
+
+ Read more about it in the
+ [FastAPI docs for Custom Docs UI Static Assets (Self-Hosting)](https://fastapi.tiangolo.com/how-to/custom-docs-ui-assets/).
+ """
html = f"""
@@ -118,6 +254,11 @@ def get_redoc_html(
def get_swagger_ui_oauth2_redirect_html() -> HTMLResponse:
+ """
+ Generate the HTML response with the OAuth2 redirection for Swagger UI.
+
+ You normally don't need to use or change this.
+ """
# copied from https://github.com/swagger-api/swagger-ui/blob/v4.14.0/dist/oauth2-redirect.html
html = """
diff --git a/fastapi/openapi/models.py b/fastapi/openapi/models.py
index 2268dd229..5f3bdbb20 100644
--- a/fastapi/openapi/models.py
+++ b/fastapi/openapi/models.py
@@ -7,11 +7,11 @@ from fastapi._compat import (
GetJsonSchemaHandler,
JsonSchemaValue,
_model_rebuild,
- general_plain_validator_function,
+ with_info_plain_validator_function,
)
from fastapi.logger import logger
from pydantic import AnyUrl, BaseModel, Field
-from typing_extensions import Annotated, Literal
+from typing_extensions import Annotated, Literal, TypedDict
from typing_extensions import deprecated as typing_deprecated
try:
@@ -52,7 +52,7 @@ except ImportError: # pragma: no cover
def __get_pydantic_core_schema__(
cls, source: Type[Any], handler: Callable[[Any], CoreSchema]
) -> CoreSchema:
- return general_plain_validator_function(cls._validate)
+ return with_info_plain_validator_function(cls._validate)
class Contact(BaseModel):
@@ -267,14 +267,14 @@ class Schema(BaseModel):
SchemaOrBool = Union[Schema, bool]
-class Example(BaseModel):
- summary: Optional[str] = None
- description: Optional[str] = None
- value: Optional[Any] = None
- externalValue: Optional[AnyUrl] = None
+class Example(TypedDict, total=False):
+ summary: Optional[str]
+ description: Optional[str]
+ value: Optional[Any]
+ externalValue: Optional[AnyUrl]
- if PYDANTIC_V2:
- model_config = {"extra": "allow"}
+ if PYDANTIC_V2: # type: ignore [misc]
+ __pydantic_config__ = {"extra": "allow"}
else:
diff --git a/fastapi/openapi/utils.py b/fastapi/openapi/utils.py
index e295361e6..5bfb5acef 100644
--- a/fastapi/openapi/utils.py
+++ b/fastapi/openapi/utils.py
@@ -95,6 +95,7 @@ def get_openapi_operation_parameters(
field_mapping: Dict[
Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
],
+ separate_input_output_schemas: bool = True,
) -> List[Dict[str, Any]]:
parameters = []
for param in all_route_params:
@@ -107,6 +108,7 @@ def get_openapi_operation_parameters(
schema_generator=schema_generator,
model_name_map=model_name_map,
field_mapping=field_mapping,
+ separate_input_output_schemas=separate_input_output_schemas,
)
parameter = {
"name": param.alias,
@@ -116,7 +118,9 @@ def get_openapi_operation_parameters(
}
if field_info.description:
parameter["description"] = field_info.description
- if field_info.example != Undefined:
+ if field_info.openapi_examples:
+ parameter["examples"] = jsonable_encoder(field_info.openapi_examples)
+ elif field_info.example != Undefined:
parameter["example"] = jsonable_encoder(field_info.example)
if field_info.deprecated:
parameter["deprecated"] = field_info.deprecated
@@ -132,6 +136,7 @@ def get_openapi_operation_request_body(
field_mapping: Dict[
Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
],
+ separate_input_output_schemas: bool = True,
) -> Optional[Dict[str, Any]]:
if not body_field:
return None
@@ -141,6 +146,7 @@ def get_openapi_operation_request_body(
schema_generator=schema_generator,
model_name_map=model_name_map,
field_mapping=field_mapping,
+ separate_input_output_schemas=separate_input_output_schemas,
)
field_info = cast(Body, body_field.field_info)
request_media_type = field_info.media_type
@@ -149,7 +155,11 @@ def get_openapi_operation_request_body(
if required:
request_body_oai["required"] = required
request_media_content: Dict[str, Any] = {"schema": body_schema}
- if field_info.example != Undefined:
+ if field_info.openapi_examples:
+ request_media_content["examples"] = jsonable_encoder(
+ field_info.openapi_examples
+ )
+ elif field_info.example != Undefined:
request_media_content["example"] = jsonable_encoder(field_info.example)
request_body_oai["content"] = {request_media_type: request_media_content}
return request_body_oai
@@ -211,6 +221,7 @@ def get_openapi_path(
field_mapping: Dict[
Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
],
+ separate_input_output_schemas: bool = True,
) -> Tuple[Dict[str, Any], Dict[str, Any], Dict[str, Any]]:
path = {}
security_schemes: Dict[str, Any] = {}
@@ -242,6 +253,7 @@ def get_openapi_path(
schema_generator=schema_generator,
model_name_map=model_name_map,
field_mapping=field_mapping,
+ separate_input_output_schemas=separate_input_output_schemas,
)
parameters.extend(operation_parameters)
if parameters:
@@ -263,6 +275,7 @@ def get_openapi_path(
schema_generator=schema_generator,
model_name_map=model_name_map,
field_mapping=field_mapping,
+ separate_input_output_schemas=separate_input_output_schemas,
)
if request_body_oai:
operation["requestBody"] = request_body_oai
@@ -280,6 +293,7 @@ def get_openapi_path(
schema_generator=schema_generator,
model_name_map=model_name_map,
field_mapping=field_mapping,
+ separate_input_output_schemas=separate_input_output_schemas,
)
callbacks[callback.name] = {callback.path: cb_path}
operation["callbacks"] = callbacks
@@ -310,6 +324,7 @@ def get_openapi_path(
schema_generator=schema_generator,
model_name_map=model_name_map,
field_mapping=field_mapping,
+ separate_input_output_schemas=separate_input_output_schemas,
)
else:
response_schema = {}
@@ -343,6 +358,7 @@ def get_openapi_path(
schema_generator=schema_generator,
model_name_map=model_name_map,
field_mapping=field_mapping,
+ separate_input_output_schemas=separate_input_output_schemas,
)
media_type = route_response_media_type or "application/json"
additional_schema = (
@@ -433,6 +449,7 @@ def get_openapi(
terms_of_service: Optional[str] = None,
contact: Optional[Dict[str, Union[str, Any]]] = None,
license_info: Optional[Dict[str, Union[str, Any]]] = None,
+ separate_input_output_schemas: bool = True,
) -> Dict[str, Any]:
info: Dict[str, Any] = {"title": title, "version": version}
if summary:
@@ -459,6 +476,7 @@ def get_openapi(
fields=all_fields,
schema_generator=schema_generator,
model_name_map=model_name_map,
+ separate_input_output_schemas=separate_input_output_schemas,
)
for route in routes or []:
if isinstance(route, routing.APIRoute):
@@ -468,6 +486,7 @@ def get_openapi(
schema_generator=schema_generator,
model_name_map=model_name_map,
field_mapping=field_mapping,
+ separate_input_output_schemas=separate_input_output_schemas,
)
if result:
path, security_schemes, path_definitions = result
@@ -487,6 +506,7 @@ def get_openapi(
schema_generator=schema_generator,
model_name_map=model_name_map,
field_mapping=field_mapping,
+ separate_input_output_schemas=separate_input_output_schemas,
)
if result:
path, security_schemes, path_definitions = result
diff --git a/fastapi/param_functions.py b/fastapi/param_functions.py
index a43afaf31..3f6dbc959 100644
--- a/fastapi/param_functions.py
+++ b/fastapi/param_functions.py
@@ -2,43 +2,219 @@ from typing import Any, Callable, Dict, List, Optional, Sequence, Union
from fastapi import params
from fastapi._compat import Undefined
-from typing_extensions import Annotated, deprecated
+from fastapi.openapi.models import Example
+from typing_extensions import Annotated, Doc, deprecated # type: ignore [attr-defined]
_Unset: Any = Undefined
def Path( # noqa: N802
- default: Any = ...,
+ default: Annotated[
+ Any,
+ Doc(
+ """
+ Default value if the parameter field is not set.
+
+ This doesn't affect `Path` parameters as the value is always required.
+ The parameter is available only for compatibility.
+ """
+ ),
+ ] = ...,
*,
- default_factory: Union[Callable[[], Any], None] = _Unset,
- alias: Optional[str] = None,
- alias_priority: Union[int, None] = _Unset,
+ default_factory: Annotated[
+ Union[Callable[[], Any], None],
+ Doc(
+ """
+ A callable to generate the default value.
+
+ This doesn't affect `Path` parameters as the value is always required.
+ The parameter is available only for compatibility.
+ """
+ ),
+ ] = _Unset,
+ alias: Annotated[
+ Optional[str],
+ Doc(
+ """
+ An alternative name for the parameter field.
+
+ This will be used to extract the data and for the generated OpenAPI.
+ It is particularly useful when you can't use the name you want because it
+ is a Python reserved keyword or similar.
+ """
+ ),
+ ] = None,
+ alias_priority: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Priority of the alias. This affects whether an alias generator is used.
+ """
+ ),
+ ] = _Unset,
# TODO: update when deprecating Pydantic v1, import these types
# validation_alias: str | AliasPath | AliasChoices | None
- validation_alias: Union[str, None] = None,
- serialization_alias: Union[str, None] = None,
- title: Optional[str] = None,
- description: Optional[str] = None,
- gt: Optional[float] = None,
- ge: Optional[float] = None,
- lt: Optional[float] = None,
- le: Optional[float] = None,
- min_length: Optional[int] = None,
- max_length: Optional[int] = None,
- pattern: Optional[str] = None,
+ validation_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Whitelist' validation step. The parameter field will be the single one
+ allowed by the alias or set of aliases defined.
+ """
+ ),
+ ] = None,
+ serialization_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Blacklist' validation step. The vanilla parameter field will be the
+ single one of the alias' or set of aliases' fields and all the other
+ fields will be ignored at serialization time.
+ """
+ ),
+ ] = None,
+ title: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable title.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable description.
+ """
+ ),
+ ] = None,
+ gt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than. If set, value must be greater than this. Only applicable to
+ numbers.
+ """
+ ),
+ ] = None,
+ ge: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than or equal. If set, value must be greater than or equal to
+ this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ lt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than. If set, value must be less than this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ le: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than or equal. If set, value must be less than or equal to this.
+ Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ min_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Minimum length for strings.
+ """
+ ),
+ ] = None,
+ max_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Maximum length for strings.
+ """
+ ),
+ ] = None,
+ pattern: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ ] = None,
regex: Annotated[
Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
deprecated(
"Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
),
] = None,
- discriminator: Union[str, None] = None,
- strict: Union[bool, None] = _Unset,
- multiple_of: Union[float, None] = _Unset,
- allow_inf_nan: Union[bool, None] = _Unset,
- max_digits: Union[int, None] = _Unset,
- decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ discriminator: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ Parameter field name for discriminating the type in a tagged union.
+ """
+ ),
+ ] = None,
+ strict: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ If `True`, strict validation is applied to the field.
+ """
+ ),
+ ] = _Unset,
+ multiple_of: Annotated[
+ Union[float, None],
+ Doc(
+ """
+ Value must be a multiple of this. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ allow_inf_nan: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ max_digits: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of allow digits for strings.
+ """
+ ),
+ ] = _Unset,
+ decimal_places: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of decimal places allowed for numbers.
+ """
+ ),
+ ] = _Unset,
+ examples: Annotated[
+ Optional[List[Any]],
+ Doc(
+ """
+ Example values for this field.
+ """
+ ),
+ ] = None,
example: Annotated[
Optional[Any],
deprecated(
@@ -46,11 +222,87 @@ def Path( # noqa: N802
"although still supported. Use examples instead."
),
] = _Unset,
- deprecated: Optional[bool] = None,
- include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
- **extra: Any,
+ openapi_examples: Annotated[
+ Optional[Dict[str, Example]],
+ Doc(
+ """
+ OpenAPI-specific examples.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Swagger UI (that provides the `/docs` interface) has better support for the
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+ use case for this.
+
+ Read more about it in the
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this parameter field as deprecated.
+
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ To include (or not) this parameter field in the generated OpenAPI.
+ You probably don't need it, but it's available.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = True,
+ json_schema_extra: Annotated[
+ Union[Dict[str, Any], None],
+ Doc(
+ """
+ Any additional JSON schema data.
+ """
+ ),
+ ] = None,
+ **extra: Annotated[
+ Any,
+ Doc(
+ """
+ Include extra fields used by the JSON Schema.
+ """
+ ),
+ deprecated(
+ """
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+ """
+ ),
+ ],
) -> Any:
+ """
+ Declare a path parameter for a *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Parameters and Numeric Validations](https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/).
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import FastAPI, Path
+
+ app = FastAPI()
+
+
+ @app.get("/items/{item_id}")
+ async def read_items(
+ item_id: Annotated[int, Path(title="The ID of the item to get")],
+ ):
+ return {"item_id": item_id}
+ ```
+ """
return params.Path(
default=default,
default_factory=default_factory,
@@ -76,6 +328,7 @@ def Path( # noqa: N802
decimal_places=decimal_places,
example=example,
examples=examples,
+ openapi_examples=openapi_examples,
deprecated=deprecated,
include_in_schema=include_in_schema,
json_schema_extra=json_schema_extra,
@@ -84,37 +337,209 @@ def Path( # noqa: N802
def Query( # noqa: N802
- default: Any = Undefined,
+ default: Annotated[
+ Any,
+ Doc(
+ """
+ Default value if the parameter field is not set.
+ """
+ ),
+ ] = Undefined,
*,
- default_factory: Union[Callable[[], Any], None] = _Unset,
- alias: Optional[str] = None,
- alias_priority: Union[int, None] = _Unset,
+ default_factory: Annotated[
+ Union[Callable[[], Any], None],
+ Doc(
+ """
+ A callable to generate the default value.
+
+ This doesn't affect `Path` parameters as the value is always required.
+ The parameter is available only for compatibility.
+ """
+ ),
+ ] = _Unset,
+ alias: Annotated[
+ Optional[str],
+ Doc(
+ """
+ An alternative name for the parameter field.
+
+ This will be used to extract the data and for the generated OpenAPI.
+ It is particularly useful when you can't use the name you want because it
+ is a Python reserved keyword or similar.
+ """
+ ),
+ ] = None,
+ alias_priority: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Priority of the alias. This affects whether an alias generator is used.
+ """
+ ),
+ ] = _Unset,
# TODO: update when deprecating Pydantic v1, import these types
# validation_alias: str | AliasPath | AliasChoices | None
- validation_alias: Union[str, None] = None,
- serialization_alias: Union[str, None] = None,
- title: Optional[str] = None,
- description: Optional[str] = None,
- gt: Optional[float] = None,
- ge: Optional[float] = None,
- lt: Optional[float] = None,
- le: Optional[float] = None,
- min_length: Optional[int] = None,
- max_length: Optional[int] = None,
- pattern: Optional[str] = None,
+ validation_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Whitelist' validation step. The parameter field will be the single one
+ allowed by the alias or set of aliases defined.
+ """
+ ),
+ ] = None,
+ serialization_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Blacklist' validation step. The vanilla parameter field will be the
+ single one of the alias' or set of aliases' fields and all the other
+ fields will be ignored at serialization time.
+ """
+ ),
+ ] = None,
+ title: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable title.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable description.
+ """
+ ),
+ ] = None,
+ gt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than. If set, value must be greater than this. Only applicable to
+ numbers.
+ """
+ ),
+ ] = None,
+ ge: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than or equal. If set, value must be greater than or equal to
+ this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ lt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than. If set, value must be less than this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ le: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than or equal. If set, value must be less than or equal to this.
+ Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ min_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Minimum length for strings.
+ """
+ ),
+ ] = None,
+ max_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Maximum length for strings.
+ """
+ ),
+ ] = None,
+ pattern: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ ] = None,
regex: Annotated[
Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
deprecated(
"Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
),
] = None,
- discriminator: Union[str, None] = None,
- strict: Union[bool, None] = _Unset,
- multiple_of: Union[float, None] = _Unset,
- allow_inf_nan: Union[bool, None] = _Unset,
- max_digits: Union[int, None] = _Unset,
- decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ discriminator: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ Parameter field name for discriminating the type in a tagged union.
+ """
+ ),
+ ] = None,
+ strict: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ If `True`, strict validation is applied to the field.
+ """
+ ),
+ ] = _Unset,
+ multiple_of: Annotated[
+ Union[float, None],
+ Doc(
+ """
+ Value must be a multiple of this. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ allow_inf_nan: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ max_digits: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of allow digits for strings.
+ """
+ ),
+ ] = _Unset,
+ decimal_places: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of decimal places allowed for numbers.
+ """
+ ),
+ ] = _Unset,
+ examples: Annotated[
+ Optional[List[Any]],
+ Doc(
+ """
+ Example values for this field.
+ """
+ ),
+ ] = None,
example: Annotated[
Optional[Any],
deprecated(
@@ -122,10 +547,65 @@ def Query( # noqa: N802
"although still supported. Use examples instead."
),
] = _Unset,
- deprecated: Optional[bool] = None,
- include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
- **extra: Any,
+ openapi_examples: Annotated[
+ Optional[Dict[str, Example]],
+ Doc(
+ """
+ OpenAPI-specific examples.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Swagger UI (that provides the `/docs` interface) has better support for the
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+ use case for this.
+
+ Read more about it in the
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this parameter field as deprecated.
+
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ To include (or not) this parameter field in the generated OpenAPI.
+ You probably don't need it, but it's available.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = True,
+ json_schema_extra: Annotated[
+ Union[Dict[str, Any], None],
+ Doc(
+ """
+ Any additional JSON schema data.
+ """
+ ),
+ ] = None,
+ **extra: Annotated[
+ Any,
+ Doc(
+ """
+ Include extra fields used by the JSON Schema.
+ """
+ ),
+ deprecated(
+ """
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+ """
+ ),
+ ],
) -> Any:
return params.Query(
default=default,
@@ -152,6 +632,7 @@ def Query( # noqa: N802
decimal_places=decimal_places,
example=example,
examples=examples,
+ openapi_examples=openapi_examples,
deprecated=deprecated,
include_in_schema=include_in_schema,
json_schema_extra=json_schema_extra,
@@ -160,38 +641,220 @@ def Query( # noqa: N802
def Header( # noqa: N802
- default: Any = Undefined,
+ default: Annotated[
+ Any,
+ Doc(
+ """
+ Default value if the parameter field is not set.
+ """
+ ),
+ ] = Undefined,
*,
- default_factory: Union[Callable[[], Any], None] = _Unset,
- alias: Optional[str] = None,
- alias_priority: Union[int, None] = _Unset,
+ default_factory: Annotated[
+ Union[Callable[[], Any], None],
+ Doc(
+ """
+ A callable to generate the default value.
+
+ This doesn't affect `Path` parameters as the value is always required.
+ The parameter is available only for compatibility.
+ """
+ ),
+ ] = _Unset,
+ alias: Annotated[
+ Optional[str],
+ Doc(
+ """
+ An alternative name for the parameter field.
+
+ This will be used to extract the data and for the generated OpenAPI.
+ It is particularly useful when you can't use the name you want because it
+ is a Python reserved keyword or similar.
+ """
+ ),
+ ] = None,
+ alias_priority: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Priority of the alias. This affects whether an alias generator is used.
+ """
+ ),
+ ] = _Unset,
# TODO: update when deprecating Pydantic v1, import these types
# validation_alias: str | AliasPath | AliasChoices | None
- validation_alias: Union[str, None] = None,
- serialization_alias: Union[str, None] = None,
- convert_underscores: bool = True,
- title: Optional[str] = None,
- description: Optional[str] = None,
- gt: Optional[float] = None,
- ge: Optional[float] = None,
- lt: Optional[float] = None,
- le: Optional[float] = None,
- min_length: Optional[int] = None,
- max_length: Optional[int] = None,
- pattern: Optional[str] = None,
+ validation_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Whitelist' validation step. The parameter field will be the single one
+ allowed by the alias or set of aliases defined.
+ """
+ ),
+ ] = None,
+ serialization_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Blacklist' validation step. The vanilla parameter field will be the
+ single one of the alias' or set of aliases' fields and all the other
+ fields will be ignored at serialization time.
+ """
+ ),
+ ] = None,
+ convert_underscores: Annotated[
+ bool,
+ Doc(
+ """
+ Automatically convert underscores to hyphens in the parameter field name.
+
+ Read more about it in the
+ [FastAPI docs for Header Parameters](https://fastapi.tiangolo.com/tutorial/header-params/#automatic-conversion)
+ """
+ ),
+ ] = True,
+ title: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable title.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable description.
+ """
+ ),
+ ] = None,
+ gt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than. If set, value must be greater than this. Only applicable to
+ numbers.
+ """
+ ),
+ ] = None,
+ ge: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than or equal. If set, value must be greater than or equal to
+ this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ lt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than. If set, value must be less than this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ le: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than or equal. If set, value must be less than or equal to this.
+ Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ min_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Minimum length for strings.
+ """
+ ),
+ ] = None,
+ max_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Maximum length for strings.
+ """
+ ),
+ ] = None,
+ pattern: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ ] = None,
regex: Annotated[
Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
deprecated(
"Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
),
] = None,
- discriminator: Union[str, None] = None,
- strict: Union[bool, None] = _Unset,
- multiple_of: Union[float, None] = _Unset,
- allow_inf_nan: Union[bool, None] = _Unset,
- max_digits: Union[int, None] = _Unset,
- decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ discriminator: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ Parameter field name for discriminating the type in a tagged union.
+ """
+ ),
+ ] = None,
+ strict: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ If `True`, strict validation is applied to the field.
+ """
+ ),
+ ] = _Unset,
+ multiple_of: Annotated[
+ Union[float, None],
+ Doc(
+ """
+ Value must be a multiple of this. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ allow_inf_nan: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ max_digits: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of allow digits for strings.
+ """
+ ),
+ ] = _Unset,
+ decimal_places: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of decimal places allowed for numbers.
+ """
+ ),
+ ] = _Unset,
+ examples: Annotated[
+ Optional[List[Any]],
+ Doc(
+ """
+ Example values for this field.
+ """
+ ),
+ ] = None,
example: Annotated[
Optional[Any],
deprecated(
@@ -199,10 +862,65 @@ def Header( # noqa: N802
"although still supported. Use examples instead."
),
] = _Unset,
- deprecated: Optional[bool] = None,
- include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
- **extra: Any,
+ openapi_examples: Annotated[
+ Optional[Dict[str, Example]],
+ Doc(
+ """
+ OpenAPI-specific examples.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Swagger UI (that provides the `/docs` interface) has better support for the
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+ use case for this.
+
+ Read more about it in the
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this parameter field as deprecated.
+
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ To include (or not) this parameter field in the generated OpenAPI.
+ You probably don't need it, but it's available.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = True,
+ json_schema_extra: Annotated[
+ Union[Dict[str, Any], None],
+ Doc(
+ """
+ Any additional JSON schema data.
+ """
+ ),
+ ] = None,
+ **extra: Annotated[
+ Any,
+ Doc(
+ """
+ Include extra fields used by the JSON Schema.
+ """
+ ),
+ deprecated(
+ """
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+ """
+ ),
+ ],
) -> Any:
return params.Header(
default=default,
@@ -230,6 +948,7 @@ def Header( # noqa: N802
decimal_places=decimal_places,
example=example,
examples=examples,
+ openapi_examples=openapi_examples,
deprecated=deprecated,
include_in_schema=include_in_schema,
json_schema_extra=json_schema_extra,
@@ -238,37 +957,209 @@ def Header( # noqa: N802
def Cookie( # noqa: N802
- default: Any = Undefined,
+ default: Annotated[
+ Any,
+ Doc(
+ """
+ Default value if the parameter field is not set.
+ """
+ ),
+ ] = Undefined,
*,
- default_factory: Union[Callable[[], Any], None] = _Unset,
- alias: Optional[str] = None,
- alias_priority: Union[int, None] = _Unset,
+ default_factory: Annotated[
+ Union[Callable[[], Any], None],
+ Doc(
+ """
+ A callable to generate the default value.
+
+ This doesn't affect `Path` parameters as the value is always required.
+ The parameter is available only for compatibility.
+ """
+ ),
+ ] = _Unset,
+ alias: Annotated[
+ Optional[str],
+ Doc(
+ """
+ An alternative name for the parameter field.
+
+ This will be used to extract the data and for the generated OpenAPI.
+ It is particularly useful when you can't use the name you want because it
+ is a Python reserved keyword or similar.
+ """
+ ),
+ ] = None,
+ alias_priority: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Priority of the alias. This affects whether an alias generator is used.
+ """
+ ),
+ ] = _Unset,
# TODO: update when deprecating Pydantic v1, import these types
# validation_alias: str | AliasPath | AliasChoices | None
- validation_alias: Union[str, None] = None,
- serialization_alias: Union[str, None] = None,
- title: Optional[str] = None,
- description: Optional[str] = None,
- gt: Optional[float] = None,
- ge: Optional[float] = None,
- lt: Optional[float] = None,
- le: Optional[float] = None,
- min_length: Optional[int] = None,
- max_length: Optional[int] = None,
- pattern: Optional[str] = None,
+ validation_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Whitelist' validation step. The parameter field will be the single one
+ allowed by the alias or set of aliases defined.
+ """
+ ),
+ ] = None,
+ serialization_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Blacklist' validation step. The vanilla parameter field will be the
+ single one of the alias' or set of aliases' fields and all the other
+ fields will be ignored at serialization time.
+ """
+ ),
+ ] = None,
+ title: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable title.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable description.
+ """
+ ),
+ ] = None,
+ gt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than. If set, value must be greater than this. Only applicable to
+ numbers.
+ """
+ ),
+ ] = None,
+ ge: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than or equal. If set, value must be greater than or equal to
+ this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ lt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than. If set, value must be less than this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ le: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than or equal. If set, value must be less than or equal to this.
+ Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ min_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Minimum length for strings.
+ """
+ ),
+ ] = None,
+ max_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Maximum length for strings.
+ """
+ ),
+ ] = None,
+ pattern: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ ] = None,
regex: Annotated[
Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
deprecated(
"Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
),
] = None,
- discriminator: Union[str, None] = None,
- strict: Union[bool, None] = _Unset,
- multiple_of: Union[float, None] = _Unset,
- allow_inf_nan: Union[bool, None] = _Unset,
- max_digits: Union[int, None] = _Unset,
- decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ discriminator: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ Parameter field name for discriminating the type in a tagged union.
+ """
+ ),
+ ] = None,
+ strict: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ If `True`, strict validation is applied to the field.
+ """
+ ),
+ ] = _Unset,
+ multiple_of: Annotated[
+ Union[float, None],
+ Doc(
+ """
+ Value must be a multiple of this. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ allow_inf_nan: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ max_digits: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of allow digits for strings.
+ """
+ ),
+ ] = _Unset,
+ decimal_places: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of decimal places allowed for numbers.
+ """
+ ),
+ ] = _Unset,
+ examples: Annotated[
+ Optional[List[Any]],
+ Doc(
+ """
+ Example values for this field.
+ """
+ ),
+ ] = None,
example: Annotated[
Optional[Any],
deprecated(
@@ -276,10 +1167,65 @@ def Cookie( # noqa: N802
"although still supported. Use examples instead."
),
] = _Unset,
- deprecated: Optional[bool] = None,
- include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
- **extra: Any,
+ openapi_examples: Annotated[
+ Optional[Dict[str, Example]],
+ Doc(
+ """
+ OpenAPI-specific examples.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Swagger UI (that provides the `/docs` interface) has better support for the
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+ use case for this.
+
+ Read more about it in the
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this parameter field as deprecated.
+
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ To include (or not) this parameter field in the generated OpenAPI.
+ You probably don't need it, but it's available.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = True,
+ json_schema_extra: Annotated[
+ Union[Dict[str, Any], None],
+ Doc(
+ """
+ Any additional JSON schema data.
+ """
+ ),
+ ] = None,
+ **extra: Annotated[
+ Any,
+ Doc(
+ """
+ Include extra fields used by the JSON Schema.
+ """
+ ),
+ deprecated(
+ """
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+ """
+ ),
+ ],
) -> Any:
return params.Cookie(
default=default,
@@ -306,6 +1252,7 @@ def Cookie( # noqa: N802
decimal_places=decimal_places,
example=example,
examples=examples,
+ openapi_examples=openapi_examples,
deprecated=deprecated,
include_in_schema=include_in_schema,
json_schema_extra=json_schema_extra,
@@ -314,39 +1261,232 @@ def Cookie( # noqa: N802
def Body( # noqa: N802
- default: Any = Undefined,
+ default: Annotated[
+ Any,
+ Doc(
+ """
+ Default value if the parameter field is not set.
+ """
+ ),
+ ] = Undefined,
*,
- default_factory: Union[Callable[[], Any], None] = _Unset,
- embed: bool = False,
- media_type: str = "application/json",
- alias: Optional[str] = None,
- alias_priority: Union[int, None] = _Unset,
+ default_factory: Annotated[
+ Union[Callable[[], Any], None],
+ Doc(
+ """
+ A callable to generate the default value.
+
+ This doesn't affect `Path` parameters as the value is always required.
+ The parameter is available only for compatibility.
+ """
+ ),
+ ] = _Unset,
+ embed: Annotated[
+ bool,
+ Doc(
+ """
+ When `embed` is `True`, the parameter will be expected in a JSON body as a
+ key instead of being the JSON body itself.
+
+ This happens automatically when more than one `Body` parameter is declared.
+
+ Read more about it in the
+ [FastAPI docs for Body - Multiple Parameters](https://fastapi.tiangolo.com/tutorial/body-multiple-params/#embed-a-single-body-parameter).
+ """
+ ),
+ ] = False,
+ media_type: Annotated[
+ str,
+ Doc(
+ """
+ The media type of this parameter field. Changing it would affect the
+ generated OpenAPI, but currently it doesn't affect the parsing of the data.
+ """
+ ),
+ ] = "application/json",
+ alias: Annotated[
+ Optional[str],
+ Doc(
+ """
+ An alternative name for the parameter field.
+
+ This will be used to extract the data and for the generated OpenAPI.
+ It is particularly useful when you can't use the name you want because it
+ is a Python reserved keyword or similar.
+ """
+ ),
+ ] = None,
+ alias_priority: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Priority of the alias. This affects whether an alias generator is used.
+ """
+ ),
+ ] = _Unset,
# TODO: update when deprecating Pydantic v1, import these types
# validation_alias: str | AliasPath | AliasChoices | None
- validation_alias: Union[str, None] = None,
- serialization_alias: Union[str, None] = None,
- title: Optional[str] = None,
- description: Optional[str] = None,
- gt: Optional[float] = None,
- ge: Optional[float] = None,
- lt: Optional[float] = None,
- le: Optional[float] = None,
- min_length: Optional[int] = None,
- max_length: Optional[int] = None,
- pattern: Optional[str] = None,
+ validation_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Whitelist' validation step. The parameter field will be the single one
+ allowed by the alias or set of aliases defined.
+ """
+ ),
+ ] = None,
+ serialization_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Blacklist' validation step. The vanilla parameter field will be the
+ single one of the alias' or set of aliases' fields and all the other
+ fields will be ignored at serialization time.
+ """
+ ),
+ ] = None,
+ title: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable title.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable description.
+ """
+ ),
+ ] = None,
+ gt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than. If set, value must be greater than this. Only applicable to
+ numbers.
+ """
+ ),
+ ] = None,
+ ge: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than or equal. If set, value must be greater than or equal to
+ this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ lt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than. If set, value must be less than this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ le: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than or equal. If set, value must be less than or equal to this.
+ Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ min_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Minimum length for strings.
+ """
+ ),
+ ] = None,
+ max_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Maximum length for strings.
+ """
+ ),
+ ] = None,
+ pattern: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ ] = None,
regex: Annotated[
Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
deprecated(
"Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
),
] = None,
- discriminator: Union[str, None] = None,
- strict: Union[bool, None] = _Unset,
- multiple_of: Union[float, None] = _Unset,
- allow_inf_nan: Union[bool, None] = _Unset,
- max_digits: Union[int, None] = _Unset,
- decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ discriminator: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ Parameter field name for discriminating the type in a tagged union.
+ """
+ ),
+ ] = None,
+ strict: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ If `True`, strict validation is applied to the field.
+ """
+ ),
+ ] = _Unset,
+ multiple_of: Annotated[
+ Union[float, None],
+ Doc(
+ """
+ Value must be a multiple of this. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ allow_inf_nan: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ max_digits: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of allow digits for strings.
+ """
+ ),
+ ] = _Unset,
+ decimal_places: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of decimal places allowed for numbers.
+ """
+ ),
+ ] = _Unset,
+ examples: Annotated[
+ Optional[List[Any]],
+ Doc(
+ """
+ Example values for this field.
+ """
+ ),
+ ] = None,
example: Annotated[
Optional[Any],
deprecated(
@@ -354,10 +1494,65 @@ def Body( # noqa: N802
"although still supported. Use examples instead."
),
] = _Unset,
- deprecated: Optional[bool] = None,
- include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
- **extra: Any,
+ openapi_examples: Annotated[
+ Optional[Dict[str, Example]],
+ Doc(
+ """
+ OpenAPI-specific examples.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Swagger UI (that provides the `/docs` interface) has better support for the
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+ use case for this.
+
+ Read more about it in the
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this parameter field as deprecated.
+
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ To include (or not) this parameter field in the generated OpenAPI.
+ You probably don't need it, but it's available.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = True,
+ json_schema_extra: Annotated[
+ Union[Dict[str, Any], None],
+ Doc(
+ """
+ Any additional JSON schema data.
+ """
+ ),
+ ] = None,
+ **extra: Annotated[
+ Any,
+ Doc(
+ """
+ Include extra fields used by the JSON Schema.
+ """
+ ),
+ deprecated(
+ """
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+ """
+ ),
+ ],
) -> Any:
return params.Body(
default=default,
@@ -386,6 +1581,7 @@ def Body( # noqa: N802
decimal_places=decimal_places,
example=example,
examples=examples,
+ openapi_examples=openapi_examples,
deprecated=deprecated,
include_in_schema=include_in_schema,
json_schema_extra=json_schema_extra,
@@ -394,38 +1590,218 @@ def Body( # noqa: N802
def Form( # noqa: N802
- default: Any = Undefined,
+ default: Annotated[
+ Any,
+ Doc(
+ """
+ Default value if the parameter field is not set.
+ """
+ ),
+ ] = Undefined,
*,
- default_factory: Union[Callable[[], Any], None] = _Unset,
- media_type: str = "application/x-www-form-urlencoded",
- alias: Optional[str] = None,
- alias_priority: Union[int, None] = _Unset,
+ default_factory: Annotated[
+ Union[Callable[[], Any], None],
+ Doc(
+ """
+ A callable to generate the default value.
+
+ This doesn't affect `Path` parameters as the value is always required.
+ The parameter is available only for compatibility.
+ """
+ ),
+ ] = _Unset,
+ media_type: Annotated[
+ str,
+ Doc(
+ """
+ The media type of this parameter field. Changing it would affect the
+ generated OpenAPI, but currently it doesn't affect the parsing of the data.
+ """
+ ),
+ ] = "application/x-www-form-urlencoded",
+ alias: Annotated[
+ Optional[str],
+ Doc(
+ """
+ An alternative name for the parameter field.
+
+ This will be used to extract the data and for the generated OpenAPI.
+ It is particularly useful when you can't use the name you want because it
+ is a Python reserved keyword or similar.
+ """
+ ),
+ ] = None,
+ alias_priority: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Priority of the alias. This affects whether an alias generator is used.
+ """
+ ),
+ ] = _Unset,
# TODO: update when deprecating Pydantic v1, import these types
# validation_alias: str | AliasPath | AliasChoices | None
- validation_alias: Union[str, None] = None,
- serialization_alias: Union[str, None] = None,
- title: Optional[str] = None,
- description: Optional[str] = None,
- gt: Optional[float] = None,
- ge: Optional[float] = None,
- lt: Optional[float] = None,
- le: Optional[float] = None,
- min_length: Optional[int] = None,
- max_length: Optional[int] = None,
- pattern: Optional[str] = None,
+ validation_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Whitelist' validation step. The parameter field will be the single one
+ allowed by the alias or set of aliases defined.
+ """
+ ),
+ ] = None,
+ serialization_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Blacklist' validation step. The vanilla parameter field will be the
+ single one of the alias' or set of aliases' fields and all the other
+ fields will be ignored at serialization time.
+ """
+ ),
+ ] = None,
+ title: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable title.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable description.
+ """
+ ),
+ ] = None,
+ gt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than. If set, value must be greater than this. Only applicable to
+ numbers.
+ """
+ ),
+ ] = None,
+ ge: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than or equal. If set, value must be greater than or equal to
+ this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ lt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than. If set, value must be less than this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ le: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than or equal. If set, value must be less than or equal to this.
+ Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ min_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Minimum length for strings.
+ """
+ ),
+ ] = None,
+ max_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Maximum length for strings.
+ """
+ ),
+ ] = None,
+ pattern: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ ] = None,
regex: Annotated[
Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
deprecated(
"Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
),
] = None,
- discriminator: Union[str, None] = None,
- strict: Union[bool, None] = _Unset,
- multiple_of: Union[float, None] = _Unset,
- allow_inf_nan: Union[bool, None] = _Unset,
- max_digits: Union[int, None] = _Unset,
- decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ discriminator: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ Parameter field name for discriminating the type in a tagged union.
+ """
+ ),
+ ] = None,
+ strict: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ If `True`, strict validation is applied to the field.
+ """
+ ),
+ ] = _Unset,
+ multiple_of: Annotated[
+ Union[float, None],
+ Doc(
+ """
+ Value must be a multiple of this. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ allow_inf_nan: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ max_digits: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of allow digits for strings.
+ """
+ ),
+ ] = _Unset,
+ decimal_places: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of decimal places allowed for numbers.
+ """
+ ),
+ ] = _Unset,
+ examples: Annotated[
+ Optional[List[Any]],
+ Doc(
+ """
+ Example values for this field.
+ """
+ ),
+ ] = None,
example: Annotated[
Optional[Any],
deprecated(
@@ -433,10 +1809,65 @@ def Form( # noqa: N802
"although still supported. Use examples instead."
),
] = _Unset,
- deprecated: Optional[bool] = None,
- include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
- **extra: Any,
+ openapi_examples: Annotated[
+ Optional[Dict[str, Example]],
+ Doc(
+ """
+ OpenAPI-specific examples.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Swagger UI (that provides the `/docs` interface) has better support for the
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+ use case for this.
+
+ Read more about it in the
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this parameter field as deprecated.
+
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ To include (or not) this parameter field in the generated OpenAPI.
+ You probably don't need it, but it's available.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = True,
+ json_schema_extra: Annotated[
+ Union[Dict[str, Any], None],
+ Doc(
+ """
+ Any additional JSON schema data.
+ """
+ ),
+ ] = None,
+ **extra: Annotated[
+ Any,
+ Doc(
+ """
+ Include extra fields used by the JSON Schema.
+ """
+ ),
+ deprecated(
+ """
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+ """
+ ),
+ ],
) -> Any:
return params.Form(
default=default,
@@ -464,6 +1895,7 @@ def Form( # noqa: N802
decimal_places=decimal_places,
example=example,
examples=examples,
+ openapi_examples=openapi_examples,
deprecated=deprecated,
include_in_schema=include_in_schema,
json_schema_extra=json_schema_extra,
@@ -472,38 +1904,218 @@ def Form( # noqa: N802
def File( # noqa: N802
- default: Any = Undefined,
+ default: Annotated[
+ Any,
+ Doc(
+ """
+ Default value if the parameter field is not set.
+ """
+ ),
+ ] = Undefined,
*,
- default_factory: Union[Callable[[], Any], None] = _Unset,
- media_type: str = "multipart/form-data",
- alias: Optional[str] = None,
- alias_priority: Union[int, None] = _Unset,
+ default_factory: Annotated[
+ Union[Callable[[], Any], None],
+ Doc(
+ """
+ A callable to generate the default value.
+
+ This doesn't affect `Path` parameters as the value is always required.
+ The parameter is available only for compatibility.
+ """
+ ),
+ ] = _Unset,
+ media_type: Annotated[
+ str,
+ Doc(
+ """
+ The media type of this parameter field. Changing it would affect the
+ generated OpenAPI, but currently it doesn't affect the parsing of the data.
+ """
+ ),
+ ] = "multipart/form-data",
+ alias: Annotated[
+ Optional[str],
+ Doc(
+ """
+ An alternative name for the parameter field.
+
+ This will be used to extract the data and for the generated OpenAPI.
+ It is particularly useful when you can't use the name you want because it
+ is a Python reserved keyword or similar.
+ """
+ ),
+ ] = None,
+ alias_priority: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Priority of the alias. This affects whether an alias generator is used.
+ """
+ ),
+ ] = _Unset,
# TODO: update when deprecating Pydantic v1, import these types
# validation_alias: str | AliasPath | AliasChoices | None
- validation_alias: Union[str, None] = None,
- serialization_alias: Union[str, None] = None,
- title: Optional[str] = None,
- description: Optional[str] = None,
- gt: Optional[float] = None,
- ge: Optional[float] = None,
- lt: Optional[float] = None,
- le: Optional[float] = None,
- min_length: Optional[int] = None,
- max_length: Optional[int] = None,
- pattern: Optional[str] = None,
+ validation_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Whitelist' validation step. The parameter field will be the single one
+ allowed by the alias or set of aliases defined.
+ """
+ ),
+ ] = None,
+ serialization_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Blacklist' validation step. The vanilla parameter field will be the
+ single one of the alias' or set of aliases' fields and all the other
+ fields will be ignored at serialization time.
+ """
+ ),
+ ] = None,
+ title: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable title.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable description.
+ """
+ ),
+ ] = None,
+ gt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than. If set, value must be greater than this. Only applicable to
+ numbers.
+ """
+ ),
+ ] = None,
+ ge: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than or equal. If set, value must be greater than or equal to
+ this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ lt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than. If set, value must be less than this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ le: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than or equal. If set, value must be less than or equal to this.
+ Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ min_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Minimum length for strings.
+ """
+ ),
+ ] = None,
+ max_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Maximum length for strings.
+ """
+ ),
+ ] = None,
+ pattern: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ ] = None,
regex: Annotated[
Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
deprecated(
"Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
),
] = None,
- discriminator: Union[str, None] = None,
- strict: Union[bool, None] = _Unset,
- multiple_of: Union[float, None] = _Unset,
- allow_inf_nan: Union[bool, None] = _Unset,
- max_digits: Union[int, None] = _Unset,
- decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ discriminator: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ Parameter field name for discriminating the type in a tagged union.
+ """
+ ),
+ ] = None,
+ strict: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ If `True`, strict validation is applied to the field.
+ """
+ ),
+ ] = _Unset,
+ multiple_of: Annotated[
+ Union[float, None],
+ Doc(
+ """
+ Value must be a multiple of this. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ allow_inf_nan: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ max_digits: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of allow digits for strings.
+ """
+ ),
+ ] = _Unset,
+ decimal_places: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of decimal places allowed for numbers.
+ """
+ ),
+ ] = _Unset,
+ examples: Annotated[
+ Optional[List[Any]],
+ Doc(
+ """
+ Example values for this field.
+ """
+ ),
+ ] = None,
example: Annotated[
Optional[Any],
deprecated(
@@ -511,10 +2123,65 @@ def File( # noqa: N802
"although still supported. Use examples instead."
),
] = _Unset,
- deprecated: Optional[bool] = None,
- include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
- **extra: Any,
+ openapi_examples: Annotated[
+ Optional[Dict[str, Example]],
+ Doc(
+ """
+ OpenAPI-specific examples.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Swagger UI (that provides the `/docs` interface) has better support for the
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+ use case for this.
+
+ Read more about it in the
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this parameter field as deprecated.
+
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ To include (or not) this parameter field in the generated OpenAPI.
+ You probably don't need it, but it's available.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = True,
+ json_schema_extra: Annotated[
+ Union[Dict[str, Any], None],
+ Doc(
+ """
+ Any additional JSON schema data.
+ """
+ ),
+ ] = None,
+ **extra: Annotated[
+ Any,
+ Doc(
+ """
+ Include extra fields used by the JSON Schema.
+ """
+ ),
+ deprecated(
+ """
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+ """
+ ),
+ ],
) -> Any:
return params.File(
default=default,
@@ -542,6 +2209,7 @@ def File( # noqa: N802
decimal_places=decimal_places,
example=example,
examples=examples,
+ openapi_examples=openapi_examples,
deprecated=deprecated,
include_in_schema=include_in_schema,
json_schema_extra=json_schema_extra,
@@ -550,15 +2218,143 @@ def File( # noqa: N802
def Depends( # noqa: N802
- dependency: Optional[Callable[..., Any]] = None, *, use_cache: bool = True
+ dependency: Annotated[
+ Optional[Callable[..., Any]],
+ Doc(
+ """
+ A "dependable" callable (like a function).
+
+ Don't call it directly, FastAPI will call it for you, just pass the object
+ directly.
+ """
+ ),
+ ] = None,
+ *,
+ use_cache: Annotated[
+ bool,
+ Doc(
+ """
+ By default, after a dependency is called the first time in a request, if
+ the dependency is declared again for the rest of the request (for example
+ if the dependency is needed by several dependencies), the value will be
+ re-used for the rest of the request.
+
+ Set `use_cache` to `False` to disable this behavior and ensure the
+ dependency is called again (if declared more than once) in the same request.
+ """
+ ),
+ ] = True,
) -> Any:
+ """
+ Declare a FastAPI dependency.
+
+ It takes a single "dependable" callable (like a function).
+
+ Don't call it directly, FastAPI will call it for you.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies](https://fastapi.tiangolo.com/tutorial/dependencies/).
+
+ **Example**
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import Depends, FastAPI
+
+ app = FastAPI()
+
+
+ async def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):
+ return {"q": q, "skip": skip, "limit": limit}
+
+
+ @app.get("/items/")
+ async def read_items(commons: Annotated[dict, Depends(common_parameters)]):
+ return commons
+ ```
+ """
return params.Depends(dependency=dependency, use_cache=use_cache)
def Security( # noqa: N802
- dependency: Optional[Callable[..., Any]] = None,
+ dependency: Annotated[
+ Optional[Callable[..., Any]],
+ Doc(
+ """
+ A "dependable" callable (like a function).
+
+ Don't call it directly, FastAPI will call it for you, just pass the object
+ directly.
+ """
+ ),
+ ] = None,
*,
- scopes: Optional[Sequence[str]] = None,
- use_cache: bool = True,
+ scopes: Annotated[
+ Optional[Sequence[str]],
+ Doc(
+ """
+ OAuth2 scopes required for the *path operation* that uses this Security
+ dependency.
+
+ The term "scope" comes from the OAuth2 specification, it seems to be
+ intentionaly vague and interpretable. It normally refers to permissions,
+ in cases to roles.
+
+ These scopes are integrated with OpenAPI (and the API docs at `/docs`).
+ So they are visible in the OpenAPI specification.
+ )
+ """
+ ),
+ ] = None,
+ use_cache: Annotated[
+ bool,
+ Doc(
+ """
+ By default, after a dependency is called the first time in a request, if
+ the dependency is declared again for the rest of the request (for example
+ if the dependency is needed by several dependencies), the value will be
+ re-used for the rest of the request.
+
+ Set `use_cache` to `False` to disable this behavior and ensure the
+ dependency is called again (if declared more than once) in the same request.
+ """
+ ),
+ ] = True,
) -> Any:
+ """
+ Declare a FastAPI Security dependency.
+
+ The only difference with a regular dependency is that it can declare OAuth2
+ scopes that will be integrated with OpenAPI and the automatic UI docs (by default
+ at `/docs`).
+
+ It takes a single "dependable" callable (like a function).
+
+ Don't call it directly, FastAPI will call it for you.
+
+ Read more about it in the
+ [FastAPI docs for Security](https://fastapi.tiangolo.com/tutorial/security/) and
+ in the
+ [FastAPI docs for OAuth2 scopes](https://fastapi.tiangolo.com/advanced/security/oauth2-scopes/).
+
+ **Example**
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import Depends, FastAPI
+
+ from .db import User
+ from .security import get_current_active_user
+
+ app = FastAPI()
+
+ @app.get("/users/me/items/")
+ async def read_own_items(
+ current_user: Annotated[User, Security(get_current_active_user, scopes=["items"])]
+ ):
+ return [{"item_id": "Foo", "owner": current_user.username}]
+ ```
+ """
return params.Security(dependency=dependency, scopes=scopes, use_cache=use_cache)
diff --git a/fastapi/params.py b/fastapi/params.py
index 2d8100650..b40944dba 100644
--- a/fastapi/params.py
+++ b/fastapi/params.py
@@ -2,6 +2,7 @@ import warnings
from enum import Enum
from typing import Any, Callable, Dict, List, Optional, Sequence, Union
+from fastapi.openapi.models import Example
from pydantic.fields import FieldInfo
from typing_extensions import Annotated, deprecated
@@ -61,6 +62,7 @@ class Param(FieldInfo):
"although still supported. Use examples instead."
),
] = _Unset,
+ openapi_examples: Optional[Dict[str, Example]] = None,
deprecated: Optional[bool] = None,
include_in_schema: bool = True,
json_schema_extra: Union[Dict[str, Any], None] = None,
@@ -75,6 +77,7 @@ class Param(FieldInfo):
)
self.example = example
self.include_in_schema = include_in_schema
+ self.openapi_examples = openapi_examples
kwargs = dict(
default=default,
default_factory=default_factory,
@@ -170,6 +173,7 @@ class Path(Param):
"although still supported. Use examples instead."
),
] = _Unset,
+ openapi_examples: Optional[Dict[str, Example]] = None,
deprecated: Optional[bool] = None,
include_in_schema: bool = True,
json_schema_extra: Union[Dict[str, Any], None] = None,
@@ -204,6 +208,7 @@ class Path(Param):
deprecated=deprecated,
example=example,
examples=examples,
+ openapi_examples=openapi_examples,
include_in_schema=include_in_schema,
json_schema_extra=json_schema_extra,
**extra,
@@ -254,6 +259,7 @@ class Query(Param):
"although still supported. Use examples instead."
),
] = _Unset,
+ openapi_examples: Optional[Dict[str, Example]] = None,
deprecated: Optional[bool] = None,
include_in_schema: bool = True,
json_schema_extra: Union[Dict[str, Any], None] = None,
@@ -286,6 +292,7 @@ class Query(Param):
deprecated=deprecated,
example=example,
examples=examples,
+ openapi_examples=openapi_examples,
include_in_schema=include_in_schema,
json_schema_extra=json_schema_extra,
**extra,
@@ -337,6 +344,7 @@ class Header(Param):
"although still supported. Use examples instead."
),
] = _Unset,
+ openapi_examples: Optional[Dict[str, Example]] = None,
deprecated: Optional[bool] = None,
include_in_schema: bool = True,
json_schema_extra: Union[Dict[str, Any], None] = None,
@@ -370,6 +378,7 @@ class Header(Param):
deprecated=deprecated,
example=example,
examples=examples,
+ openapi_examples=openapi_examples,
include_in_schema=include_in_schema,
json_schema_extra=json_schema_extra,
**extra,
@@ -420,6 +429,7 @@ class Cookie(Param):
"although still supported. Use examples instead."
),
] = _Unset,
+ openapi_examples: Optional[Dict[str, Example]] = None,
deprecated: Optional[bool] = None,
include_in_schema: bool = True,
json_schema_extra: Union[Dict[str, Any], None] = None,
@@ -452,6 +462,7 @@ class Cookie(Param):
deprecated=deprecated,
example=example,
examples=examples,
+ openapi_examples=openapi_examples,
include_in_schema=include_in_schema,
json_schema_extra=json_schema_extra,
**extra,
@@ -502,6 +513,7 @@ class Body(FieldInfo):
"although still supported. Use examples instead."
),
] = _Unset,
+ openapi_examples: Optional[Dict[str, Example]] = None,
deprecated: Optional[bool] = None,
include_in_schema: bool = True,
json_schema_extra: Union[Dict[str, Any], None] = None,
@@ -518,6 +530,7 @@ class Body(FieldInfo):
)
self.example = example
self.include_in_schema = include_in_schema
+ self.openapi_examples = openapi_examples
kwargs = dict(
default=default,
default_factory=default_factory,
@@ -613,6 +626,7 @@ class Form(Body):
"although still supported. Use examples instead."
),
] = _Unset,
+ openapi_examples: Optional[Dict[str, Example]] = None,
deprecated: Optional[bool] = None,
include_in_schema: bool = True,
json_schema_extra: Union[Dict[str, Any], None] = None,
@@ -647,6 +661,7 @@ class Form(Body):
deprecated=deprecated,
example=example,
examples=examples,
+ openapi_examples=openapi_examples,
include_in_schema=include_in_schema,
json_schema_extra=json_schema_extra,
**extra,
@@ -696,6 +711,7 @@ class File(Form):
"although still supported. Use examples instead."
),
] = _Unset,
+ openapi_examples: Optional[Dict[str, Example]] = None,
deprecated: Optional[bool] = None,
include_in_schema: bool = True,
json_schema_extra: Union[Dict[str, Any], None] = None,
@@ -729,6 +745,7 @@ class File(Form):
deprecated=deprecated,
example=example,
examples=examples,
+ openapi_examples=openapi_examples,
include_in_schema=include_in_schema,
json_schema_extra=json_schema_extra,
**extra,
diff --git a/fastapi/responses.py b/fastapi/responses.py
index c0a13b755..6c8db6f33 100644
--- a/fastapi/responses.py
+++ b/fastapi/responses.py
@@ -21,12 +21,26 @@ except ImportError: # pragma: nocover
class UJSONResponse(JSONResponse):
+ """
+ JSON response using the high-performance ujson library to serialize data to JSON.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/).
+ """
+
def render(self, content: Any) -> bytes:
assert ujson is not None, "ujson must be installed to use UJSONResponse"
return ujson.dumps(content, ensure_ascii=False).encode("utf-8")
class ORJSONResponse(JSONResponse):
+ """
+ JSON response using the high-performance orjson library to serialize data to JSON.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/).
+ """
+
def render(self, content: Any) -> bytes:
assert orjson is not None, "orjson must be installed to use ORJSONResponse"
return orjson.dumps(
diff --git a/fastapi/routing.py b/fastapi/routing.py
index 1e3dfb4d5..54d53bbbf 100644
--- a/fastapi/routing.py
+++ b/fastapi/routing.py
@@ -69,6 +69,7 @@ from starlette.routing import (
from starlette.routing import Mount as Mount # noqa
from starlette.types import ASGIApp, Lifespan, Scope
from starlette.websockets import WebSocket
+from typing_extensions import Annotated, Doc, deprecated # type: ignore [attr-defined]
def _prepare_response_content(
@@ -519,30 +520,246 @@ class APIRoute(routing.Route):
class APIRouter(routing.Router):
+ """
+ `APIRouter` class, used to group *path operations*, for example to structure
+ an app in multiple files. It would then be included in the `FastAPI` app, or
+ in another `APIRouter` (ultimately included in the app).
+
+ Read more about it in the
+ [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/).
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+
+ app = FastAPI()
+ router = APIRouter()
+
+
+ @router.get("/users/", tags=["users"])
+ async def read_users():
+ return [{"username": "Rick"}, {"username": "Morty"}]
+
+
+ app.include_router(router)
+ ```
+ """
+
def __init__(
self,
*,
- prefix: str = "",
- tags: Optional[List[Union[str, Enum]]] = None,
- dependencies: Optional[Sequence[params.Depends]] = None,
- default_response_class: Type[Response] = Default(JSONResponse),
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- routes: Optional[List[routing.BaseRoute]] = None,
- redirect_slashes: bool = True,
- default: Optional[ASGIApp] = None,
- dependency_overrides_provider: Optional[Any] = None,
- route_class: Type[APIRoute] = APIRoute,
- on_startup: Optional[Sequence[Callable[[], Any]]] = None,
- on_shutdown: Optional[Sequence[Callable[[], Any]]] = None,
+ prefix: Annotated[str, Doc("An optional path prefix for the router.")] = "",
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to all the *path operations* in this
+ router.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to all the
+ *path operations* in this router.
+
+ Read more about it in the
+ [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+ """
+ ),
+ ] = None,
+ default_response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ The default response class to be used.
+
+ Read more in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class).
+ """
+ ),
+ ] = Default(JSONResponse),
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses to be shown in OpenAPI.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Additional Responses in OpenAPI](https://fastapi.tiangolo.com/advanced/additional-responses/).
+
+ And in the
+ [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ OpenAPI callbacks that should apply to all *path operations* in this
+ router.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ routes: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ **Note**: you probably shouldn't use this parameter, it is inherited
+ from Starlette and supported for compatibility.
+
+ ---
+
+ A list of routes to serve incoming HTTP and WebSocket requests.
+ """
+ ),
+ deprecated(
+ """
+ You normally wouldn't use this parameter with FastAPI, it is inherited
+ from Starlette and supported for compatibility.
+
+ In FastAPI, you normally would use the *path operation methods*,
+ like `router.get()`, `router.post()`, etc.
+ """
+ ),
+ ] = None,
+ redirect_slashes: Annotated[
+ bool,
+ Doc(
+ """
+ Whether to detect and redirect slashes in URLs when the client doesn't
+ use the same format.
+ """
+ ),
+ ] = True,
+ default: Annotated[
+ Optional[ASGIApp],
+ Doc(
+ """
+ Default function handler for this router. Used to handle
+ 404 Not Found errors.
+ """
+ ),
+ ] = None,
+ dependency_overrides_provider: Annotated[
+ Optional[Any],
+ Doc(
+ """
+ Only used internally by FastAPI to handle dependency overrides.
+
+ You shouldn't need to use it. It normally points to the `FastAPI` app
+ object.
+ """
+ ),
+ ] = None,
+ route_class: Annotated[
+ Type[APIRoute],
+ Doc(
+ """
+ Custom route (*path operation*) class to be used by this router.
+
+ Read more about it in the
+ [FastAPI docs for Custom Request and APIRoute class](https://fastapi.tiangolo.com/how-to/custom-request-and-route/#custom-apiroute-class-in-a-router).
+ """
+ ),
+ ] = APIRoute,
+ on_startup: Annotated[
+ Optional[Sequence[Callable[[], Any]]],
+ Doc(
+ """
+ A list of startup event handler functions.
+
+ You should instead use the `lifespan` handlers.
+
+ Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/).
+ """
+ ),
+ ] = None,
+ on_shutdown: Annotated[
+ Optional[Sequence[Callable[[], Any]]],
+ Doc(
+ """
+ A list of shutdown event handler functions.
+
+ You should instead use the `lifespan` handlers.
+
+ Read more in the
+ [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/).
+ """
+ ),
+ ] = None,
# the generic to Lifespan[AppType] is the type of the top level application
# which the router cannot know statically, so we use typing.Any
- lifespan: Optional[Lifespan[Any]] = None,
- deprecated: Optional[bool] = None,
- include_in_schema: bool = True,
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
- generate_unique_id
- ),
+ lifespan: Annotated[
+ Optional[Lifespan[Any]],
+ Doc(
+ """
+ A `Lifespan` context manager handler. This replaces `startup` and
+ `shutdown` functions with a single context manager.
+
+ Read more in the
+ [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark all *path operations* in this router as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ To include (or not) all the *path operations* in this router in the
+ generated OpenAPI.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+ """
+ ),
+ ] = True,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
) -> None:
super().__init__(
routes=routes,
@@ -755,11 +972,63 @@ class APIRouter(routing.Router):
def websocket(
self,
- path: str,
- name: Optional[str] = None,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ WebSocket path.
+ """
+ ),
+ ],
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A name for the WebSocket. Only used internally.
+ """
+ ),
+ ] = None,
*,
- dependencies: Optional[Sequence[params.Depends]] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be used for this
+ WebSocket.
+
+ Read more about it in the
+ [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/).
+ """
+ ),
+ ] = None,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Decorate a WebSocket function.
+
+ Read more about it in the
+ [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/).
+
+ **Example**
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI, WebSocket
+
+ app = FastAPI()
+ router = APIRouter()
+
+ @router.websocket("/ws")
+ async def websocket_endpoint(websocket: WebSocket):
+ await websocket.accept()
+ while True:
+ data = await websocket.receive_text()
+ await websocket.send_text(f"Message text was: {data}")
+
+ app.include_router(router)
+ ```
+ """
+
def decorator(func: DecoratedCallable) -> DecoratedCallable:
self.add_api_websocket_route(
path, func, name=name, dependencies=dependencies
@@ -779,20 +1048,139 @@ class APIRouter(routing.Router):
def include_router(
self,
- router: "APIRouter",
+ router: Annotated["APIRouter", Doc("The `APIRouter` to include.")],
*,
- prefix: str = "",
- tags: Optional[List[Union[str, Enum]]] = None,
- dependencies: Optional[Sequence[params.Depends]] = None,
- default_response_class: Type[Response] = Default(JSONResponse),
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- deprecated: Optional[bool] = None,
- include_in_schema: bool = True,
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
- generate_unique_id
- ),
+ prefix: Annotated[str, Doc("An optional path prefix for the router.")] = "",
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to all the *path operations* in this
+ router.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to all the
+ *path operations* in this router.
+
+ Read more about it in the
+ [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+ """
+ ),
+ ] = None,
+ default_response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ The default response class to be used.
+
+ Read more in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class).
+ """
+ ),
+ ] = Default(JSONResponse),
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses to be shown in OpenAPI.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Additional Responses in OpenAPI](https://fastapi.tiangolo.com/advanced/additional-responses/).
+
+ And in the
+ [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ OpenAPI callbacks that should apply to all *path operations* in this
+ router.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark all *path operations* in this router as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include (or not) all the *path operations* in this router in the
+ generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = True,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
) -> None:
+ """
+ Include another `APIRouter` in the same current `APIRouter`.
+
+ Read more about it in the
+ [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/).
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+
+ app = FastAPI()
+ internal_router = APIRouter()
+ users_router = APIRouter()
+
+ @users_router.get("/users/")
+ def read_users():
+ return [{"name": "Rick"}, {"name": "Morty"}]
+
+ internal_router.include_router(users_router)
+ app.include_router(internal_router)
+ ```
+ """
if prefix:
assert prefix.startswith("/"), "A path prefix must start with '/'"
assert not prefix.endswith(
@@ -900,33 +1288,354 @@ class APIRouter(routing.Router):
def get(
self,
- path: str,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
*,
- response_model: Any = Default(None),
- status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
- dependencies: Optional[Sequence[params.Depends]] = None,
- summary: Optional[str] = None,
- description: Optional[str] = None,
- response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- deprecated: Optional[bool] = None,
- operation_id: Optional[str] = None,
- response_model_include: Optional[IncEx] = None,
- response_model_exclude: Optional[IncEx] = None,
- response_model_by_alias: bool = True,
- response_model_exclude_unset: bool = False,
- response_model_exclude_defaults: bool = False,
- response_model_exclude_none: bool = False,
- include_in_schema: bool = True,
- response_class: Type[Response] = Default(JSONResponse),
- name: Optional[str] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
- generate_unique_id
- ),
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP GET operation.
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+
+ app = FastAPI()
+ router = APIRouter()
+
+ @router.get("/items/")
+ def read_items():
+ return [{"name": "Empanada"}, {"name": "Arepa"}]
+
+ app.include_router(router)
+ ```
+ """
return self.api_route(
path=path,
response_model=response_model,
@@ -956,33 +1665,359 @@ class APIRouter(routing.Router):
def put(
self,
- path: str,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
*,
- response_model: Any = Default(None),
- status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
- dependencies: Optional[Sequence[params.Depends]] = None,
- summary: Optional[str] = None,
- description: Optional[str] = None,
- response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- deprecated: Optional[bool] = None,
- operation_id: Optional[str] = None,
- response_model_include: Optional[IncEx] = None,
- response_model_exclude: Optional[IncEx] = None,
- response_model_by_alias: bool = True,
- response_model_exclude_unset: bool = False,
- response_model_exclude_defaults: bool = False,
- response_model_exclude_none: bool = False,
- include_in_schema: bool = True,
- response_class: Type[Response] = Default(JSONResponse),
- name: Optional[str] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
- generate_unique_id
- ),
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP PUT operation.
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+ from pydantic import BaseModel
+
+ class Item(BaseModel):
+ name: str
+ description: str | None = None
+
+ app = FastAPI()
+ router = APIRouter()
+
+ @router.put("/items/{item_id}")
+ def replace_item(item_id: str, item: Item):
+ return {"message": "Item replaced", "id": item_id}
+
+ app.include_router(router)
+ ```
+ """
return self.api_route(
path=path,
response_model=response_model,
@@ -1012,33 +2047,359 @@ class APIRouter(routing.Router):
def post(
self,
- path: str,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
*,
- response_model: Any = Default(None),
- status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
- dependencies: Optional[Sequence[params.Depends]] = None,
- summary: Optional[str] = None,
- description: Optional[str] = None,
- response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- deprecated: Optional[bool] = None,
- operation_id: Optional[str] = None,
- response_model_include: Optional[IncEx] = None,
- response_model_exclude: Optional[IncEx] = None,
- response_model_by_alias: bool = True,
- response_model_exclude_unset: bool = False,
- response_model_exclude_defaults: bool = False,
- response_model_exclude_none: bool = False,
- include_in_schema: bool = True,
- response_class: Type[Response] = Default(JSONResponse),
- name: Optional[str] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
- generate_unique_id
- ),
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP POST operation.
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+ from pydantic import BaseModel
+
+ class Item(BaseModel):
+ name: str
+ description: str | None = None
+
+ app = FastAPI()
+ router = APIRouter()
+
+ @router.post("/items/")
+ def create_item(item: Item):
+ return {"message": "Item created"}
+
+ app.include_router(router)
+ ```
+ """
return self.api_route(
path=path,
response_model=response_model,
@@ -1068,33 +2429,354 @@ class APIRouter(routing.Router):
def delete(
self,
- path: str,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
*,
- response_model: Any = Default(None),
- status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
- dependencies: Optional[Sequence[params.Depends]] = None,
- summary: Optional[str] = None,
- description: Optional[str] = None,
- response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- deprecated: Optional[bool] = None,
- operation_id: Optional[str] = None,
- response_model_include: Optional[IncEx] = None,
- response_model_exclude: Optional[IncEx] = None,
- response_model_by_alias: bool = True,
- response_model_exclude_unset: bool = False,
- response_model_exclude_defaults: bool = False,
- response_model_exclude_none: bool = False,
- include_in_schema: bool = True,
- response_class: Type[Response] = Default(JSONResponse),
- name: Optional[str] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
- generate_unique_id
- ),
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP DELETE operation.
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+
+ app = FastAPI()
+ router = APIRouter()
+
+ @router.delete("/items/{item_id}")
+ def delete_item(item_id: str):
+ return {"message": "Item deleted"}
+
+ app.include_router(router)
+ ```
+ """
return self.api_route(
path=path,
response_model=response_model,
@@ -1124,33 +2806,354 @@ class APIRouter(routing.Router):
def options(
self,
- path: str,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
*,
- response_model: Any = Default(None),
- status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
- dependencies: Optional[Sequence[params.Depends]] = None,
- summary: Optional[str] = None,
- description: Optional[str] = None,
- response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- deprecated: Optional[bool] = None,
- operation_id: Optional[str] = None,
- response_model_include: Optional[IncEx] = None,
- response_model_exclude: Optional[IncEx] = None,
- response_model_by_alias: bool = True,
- response_model_exclude_unset: bool = False,
- response_model_exclude_defaults: bool = False,
- response_model_exclude_none: bool = False,
- include_in_schema: bool = True,
- response_class: Type[Response] = Default(JSONResponse),
- name: Optional[str] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
- generate_unique_id
- ),
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP OPTIONS operation.
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+
+ app = FastAPI()
+ router = APIRouter()
+
+ @router.options("/items/")
+ def get_item_options():
+ return {"additions": ["Aji", "Guacamole"]}
+
+ app.include_router(router)
+ ```
+ """
return self.api_route(
path=path,
response_model=response_model,
@@ -1180,33 +3183,359 @@ class APIRouter(routing.Router):
def head(
self,
- path: str,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
*,
- response_model: Any = Default(None),
- status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
- dependencies: Optional[Sequence[params.Depends]] = None,
- summary: Optional[str] = None,
- description: Optional[str] = None,
- response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- deprecated: Optional[bool] = None,
- operation_id: Optional[str] = None,
- response_model_include: Optional[IncEx] = None,
- response_model_exclude: Optional[IncEx] = None,
- response_model_by_alias: bool = True,
- response_model_exclude_unset: bool = False,
- response_model_exclude_defaults: bool = False,
- response_model_exclude_none: bool = False,
- include_in_schema: bool = True,
- response_class: Type[Response] = Default(JSONResponse),
- name: Optional[str] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
- generate_unique_id
- ),
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP HEAD operation.
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+ from pydantic import BaseModel
+
+ class Item(BaseModel):
+ name: str
+ description: str | None = None
+
+ app = FastAPI()
+ router = APIRouter()
+
+ @router.head("/items/", status_code=204)
+ def get_items_headers(response: Response):
+ response.headers["X-Cat-Dog"] = "Alone in the world"
+
+ app.include_router(router)
+ ```
+ """
return self.api_route(
path=path,
response_model=response_model,
@@ -1236,33 +3565,359 @@ class APIRouter(routing.Router):
def patch(
self,
- path: str,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
*,
- response_model: Any = Default(None),
- status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
- dependencies: Optional[Sequence[params.Depends]] = None,
- summary: Optional[str] = None,
- description: Optional[str] = None,
- response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- deprecated: Optional[bool] = None,
- operation_id: Optional[str] = None,
- response_model_include: Optional[IncEx] = None,
- response_model_exclude: Optional[IncEx] = None,
- response_model_by_alias: bool = True,
- response_model_exclude_unset: bool = False,
- response_model_exclude_defaults: bool = False,
- response_model_exclude_none: bool = False,
- include_in_schema: bool = True,
- response_class: Type[Response] = Default(JSONResponse),
- name: Optional[str] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
- generate_unique_id
- ),
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP PATCH operation.
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+ from pydantic import BaseModel
+
+ class Item(BaseModel):
+ name: str
+ description: str | None = None
+
+ app = FastAPI()
+ router = APIRouter()
+
+ @router.patch("/items/")
+ def update_item(item: Item):
+ return {"message": "Item updated in place"}
+
+ app.include_router(router)
+ ```
+ """
return self.api_route(
path=path,
response_model=response_model,
@@ -1292,33 +3947,359 @@ class APIRouter(routing.Router):
def trace(
self,
- path: str,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
*,
- response_model: Any = Default(None),
- status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
- dependencies: Optional[Sequence[params.Depends]] = None,
- summary: Optional[str] = None,
- description: Optional[str] = None,
- response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
- deprecated: Optional[bool] = None,
- operation_id: Optional[str] = None,
- response_model_include: Optional[IncEx] = None,
- response_model_exclude: Optional[IncEx] = None,
- response_model_by_alias: bool = True,
- response_model_exclude_unset: bool = False,
- response_model_exclude_defaults: bool = False,
- response_model_exclude_none: bool = False,
- include_in_schema: bool = True,
- response_class: Type[Response] = Default(JSONResponse),
- name: Optional[str] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
- generate_unique_id
- ),
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP TRACE operation.
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+ from pydantic import BaseModel
+
+ class Item(BaseModel):
+ name: str
+ description: str | None = None
+
+ app = FastAPI()
+ router = APIRouter()
+
+ @router.put("/items/{item_id}")
+ def trace_item(item_id: str):
+ return None
+
+ app.include_router(router)
+ ```
+ """
return self.api_route(
path=path,
response_model=response_model,
@@ -1346,9 +4327,34 @@ class APIRouter(routing.Router):
generate_unique_id_function=generate_unique_id_function,
)
+ @deprecated(
+ """
+ on_event is deprecated, use lifespan event handlers instead.
+
+ Read more about it in the
+ [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/).
+ """
+ )
def on_event(
- self, event_type: str
+ self,
+ event_type: Annotated[
+ str,
+ Doc(
+ """
+ The type of event. `startup` or `shutdown`.
+ """
+ ),
+ ],
) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add an event handler for the router.
+
+ `on_event` is deprecated, use `lifespan` event handlers instead.
+
+ Read more about it in the
+ [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/#alternative-events-deprecated).
+ """
+
def decorator(func: DecoratedCallable) -> DecoratedCallable:
self.add_event_handler(event_type, func)
return func
diff --git a/fastapi/security/api_key.py b/fastapi/security/api_key.py
index 8b2c5c080..b1a6b4f94 100644
--- a/fastapi/security/api_key.py
+++ b/fastapi/security/api_key.py
@@ -5,6 +5,7 @@ from fastapi.security.base import SecurityBase
from starlette.exceptions import HTTPException
from starlette.requests import Request
from starlette.status import HTTP_403_FORBIDDEN
+from typing_extensions import Annotated, Doc # type: ignore [attr-defined]
class APIKeyBase(SecurityBase):
@@ -12,13 +13,83 @@ class APIKeyBase(SecurityBase):
class APIKeyQuery(APIKeyBase):
+ """
+ API key authentication using a query parameter.
+
+ This defines the name of the query parameter that should be provided in the request
+ with the API key and integrates that into the OpenAPI documentation. It extracts
+ the key value sent in the query parameter automatically and provides it as the
+ dependency result. But it doesn't define how to send that API key to the client.
+
+ ## Usage
+
+ Create an instance object and use that object as the dependency in `Depends()`.
+
+ The dependency result will be a string containing the key value.
+
+ ## Example
+
+ ```python
+ from fastapi import Depends, FastAPI
+ from fastapi.security import APIKeyQuery
+
+ app = FastAPI()
+
+ query_scheme = APIKeyQuery(name="api_key")
+
+
+ @app.get("/items/")
+ async def read_items(api_key: str = Depends(query_scheme)):
+ return {"api_key": api_key}
+ ```
+ """
+
def __init__(
self,
*,
- name: str,
- scheme_name: Optional[str] = None,
- description: Optional[str] = None,
- auto_error: bool = True,
+ name: Annotated[
+ str,
+ Doc("Query parameter name."),
+ ],
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if the query parameter is not provided, `APIKeyQuery` will
+ automatically cancel the request and sebd the client an error.
+
+ If `auto_error` is set to `False`, when the query parameter is not
+ available, instead of erroring out, the dependency result will be
+ `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, in a query
+ parameter or in an HTTP Bearer token).
+ """
+ ),
+ ] = True,
):
self.model: APIKey = APIKey(
**{"in": APIKeyIn.query}, # type: ignore[arg-type]
@@ -41,13 +112,79 @@ class APIKeyQuery(APIKeyBase):
class APIKeyHeader(APIKeyBase):
+ """
+ API key authentication using a header.
+
+ This defines the name of the header that should be provided in the request with
+ the API key and integrates that into the OpenAPI documentation. It extracts
+ the key value sent in the header automatically and provides it as the dependency
+ result. But it doesn't define how to send that key to the client.
+
+ ## Usage
+
+ Create an instance object and use that object as the dependency in `Depends()`.
+
+ The dependency result will be a string containing the key value.
+
+ ## Example
+
+ ```python
+ from fastapi import Depends, FastAPI
+ from fastapi.security import APIKeyHeader
+
+ app = FastAPI()
+
+ header_scheme = APIKeyHeader(name="x-key")
+
+
+ @app.get("/items/")
+ async def read_items(key: str = Depends(header_scheme)):
+ return {"key": key}
+ ```
+ """
+
def __init__(
self,
*,
- name: str,
- scheme_name: Optional[str] = None,
- description: Optional[str] = None,
- auto_error: bool = True,
+ name: Annotated[str, Doc("Header name.")],
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if the header is not provided, `APIKeyHeader` will
+ automatically cancel the request and send the client an error.
+
+ If `auto_error` is set to `False`, when the header is not available,
+ instead of erroring out, the dependency result will be `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, in a header or
+ in an HTTP Bearer token).
+ """
+ ),
+ ] = True,
):
self.model: APIKey = APIKey(
**{"in": APIKeyIn.header}, # type: ignore[arg-type]
@@ -70,13 +207,79 @@ class APIKeyHeader(APIKeyBase):
class APIKeyCookie(APIKeyBase):
+ """
+ API key authentication using a cookie.
+
+ This defines the name of the cookie that should be provided in the request with
+ the API key and integrates that into the OpenAPI documentation. It extracts
+ the key value sent in the cookie automatically and provides it as the dependency
+ result. But it doesn't define how to set that cookie.
+
+ ## Usage
+
+ Create an instance object and use that object as the dependency in `Depends()`.
+
+ The dependency result will be a string containing the key value.
+
+ ## Example
+
+ ```python
+ from fastapi import Depends, FastAPI
+ from fastapi.security import APIKeyCookie
+
+ app = FastAPI()
+
+ cookie_scheme = APIKeyCookie(name="session")
+
+
+ @app.get("/items/")
+ async def read_items(session: str = Depends(cookie_scheme)):
+ return {"session": session}
+ ```
+ """
+
def __init__(
self,
*,
- name: str,
- scheme_name: Optional[str] = None,
- description: Optional[str] = None,
- auto_error: bool = True,
+ name: Annotated[str, Doc("Cookie name.")],
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if the cookie is not provided, `APIKeyCookie` will
+ automatically cancel the request and send the client an error.
+
+ If `auto_error` is set to `False`, when the cookie is not available,
+ instead of erroring out, the dependency result will be `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, in a cookie or
+ in an HTTP Bearer token).
+ """
+ ),
+ ] = True,
):
self.model: APIKey = APIKey(
**{"in": APIKeyIn.cookie}, # type: ignore[arg-type]
diff --git a/fastapi/security/http.py b/fastapi/security/http.py
index 8fc0aafd9..738455de3 100644
--- a/fastapi/security/http.py
+++ b/fastapi/security/http.py
@@ -10,16 +10,60 @@ from fastapi.security.utils import get_authorization_scheme_param
from pydantic import BaseModel
from starlette.requests import Request
from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN
+from typing_extensions import Annotated, Doc # type: ignore [attr-defined]
class HTTPBasicCredentials(BaseModel):
- username: str
- password: str
+ """
+ The HTTP Basic credendials given as the result of using `HTTPBasic` in a
+ dependency.
+
+ Read more about it in the
+ [FastAPI docs for HTTP Basic Auth](https://fastapi.tiangolo.com/advanced/security/http-basic-auth/).
+ """
+
+ username: Annotated[str, Doc("The HTTP Basic username.")]
+ password: Annotated[str, Doc("The HTTP Basic password.")]
class HTTPAuthorizationCredentials(BaseModel):
- scheme: str
- credentials: str
+ """
+ The HTTP authorization credentials in the result of using `HTTPBearer` or
+ `HTTPDigest` in a dependency.
+
+ The HTTP authorization header value is split by the first space.
+
+ The first part is the `scheme`, the second part is the `credentials`.
+
+ For example, in an HTTP Bearer token scheme, the client will send a header
+ like:
+
+ ```
+ Authorization: Bearer deadbeef12346
+ ```
+
+ In this case:
+
+ * `scheme` will have the value `"Bearer"`
+ * `credentials` will have the value `"deadbeef12346"`
+ """
+
+ scheme: Annotated[
+ str,
+ Doc(
+ """
+ The HTTP authorization scheme extracted from the header value.
+ """
+ ),
+ ]
+ credentials: Annotated[
+ str,
+ Doc(
+ """
+ The HTTP authorization credentials extracted from the header value.
+ """
+ ),
+ ]
class HTTPBase(SecurityBase):
@@ -51,13 +95,89 @@ class HTTPBase(SecurityBase):
class HTTPBasic(HTTPBase):
+ """
+ HTTP Basic authentication.
+
+ ## Usage
+
+ Create an instance object and use that object as the dependency in `Depends()`.
+
+ The dependency result will be an `HTTPBasicCredentials` object containing the
+ `username` and the `password`.
+
+ Read more about it in the
+ [FastAPI docs for HTTP Basic Auth](https://fastapi.tiangolo.com/advanced/security/http-basic-auth/).
+
+ ## Example
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import Depends, FastAPI
+ from fastapi.security import HTTPBasic, HTTPBasicCredentials
+
+ app = FastAPI()
+
+ security = HTTPBasic()
+
+
+ @app.get("/users/me")
+ def read_current_user(credentials: Annotated[HTTPBasicCredentials, Depends(security)]):
+ return {"username": credentials.username, "password": credentials.password}
+ ```
+ """
+
def __init__(
self,
*,
- scheme_name: Optional[str] = None,
- realm: Optional[str] = None,
- description: Optional[str] = None,
- auto_error: bool = True,
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ realm: Annotated[
+ Optional[str],
+ Doc(
+ """
+ HTTP Basic authentication realm.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if the HTTP Basic authentication is not provided (a
+ header), `HTTPBasic` will automatically cancel the request and send the
+ client an error.
+
+ If `auto_error` is set to `False`, when the HTTP Basic authentication
+ is not available, instead of erroring out, the dependency result will
+ be `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, in HTTP Basic
+ authentication or in an HTTP Bearer token).
+ """
+ ),
+ ] = True,
):
self.model = HTTPBaseModel(scheme="basic", description=description)
self.scheme_name = scheme_name or self.__class__.__name__
@@ -90,7 +210,7 @@ class HTTPBasic(HTTPBase):
try:
data = b64decode(param).decode("ascii")
except (ValueError, UnicodeDecodeError, binascii.Error):
- raise invalid_user_credentials_exc
+ raise invalid_user_credentials_exc # noqa: B904
username, separator, password = data.partition(":")
if not separator:
raise invalid_user_credentials_exc
@@ -98,13 +218,81 @@ class HTTPBasic(HTTPBase):
class HTTPBearer(HTTPBase):
+ """
+ HTTP Bearer token authentication.
+
+ ## Usage
+
+ Create an instance object and use that object as the dependency in `Depends()`.
+
+ The dependency result will be an `HTTPAuthorizationCredentials` object containing
+ the `scheme` and the `credentials`.
+
+ ## Example
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import Depends, FastAPI
+ from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
+
+ app = FastAPI()
+
+ security = HTTPBearer()
+
+
+ @app.get("/users/me")
+ def read_current_user(
+ credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)]
+ ):
+ return {"scheme": credentials.scheme, "credentials": credentials.credentials}
+ ```
+ """
+
def __init__(
self,
*,
- bearerFormat: Optional[str] = None,
- scheme_name: Optional[str] = None,
- description: Optional[str] = None,
- auto_error: bool = True,
+ bearerFormat: Annotated[Optional[str], Doc("Bearer token format.")] = None,
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if the HTTP Bearer token not provided (in an
+ `Authorization` header), `HTTPBearer` will automatically cancel the
+ request and send the client an error.
+
+ If `auto_error` is set to `False`, when the HTTP Bearer token
+ is not available, instead of erroring out, the dependency result will
+ be `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, in an HTTP
+ Bearer token or in a cookie).
+ """
+ ),
+ ] = True,
):
self.model = HTTPBearerModel(bearerFormat=bearerFormat, description=description)
self.scheme_name = scheme_name or self.__class__.__name__
@@ -134,12 +322,79 @@ class HTTPBearer(HTTPBase):
class HTTPDigest(HTTPBase):
+ """
+ HTTP Digest authentication.
+
+ ## Usage
+
+ Create an instance object and use that object as the dependency in `Depends()`.
+
+ The dependency result will be an `HTTPAuthorizationCredentials` object containing
+ the `scheme` and the `credentials`.
+
+ ## Example
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import Depends, FastAPI
+ from fastapi.security import HTTPAuthorizationCredentials, HTTPDigest
+
+ app = FastAPI()
+
+ security = HTTPDigest()
+
+
+ @app.get("/users/me")
+ def read_current_user(
+ credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)]
+ ):
+ return {"scheme": credentials.scheme, "credentials": credentials.credentials}
+ ```
+ """
+
def __init__(
self,
*,
- scheme_name: Optional[str] = None,
- description: Optional[str] = None,
- auto_error: bool = True,
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if the HTTP Digest not provided, `HTTPDigest` will
+ automatically cancel the request and send the client an error.
+
+ If `auto_error` is set to `False`, when the HTTP Digest is not
+ available, instead of erroring out, the dependency result will
+ be `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, in HTTP
+ Digest or in a cookie).
+ """
+ ),
+ ] = True,
):
self.model = HTTPBaseModel(scheme="digest", description=description)
self.scheme_name = scheme_name or self.__class__.__name__
diff --git a/fastapi/security/oauth2.py b/fastapi/security/oauth2.py
index e4c4357e7..9281dfb64 100644
--- a/fastapi/security/oauth2.py
+++ b/fastapi/security/oauth2.py
@@ -10,51 +10,136 @@ from starlette.requests import Request
from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN
# TODO: import from typing when deprecating Python 3.9
-from typing_extensions import Annotated
+from typing_extensions import Annotated, Doc # type: ignore [attr-defined]
class OAuth2PasswordRequestForm:
"""
- This is a dependency class, use it like:
+ This is a dependency class to collect the `username` and `password` as form data
+ for an OAuth2 password flow.
- @app.post("/login")
- def login(form_data: OAuth2PasswordRequestForm = Depends()):
- data = form_data.parse()
- print(data.username)
- print(data.password)
- for scope in data.scopes:
- print(scope)
- if data.client_id:
- print(data.client_id)
- if data.client_secret:
- print(data.client_secret)
- return data
+ The OAuth2 specification dictates that for a password flow the data should be
+ collected using form data (instead of JSON) and that it should have the specific
+ fields `username` and `password`.
+
+ All the initialization parameters are extracted from the request.
+
+ Read more about it in the
+ [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/).
+
+ ## Example
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import Depends, FastAPI
+ from fastapi.security import OAuth2PasswordRequestForm
+
+ app = FastAPI()
- It creates the following Form request parameters in your endpoint:
+ @app.post("/login")
+ def login(form_data: Annotated[OAuth2PasswordRequestForm, Depends()]):
+ data = {}
+ data["scopes"] = []
+ for scope in form_data.scopes:
+ data["scopes"].append(scope)
+ if form_data.client_id:
+ data["client_id"] = form_data.client_id
+ if form_data.client_secret:
+ data["client_secret"] = form_data.client_secret
+ return data
+ ```
- grant_type: the OAuth2 spec says it is required and MUST be the fixed string "password".
- Nevertheless, this dependency class is permissive and allows not passing it. If you want to enforce it,
- use instead the OAuth2PasswordRequestFormStrict dependency.
- username: username string. The OAuth2 spec requires the exact field name "username".
- password: password string. The OAuth2 spec requires the exact field name "password".
- scope: Optional string. Several scopes (each one a string) separated by spaces. E.g.
- "items:read items:write users:read profile openid"
- client_id: optional string. OAuth2 recommends sending the client_id and client_secret (if any)
- using HTTP Basic auth, as: client_id:client_secret
- client_secret: optional string. OAuth2 recommends sending the client_id and client_secret (if any)
- using HTTP Basic auth, as: client_id:client_secret
+ Note that for OAuth2 the scope `items:read` is a single scope in an opaque string.
+ You could have custom internal logic to separate it by colon caracters (`:`) or
+ similar, and get the two parts `items` and `read`. Many applications do that to
+ group and organize permisions, you could do it as well in your application, just
+ know that that it is application specific, it's not part of the specification.
"""
def __init__(
self,
*,
- grant_type: Annotated[Union[str, None], Form(pattern="password")] = None,
- username: Annotated[str, Form()],
- password: Annotated[str, Form()],
- scope: Annotated[str, Form()] = "",
- client_id: Annotated[Union[str, None], Form()] = None,
- client_secret: Annotated[Union[str, None], Form()] = None,
+ grant_type: Annotated[
+ Union[str, None],
+ Form(pattern="password"),
+ Doc(
+ """
+ The OAuth2 spec says it is required and MUST be the fixed string
+ "password". Nevertheless, this dependency class is permissive and
+ allows not passing it. If you want to enforce it, use instead the
+ `OAuth2PasswordRequestFormStrict` dependency.
+ """
+ ),
+ ] = None,
+ username: Annotated[
+ str,
+ Form(),
+ Doc(
+ """
+ `username` string. The OAuth2 spec requires the exact field name
+ `username`.
+ """
+ ),
+ ],
+ password: Annotated[
+ str,
+ Form(),
+ Doc(
+ """
+ `password` string. The OAuth2 spec requires the exact field name
+ `password".
+ """
+ ),
+ ],
+ scope: Annotated[
+ str,
+ Form(),
+ Doc(
+ """
+ A single string with actually several scopes separated by spaces. Each
+ scope is also a string.
+
+ For example, a single string with:
+
+ ```python
+ "items:read items:write users:read profile openid"
+ ````
+
+ would represent the scopes:
+
+ * `items:read`
+ * `items:write`
+ * `users:read`
+ * `profile`
+ * `openid`
+ """
+ ),
+ ] = "",
+ client_id: Annotated[
+ Union[str, None],
+ Form(),
+ Doc(
+ """
+ If there's a `client_id`, it can be sent as part of the form fields.
+ But the OAuth2 specification recommends sending the `client_id` and
+ `client_secret` (if any) using HTTP Basic auth.
+ """
+ ),
+ ] = None,
+ client_secret: Annotated[
+ Union[str, None],
+ Form(),
+ Doc(
+ """
+ If there's a `client_password` (and a `client_id`), they can be sent
+ as part of the form fields. But the OAuth2 specification recommends
+ sending the `client_id` and `client_secret` (if any) using HTTP Basic
+ auth.
+ """
+ ),
+ ] = None,
):
self.grant_type = grant_type
self.username = username
@@ -66,23 +151,54 @@ class OAuth2PasswordRequestForm:
class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm):
"""
- This is a dependency class, use it like:
+ This is a dependency class to collect the `username` and `password` as form data
+ for an OAuth2 password flow.
- @app.post("/login")
- def login(form_data: OAuth2PasswordRequestFormStrict = Depends()):
- data = form_data.parse()
- print(data.username)
- print(data.password)
- for scope in data.scopes:
- print(scope)
- if data.client_id:
- print(data.client_id)
- if data.client_secret:
- print(data.client_secret)
- return data
+ The OAuth2 specification dictates that for a password flow the data should be
+ collected using form data (instead of JSON) and that it should have the specific
+ fields `username` and `password`.
+
+ All the initialization parameters are extracted from the request.
+
+ The only difference between `OAuth2PasswordRequestFormStrict` and
+ `OAuth2PasswordRequestForm` is that `OAuth2PasswordRequestFormStrict` requires the
+ client to send the form field `grant_type` with the value `"password"`, which
+ is required in the OAuth2 specification (it seems that for no particular reason),
+ while for `OAuth2PasswordRequestForm` `grant_type` is optional.
+
+ Read more about it in the
+ [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/).
+
+ ## Example
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import Depends, FastAPI
+ from fastapi.security import OAuth2PasswordRequestForm
+
+ app = FastAPI()
- It creates the following Form request parameters in your endpoint:
+ @app.post("/login")
+ def login(form_data: Annotated[OAuth2PasswordRequestFormStrict, Depends()]):
+ data = {}
+ data["scopes"] = []
+ for scope in form_data.scopes:
+ data["scopes"].append(scope)
+ if form_data.client_id:
+ data["client_id"] = form_data.client_id
+ if form_data.client_secret:
+ data["client_secret"] = form_data.client_secret
+ return data
+ ```
+
+ Note that for OAuth2 the scope `items:read` is a single scope in an opaque string.
+ You could have custom internal logic to separate it by colon caracters (`:`) or
+ similar, and get the two parts `items` and `read`. Many applications do that to
+ group and organize permisions, you could do it as well in your application, just
+ know that that it is application specific, it's not part of the specification.
+
grant_type: the OAuth2 spec says it is required and MUST be the fixed string "password".
This dependency is strict about it. If you want to be permissive, use instead the
@@ -99,12 +215,85 @@ class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm):
def __init__(
self,
- grant_type: Annotated[str, Form(pattern="password")],
- username: Annotated[str, Form()],
- password: Annotated[str, Form()],
- scope: Annotated[str, Form()] = "",
- client_id: Annotated[Union[str, None], Form()] = None,
- client_secret: Annotated[Union[str, None], Form()] = None,
+ grant_type: Annotated[
+ str,
+ Form(pattern="password"),
+ Doc(
+ """
+ The OAuth2 spec says it is required and MUST be the fixed string
+ "password". This dependency is strict about it. If you want to be
+ permissive, use instead the `OAuth2PasswordRequestForm` dependency
+ class.
+ """
+ ),
+ ],
+ username: Annotated[
+ str,
+ Form(),
+ Doc(
+ """
+ `username` string. The OAuth2 spec requires the exact field name
+ `username`.
+ """
+ ),
+ ],
+ password: Annotated[
+ str,
+ Form(),
+ Doc(
+ """
+ `password` string. The OAuth2 spec requires the exact field name
+ `password".
+ """
+ ),
+ ],
+ scope: Annotated[
+ str,
+ Form(),
+ Doc(
+ """
+ A single string with actually several scopes separated by spaces. Each
+ scope is also a string.
+
+ For example, a single string with:
+
+ ```python
+ "items:read items:write users:read profile openid"
+ ````
+
+ would represent the scopes:
+
+ * `items:read`
+ * `items:write`
+ * `users:read`
+ * `profile`
+ * `openid`
+ """
+ ),
+ ] = "",
+ client_id: Annotated[
+ Union[str, None],
+ Form(),
+ Doc(
+ """
+ If there's a `client_id`, it can be sent as part of the form fields.
+ But the OAuth2 specification recommends sending the `client_id` and
+ `client_secret` (if any) using HTTP Basic auth.
+ """
+ ),
+ ] = None,
+ client_secret: Annotated[
+ Union[str, None],
+ Form(),
+ Doc(
+ """
+ If there's a `client_password` (and a `client_id`), they can be sent
+ as part of the form fields. But the OAuth2 specification recommends
+ sending the `client_id` and `client_secret` (if any) using HTTP Basic
+ auth.
+ """
+ ),
+ ] = None,
):
super().__init__(
grant_type=grant_type,
@@ -117,13 +306,69 @@ class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm):
class OAuth2(SecurityBase):
+ """
+ This is the base class for OAuth2 authentication, an instance of it would be used
+ as a dependency. All other OAuth2 classes inherit from it and customize it for
+ each OAuth2 flow.
+
+ You normally would not create a new class inheriting from it but use one of the
+ existing subclasses, and maybe compose them if you want to support multiple flows.
+
+ Read more about it in the
+ [FastAPI docs for Security](https://fastapi.tiangolo.com/tutorial/security/).
+ """
+
def __init__(
self,
*,
- flows: Union[OAuthFlowsModel, Dict[str, Dict[str, Any]]] = OAuthFlowsModel(),
- scheme_name: Optional[str] = None,
- description: Optional[str] = None,
- auto_error: bool = True,
+ flows: Annotated[
+ Union[OAuthFlowsModel, Dict[str, Dict[str, Any]]],
+ Doc(
+ """
+ The dictionary of OAuth2 flows.
+ """
+ ),
+ ] = OAuthFlowsModel(),
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if no HTTP Auhtorization header is provided, required for
+ OAuth2 authentication, it will automatically cancel the request and
+ send the client an error.
+
+ If `auto_error` is set to `False`, when the HTTP Authorization header
+ is not available, instead of erroring out, the dependency result will
+ be `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, with OAuth2
+ or in a cookie).
+ """
+ ),
+ ] = True,
):
self.model = OAuth2Model(
flows=cast(OAuthFlowsModel, flows), description=description
@@ -144,13 +389,74 @@ class OAuth2(SecurityBase):
class OAuth2PasswordBearer(OAuth2):
+ """
+ OAuth2 flow for authentication using a bearer token obtained with a password.
+ An instance of it would be used as a dependency.
+
+ Read more about it in the
+ [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/).
+ """
+
def __init__(
self,
- tokenUrl: str,
- scheme_name: Optional[str] = None,
- scopes: Optional[Dict[str, str]] = None,
- description: Optional[str] = None,
- auto_error: bool = True,
+ tokenUrl: Annotated[
+ str,
+ Doc(
+ """
+ The URL to obtain the OAuth2 token. This would be the *path operation*
+ that has `OAuth2PasswordRequestForm` as a dependency.
+ """
+ ),
+ ],
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ scopes: Annotated[
+ Optional[Dict[str, str]],
+ Doc(
+ """
+ The OAuth2 scopes that would be required by the *path operations* that
+ use this dependency.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if no HTTP Auhtorization header is provided, required for
+ OAuth2 authentication, it will automatically cancel the request and
+ send the client an error.
+
+ If `auto_error` is set to `False`, when the HTTP Authorization header
+ is not available, instead of erroring out, the dependency result will
+ be `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, with OAuth2
+ or in a cookie).
+ """
+ ),
+ ] = True,
):
if not scopes:
scopes = {}
@@ -180,15 +486,79 @@ class OAuth2PasswordBearer(OAuth2):
class OAuth2AuthorizationCodeBearer(OAuth2):
+ """
+ OAuth2 flow for authentication using a bearer token obtained with an OAuth2 code
+ flow. An instance of it would be used as a dependency.
+ """
+
def __init__(
self,
authorizationUrl: str,
- tokenUrl: str,
- refreshUrl: Optional[str] = None,
- scheme_name: Optional[str] = None,
- scopes: Optional[Dict[str, str]] = None,
- description: Optional[str] = None,
- auto_error: bool = True,
+ tokenUrl: Annotated[
+ str,
+ Doc(
+ """
+ The URL to obtain the OAuth2 token.
+ """
+ ),
+ ],
+ refreshUrl: Annotated[
+ Optional[str],
+ Doc(
+ """
+ The URL to refresh the token and obtain a new one.
+ """
+ ),
+ ] = None,
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ scopes: Annotated[
+ Optional[Dict[str, str]],
+ Doc(
+ """
+ The OAuth2 scopes that would be required by the *path operations* that
+ use this dependency.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if no HTTP Auhtorization header is provided, required for
+ OAuth2 authentication, it will automatically cancel the request and
+ send the client an error.
+
+ If `auto_error` is set to `False`, when the HTTP Authorization header
+ is not available, instead of erroring out, the dependency result will
+ be `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, with OAuth2
+ or in a cookie).
+ """
+ ),
+ ] = True,
):
if not scopes:
scopes = {}
@@ -226,6 +596,43 @@ class OAuth2AuthorizationCodeBearer(OAuth2):
class SecurityScopes:
- def __init__(self, scopes: Optional[List[str]] = None):
- self.scopes = scopes or []
- self.scope_str = " ".join(self.scopes)
+ """
+ This is a special class that you can define in a parameter in a dependency to
+ obtain the OAuth2 scopes required by all the dependencies in the same chain.
+
+ This way, multiple dependencies can have different scopes, even when used in the
+ same *path operation*. And with this, you can access all the scopes required in
+ all those dependencies in a single place.
+
+ Read more about it in the
+ [FastAPI docs for OAuth2 scopes](https://fastapi.tiangolo.com/advanced/security/oauth2-scopes/).
+ """
+
+ def __init__(
+ self,
+ scopes: Annotated[
+ Optional[List[str]],
+ Doc(
+ """
+ This will be filled by FastAPI.
+ """
+ ),
+ ] = None,
+ ):
+ self.scopes: Annotated[
+ List[str],
+ Doc(
+ """
+ The list of all the scopes required by dependencies.
+ """
+ ),
+ ] = scopes or []
+ self.scope_str: Annotated[
+ str,
+ Doc(
+ """
+ All the scopes required by all the dependencies in a single string
+ separated by spaces, as defined in the OAuth2 specification.
+ """
+ ),
+ ] = " ".join(self.scopes)
diff --git a/fastapi/security/open_id_connect_url.py b/fastapi/security/open_id_connect_url.py
index 4e65f1f6c..c612b475d 100644
--- a/fastapi/security/open_id_connect_url.py
+++ b/fastapi/security/open_id_connect_url.py
@@ -5,16 +5,66 @@ from fastapi.security.base import SecurityBase
from starlette.exceptions import HTTPException
from starlette.requests import Request
from starlette.status import HTTP_403_FORBIDDEN
+from typing_extensions import Annotated, Doc # type: ignore [attr-defined]
class OpenIdConnect(SecurityBase):
+ """
+ OpenID Connect authentication class. An instance of it would be used as a
+ dependency.
+ """
+
def __init__(
self,
*,
- openIdConnectUrl: str,
- scheme_name: Optional[str] = None,
- description: Optional[str] = None,
- auto_error: bool = True,
+ openIdConnectUrl: Annotated[
+ str,
+ Doc(
+ """
+ The OpenID Connect URL.
+ """
+ ),
+ ],
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if no HTTP Auhtorization header is provided, required for
+ OpenID Connect authentication, it will automatically cancel the request
+ and send the client an error.
+
+ If `auto_error` is set to `False`, when the HTTP Authorization header
+ is not available, instead of erroring out, the dependency result will
+ be `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, with OpenID
+ Connect or in a cookie).
+ """
+ ),
+ ] = True,
):
self.model = OpenIdConnectModel(
openIdConnectUrl=openIdConnectUrl, description=description
diff --git a/fastapi/types.py b/fastapi/types.py
index 7adf565a7..3205654c7 100644
--- a/fastapi/types.py
+++ b/fastapi/types.py
@@ -6,6 +6,5 @@ from pydantic import BaseModel
DecoratedCallable = TypeVar("DecoratedCallable", bound=Callable[..., Any])
UnionType = getattr(types, "UnionType", Union)
-NoneType = getattr(types, "UnionType", None)
ModelNameMap = Dict[Union[Type[BaseModel], Type[Enum]], str]
IncEx = Union[Set[int], Set[str], Dict[int, Any], Dict[str, Any]]
diff --git a/fastapi/utils.py b/fastapi/utils.py
index 267d64ce8..f8463dda2 100644
--- a/fastapi/utils.py
+++ b/fastapi/utils.py
@@ -117,7 +117,7 @@ def create_cloned_field(
if PYDANTIC_V2:
return field
# cloned_types caches already cloned types to support recursive models and improve
- # performance by avoiding unecessary cloning
+ # performance by avoiding unnecessary cloning
if cloned_types is None:
cloned_types = _CLONED_TYPES_CACHE
@@ -152,7 +152,8 @@ def create_cloned_field(
]
if field.key_field: # type: ignore[attr-defined]
new_field.key_field = create_cloned_field( # type: ignore[attr-defined]
- field.key_field, cloned_types=cloned_types # type: ignore[attr-defined]
+ field.key_field, # type: ignore[attr-defined]
+ cloned_types=cloned_types,
)
new_field.validators = field.validators # type: ignore[attr-defined]
new_field.pre_validators = field.pre_validators # type: ignore[attr-defined]
diff --git a/pyproject.toml b/pyproject.toml
index 9b7cca9c9..e67486ae3 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
name = "fastapi"
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
readme = "README.md"
-requires-python = ">=3.7"
+requires-python = ">=3.8"
license = "MIT"
authors = [
{ name = "Sebastiรกn Ramรญrez", email = "tiangolo@gmail.com" },
@@ -32,7 +32,6 @@ classifiers = [
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3 :: Only",
- "Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
@@ -43,7 +42,9 @@ classifiers = [
dependencies = [
"starlette>=0.27.0,<0.28.0",
"pydantic>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0",
- "typing-extensions>=4.5.0",
+ "typing-extensions>=4.8.0",
+ # TODO: remove this pin after upgrading Starlette 0.31.1
+ "anyio>=3.7.1,<4.0.0",
]
dynamic = ["version"]
@@ -129,11 +130,13 @@ select = [
"I", # isort
"C", # flake8-comprehensions
"B", # flake8-bugbear
+ "UP", # pyupgrade
]
ignore = [
"E501", # line too long, handled by black
"B008", # do not perform function calls in argument defaults
"C901", # too complex
+ "W191", # indentation contains tabs
]
[tool.ruff.per-file-ignores]
@@ -153,6 +156,22 @@ ignore = [
"docs_src/query_params_str_validations/tutorial012_an_py39.py" = ["B006"]
"docs_src/query_params_str_validations/tutorial013_an.py" = ["B006"]
"docs_src/query_params_str_validations/tutorial013_an_py39.py" = ["B006"]
+"docs_src/security/tutorial004.py" = ["B904"]
+"docs_src/security/tutorial004_an.py" = ["B904"]
+"docs_src/security/tutorial004_an_py310.py" = ["B904"]
+"docs_src/security/tutorial004_an_py39.py" = ["B904"]
+"docs_src/security/tutorial004_py310.py" = ["B904"]
+"docs_src/security/tutorial005.py" = ["B904"]
+"docs_src/security/tutorial005_an.py" = ["B904"]
+"docs_src/security/tutorial005_an_py310.py" = ["B904"]
+"docs_src/security/tutorial005_an_py39.py" = ["B904"]
+"docs_src/security/tutorial005_py310.py" = ["B904"]
+"docs_src/security/tutorial005_py39.py" = ["B904"]
+
[tool.ruff.isort]
known-third-party = ["fastapi", "pydantic", "starlette"]
+
+[tool.ruff.pyupgrade]
+# Preserve types, even if a file imports `from __future__ import annotations`.
+keep-runtime-typing = true
diff --git a/requirements-docs-tests.txt b/requirements-docs-tests.txt
new file mode 100644
index 000000000..b82df4933
--- /dev/null
+++ b/requirements-docs-tests.txt
@@ -0,0 +1,2 @@
+# For mkdocstrings and tests
+httpx >=0.23.0,<0.25.0
diff --git a/requirements-docs.txt b/requirements-docs.txt
index 220d1ec3a..28408a9f1 100644
--- a/requirements-docs.txt
+++ b/requirements-docs.txt
@@ -1,13 +1,19 @@
-e .
-mkdocs-material==9.1.21
+-r requirements-docs-tests.txt
+mkdocs-material==9.4.7
mdx-include >=1.4.1,<2.0.0
mkdocs-markdownextradata-plugin >=0.1.7,<0.3.0
+mkdocs-redirects>=1.2.1,<1.3.0
typer-cli >=0.0.13,<0.0.14
typer[all] >=0.6.1,<0.8.0
pyyaml >=5.3.1,<7.0.0
# For Material for MkDocs, Chinese search
jieba==0.42.1
# For image processing by Material for MkDocs
-pillow==9.5.0
+pillow==10.1.0
# For image processing by Material for MkDocs
cairosvg==2.7.0
+mkdocstrings[python]==0.23.0
+griffe-typingdoc==0.2.2
+# For griffe, it formats with black
+black==23.3.0
diff --git a/requirements-tests.txt b/requirements-tests.txt
index 0113b6f7a..e1a976c13 100644
--- a/requirements-tests.txt
+++ b/requirements-tests.txt
@@ -1,17 +1,15 @@
-e .
+-r requirements-docs-tests.txt
pydantic-settings >=2.0.0
pytest >=7.1.3,<8.0.0
coverage[toml] >= 6.5.0,< 8.0
mypy ==1.4.1
-ruff ==0.0.275
-black == 23.3.0
-httpx >=0.23.0,<0.25.0
+ruff ==0.1.2
email_validator >=1.1.1,<3.0.0
dirty-equals ==0.6.0
# TODO: once removing databases from tutorial, upgrade SQLAlchemy
# probably when including SQLModel
sqlalchemy >=1.3.18,<1.4.43
-peewee >=3.13.3,<4.0.0
databases[sqlite] >=0.3.2,<0.7.0
orjson >=3.2.1,<4.0.0
ujson >=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0,<6.0.0
diff --git a/requirements.txt b/requirements.txt
index 7e746016a..ef25ec483 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,3 +3,5 @@
-r requirements-docs.txt
uvicorn[standard] >=0.12.0,<0.23.0
pre-commit >=2.17.0,<4.0.0
+# For generating screenshots
+playwright
diff --git a/scripts/docs.py b/scripts/docs.py
index 968dd9a3d..73e1900ad 100644
--- a/scripts/docs.py
+++ b/scripts/docs.py
@@ -36,7 +36,7 @@ site_path = Path("site").absolute()
build_site_path = Path("site_build").absolute()
-@lru_cache()
+@lru_cache
def is_mkdocs_insiders() -> bool:
version = metadata.version("mkdocs-material")
return "insiders" in version
@@ -104,7 +104,7 @@ def new_lang(lang: str = typer.Argument(..., callback=lang_callback)):
def build_lang(
lang: str = typer.Argument(
..., callback=lang_callback, autocompletion=complete_existing_lang
- )
+ ),
) -> None:
"""
Build the docs for a language.
@@ -153,17 +153,21 @@ index_sponsors_template = """
def generate_readme_content() -> str:
en_index = en_docs_path / "docs" / "index.md"
content = en_index.read_text("utf-8")
+ match_pre = re.search(r"\n\n", content)
match_start = re.search(r"", content)
match_end = re.search(r"", content)
sponsors_data_path = en_docs_path / "data" / "sponsors.yml"
sponsors = mkdocs.utils.yaml_load(sponsors_data_path.read_text(encoding="utf-8"))
if not (match_start and match_end):
raise RuntimeError("Couldn't auto-generate sponsors section")
+ if not match_pre:
+ raise RuntimeError("Couldn't find pre section (