diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 6a512a019b..c9723b25bb 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -29,7 +29,7 @@ jobs:
id: cache
with:
path: ${{ env.pythonLocation }}
- key: ${{ runner.os }}-python-${{ env.pythonLocation }}-pydantic-v2-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v04
+ key: ${{ runner.os }}-python-${{ env.pythonLocation }}-pydantic-v2-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v05
- name: Install Dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: pip install -r requirements-tests.txt
@@ -62,7 +62,7 @@ jobs:
id: cache
with:
path: ${{ env.pythonLocation }}
- key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ matrix.pydantic-version }}-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v04
+ key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ matrix.pydantic-version }}-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v05
- name: Install Dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: pip install -r requirements-tests.txt
diff --git a/.gitignore b/.gitignore
index d380d16b7d..9be494cec0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,6 @@ archive.zip
*~
.*.sw?
.cache
+
+# macOS
+.DS_Store
diff --git a/README.md b/README.md
index 50f80ded67..2662134261 100644
--- a/README.md
+++ b/README.md
@@ -49,6 +49,7 @@ The key features are:
+
@@ -56,6 +57,7 @@ The key features are:
+
diff --git a/docs/em/docs/advanced/extending-openapi.md b/docs/em/docs/advanced/extending-openapi.md
deleted file mode 100644
index 496a8d9de3..0000000000
--- a/docs/em/docs/advanced/extending-openapi.md
+++ /dev/null
@@ -1,314 +0,0 @@
-# ↔ 🗄
-
-!!! warning
- 👉 👍 🏧 ⚒. 👆 🎲 💪 🚶 ⚫️.
-
- 🚥 👆 📄 🔰 - 👩💻 🦮, 👆 💪 🎲 🚶 👉 📄.
-
- 🚥 👆 ⏪ 💭 👈 👆 💪 🔀 🏗 🗄 🔗, 😣 👂.
-
-📤 💼 🌐❔ 👆 💪 💪 🔀 🏗 🗄 🔗.
-
-👉 📄 👆 🔜 👀 ❔.
-
-## 😐 🛠️
-
-😐 (🔢) 🛠️, ⏩.
-
-`FastAPI` 🈸 (👐) ✔️ `.openapi()` 👩🔬 👈 📈 📨 🗄 🔗.
-
-🍕 🈸 🎚 🏗, *➡ 🛠️* `/openapi.json` (⚖️ ⚫️❔ 👆 ⚒ 👆 `openapi_url`) ®.
-
-⚫️ 📨 🎻 📨 ⏮️ 🏁 🈸 `.openapi()` 👩🔬.
-
-🔢, ⚫️❔ 👩🔬 `.openapi()` 🔨 ✅ 🏠 `.openapi_schema` 👀 🚥 ⚫️ ✔️ 🎚 & 📨 👫.
-
-🚥 ⚫️ 🚫, ⚫️ 🏗 👫 ⚙️ 🚙 🔢 `fastapi.openapi.utils.get_openapi`.
-
-& 👈 🔢 `get_openapi()` 📨 🔢:
-
-* `title`: 🗄 📛, 🎦 🩺.
-* `version`: ⏬ 👆 🛠️, ✅ `2.5.0`.
-* `openapi_version`: ⏬ 🗄 🔧 ⚙️. 🔢, ⏪: `3.0.2`.
-* `description`: 📛 👆 🛠️.
-* `routes`: 📇 🛣, 👫 🔠 ® *➡ 🛠️*. 👫 ✊ ⚪️➡️ `app.routes`.
-
-## 🔑 🔢
-
-⚙️ ℹ 🔛, 👆 💪 ⚙️ 🎏 🚙 🔢 🏗 🗄 🔗 & 🔐 🔠 🍕 👈 👆 💪.
-
-🖼, ➡️ 🚮 📄 🗄 ↔ 🔌 🛃 🔱.
-
-### 😐 **FastAPI**
-
-🥇, ✍ 🌐 👆 **FastAPI** 🈸 🛎:
-
-```Python hl_lines="1 4 7-9"
-{!../../../docs_src/extending_openapi/tutorial001.py!}
-```
-
-### 🏗 🗄 🔗
-
-⤴️, ⚙️ 🎏 🚙 🔢 🏗 🗄 🔗, 🔘 `custom_openapi()` 🔢:
-
-```Python hl_lines="2 15-20"
-{!../../../docs_src/extending_openapi/tutorial001.py!}
-```
-
-### 🔀 🗄 🔗
-
-🔜 👆 💪 🚮 📄 ↔, ❎ 🛃 `x-logo` `info` "🎚" 🗄 🔗:
-
-```Python hl_lines="21-23"
-{!../../../docs_src/extending_openapi/tutorial001.py!}
-```
-
-### 💾 🗄 🔗
-
-👆 💪 ⚙️ 🏠 `.openapi_schema` "💾", 🏪 👆 🏗 🔗.
-
-👈 🌌, 👆 🈸 🏆 🚫 ✔️ 🏗 🔗 🔠 🕰 👩💻 📂 👆 🛠️ 🩺.
-
-⚫️ 🔜 🏗 🕴 🕐, & ⤴️ 🎏 💾 🔗 🔜 ⚙️ ⏭ 📨.
-
-```Python hl_lines="13-14 24-25"
-{!../../../docs_src/extending_openapi/tutorial001.py!}
-```
-
-### 🔐 👩🔬
-
-🔜 👆 💪 ❎ `.openapi()` 👩🔬 ⏮️ 👆 🆕 🔢.
-
-```Python hl_lines="28"
-{!../../../docs_src/extending_openapi/tutorial001.py!}
-```
-
-### ✅ ⚫️
-
-🕐 👆 🚶 http://127.0.0.1:8000/redoc 👆 🔜 👀 👈 👆 ⚙️ 👆 🛃 🔱 (👉 🖼, **FastAPI**'Ⓜ 🔱):
-
-
-
-## 👤-🕸 🕸 & 🎚 🩺
-
-🛠️ 🩺 ⚙️ **🦁 🎚** & **📄**, & 🔠 👈 💪 🕸 & 🎚 📁.
-
-🔢, 👈 📁 🍦 ⚪️➡️ 💲.
-
-✋️ ⚫️ 💪 🛃 ⚫️, 👆 💪 ⚒ 🎯 💲, ⚖️ 🍦 📁 👆.
-
-👈 ⚠, 🖼, 🚥 👆 💪 👆 📱 🚧 👷 ⏪ 📱, 🍵 📂 🕸 🔐, ⚖️ 🇧🇿 🕸.
-
-📥 👆 🔜 👀 ❔ 🍦 👈 📁 👆, 🎏 FastAPI 📱, & 🔗 🩺 ⚙️ 👫.
-
-### 🏗 📁 📊
-
-➡️ 💬 👆 🏗 📁 📊 👀 💖 👉:
-
-```
-.
-├── app
-│ ├── __init__.py
-│ ├── main.py
-```
-
-🔜 ✍ 📁 🏪 📚 🎻 📁.
-
-👆 🆕 📁 📊 💪 👀 💖 👉:
-
-```
-.
-├── app
-│ ├── __init__.py
-│ ├── main.py
-└── static/
-```
-
-### ⏬ 📁
-
-⏬ 🎻 📁 💪 🩺 & 🚮 👫 🔛 👈 `static/` 📁.
-
-👆 💪 🎲 ▶️️-🖊 🔠 🔗 & 🖊 🎛 🎏 `Save link as...`.
-
-**🦁 🎚** ⚙️ 📁:
-
-* `swagger-ui-bundle.js`
-* `swagger-ui.css`
-
-& **📄** ⚙️ 📁:
-
-* `redoc.standalone.js`
-
-⏮️ 👈, 👆 📁 📊 💪 👀 💖:
-
-```
-.
-├── app
-│ ├── __init__.py
-│ ├── main.py
-└── static
- ├── redoc.standalone.js
- ├── swagger-ui-bundle.js
- └── swagger-ui.css
-```
-
-### 🍦 🎻 📁
-
-* 🗄 `StaticFiles`.
-* "🗻" `StaticFiles()` 👐 🎯 ➡.
-
-```Python hl_lines="7 11"
-{!../../../docs_src/extending_openapi/tutorial002.py!}
-```
-
-### 💯 🎻 📁
-
-▶️ 👆 🈸 & 🚶 http://127.0.0.1:8000/static/redoc.standalone.js.
-
-👆 🔜 👀 📶 📏 🕸 📁 **📄**.
-
-⚫️ 💪 ▶️ ⏮️ 🕳 💖:
-
-```JavaScript
-/*!
- * ReDoc - OpenAPI/Swagger-generated API Reference Documentation
- * -------------------------------------------------------------
- * Version: "2.0.0-rc.18"
- * Repo: https://github.com/Redocly/redoc
- */
-!function(e,t){"object"==typeof exports&&"object"==typeof m
-
-...
-```
-
-👈 ✔ 👈 👆 💆♂ 💪 🍦 🎻 📁 ⚪️➡️ 👆 📱, & 👈 👆 🥉 🎻 📁 🩺 ☑ 🥉.
-
-🔜 👥 💪 🔗 📱 ⚙️ 📚 🎻 📁 🩺.
-
-### ❎ 🏧 🩺
-
-🥇 🔁 ❎ 🏧 🩺, 📚 ⚙️ 💲 🔢.
-
-❎ 👫, ⚒ 👫 📛 `None` 🕐❔ 🏗 👆 `FastAPI` 📱:
-
-```Python hl_lines="9"
-{!../../../docs_src/extending_openapi/tutorial002.py!}
-```
-
-### 🔌 🛃 🩺
-
-🔜 👆 💪 ✍ *➡ 🛠️* 🛃 🩺.
-
-👆 💪 🏤-⚙️ FastAPI 🔗 🔢 ✍ 🕸 📃 🩺, & 🚶♀️ 👫 💪 ❌:
-
-* `openapi_url`: 📛 🌐❔ 🕸 📃 🩺 💪 🤚 🗄 🔗 👆 🛠️. 👆 💪 ⚙️ 📥 🔢 `app.openapi_url`.
-* `title`: 📛 👆 🛠️.
-* `oauth2_redirect_url`: 👆 💪 ⚙️ `app.swagger_ui_oauth2_redirect_url` 📥 ⚙️ 🔢.
-* `swagger_js_url`: 📛 🌐❔ 🕸 👆 🦁 🎚 🩺 💪 🤚 **🕸** 📁. 👉 1️⃣ 👈 👆 👍 📱 🔜 🍦.
-* `swagger_css_url`: 📛 🌐❔ 🕸 👆 🦁 🎚 🩺 💪 🤚 **🎚** 📁. 👉 1️⃣ 👈 👆 👍 📱 🔜 🍦.
-
-& ➡ 📄...
-
-```Python hl_lines="2-6 14-22 25-27 30-36"
-{!../../../docs_src/extending_openapi/tutorial002.py!}
-```
-
-!!! tip
- *➡ 🛠️* `swagger_ui_redirect` 👩🎓 🕐❔ 👆 ⚙️ Oauth2️⃣.
-
- 🚥 👆 🛠️ 👆 🛠️ ⏮️ Oauth2️⃣ 🐕🦺, 👆 🔜 💪 🔓 & 👟 🔙 🛠️ 🩺 ⏮️ 📎 🎓. & 🔗 ⏮️ ⚫️ ⚙️ 🎰 Oauth2️⃣ 🤝.
-
- 🦁 🎚 🔜 🍵 ⚫️ ⛅ 🎑 👆, ✋️ ⚫️ 💪 👉 "❎" 👩🎓.
-
-### ✍ *➡ 🛠️* 💯 ⚫️
-
-🔜, 💪 💯 👈 🌐 👷, ✍ *➡ 🛠️*:
-
-```Python hl_lines="39-41"
-{!../../../docs_src/extending_openapi/tutorial002.py!}
-```
-
-### 💯 ⚫️
-
-🔜, 👆 🔜 💪 🔌 👆 📻, 🚶 👆 🩺 http://127.0.0.1:8000/docs, & 🔃 📃.
-
-& 🍵 🕸, 👆 🔜 💪 👀 🩺 👆 🛠️ & 🔗 ⏮️ ⚫️.
-
-## 🛠️ 🦁 🎚
-
-👆 💪 🔗 ➕ 🦁 🎚 🔢.
-
-🔗 👫, 🚶♀️ `swagger_ui_parameters` ❌ 🕐❔ 🏗 `FastAPI()` 📱 🎚 ⚖️ `get_swagger_ui_html()` 🔢.
-
-`swagger_ui_parameters` 📨 📖 ⏮️ 📳 🚶♀️ 🦁 🎚 🔗.
-
-FastAPI 🗜 📳 **🎻** ⚒ 👫 🔗 ⏮️ 🕸, 👈 ⚫️❔ 🦁 🎚 💪.
-
-### ❎ ❕ 🎦
-
-🖼, 👆 💪 ❎ ❕ 🎦 🦁 🎚.
-
-🍵 🔀 ⚒, ❕ 🎦 🛠️ 🔢:
-
-
-
-✋️ 👆 💪 ❎ ⚫️ ⚒ `syntaxHighlight` `False`:
-
-```Python hl_lines="3"
-{!../../../docs_src/extending_openapi/tutorial003.py!}
-```
-
-...& ⤴️ 🦁 🎚 🏆 🚫 🎦 ❕ 🎦 🚫🔜:
-
-
-
-### 🔀 🎢
-
-🎏 🌌 👆 💪 ⚒ ❕ 🎦 🎢 ⏮️ 🔑 `"syntaxHighlight.theme"` (👀 👈 ⚫️ ✔️ ❣ 🖕):
-
-```Python hl_lines="3"
-{!../../../docs_src/extending_openapi/tutorial004.py!}
-```
-
-👈 📳 🔜 🔀 ❕ 🎦 🎨 🎢:
-
-
-
-### 🔀 🔢 🦁 🎚 🔢
-
-FastAPI 🔌 🔢 📳 🔢 ☑ 🌅 ⚙️ 💼.
-
-⚫️ 🔌 👫 🔢 📳:
-
-```Python
-{!../../../fastapi/openapi/docs.py[ln:7-13]!}
-```
-
-👆 💪 🔐 🙆 👫 ⚒ 🎏 💲 ❌ `swagger_ui_parameters`.
-
-🖼, ❎ `deepLinking` 👆 💪 🚶♀️ 👉 ⚒ `swagger_ui_parameters`:
-
-```Python hl_lines="3"
-{!../../../docs_src/extending_openapi/tutorial005.py!}
-```
-
-### 🎏 🦁 🎚 🔢
-
-👀 🌐 🎏 💪 📳 👆 💪 ⚙️, ✍ 🛂 🩺 🦁 🎚 🔢.
-
-### 🕸-🕴 ⚒
-
-🦁 🎚 ✔ 🎏 📳 **🕸-🕴** 🎚 (🖼, 🕸 🔢).
-
-FastAPI 🔌 👫 🕸-🕴 `presets` ⚒:
-
-```JavaScript
-presets: [
- SwaggerUIBundle.presets.apis,
- SwaggerUIBundle.SwaggerUIStandalonePreset
-]
-```
-
-👫 **🕸** 🎚, 🚫 🎻, 👆 💪 🚫 🚶♀️ 👫 ⚪️➡️ 🐍 📟 🔗.
-
-🚥 👆 💪 ⚙️ 🕸-🕴 📳 💖 📚, 👆 💪 ⚙️ 1️⃣ 👩🔬 🔛. 🔐 🌐 🦁 🎚 *➡ 🛠️* & ❎ ✍ 🙆 🕸 👆 💪.
diff --git a/docs/em/docs/deployment/deta.md b/docs/em/docs/deployment/deta.md
deleted file mode 100644
index 89b6c4bdbe..0000000000
--- a/docs/em/docs/deployment/deta.md
+++ /dev/null
@@ -1,258 +0,0 @@
-# 🛠️ FastAPI 🔛 🪔
-
-👉 📄 👆 🔜 💡 ❔ 💪 🛠️ **FastAPI** 🈸 🔛 🪔 ⚙️ 🆓 📄. 👶
-
-⚫️ 🔜 ✊ 👆 🔃 **1️⃣0️⃣ ⏲**.
-
-!!! info
- 🪔 **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.txt` ⏮️:
-
-```text
-fastapi
-```
-
-!!! tip
- 👆 🚫 💪 ❎ Uvicorn 🛠️ 🔛 🪔, 👐 👆 🔜 🎲 💚 ❎ ⚫️ 🌐 💯 👆 📱.
-
-### 📁 📊
-
-👆 🔜 🔜 ✔️ 1️⃣ 📁 `./fastapideta/` ⏮️ 2️⃣ 📁:
-
-```
-.
-└── main.py
-└── requirements.txt
-```
-
-## ✍ 🆓 🪔 🏧
-
-🔜 ✍ 🆓 🏧 🔛 🪔, 👆 💪 📧 & 🔐.
-
-👆 🚫 💪 💳.
-
-## ❎ ✳
-
-🕐 👆 ✔️ 👆 🏧, ❎ 🪔 ✳:
-
-=== "💾, 🇸🇻"
-
-
-
-## 🛠️ 📢 🔐
-
-🔢, 🪔 🔜 🍵 🤝 ⚙️ 🍪 👆 🏧.
-
-✋️ 🕐 👆 🔜, 👆 💪 ⚒ ⚫️ 📢 ⏮️:
-
-
-
-## 💡 🌅
-
-☝, 👆 🔜 🎲 💚 🏪 💽 👆 📱 🌌 👈 😣 🔘 🕰. 👈 👆 💪 ⚙️ 🪔 🧢, ⚫️ ✔️ 👍 **🆓 🎚**.
-
-👆 💪 ✍ 🌅 🪔 🩺.
-
-## 🛠️ 🔧
-
-👟 🔙 🔧 👥 🔬 [🛠️ 🔧](./concepts.md){.internal-link target=_blank}, 📥 ❔ 🔠 👫 🔜 🍵 ⏮️ 🪔:
-
-* **🇺🇸🔍**: 🍵 🪔, 👫 🔜 🤝 👆 📁 & 🍵 🇺🇸🔍 🔁.
-* **🏃♂ 🔛 🕴**: 🍵 🪔, 🍕 👫 🐕🦺.
-* **⏏**: 🍵 🪔, 🍕 👫 🐕🦺.
-* **🧬**: 🍵 🪔, 🍕 👫 🐕🦺.
-* **💾**: 📉 🔁 🪔, 👆 💪 📧 👫 📈 ⚫️.
-* **⏮️ 🔁 ⏭ ▶️**: 🚫 🔗 🐕🦺, 👆 💪 ⚒ ⚫️ 👷 ⏮️ 👫 💾 ⚙️ ⚖️ 🌖 ✍.
-
-!!! note
- 🪔 🔧 ⚒ ⚫️ ⏩ (& 🆓) 🛠️ 🙅 🈸 🔜.
-
- ⚫️ 💪 📉 📚 ⚙️ 💼, ✋️ 🎏 🕰, ⚫️ 🚫 🐕🦺 🎏, 💖 ⚙️ 🔢 💽 (↖️ ⚪️➡️ 🪔 👍 ☁ 💽 ⚙️), 🛃 🕹 🎰, ♒️.
-
- 👆 💪 ✍ 🌅 ℹ 🪔 🩺 👀 🚥 ⚫️ ▶️️ ⚒ 👆.
diff --git a/docs/em/docs/advanced/conditional-openapi.md b/docs/em/docs/how-to/conditional-openapi.md
similarity index 100%
rename from docs/em/docs/advanced/conditional-openapi.md
rename to docs/em/docs/how-to/conditional-openapi.md
diff --git a/docs/em/docs/advanced/custom-request-and-route.md b/docs/em/docs/how-to/custom-request-and-route.md
similarity index 100%
rename from docs/em/docs/advanced/custom-request-and-route.md
rename to docs/em/docs/how-to/custom-request-and-route.md
diff --git a/docs/em/docs/how-to/extending-openapi.md b/docs/em/docs/how-to/extending-openapi.md
new file mode 100644
index 0000000000..6b3bc00757
--- /dev/null
+++ b/docs/em/docs/how-to/extending-openapi.md
@@ -0,0 +1,90 @@
+# ↔ 🗄
+
+!!! warning
+ 👉 👍 🏧 ⚒. 👆 🎲 💪 🚶 ⚫️.
+
+ 🚥 👆 📄 🔰 - 👩💻 🦮, 👆 💪 🎲 🚶 👉 📄.
+
+ 🚥 👆 ⏪ 💭 👈 👆 💪 🔀 🏗 🗄 🔗, 😣 👂.
+
+📤 💼 🌐❔ 👆 💪 💪 🔀 🏗 🗄 🔗.
+
+👉 📄 👆 🔜 👀 ❔.
+
+## 😐 🛠️
+
+😐 (🔢) 🛠️, ⏩.
+
+`FastAPI` 🈸 (👐) ✔️ `.openapi()` 👩🔬 👈 📈 📨 🗄 🔗.
+
+🍕 🈸 🎚 🏗, *➡ 🛠️* `/openapi.json` (⚖️ ⚫️❔ 👆 ⚒ 👆 `openapi_url`) ®.
+
+⚫️ 📨 🎻 📨 ⏮️ 🏁 🈸 `.openapi()` 👩🔬.
+
+🔢, ⚫️❔ 👩🔬 `.openapi()` 🔨 ✅ 🏠 `.openapi_schema` 👀 🚥 ⚫️ ✔️ 🎚 & 📨 👫.
+
+🚥 ⚫️ 🚫, ⚫️ 🏗 👫 ⚙️ 🚙 🔢 `fastapi.openapi.utils.get_openapi`.
+
+& 👈 🔢 `get_openapi()` 📨 🔢:
+
+* `title`: 🗄 📛, 🎦 🩺.
+* `version`: ⏬ 👆 🛠️, ✅ `2.5.0`.
+* `openapi_version`: ⏬ 🗄 🔧 ⚙️. 🔢, ⏪: `3.0.2`.
+* `description`: 📛 👆 🛠️.
+* `routes`: 📇 🛣, 👫 🔠 ® *➡ 🛠️*. 👫 ✊ ⚪️➡️ `app.routes`.
+
+## 🔑 🔢
+
+⚙️ ℹ 🔛, 👆 💪 ⚙️ 🎏 🚙 🔢 🏗 🗄 🔗 & 🔐 🔠 🍕 👈 👆 💪.
+
+🖼, ➡️ 🚮 📄 🗄 ↔ 🔌 🛃 🔱.
+
+### 😐 **FastAPI**
+
+🥇, ✍ 🌐 👆 **FastAPI** 🈸 🛎:
+
+```Python hl_lines="1 4 7-9"
+{!../../../docs_src/extending_openapi/tutorial001.py!}
+```
+
+### 🏗 🗄 🔗
+
+⤴️, ⚙️ 🎏 🚙 🔢 🏗 🗄 🔗, 🔘 `custom_openapi()` 🔢:
+
+```Python hl_lines="2 15-20"
+{!../../../docs_src/extending_openapi/tutorial001.py!}
+```
+
+### 🔀 🗄 🔗
+
+🔜 👆 💪 🚮 📄 ↔, ❎ 🛃 `x-logo` `info` "🎚" 🗄 🔗:
+
+```Python hl_lines="21-23"
+{!../../../docs_src/extending_openapi/tutorial001.py!}
+```
+
+### 💾 🗄 🔗
+
+👆 💪 ⚙️ 🏠 `.openapi_schema` "💾", 🏪 👆 🏗 🔗.
+
+👈 🌌, 👆 🈸 🏆 🚫 ✔️ 🏗 🔗 🔠 🕰 👩💻 📂 👆 🛠️ 🩺.
+
+⚫️ 🔜 🏗 🕴 🕐, & ⤴️ 🎏 💾 🔗 🔜 ⚙️ ⏭ 📨.
+
+```Python hl_lines="13-14 24-25"
+{!../../../docs_src/extending_openapi/tutorial001.py!}
+```
+
+### 🔐 👩🔬
+
+🔜 👆 💪 ❎ `.openapi()` 👩🔬 ⏮️ 👆 🆕 🔢.
+
+```Python hl_lines="28"
+{!../../../docs_src/extending_openapi/tutorial001.py!}
+```
+
+### ✅ ⚫️
+
+🕐 👆 🚶 http://127.0.0.1:8000/redoc 👆 🔜 👀 👈 👆 ⚙️ 👆 🛃 🔱 (👉 🖼, **FastAPI**'Ⓜ 🔱):
+
+
diff --git a/docs/em/docs/advanced/graphql.md b/docs/em/docs/how-to/graphql.md
similarity index 100%
rename from docs/em/docs/advanced/graphql.md
rename to docs/em/docs/how-to/graphql.md
diff --git a/docs/em/docs/advanced/sql-databases-peewee.md b/docs/em/docs/how-to/sql-databases-peewee.md
similarity index 100%
rename from docs/em/docs/advanced/sql-databases-peewee.md
rename to docs/em/docs/how-to/sql-databases-peewee.md
diff --git a/docs/en/data/sponsors.yml b/docs/en/data/sponsors.yml
index 53cdb9bad1..0d9597f077 100644
--- a/docs/en/data/sponsors.yml
+++ b/docs/en/data/sponsors.yml
@@ -8,6 +8,9 @@ gold:
- url: https://www.buildwithfern.com/?utm_source=tiangolo&utm_medium=website&utm_campaign=main-badge
title: Fern | SDKs and API docs
img: https://fastapi.tiangolo.com/img/sponsors/fern.svg
+ - url: https://www.porter.run
+ title: Deploy FastAPI on AWS with a few clicks
+ img: https://fastapi.tiangolo.com/img/sponsors/porter.png
silver:
- url: https://www.deta.sh/?ref=fastapi
title: The launchpad for all your (team's) ideas
@@ -30,6 +33,9 @@ silver:
- url: https://databento.com/
title: Pay as you go for market data
img: https://fastapi.tiangolo.com/img/sponsors/databento.svg
+ - url: https://speakeasyapi.dev?utm_source=fastapi+repo&utm_medium=github+sponsorship
+ title: SDKs for your API | Speakeasy
+ img: https://fastapi.tiangolo.com/img/sponsors/speakeasy.png
bronze:
- url: https://www.exoflare.com/open-source/?utm_source=FastAPI&utm_campaign=open_source
title: Biosecurity risk assessments made easy.
@@ -37,3 +43,6 @@ bronze:
- url: https://www.flint.sh
title: IT expertise, consulting and development by passionate people
img: https://fastapi.tiangolo.com/img/sponsors/flint.png
+ - url: https://bit.ly/3JJ7y5C
+ title: Build cross-modal and multimodal applications on the cloud
+ img: https://fastapi.tiangolo.com/img/sponsors/jina2.svg
diff --git a/docs/en/data/sponsors_badge.yml b/docs/en/data/sponsors_badge.yml
index b3cb063270..7b605e0ffe 100644
--- a/docs/en/data/sponsors_badge.yml
+++ b/docs/en/data/sponsors_badge.yml
@@ -17,3 +17,6 @@ logins:
- databento-bot
- nanram22
- Flint-company
+ - porter-dev
+ - fern-api
+ - ndimares
diff --git a/docs/en/docs/advanced/extending-openapi.md b/docs/en/docs/advanced/extending-openapi.md
deleted file mode 100644
index bec184deec..0000000000
--- a/docs/en/docs/advanced/extending-openapi.md
+++ /dev/null
@@ -1,318 +0,0 @@
-# Extending OpenAPI
-
-!!! warning
- This is a rather advanced feature. You probably can skip it.
-
- If you are just following the tutorial - user guide, you can probably skip this section.
-
- If you already know that you need to modify the generated OpenAPI schema, continue reading.
-
-There are some cases where you might need to modify the generated OpenAPI schema.
-
-In this section you will see how.
-
-## The normal process
-
-The normal (default) process, is as follows.
-
-A `FastAPI` application (instance) has an `.openapi()` method that is expected to return the OpenAPI schema.
-
-As part of the application object creation, a *path operation* for `/openapi.json` (or for whatever you set your `openapi_url`) is registered.
-
-It just returns a JSON response with the result of the application's `.openapi()` method.
-
-By default, what the method `.openapi()` does is check the property `.openapi_schema` to see if it has contents and return them.
-
-If it doesn't, it generates them using the utility function at `fastapi.openapi.utils.get_openapi`.
-
-And that function `get_openapi()` receives as parameters:
-
-* `title`: The OpenAPI title, shown in the docs.
-* `version`: The version of your API, e.g. `2.5.0`.
-* `openapi_version`: The version of the OpenAPI specification used. By default, the latest: `3.1.0`.
-* `summary`: A short summary of the API.
-* `description`: The description of your API, this can include markdown and will be shown in the docs.
-* `routes`: A list of routes, these are each of the registered *path operations*. They are taken from `app.routes`.
-
-!!! info
- The parameter `summary` is available in OpenAPI 3.1.0 and above, supported by FastAPI 0.99.0 and above.
-
-## Overriding the defaults
-
-Using the information above, you can use the same utility function to generate the OpenAPI schema and override each part that you need.
-
-For example, let's add ReDoc's OpenAPI extension to include a custom logo.
-
-### Normal **FastAPI**
-
-First, write all your **FastAPI** application as normally:
-
-```Python hl_lines="1 4 7-9"
-{!../../../docs_src/extending_openapi/tutorial001.py!}
-```
-
-### Generate the OpenAPI schema
-
-Then, use the same utility function to generate the OpenAPI schema, inside a `custom_openapi()` function:
-
-```Python hl_lines="2 15-21"
-{!../../../docs_src/extending_openapi/tutorial001.py!}
-```
-
-### Modify the OpenAPI schema
-
-Now you can add the ReDoc extension, adding a custom `x-logo` to the `info` "object" in the OpenAPI schema:
-
-```Python hl_lines="22-24"
-{!../../../docs_src/extending_openapi/tutorial001.py!}
-```
-
-### Cache the OpenAPI schema
-
-You can use the property `.openapi_schema` as a "cache", to store your generated schema.
-
-That way, your application won't have to generate the schema every time a user opens your API docs.
-
-It will be generated only once, and then the same cached schema will be used for the next requests.
-
-```Python hl_lines="13-14 25-26"
-{!../../../docs_src/extending_openapi/tutorial001.py!}
-```
-
-### Override the method
-
-Now you can replace the `.openapi()` method with your new function.
-
-```Python hl_lines="29"
-{!../../../docs_src/extending_openapi/tutorial001.py!}
-```
-
-### Check it
-
-Once you go to http://127.0.0.1:8000/redoc you will see that you are using your custom logo (in this example, **FastAPI**'s logo):
-
-
-
-## Self-hosting JavaScript and CSS for docs
-
-The API docs use **Swagger UI** and **ReDoc**, and each of those need some JavaScript and CSS files.
-
-By default, those files are served from a CDN.
-
-But it's possible to customize it, you can set a specific CDN, or serve the files yourself.
-
-That's useful, for example, if you need your app to keep working even while offline, without open Internet access, or in a local network.
-
-Here you'll see how to serve those files yourself, in the same FastAPI app, and configure the docs to use them.
-
-### Project file structure
-
-Let's say your project file structure looks like this:
-
-```
-.
-├── app
-│ ├── __init__.py
-│ ├── main.py
-```
-
-Now create a directory to store those static files.
-
-Your new file structure could look like this:
-
-```
-.
-├── app
-│ ├── __init__.py
-│ ├── main.py
-└── static/
-```
-
-### Download the files
-
-Download the static files needed for the docs and put them on that `static/` directory.
-
-You can probably right-click each link and select an option similar to `Save link as...`.
-
-**Swagger UI** uses the files:
-
-* `swagger-ui-bundle.js`
-* `swagger-ui.css`
-
-And **ReDoc** uses the file:
-
-* `redoc.standalone.js`
-
-After that, your file structure could look like:
-
-```
-.
-├── app
-│ ├── __init__.py
-│ ├── main.py
-└── static
- ├── redoc.standalone.js
- ├── swagger-ui-bundle.js
- └── swagger-ui.css
-```
-
-### Serve the static files
-
-* Import `StaticFiles`.
-* "Mount" a `StaticFiles()` instance in a specific path.
-
-```Python hl_lines="7 11"
-{!../../../docs_src/extending_openapi/tutorial002.py!}
-```
-
-### Test the static files
-
-Start your application and go to http://127.0.0.1:8000/static/redoc.standalone.js.
-
-You should see a very long JavaScript file for **ReDoc**.
-
-It could start with something like:
-
-```JavaScript
-/*!
- * ReDoc - OpenAPI/Swagger-generated API Reference Documentation
- * -------------------------------------------------------------
- * Version: "2.0.0-rc.18"
- * Repo: https://github.com/Redocly/redoc
- */
-!function(e,t){"object"==typeof exports&&"object"==typeof m
-
-...
-```
-
-That confirms that you are being able to serve static files from your app, and that you placed the static files for the docs in the correct place.
-
-Now we can configure the app to use those static files for the docs.
-
-### Disable the automatic docs
-
-The first step is to disable the automatic docs, as those use the CDN by default.
-
-To disable them, set their URLs to `None` when creating your `FastAPI` app:
-
-```Python hl_lines="9"
-{!../../../docs_src/extending_openapi/tutorial002.py!}
-```
-
-### Include the custom docs
-
-Now you can create the *path operations* for the custom docs.
-
-You can re-use FastAPI's internal functions to create the HTML pages for the docs, and pass them the needed arguments:
-
-* `openapi_url`: the URL where the HTML page for the docs can get the OpenAPI schema for your API. You can use here the attribute `app.openapi_url`.
-* `title`: the title of your API.
-* `oauth2_redirect_url`: you can use `app.swagger_ui_oauth2_redirect_url` here to use the default.
-* `swagger_js_url`: the URL where the HTML for your Swagger UI docs can get the **JavaScript** file. This is the one that your own app is now serving.
-* `swagger_css_url`: the URL where the HTML for your Swagger UI docs can get the **CSS** file. This is the one that your own app is now serving.
-
-And similarly for ReDoc...
-
-```Python hl_lines="2-6 14-22 25-27 30-36"
-{!../../../docs_src/extending_openapi/tutorial002.py!}
-```
-
-!!! tip
- The *path operation* for `swagger_ui_redirect` is a helper for when you use OAuth2.
-
- If you integrate your API with an OAuth2 provider, you will be able to authenticate and come back to the API docs with the acquired credentials. And interact with it using the real OAuth2 authentication.
-
- Swagger UI will handle it behind the scenes for you, but it needs this "redirect" helper.
-
-### Create a *path operation* to test it
-
-Now, to be able to test that everything works, create a *path operation*:
-
-```Python hl_lines="39-41"
-{!../../../docs_src/extending_openapi/tutorial002.py!}
-```
-
-### Test it
-
-Now, you should be able to disconnect your WiFi, go to your docs at http://127.0.0.1:8000/docs, and reload the page.
-
-And even without Internet, you would be able to see the docs for your API and interact with it.
-
-## Configuring Swagger UI
-
-You can configure some extra Swagger UI parameters.
-
-To configure them, pass the `swagger_ui_parameters` argument when creating the `FastAPI()` app object or to the `get_swagger_ui_html()` function.
-
-`swagger_ui_parameters` receives a dictionary with the configurations passed to Swagger UI directly.
-
-FastAPI converts the configurations to **JSON** to make them compatible with JavaScript, as that's what Swagger UI needs.
-
-### Disable Syntax Highlighting
-
-For example, you could disable syntax highlighting in Swagger UI.
-
-Without changing the settings, syntax highlighting is enabled by default:
-
-
-
-But you can disable it by setting `syntaxHighlight` to `False`:
-
-```Python hl_lines="3"
-{!../../../docs_src/extending_openapi/tutorial003.py!}
-```
-
-...and then Swagger UI won't show the syntax highlighting anymore:
-
-
-
-### Change the Theme
-
-The same way you could set the syntax highlighting theme with the key `"syntaxHighlight.theme"` (notice that it has a dot in the middle):
-
-```Python hl_lines="3"
-{!../../../docs_src/extending_openapi/tutorial004.py!}
-```
-
-That configuration would change the syntax highlighting color theme:
-
-
-
-### Change Default Swagger UI Parameters
-
-FastAPI includes some default configuration parameters appropriate for most of the use cases.
-
-It includes these default configurations:
-
-```Python
-{!../../../fastapi/openapi/docs.py[ln:7-13]!}
-```
-
-You can override any of them by setting a different value in the argument `swagger_ui_parameters`.
-
-For example, to disable `deepLinking` you could pass these settings to `swagger_ui_parameters`:
-
-```Python hl_lines="3"
-{!../../../docs_src/extending_openapi/tutorial005.py!}
-```
-
-### Other Swagger UI Parameters
-
-To see all the other possible configurations you can use, read the official docs for Swagger UI parameters.
-
-### JavaScript-only settings
-
-Swagger UI also allows other configurations to be **JavaScript-only** objects (for example, JavaScript functions).
-
-FastAPI also includes these JavaScript-only `presets` settings:
-
-```JavaScript
-presets: [
- SwaggerUIBundle.presets.apis,
- SwaggerUIBundle.SwaggerUIStandalonePreset
-]
-```
-
-These are **JavaScript** objects, not strings, so you can't pass them from Python code directly.
-
-If you need to use JavaScript-only configurations like those, you can use one of the methods above. Override all the Swagger UI *path operation* and manually write any JavaScript you need.
diff --git a/docs/en/docs/advanced/generate-clients.md b/docs/en/docs/advanced/generate-clients.md
index 3fed48b0bc..f439ed93ab 100644
--- a/docs/en/docs/advanced/generate-clients.md
+++ b/docs/en/docs/advanced/generate-clients.md
@@ -12,10 +12,18 @@ A common tool is openapi-typescript-codegen.
-Another option you could consider for several languages is Fern.
+## Client and SDK Generators - Sponsor
-!!! info
- Fern is also a FastAPI sponsor. 😎🎉
+There are also some **company-backed** Client and SDK generators based on OpenAPI (FastAPI), in some cases they can offer you **additional features** on top of high-quality generated SDKs/clients.
+
+Some of them also ✨ [**sponsor FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, this ensures the continued and healthy **development** of FastAPI and its **ecosystem**.
+
+And it shows their true commitment to FastAPI and its **community** (you), as they not only want to provide you a **good service** but also want to make sure you have a **good and healthy framework**, FastAPI. 🙇
+
+You might want to try their services and follow their guides:
+
+* Fern
+* Speakeasy
## Generate a TypeScript Frontend Client
diff --git a/docs/en/docs/advanced/index.md b/docs/en/docs/advanced/index.md
index 467f0833e6..d8dcd4ca67 100644
--- a/docs/en/docs/advanced/index.md
+++ b/docs/en/docs/advanced/index.md
@@ -17,8 +17,17 @@ You could still use most of the features in **FastAPI** with the knowledge from
And the next sections assume you already read it, and assume that you know those main ideas.
-## TestDriven.io course
+## External Courses
-If you would like to take an advanced-beginner course to complement this section of the docs, you might want to check: Test-Driven Development with FastAPI and Docker by **TestDriven.io**.
+Although the [Tutorial - User Guide](../tutorial/){.internal-link target=_blank} and this **Advanced User Guide** are written as a guided tutorial (like a book) and should be enough for you to **learn FastAPI**, you might want to complement it with additional courses.
-They are currently donating 10% of all profits to the development of **FastAPI**. 🎉 😄
+Or it might be the case that you just prefer to take other courses because they adapt better to your learning style.
+
+Some course providers ✨ [**sponsor FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, this ensures the continued and healthy **development** of FastAPI and its **ecosystem**.
+
+And it shows their true commitment to FastAPI and its **community** (you), as they not only want to provide you a **good learning experience** but also want to make sure you have a **good and healthy framework**, FastAPI. 🙇
+
+You might want to try their courses:
+
+* Talk Python Training
+* Test-Driven Development
diff --git a/docs/en/docs/deployment/cloud.md b/docs/en/docs/deployment/cloud.md
new file mode 100644
index 0000000000..b2836aeb49
--- /dev/null
+++ b/docs/en/docs/deployment/cloud.md
@@ -0,0 +1,17 @@
+# Deploy FastAPI on Cloud Providers
+
+You can use virtually **any cloud provider** to deploy your FastAPI application.
+
+In most of the cases, the main cloud providers have guides to deploy FastAPI with them.
+
+## Cloud Providers - Sponsors
+
+Some cloud providers ✨ [**sponsor FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, this ensures the continued and healthy **development** of FastAPI and its **ecosystem**.
+
+And it shows their true commitment to FastAPI and its **community** (you), as they not only want to provide you a **good service** but also want to make sure you have a **good and healthy framework**, FastAPI. 🙇
+
+You might want to try their services and follow their guides:
+
+* Platform.sh
+* Porter
+* Deta
diff --git a/docs/en/docs/deployment/deta.md b/docs/en/docs/deployment/deta.md
deleted file mode 100644
index 229d7fd5d8..0000000000
--- a/docs/en/docs/deployment/deta.md
+++ /dev/null
@@ -1,391 +0,0 @@
-# Deploy FastAPI on Deta Space
-
-In this section you will learn how to easily deploy a **FastAPI** application on Deta Space, for free. 🎁
-
-It will take you about **10 minutes** to deploy an API that you can use. After that, you can optionally release it to anyone.
-
-Let's dive in.
-
-!!! info
- Deta is a **FastAPI** sponsor. 🎉
-
-## A simple **FastAPI** app
-
-* To start, create an empty directory with the name of your app, for example `./fastapi-deta/`, and then navigate into it.
-
-```console
-$ mkdir fastapi-deta
-$ cd fastapi-deta
-```
-
-### FastAPI code
-
-* Create a `main.py` file with:
-
-```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
-
-Now, in the same directory create a file `requirements.txt` with:
-
-```text
-fastapi
-uvicorn[standard]
-```
-
-### Directory structure
-
-You will now have a directory `./fastapi-deta/` with two files:
-
-```
-.
-└── main.py
-└── requirements.txt
-```
-
-## Create a free **Deta Space** account
-
-Next, create a free account on Deta Space, you just need an email and password.
-
-You don't even need a credit card, but make sure **Developer Mode** is enabled when you sign up.
-
-
-## Install the CLI
-
-Once you have your account, install the Deta Space CLI:
-
-=== "Linux, macOS"
-
-
-
-Now run `space login` from the Space CLI. Upon pasting the token into the CLI prompt and pressing enter, you should see a confirmation message.
-
-
-
-Click on the new app called `fastapi-deta`, and it will open your API in a new browser tab on a URL like `https://fastapi-deta-gj7ka8.deta.app/`.
-
-You will get a JSON response from your FastAPI app:
-
-```JSON
-{
- "Hello": "World"
-}
-```
-
-And now you can head over to the `/docs` of your API. For this example, it would be `https://fastapi-deta-gj7ka8.deta.app/docs`.
-
-
-
-## Enable public access
-
-Deta will handle authentication for your account using cookies. By default, every app or API that you `push` or install to your Space is personal - it's only accessible to you.
-
-But you can also make your API public using the `Spacefile` from earlier.
-
-With a `public_routes` parameter, you can specify which paths of your API should be available to the public.
-
-Set your `public_routes` to `"*"` to open every route of your API to the public:
-
-```yaml
-v: 0
-micros:
- - name: fastapi-deta
- src: .
- engine: python3.9
- public_routes:
- - "/*"
-```
-
-Then run `space push` again to update your live API on Deta Space.
-
-Once it deploys, you can share your URL with anyone and they will be able to access your API. 🚀
-
-## HTTPS
-
-Congrats! You deployed your FastAPI app to Deta Space! 🎉 🍰
-
-Also, notice that Deta Space correctly handles HTTPS for you, so you don't have to take care of that and can be sure that your users will have a secure encrypted connection. ✅ 🔒
-
-## Create a release
-
-Space also allows you to publish your API. When you publish it, anyone else can install their own copy of your API, in their own Deta Space cloud.
-
-To do so, run `space release` in the Space CLI to create an **unlisted release**:
-
-
-
-## Learn more
-
-At some point, you will probably want to store some data for your app in a way that persists through time. For that you can use Deta Base and Deta Drive, both of which have a generous **free tier**.
-
-You can also read more in the Deta Space Documentation.
-
-!!! tip
- If you have any Deta related questions, comments, or feedback, head to the Deta Discord server.
-
-
-## Deployment Concepts
-
-Coming back to the concepts we discussed in [Deployments Concepts](./concepts.md){.internal-link target=_blank}, here's how each of them would be handled with Deta Space:
-
-- **HTTPS**: Handled by Deta Space, they will give you a subdomain and handle HTTPS automatically.
-- **Running on startup**: Handled by Deta Space, as part of their service.
-- **Restarts**: Handled by Deta Space, as part of their service.
-- **Replication**: Handled by Deta Space, as part of their service.
-- **Authentication**: Handled by Deta Space, as part of their service.
-- **Memory**: Limit predefined by Deta Space, you could contact them to increase it.
-- **Previous steps before starting**: Can be configured using the `Spacefile`.
-
-!!! note
- Deta Space is designed to make it easy and free to build cloud applications for yourself. Then you can optionally share them with anyone.
-
- It can simplify several use cases, but at the same time, it doesn't support others, like using external databases (apart from Deta's own NoSQL database system), custom virtual machines, etc.
-
- You can read more details in the Deta Space Documentation to see if it's the right choice for you.
diff --git a/docs/en/docs/advanced/async-sql-databases.md b/docs/en/docs/how-to/async-sql-encode-databases.md
similarity index 98%
rename from docs/en/docs/advanced/async-sql-databases.md
rename to docs/en/docs/how-to/async-sql-encode-databases.md
index 12549a1903..697167f790 100644
--- a/docs/en/docs/advanced/async-sql-databases.md
+++ b/docs/en/docs/how-to/async-sql-encode-databases.md
@@ -1,4 +1,4 @@
-# Async SQL (Relational) Databases
+# Async SQL (Relational) Databases with Encode/Databases
!!! info
These docs are about to be updated. 🎉
diff --git a/docs/en/docs/advanced/conditional-openapi.md b/docs/en/docs/how-to/conditional-openapi.md
similarity index 100%
rename from docs/en/docs/advanced/conditional-openapi.md
rename to docs/en/docs/how-to/conditional-openapi.md
diff --git a/docs/en/docs/how-to/configure-swagger-ui.md b/docs/en/docs/how-to/configure-swagger-ui.md
new file mode 100644
index 0000000000..f36ba5ba8c
--- /dev/null
+++ b/docs/en/docs/how-to/configure-swagger-ui.md
@@ -0,0 +1,78 @@
+# Configure Swagger UI
+
+You can configure some extra Swagger UI parameters.
+
+To configure them, pass the `swagger_ui_parameters` argument when creating the `FastAPI()` app object or to the `get_swagger_ui_html()` function.
+
+`swagger_ui_parameters` receives a dictionary with the configurations passed to Swagger UI directly.
+
+FastAPI converts the configurations to **JSON** to make them compatible with JavaScript, as that's what Swagger UI needs.
+
+## Disable Syntax Highlighting
+
+For example, you could disable syntax highlighting in Swagger UI.
+
+Without changing the settings, syntax highlighting is enabled by default:
+
+
+
+But you can disable it by setting `syntaxHighlight` to `False`:
+
+```Python hl_lines="3"
+{!../../../docs_src/configure_swagger_ui/tutorial001.py!}
+```
+
+...and then Swagger UI won't show the syntax highlighting anymore:
+
+
+
+## Change the Theme
+
+The same way you could set the syntax highlighting theme with the key `"syntaxHighlight.theme"` (notice that it has a dot in the middle):
+
+```Python hl_lines="3"
+{!../../../docs_src/configure_swagger_ui/tutorial002.py!}
+```
+
+That configuration would change the syntax highlighting color theme:
+
+
+
+## Change Default Swagger UI Parameters
+
+FastAPI includes some default configuration parameters appropriate for most of the use cases.
+
+It includes these default configurations:
+
+```Python
+{!../../../fastapi/openapi/docs.py[ln:7-13]!}
+```
+
+You can override any of them by setting a different value in the argument `swagger_ui_parameters`.
+
+For example, to disable `deepLinking` you could pass these settings to `swagger_ui_parameters`:
+
+```Python hl_lines="3"
+{!../../../docs_src/configure_swagger_ui/tutorial003.py!}
+```
+
+## Other Swagger UI Parameters
+
+To see all the other possible configurations you can use, read the official docs for Swagger UI parameters.
+
+## JavaScript-only settings
+
+Swagger UI also allows other configurations to be **JavaScript-only** objects (for example, JavaScript functions).
+
+FastAPI also includes these JavaScript-only `presets` settings:
+
+```JavaScript
+presets: [
+ SwaggerUIBundle.presets.apis,
+ SwaggerUIBundle.SwaggerUIStandalonePreset
+]
+```
+
+These are **JavaScript** objects, not strings, so you can't pass them from Python code directly.
+
+If you need to use JavaScript-only configurations like those, you can use one of the methods above. Override all the Swagger UI *path operation* and manually write any JavaScript you need.
diff --git a/docs/en/docs/how-to/custom-docs-ui-assets.md b/docs/en/docs/how-to/custom-docs-ui-assets.md
new file mode 100644
index 0000000000..f263248692
--- /dev/null
+++ b/docs/en/docs/how-to/custom-docs-ui-assets.md
@@ -0,0 +1,199 @@
+# Custom Docs UI Static Assets (Self-Hosting)
+
+The API docs use **Swagger UI** and **ReDoc**, and each of those need some JavaScript and CSS files.
+
+By default, those files are served from a CDN.
+
+But it's possible to customize it, you can set a specific CDN, or serve the files yourself.
+
+## Custom CDN for JavaScript and CSS
+
+Let's say that you want to use a different CDN, for example you want to use `https://unpkg.com/`.
+
+This could be useful if for example you live in a country that restricts some URLs.
+
+### Disable the automatic docs
+
+The first step is to disable the automatic docs, as by default, those use the default CDN.
+
+To disable them, set their URLs to `None` when creating your `FastAPI` app:
+
+```Python hl_lines="8"
+{!../../../docs_src/custom_docs_ui/tutorial001.py!}
+```
+
+### Include the custom docs
+
+Now you can create the *path operations* for the custom docs.
+
+You can re-use FastAPI's internal functions to create the HTML pages for the docs, and pass them the needed arguments:
+
+* `openapi_url`: the URL where the HTML page for the docs can get the OpenAPI schema for your API. You can use here the attribute `app.openapi_url`.
+* `title`: the title of your API.
+* `oauth2_redirect_url`: you can use `app.swagger_ui_oauth2_redirect_url` here to use the default.
+* `swagger_js_url`: the URL where the HTML for your Swagger UI docs can get the **JavaScript** file. This is the custom CDN URL.
+* `swagger_css_url`: the URL where the HTML for your Swagger UI docs can get the **CSS** file. This is the custom CDN URL.
+
+And similarly for ReDoc...
+
+```Python hl_lines="2-6 11-19 22-24 27-33"
+{!../../../docs_src/custom_docs_ui/tutorial001.py!}
+```
+
+!!! tip
+ The *path operation* for `swagger_ui_redirect` is a helper for when you use OAuth2.
+
+ If you integrate your API with an OAuth2 provider, you will be able to authenticate and come back to the API docs with the acquired credentials. And interact with it using the real OAuth2 authentication.
+
+ Swagger UI will handle it behind the scenes for you, but it needs this "redirect" helper.
+
+### Create a *path operation* to test it
+
+Now, to be able to test that everything works, create a *path operation*:
+
+```Python hl_lines="36-38"
+{!../../../docs_src/custom_docs_ui/tutorial001.py!}
+```
+
+### Test it
+
+Now, you should be able to go to your docs at http://127.0.0.1:8000/docs, and reload the page, it will load those assets from the new CDN.
+
+## Self-hosting JavaScript and CSS for docs
+
+Self-hosting the JavaScript and CSS could be useful if, for example, you need your app to keep working even while offline, without open Internet access, or in a local network.
+
+Here you'll see how to serve those files yourself, in the same FastAPI app, and configure the docs to use them.
+
+### Project file structure
+
+Let's say your project file structure looks like this:
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+```
+
+Now create a directory to store those static files.
+
+Your new file structure could look like this:
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+└── static/
+```
+
+### Download the files
+
+Download the static files needed for the docs and put them on that `static/` directory.
+
+You can probably right-click each link and select an option similar to `Save link as...`.
+
+**Swagger UI** uses the files:
+
+* `swagger-ui-bundle.js`
+* `swagger-ui.css`
+
+And **ReDoc** uses the file:
+
+* `redoc.standalone.js`
+
+After that, your file structure could look like:
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+└── static
+ ├── redoc.standalone.js
+ ├── swagger-ui-bundle.js
+ └── swagger-ui.css
+```
+
+### Serve the static files
+
+* Import `StaticFiles`.
+* "Mount" a `StaticFiles()` instance in a specific path.
+
+```Python hl_lines="7 11"
+{!../../../docs_src/custom_docs_ui/tutorial002.py!}
+```
+
+### Test the static files
+
+Start your application and go to http://127.0.0.1:8000/static/redoc.standalone.js.
+
+You should see a very long JavaScript file for **ReDoc**.
+
+It could start with something like:
+
+```JavaScript
+/*!
+ * ReDoc - OpenAPI/Swagger-generated API Reference Documentation
+ * -------------------------------------------------------------
+ * Version: "2.0.0-rc.18"
+ * Repo: https://github.com/Redocly/redoc
+ */
+!function(e,t){"object"==typeof exports&&"object"==typeof m
+
+...
+```
+
+That confirms that you are being able to serve static files from your app, and that you placed the static files for the docs in the correct place.
+
+Now we can configure the app to use those static files for the docs.
+
+### Disable the automatic docs for static files
+
+The same as when using a custom CDN, the first step is to disable the automatic docs, as those use the CDN by default.
+
+To disable them, set their URLs to `None` when creating your `FastAPI` app:
+
+```Python hl_lines="9"
+{!../../../docs_src/custom_docs_ui/tutorial002.py!}
+```
+
+### Include the custom docs for static files
+
+And the same way as with a custom CDN, now you can create the *path operations* for the custom docs.
+
+Again, you can re-use FastAPI's internal functions to create the HTML pages for the docs, and pass them the needed arguments:
+
+* `openapi_url`: the URL where the HTML page for the docs can get the OpenAPI schema for your API. You can use here the attribute `app.openapi_url`.
+* `title`: the title of your API.
+* `oauth2_redirect_url`: you can use `app.swagger_ui_oauth2_redirect_url` here to use the default.
+* `swagger_js_url`: the URL where the HTML for your Swagger UI docs can get the **JavaScript** file. **This is the one that your own app is now serving**.
+* `swagger_css_url`: the URL where the HTML for your Swagger UI docs can get the **CSS** file. **This is the one that your own app is now serving**.
+
+And similarly for ReDoc...
+
+```Python hl_lines="2-6 14-22 25-27 30-36"
+{!../../../docs_src/custom_docs_ui/tutorial002.py!}
+```
+
+!!! tip
+ The *path operation* for `swagger_ui_redirect` is a helper for when you use OAuth2.
+
+ If you integrate your API with an OAuth2 provider, you will be able to authenticate and come back to the API docs with the acquired credentials. And interact with it using the real OAuth2 authentication.
+
+ Swagger UI will handle it behind the scenes for you, but it needs this "redirect" helper.
+
+### Create a *path operation* to test static files
+
+Now, to be able to test that everything works, create a *path operation*:
+
+```Python hl_lines="39-41"
+{!../../../docs_src/custom_docs_ui/tutorial002.py!}
+```
+
+### Test Static Files UI
+
+Now, you should be able to disconnect your WiFi, go to your docs at http://127.0.0.1:8000/docs, and reload the page.
+
+And even without Internet, you would be able to see the docs for your API and interact with it.
diff --git a/docs/en/docs/advanced/custom-request-and-route.md b/docs/en/docs/how-to/custom-request-and-route.md
similarity index 100%
rename from docs/en/docs/advanced/custom-request-and-route.md
rename to docs/en/docs/how-to/custom-request-and-route.md
diff --git a/docs/en/docs/how-to/extending-openapi.md b/docs/en/docs/how-to/extending-openapi.md
new file mode 100644
index 0000000000..a18fd737e6
--- /dev/null
+++ b/docs/en/docs/how-to/extending-openapi.md
@@ -0,0 +1,87 @@
+# Extending OpenAPI
+
+There are some cases where you might need to modify the generated OpenAPI schema.
+
+In this section you will see how.
+
+## The normal process
+
+The normal (default) process, is as follows.
+
+A `FastAPI` application (instance) has an `.openapi()` method that is expected to return the OpenAPI schema.
+
+As part of the application object creation, a *path operation* for `/openapi.json` (or for whatever you set your `openapi_url`) is registered.
+
+It just returns a JSON response with the result of the application's `.openapi()` method.
+
+By default, what the method `.openapi()` does is check the property `.openapi_schema` to see if it has contents and return them.
+
+If it doesn't, it generates them using the utility function at `fastapi.openapi.utils.get_openapi`.
+
+And that function `get_openapi()` receives as parameters:
+
+* `title`: The OpenAPI title, shown in the docs.
+* `version`: The version of your API, e.g. `2.5.0`.
+* `openapi_version`: The version of the OpenAPI specification used. By default, the latest: `3.1.0`.
+* `summary`: A short summary of the API.
+* `description`: The description of your API, this can include markdown and will be shown in the docs.
+* `routes`: A list of routes, these are each of the registered *path operations*. They are taken from `app.routes`.
+
+!!! info
+ The parameter `summary` is available in OpenAPI 3.1.0 and above, supported by FastAPI 0.99.0 and above.
+
+## Overriding the defaults
+
+Using the information above, you can use the same utility function to generate the OpenAPI schema and override each part that you need.
+
+For example, let's add ReDoc's OpenAPI extension to include a custom logo.
+
+### Normal **FastAPI**
+
+First, write all your **FastAPI** application as normally:
+
+```Python hl_lines="1 4 7-9"
+{!../../../docs_src/extending_openapi/tutorial001.py!}
+```
+
+### Generate the OpenAPI schema
+
+Then, use the same utility function to generate the OpenAPI schema, inside a `custom_openapi()` function:
+
+```Python hl_lines="2 15-21"
+{!../../../docs_src/extending_openapi/tutorial001.py!}
+```
+
+### Modify the OpenAPI schema
+
+Now you can add the ReDoc extension, adding a custom `x-logo` to the `info` "object" in the OpenAPI schema:
+
+```Python hl_lines="22-24"
+{!../../../docs_src/extending_openapi/tutorial001.py!}
+```
+
+### Cache the OpenAPI schema
+
+You can use the property `.openapi_schema` as a "cache", to store your generated schema.
+
+That way, your application won't have to generate the schema every time a user opens your API docs.
+
+It will be generated only once, and then the same cached schema will be used for the next requests.
+
+```Python hl_lines="13-14 25-26"
+{!../../../docs_src/extending_openapi/tutorial001.py!}
+```
+
+### Override the method
+
+Now you can replace the `.openapi()` method with your new function.
+
+```Python hl_lines="29"
+{!../../../docs_src/extending_openapi/tutorial001.py!}
+```
+
+### Check it
+
+Once you go to http://127.0.0.1:8000/redoc you will see that you are using your custom logo (in this example, **FastAPI**'s logo):
+
+
diff --git a/docs/en/docs/how-to/general.md b/docs/en/docs/how-to/general.md
new file mode 100644
index 0000000000..04367c6b76
--- /dev/null
+++ b/docs/en/docs/how-to/general.md
@@ -0,0 +1,39 @@
+# General - How To - Recipes
+
+Here are several pointers to other places in the docs, for general or frequent questions.
+
+## Filter Data - Security
+
+To ensure that you don't return more data than you should, read the docs for [Tutorial - Response Model - Return Type](../tutorial/response-model.md){.internal-link target=_blank}.
+
+## Documentation Tags - OpenAPI
+
+To add tags to your *path operations*, and group them in the docs UI, read the docs for [Tutorial - Path Operation Configurations - Tags](../tutorial/path-operation-configuration.md#tags){.internal-link target=_blank}.
+
+## Documentation Summary and Description - OpenAPI
+
+To add a summary and description to your *path operations*, and show them in the docs UI, read the docs for [Tutorial - Path Operation Configurations - Summary and Description](../tutorial/path-operation-configuration.md#summary-and-description){.internal-link target=_blank}.
+
+## Documentation Response description - OpenAPI
+
+To define the description of the response, shown in the docs UI, read the docs for [Tutorial - Path Operation Configurations - Response description](../tutorial/path-operation-configuration.md#response-description){.internal-link target=_blank}.
+
+## Documentation Deprecate a *Path Operation* - OpenAPI
+
+To deprecate a *path operation*, and show it in the docs UI, read the docs for [Tutorial - Path Operation Configurations - Deprecation](../tutorial/path-operation-configuration.md#deprecate-a-path-operation){.internal-link target=_blank}.
+
+## Convert any Data to JSON-compatible
+
+To convert any data to JSON-compatible, read the docs for [Tutorial - JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank}.
+
+## OpenAPI Metadata - Docs
+
+To add metadata to your OpenAPI schema, including a license, version, contact, etc, read the docs for [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md){.internal-link target=_blank}.
+
+## OpenAPI Custom URL
+
+To customize the OpenAPI URL (or remove it), read the docs for [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#openapi-url){.internal-link target=_blank}.
+
+## OpenAPI Docs URLs
+
+To update the URLs used for the automatically generated docs user interfaces, read the docs for [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#docs-urls){.internal-link target=_blank}.
diff --git a/docs/en/docs/advanced/graphql.md b/docs/en/docs/how-to/graphql.md
similarity index 100%
rename from docs/en/docs/advanced/graphql.md
rename to docs/en/docs/how-to/graphql.md
diff --git a/docs/en/docs/how-to/index.md b/docs/en/docs/how-to/index.md
new file mode 100644
index 0000000000..ec7fd38f8f
--- /dev/null
+++ b/docs/en/docs/how-to/index.md
@@ -0,0 +1,11 @@
+# How To - Recipes
+
+Here you will see different recipes or "how to" guides for **several topics**.
+
+Most of these ideas would be more or less **independent**, and in most cases you should only need to study them if they apply directly to **your project**.
+
+If something seems interesting and useful to your project, go ahead and check it, but otherwise, you might probably just skip them.
+
+!!! tip
+
+ If you want to **learn FastAPI** in a structured way (recommended), go and read the [Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank} chapter by chapter instead.
diff --git a/docs/en/docs/advanced/nosql-databases.md b/docs/en/docs/how-to/nosql-databases-couchbase.md
similarity index 99%
rename from docs/en/docs/advanced/nosql-databases.md
rename to docs/en/docs/how-to/nosql-databases-couchbase.md
index 606db35c75..ae6ad604ba 100644
--- a/docs/en/docs/advanced/nosql-databases.md
+++ b/docs/en/docs/how-to/nosql-databases-couchbase.md
@@ -1,4 +1,4 @@
-# NoSQL (Distributed / Big Data) Databases
+# NoSQL (Distributed / Big Data) Databases with Couchbase
!!! info
These docs are about to be updated. 🎉
diff --git a/docs/en/docs/advanced/sql-databases-peewee.md b/docs/en/docs/how-to/sql-databases-peewee.md
similarity index 99%
rename from docs/en/docs/advanced/sql-databases-peewee.md
rename to docs/en/docs/how-to/sql-databases-peewee.md
index 6a469634fa..bf2f2e714a 100644
--- a/docs/en/docs/advanced/sql-databases-peewee.md
+++ b/docs/en/docs/how-to/sql-databases-peewee.md
@@ -12,6 +12,8 @@
Because Pewee doesn't play well with anything async and there are better alternatives, I won't update these docs for Pydantic v2, they are kept for now only for historical purposes.
+ The examples here are no longer tested in CI (as they were before).
+
If you are starting a project from scratch, you are probably better off with SQLAlchemy ORM ([SQL (Relational) Databases](../tutorial/sql-databases.md){.internal-link target=_blank}), or any other async ORM.
If you already have a code base that uses Peewee ORM, you can check here how to use it with **FastAPI**.
diff --git a/docs/en/docs/img/sponsors/porter-banner.png b/docs/en/docs/img/sponsors/porter-banner.png
new file mode 100755
index 0000000000..fa2e741c0c
Binary files /dev/null and b/docs/en/docs/img/sponsors/porter-banner.png differ
diff --git a/docs/en/docs/img/sponsors/porter.png b/docs/en/docs/img/sponsors/porter.png
new file mode 100755
index 0000000000..582a151564
Binary files /dev/null and b/docs/en/docs/img/sponsors/porter.png differ
diff --git a/docs/en/docs/img/sponsors/speakeasy.png b/docs/en/docs/img/sponsors/speakeasy.png
new file mode 100644
index 0000000000..001b4b4caf
Binary files /dev/null and b/docs/en/docs/img/sponsors/speakeasy.png differ
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index 723f338a9f..61ec91b4ae 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -2,14 +2,47 @@
## Latest Changes
+* 📝 Add new docs section, How To - Recipes, move docs that don't have to be read by everyone to How To. PR [#10114](https://github.com/tiangolo/fastapi/pull/10114) by [@tiangolo](https://github.com/tiangolo).
+* ♻️ Refactor tests for new Pydantic 2.2.1. PR [#10115](https://github.com/tiangolo/fastapi/pull/10115) by [@tiangolo](https://github.com/tiangolo).
+* 📝 Update Advanced docs, add links to sponsor courses. PR [#10113](https://github.com/tiangolo/fastapi/pull/10113) by [@tiangolo](https://github.com/tiangolo).
+* 📝 Update docs for generating clients. PR [#10112](https://github.com/tiangolo/fastapi/pull/10112) by [@tiangolo](https://github.com/tiangolo).
+* 📝 Tweak MkDocs and add redirects. PR [#10111](https://github.com/tiangolo/fastapi/pull/10111) by [@tiangolo](https://github.com/tiangolo).
+* 📝 Restructure docs for cloud providers, include links to sponsors. PR [#10110](https://github.com/tiangolo/fastapi/pull/10110) by [@tiangolo](https://github.com/tiangolo).
+* 🔧 Update sponsors, add Speakeasy. PR [#10098](https://github.com/tiangolo/fastapi/pull/10098) by [@tiangolo](https://github.com/tiangolo).
+## 0.101.1
+
+### Fixes
+
+* ✨ Add `ResponseValidationError` printable details, to show up in server error logs. PR [#10078](https://github.com/tiangolo/fastapi/pull/10078) by [@tiangolo](https://github.com/tiangolo).
+
+### Refactors
+
* ✏️ Fix typo in deprecation warnings in `fastapi/params.py`. PR [#9854](https://github.com/tiangolo/fastapi/pull/9854) by [@russbiggs](https://github.com/russbiggs).
-* ✏️ Fix typo in release notes. PR [#9835](https://github.com/tiangolo/fastapi/pull/9835) by [@francisbergin](https://github.com/francisbergin).
* ✏️ Fix typos in comments on internal code in `fastapi/concurrency.py` and `fastapi/routing.py`. PR [#9590](https://github.com/tiangolo/fastapi/pull/9590) by [@ElliottLarsen](https://github.com/ElliottLarsen).
+
+### Docs
+
+* ✏️ Fix typo in release notes. PR [#9835](https://github.com/tiangolo/fastapi/pull/9835) by [@francisbergin](https://github.com/francisbergin).
* 📝 Add external article: Build an SMS Spam Classifier Serverless Database with FaunaDB and FastAPI. PR [#9847](https://github.com/tiangolo/fastapi/pull/9847) by [@adejumoridwan](https://github.com/adejumoridwan).
* 📝 Fix typo in `docs/en/docs/contributing.md`. PR [#9878](https://github.com/tiangolo/fastapi/pull/9878) by [@VicenteMerino](https://github.com/VicenteMerino).
* 📝 Fix code highlighting in `docs/en/docs/tutorial/bigger-applications.md`. PR [#9806](https://github.com/tiangolo/fastapi/pull/9806) by [@theonlykingpin](https://github.com/theonlykingpin).
+
+### Translations
+
+* 🌐 Add Japanese translation for `docs/ja/docs/deployment/concepts.md`. PR [#10062](https://github.com/tiangolo/fastapi/pull/10062) by [@tamtam-fitness](https://github.com/tamtam-fitness).
+* 🌐 Add Japanese translation for `docs/ja/docs/deployment/server-workers.md`. PR [#10064](https://github.com/tiangolo/fastapi/pull/10064) by [@tamtam-fitness](https://github.com/tamtam-fitness).
+* 🌐 Update Japanese translation for `docs/ja/docs/deployment/docker.md`. PR [#10073](https://github.com/tiangolo/fastapi/pull/10073) by [@tamtam-fitness](https://github.com/tamtam-fitness).
+* 🌐 Add Ukrainian translation for `docs/uk/docs/fastapi-people.md`. PR [#10059](https://github.com/tiangolo/fastapi/pull/10059) by [@rostik1410](https://github.com/rostik1410).
+* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/cookie-params.md`. PR [#10032](https://github.com/tiangolo/fastapi/pull/10032) by [@rostik1410](https://github.com/rostik1410).
+* 🌐 Add Russian translation for `docs/ru/docs/deployment/docker.md`. PR [#9971](https://github.com/tiangolo/fastapi/pull/9971) by [@Xewus](https://github.com/Xewus).
+* 🌐 Add Vietnamese translation for `docs/vi/docs/python-types.md`. PR [#10047](https://github.com/tiangolo/fastapi/pull/10047) by [@magiskboy](https://github.com/magiskboy).
* 🌐 Add Russian translation for `docs/ru/docs/tutorial/dependencies/global-dependencies.md`. PR [#9970](https://github.com/tiangolo/fastapi/pull/9970) by [@dudyaosuplayer](https://github.com/dudyaosuplayer).
* 🌐 Add Urdu translation for `docs/ur/docs/benchmarks.md`. PR [#9974](https://github.com/tiangolo/fastapi/pull/9974) by [@AhsanSheraz](https://github.com/AhsanSheraz).
+
+### Internal
+
+* 🔧 Add sponsor Porter. PR [#10051](https://github.com/tiangolo/fastapi/pull/10051) by [@tiangolo](https://github.com/tiangolo).
+* 🔧 Update sponsors, add Jina back as bronze sponsor. PR [#10050](https://github.com/tiangolo/fastapi/pull/10050) by [@tiangolo](https://github.com/tiangolo).
* ⬆ Bump mypy from 1.4.0 to 1.4.1. PR [#9756](https://github.com/tiangolo/fastapi/pull/9756) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-material from 9.1.17 to 9.1.21. PR [#9960](https://github.com/tiangolo/fastapi/pull/9960) by [@dependabot[bot]](https://github.com/apps/dependabot).
diff --git a/docs/en/mkdocs.yml b/docs/en/mkdocs.yml
index a186131858..f75b84ff5b 100644
--- a/docs/en/mkdocs.yml
+++ b/docs/en/mkdocs.yml
@@ -42,6 +42,16 @@ plugins:
search: null
markdownextradata:
data: ../en/data
+ redirects:
+ redirect_maps:
+ deployment/deta.md: deployment/cloud.md
+ advanced/sql-databases-peewee.md: how-to/sql-databases-peewee.md
+ advanced/async-sql-databases.md: how-to/async-sql-encode-databases.md
+ advanced/nosql-databases.md: how-to/nosql-databases-couchbase.md
+ advanced/graphql.md: how-to/graphql.md
+ advanced/custom-request-and-route.md: how-to/custom-request-and-route.md
+ advanced/conditional-openapi.md: how-to/conditional-openapi.md
+ advanced/extending-openapi.md: how-to/extending-openapi.md
nav:
- FastAPI: index.md
- Languages:
@@ -60,6 +70,7 @@ nav:
- ru: /ru/
- tr: /tr/
- uk: /uk/
+ - ur: /ur/
- vi: /vi/
- zh: /zh/
- features.md
@@ -130,24 +141,17 @@ nav:
- advanced/using-request-directly.md
- advanced/dataclasses.md
- advanced/middleware.md
- - advanced/sql-databases-peewee.md
- - advanced/async-sql-databases.md
- - advanced/nosql-databases.md
- advanced/sub-applications.md
- advanced/behind-a-proxy.md
- advanced/templates.md
- - advanced/graphql.md
- advanced/websockets.md
- advanced/events.md
- - advanced/custom-request-and-route.md
- advanced/testing-websockets.md
- advanced/testing-events.md
- advanced/testing-dependencies.md
- advanced/testing-database.md
- advanced/async-tests.md
- advanced/settings.md
- - advanced/conditional-openapi.md
- - advanced/extending-openapi.md
- advanced/openapi-callbacks.md
- advanced/openapi-webhooks.md
- advanced/wsgi.md
@@ -159,9 +163,21 @@ nav:
- deployment/https.md
- deployment/manually.md
- deployment/concepts.md
- - deployment/deta.md
+ - deployment/cloud.md
- deployment/server-workers.md
- deployment/docker.md
+- How To - Recipes:
+ - how-to/index.md
+ - how-to/general.md
+ - how-to/sql-databases-peewee.md
+ - how-to/async-sql-encode-databases.md
+ - how-to/nosql-databases-couchbase.md
+ - how-to/graphql.md
+ - how-to/custom-request-and-route.md
+ - how-to/conditional-openapi.md
+ - how-to/extending-openapi.md
+ - how-to/custom-docs-ui-assets.md
+ - how-to/configure-swagger-ui.md
- project-generation.md
- alternatives.md
- history-design-future.md
@@ -178,9 +194,9 @@ markdown_extensions:
guess_lang: false
mdx_include:
base_path: docs
- admonition:
- codehilite:
- extra:
+ admonition: null
+ codehilite: null
+ extra: null
pymdownx.superfences:
custom_fences:
- name: mermaid
@@ -188,8 +204,8 @@ markdown_extensions:
format: !!python/name:pymdownx.superfences.fence_code_format ''
pymdownx.tabbed:
alternate_style: true
- attr_list:
- md_in_html:
+ attr_list: null
+ md_in_html: null
extra:
analytics:
provider: google
@@ -240,8 +256,10 @@ extra:
name: tr - Türkçe
- link: /uk/
name: uk
+ - link: /ur/
+ name: ur
- link: /vi/
- name: vi
+ name: vi - Tiếng Việt
- link: /zh/
name: zh - 汉语
extra_css:
diff --git a/docs/en/overrides/main.html b/docs/en/overrides/main.html
index 7e6c0f7634..983d7eb3e7 100644
--- a/docs/en/overrides/main.html
+++ b/docs/en/overrides/main.html
@@ -40,6 +40,12 @@
+
+
-
-## Activer l'accès public
-
-Par défaut, Deta va gérer l'authentification en utilisant des cookies pour votre compte.
-
-Mais une fois que vous êtes prêt, vous pouvez le rendre public avec :
-
-
-
-## En savoir plus
-
-À un moment donné, vous voudrez probablement stocker certaines données pour votre application d'une manière qui
-persiste dans le temps. Pour cela, vous pouvez utiliser Deta Base, il dispose également d'un généreux **plan gratuit**.
-
-Vous pouvez également en lire plus dans la documentation Deta.
diff --git a/docs/ja/docs/deployment/concepts.md b/docs/ja/docs/deployment/concepts.md
new file mode 100644
index 0000000000..38cbca2192
--- /dev/null
+++ b/docs/ja/docs/deployment/concepts.md
@@ -0,0 +1,323 @@
+# デプロイメントのコンセプト
+
+**FastAPI**を用いたアプリケーションをデプロイするとき、もしくはどのようなタイプのWeb APIであっても、おそらく気になるコンセプトがいくつかあります。
+
+それらを活用することでアプリケーションを**デプロイするための最適な方法**を見つけることができます。
+
+重要なコンセプトのいくつかを紹介します:
+
+* セキュリティ - HTTPS
+* 起動時の実行
+* 再起動
+* レプリケーション(実行中のプロセス数)
+* メモリー
+* 開始前の事前のステップ
+
+これらが**デプロイメント**にどのような影響を与えるかを見ていきましょう。
+
+最終的な目的は、**安全な方法で**APIクライアントに**サービスを提供**し、**中断を回避**するだけでなく、**計算リソース**(例えばリモートサーバー/仮想マシン)を可能な限り効率的に使用することです。🚀
+
+この章では前述した**コンセプト**についてそれぞれ説明します。
+
+この説明を通して、普段とは非常に異なる環境や存在しないであろう**将来の**環境に対し、デプロイの方法を決める上で必要な**直感**を与えてくれることを願っています。
+
+これらのコンセプトを意識することにより、**あなた自身のAPI**をデプロイするための最適な方法を**評価**し、**設計**することができるようになるでしょう。
+
+次の章では、FastAPIアプリケーションをデプロイするための**具体的なレシピ**を紹介します。
+
+しかし、今はこれらの重要な**コンセプトに基づくアイデア**を確認しましょう。これらのコンセプトは、他のどのタイプのWeb APIにも当てはまります。💡
+
+## セキュリティ - HTTPS
+
+
+[前チャプターのHTTPSについて](./https.md){.internal-link target=_blank}では、HTTPSがどのようにAPIを暗号化するのかについて学びました。
+
+通常、アプリケーションサーバにとって**外部の**コンポーネントである**TLS Termination Proxy**によって提供されることが一般的です。このプロキシは通信の暗号化を担当します。
+
+さらにセキュアな通信において、HTTPS証明書の定期的な更新を行いますが、これはTLS Termination Proxyと同じコンポーネントが担当することもあれば、別のコンポーネントが担当することもあります。
+
+### HTTPS 用ツールの例
+TLS Termination Proxyとして使用できるツールには以下のようなものがあります:
+
+* Traefik
+ * 証明書の更新を自動的に処理 ✨
+* Caddy
+ * 証明書の更新を自動的に処理 ✨
+* Nginx
+ * 証明書更新のためにCertbotのような外部コンポーネントを使用
+* HAProxy
+ * 証明書更新のためにCertbotのような外部コンポーネントを使用
+* Nginx のような Ingress Controller を持つ Kubernetes
+ * 証明書の更新に cert-manager のような外部コンポーネントを使用
+* クラウド・プロバイダーがサービスの一部として内部的に処理(下記を参照👇)
+
+もう1つの選択肢は、HTTPSのセットアップを含んだより多くの作業を行う**クラウド・サービス**を利用することです。 このサービスには制限があったり、料金が高くなったりする可能性があります。しかしその場合、TLS Termination Proxyを自分でセットアップする必要はないです。
+
+次の章で具体例をいくつか紹介します。
+
+---
+
+次に考慮すべきコンセプトは、実際のAPIを実行するプログラム(例:Uvicorn)に関連するものすべてです。
+
+## プログラム と プロセス
+
+私たちは「**プロセス**」という言葉についてたくさん話すので、その意味や「**プログラム**」という言葉との違いを明確にしておくと便利です。
+
+### プログラムとは何か
+
+**プログラム**という言葉は、一般的にいろいろなものを表現するのに使われます:
+
+* プログラマが書く**コード**、**Pythonファイル**
+* OSによって実行することができるファイル(例: `python`, `python.exe` or `uvicorn`)
+* OS上で**実行**している間、CPUを使用し、メモリ上に何かを保存する特定のプログラム(**プロセス**とも呼ばれる)
+
+### プロセスとは何か
+
+**プロセス**という言葉は通常、より具体的な意味で使われ、OSで実行されているものだけを指します(先ほどの最後の説明のように):
+
+* OS上で**実行**している特定のプログラム
+ * これはファイルやコードを指すのではなく、OSによって**実行**され、管理されているものを指します。
+* どんなプログラムやコードも、それが**実行されているときにだけ機能**します。つまり、**プロセスとして実行されているときだけ**です。
+* プロセスは、ユーザーにあるいはOSによって、 **終了**(あるいは "kill")させることができます。その時点で、プロセスは実行/実行されることを停止し、それ以降は**何もできなくなります**。
+* コンピュータで実行されている各アプリケーションは、実行中のプログラムや各ウィンドウなど、その背後にいくつかのプロセスを持っています。そして通常、コンピュータが起動している間、**多くのプロセスが**同時に実行されています。
+* **同じプログラム**の**複数のプロセス**が同時に実行されていることがあります。
+
+OSの「タスク・マネージャー」や「システム・モニター」(または同様のツール)を確認すれば、これらのプロセスの多くが実行されているの見ることができるでしょう。
+
+例えば、同じブラウザプログラム(Firefox、Chrome、Edgeなど)を実行しているプロセスが複数あることがわかります。通常、1つのタブにつき1つのプロセスが実行され、さらに他のプロセスも実行されます。
+
+
+
+---
+
+さて、**プロセス**と**プログラム**という用語の違いを確認したところで、デプロイメントについて話を続けます。
+
+## 起動時の実行
+
+ほとんどの場合、Web APIを作成するときは、クライアントがいつでもアクセスできるように、**常に**中断されることなく**実行される**ことを望みます。もちろん、特定の状況でのみ実行させたい特別な理由がある場合は別ですが、その時間のほとんどは、常に実行され、**利用可能**であることを望みます。
+
+### リモートサーバー上での実行
+
+リモートサーバー(クラウドサーバー、仮想マシンなど)をセットアップするときにできる最も簡単なことは、ローカルで開発するときと同じように、Uvicorn(または同様のもの)を手動で実行することです。 この方法は**開発中**には役に立つと思われます。
+
+しかし、サーバーへの接続が切れた場合、**実行中のプロセス**はおそらくダウンしてしまうでしょう。
+
+そしてサーバーが再起動された場合(アップデートやクラウドプロバイダーからのマイグレーションの後など)、おそらくあなたはそれに**気づかないでしょう**。そのため、プロセスを手動で再起動しなければならないことすら気づかないでしょう。つまり、APIはダウンしたままなのです。😱
+
+### 起動時に自動的に実行
+
+一般的に、サーバープログラム(Uvicornなど)はサーバー起動時に自動的に開始され、**人の介入**を必要とせずに、APIと一緒にプロセスが常に実行されるようにしたいと思われます(UvicornがFastAPIアプリを実行するなど)。
+
+### 別のプログラムの用意
+
+これを実現するために、通常は**別のプログラム**を用意し、起動時にアプリケーションが実行されるようにします。そして多くの場合、他のコンポーネントやアプリケーション、例えばデータベースも実行されるようにします。
+
+### 起動時に実行するツールの例
+
+実行するツールの例をいくつか挙げます:
+
+* Docker
+* Kubernetes
+* Docker Compose
+* Swarm モードによる Docker
+* Systemd
+* Supervisor
+* クラウドプロバイダーがサービスの一部として内部的に処理
+* そのほか...
+
+次の章で、より具体的な例を挙げていきます。
+
+## 再起動
+
+起動時にアプリケーションが実行されることを確認するのと同様に、失敗後にアプリケーションが**再起動**されることも確認したいと思われます。
+
+### 我々は間違いを犯す
+
+私たち人間は常に**間違い**を犯します。ソフトウェアには、ほとんど常に**バグ**があらゆる箇所に隠されています。🐛
+
+### 小さなエラーは自動的に処理される
+
+FastAPIでWeb APIを構築する際に、コードにエラーがある場合、FastAPIは通常、エラーを引き起こした単一のリクエストにエラーを含めます。🛡
+
+クライアントはそのリクエストに対して**500 Internal Server Error**を受け取りますが、アプリケーションは完全にクラッシュするのではなく、次のリクエストのために動作を続けます。
+
+### 重大なエラー - クラッシュ
+
+しかしながら、**アプリケーション全体をクラッシュさせるようなコードを書いて**UvicornとPythonをクラッシュさせるようなケースもあるかもしれません。💥
+
+それでも、ある箇所でエラーが発生したからといって、アプリケーションを停止させたままにしたくないでしょう。 少なくとも壊れていない*パスオペレーション*については、**実行し続けたい**はずです。
+
+### クラッシュ後の再起動
+
+しかし、実行中の**プロセス**をクラッシュさせるような本当にひどいエラーの場合、少なくとも2〜3回ほどプロセスを**再起動**させる外部コンポーネントが必要でしょう。
+
+!!! tip
+ ...とはいえ、アプリケーション全体が**すぐにクラッシュする**のであれば、いつまでも再起動し続けるのは意味がないでしょう。しかし、その場合はおそらく開発中か少なくともデプロイ直後に気づくと思われます。
+
+ そこで、**将来**クラッシュする可能性があり、それでも再スタートさせることに意味があるような、主なケースに焦点を当ててみます。
+
+あなたはおそらく**外部コンポーネント**がアプリケーションの再起動を担当することを望むと考えます。 なぜなら、その時点でUvicornとPythonを使った同じアプリケーションはすでにクラッシュしており、同じアプリケーションの同じコードに対して何もできないためです。
+
+### 自動的に再起動するツールの例
+
+ほとんどの場合、前述した**起動時にプログラムを実行する**ために使用されるツールは、自動で**再起動**することにも利用されます。
+
+例えば、次のようなものがあります:
+
+* Docker
+* Kubernetes
+* Docker Compose
+* Swarm モードによる Docker
+* Systemd
+* Supervisor
+* クラウドプロバイダーがサービスの一部として内部的に処理
+* そのほか...
+
+## レプリケーション - プロセスとメモリー
+
+FastAPI アプリケーションでは、Uvicorn のようなサーバープログラムを使用し、**1つのプロセス**で1度に複数のクライアントに同時に対応できます。
+
+しかし、多くの場合、複数のワーカー・プロセスを同時に実行したいと考えるでしょう。
+
+### 複数のプロセス - Worker
+
+クライアントの数が単一のプロセスで処理できる数を超えており(たとえば仮想マシンがそれほど大きくない場合)、かつサーバーの CPU に**複数のコア**がある場合、同じアプリケーションで同時に**複数のプロセス**を実行させ、すべてのリクエストを分散させることができます。
+
+同じAPIプログラムの**複数のプロセス**を実行する場合、それらは一般的に**Worker/ワーカー**と呼ばれます。
+
+### ワーカー・プロセス と ポート
+
+
+[HTTPSについて](./https.md){.internal-link target=_blank}のドキュメントで、1つのサーバーで1つのポートとIPアドレスの組み合わせでリッスンできるのは1つのプロセスだけであることを覚えていますでしょうか?
+
+これはいまだに同じです。
+
+そのため、**複数のプロセス**を同時に持つには**ポートでリッスンしている単一のプロセス**が必要であり、それが何らかの方法で各ワーカー・プロセスに通信を送信することが求められます。
+
+### プロセスあたりのメモリー
+
+さて、プログラムがメモリにロードする際には、例えば機械学習モデルや大きなファイルの内容を変数に入れたりする場合では、**サーバーのメモリ(RAM)**を少し消費します。
+
+そして複数のプロセスは通常、**メモリを共有しません**。これは、実行中の各プロセスがそれぞれ独自の変数やメモリ等を持っていることを意味します。つまり、コード内で大量のメモリを消費している場合、**各プロセス**は同等の量のメモリを消費することになります。
+
+### サーバーメモリー
+
+例えば、あなたのコードが **1GBのサイズの機械学習モデル**をロードする場合、APIで1つのプロセスを実行すると、少なくとも1GBのRAMを消費します。
+
+また、**4つのプロセス**(4つのワーカー)を起動すると、それぞれが1GBのRAMを消費します。つまり、合計でAPIは**4GBのRAM**を消費することになります。
+
+リモートサーバーや仮想マシンのRAMが3GBしかない場合、4GB以上のRAMをロードしようとすると問題が発生します。🚨
+
+### 複数プロセス - 例
+
+この例では、2つの**ワーカー・プロセス**を起動し制御する**マネージャー・ プロセス**があります。
+
+このマネージャー・ プロセスは、おそらくIPの**ポート**でリッスンしているものです。そして、すべての通信をワーカー・プロセスに転送します。
+
+これらのワーカー・プロセスは、アプリケーションを実行するものであり、**リクエスト**を受けて**レスポンス**を返すための主要な計算を行い、あなたが変数に入れたものは何でもRAMにロードします。
+
+
-
-## パブリックアクセスの有効化
-
-デフォルトでは、Deta はクッキーを用いてアカウントの認証を行います。
-
-しかし、準備が整えば、以下の様に公開できます:
-
-
-
-## さらに詳しく知る
-
-様々な箇所で永続的にデータを保存したくなるでしょう。そのためには Deta Base を使用できます。惜しみない **無料利用枠** もあります。
-
-詳しくは Deta ドキュメントを参照してください。
diff --git a/docs/ja/docs/deployment/docker.md b/docs/ja/docs/deployment/docker.md
index f10312b516..ca9dedc3c1 100644
--- a/docs/ja/docs/deployment/docker.md
+++ b/docs/ja/docs/deployment/docker.md
@@ -1,71 +1,157 @@
-# Dockerを使用したデプロイ
+# コンテナ内のFastAPI - Docker
-このセクションでは以下の使い方の紹介とガイドへのリンクが確認できます:
+FastAPIアプリケーションをデプロイする場合、一般的なアプローチは**Linuxコンテナ・イメージ**をビルドすることです。
-* **5分**程度で、**FastAPI** のアプリケーションを、パフォーマンスを最大限に発揮するDockerイメージ (コンテナ)にする。
-* (オプション) 開発者として必要な範囲でHTTPSを理解する。
-* **20分**程度で、自動的なHTTPS生成とともにDockerのSwarmモード クラスタをセットアップする (月5ドルのシンプルなサーバー上で)。
-* **10分**程度で、DockerのSwarmモード クラスタを使って、HTTPSなどを使用した完全な**FastAPI** アプリケーションの作成とデプロイ。
+基本的には **Docker**を用いて行われます。生成されたコンテナ・イメージは、いくつかの方法のいずれかでデプロイできます。
-デプロイのために、**Docker** を利用できます。セキュリティ、再現性、開発のシンプルさなどに利点があります。
+Linuxコンテナの使用には、**セキュリティ**、**反復可能性(レプリカビリティ)**、**シンプリシティ**など、いくつかの利点があります。
-Dockerを使う場合、公式のDockerイメージが利用できます:
+!!! tip
+ TODO: なぜか遷移できない
+ お急ぎで、すでにこれらの情報をご存じですか? [以下の`Dockerfile`の箇所👇](#build-a-docker-image-for-fastapi)へジャンプしてください。
-## tiangolo/uvicorn-gunicorn-fastapi
-
-このイメージは「自動チューニング」機構を含んでいます。犠牲を払うことなく、ただコードを加えるだけで自動的に高パフォーマンスを実現できます。
-
-ただし、環境変数や設定ファイルを使って全ての設定の変更や更新を行えます。
-
-!!! tip "豆知識"
- 全ての設定とオプションを確認するには、Dockerイメージページを開いて下さい: tiangolo/uvicorn-gunicorn-fastapi.
-
-## `Dockerfile` の作成
-
-* プロジェクトディレクトリへ移動。
-* 以下の`Dockerfile` を作成:
+
-
-## 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:
-
-
-
-## 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/ru/docs/deployment/docker.md b/docs/ru/docs/deployment/docker.md
new file mode 100644
index 0000000000..f045ca9448
--- /dev/null
+++ b/docs/ru/docs/deployment/docker.md
@@ -0,0 +1,700 @@
+# FastAPI и Docker-контейнеры
+
+При развёртывании приложений FastAPI, часто начинают с создания **образа контейнера на основе Linux**. Обычно для этого используют **Docker**. Затем можно развернуть такой контейнер на сервере одним из нескольких способов.
+
+Использование контейнеров на основе Linux имеет ряд преимуществ, включая **безопасность**, **воспроизводимость**, **простоту** и прочие.
+
+!!! tip "Подсказка"
+ Торопитесь или уже знакомы с этой технологией? Перепрыгните на раздел [Создать Docker-образ для FastAPI 👇](#docker-fastapi)
+
+
+
+### Thêm kiểu dữ liệu
+
+Hãy sửa một dòng từ phiên bản trước.
+
+Chúng ta sẽ thay đổi chính xác đoạn này, tham số của hàm, từ:
+
+```Python
+ first_name, last_name
+```
+
+sang:
+
+```Python
+ first_name: str, last_name: str
+```
+
+Chính là nó.
+
+Những thứ đó là "type hints":
+
+```Python hl_lines="1"
+{!../../../docs_src/python_types/tutorial002.py!}
+```
+
+Đó không giống như khai báo những giá trị mặc định giống như:
+
+```Python
+ first_name="john", last_name="doe"
+```
+
+Nó là một thứ khác.
+
+Chúng ta sử dụng dấu hai chấm (`:`), không phải dấu bằng (`=`).
+
+Và việc thêm gợi ý kiểu dữ liệu không làm thay đổi những gì xảy ra so với khi chưa thêm chúng.
+
+But now, imagine you are again in the middle of creating that function, but with type hints.
+
+Tại cùng một điểm, bạn thử kích hoạt autocomplete với `Ctrl+Space` và bạn thấy:
+
+
+
+Với cái đó, bạn có thể cuộn, nhìn thấy các lựa chọn, cho đến khi bạn tìm thấy một "tiếng chuông":
+
+
+
+## Động lực nhiều hơn
+
+Kiểm tra hàm này, nó đã có gợi ý kiểu dữ liệu:
+
+```Python hl_lines="1"
+{!../../../docs_src/python_types/tutorial003.py!}
+```
+
+Bởi vì trình soạn thảo biết kiểu dữ liệu của các biến, bạn không chỉ có được completion, bạn cũng được kiểm tra lỗi:
+
+
+
+Bây giờ bạn biết rằng bạn phải sửa nó, chuyển `age` sang một xâu với `str(age)`:
+
+```Python hl_lines="2"
+{!../../../docs_src/python_types/tutorial004.py!}
+```
+
+## Khai báo các kiểu dữ liệu
+
+Bạn mới chỉ nhìn thấy những nơi chủ yếu để đặt khai báo kiểu dữ liệu. Như là các tham số của hàm.
+
+Đây cũng là nơi chủ yếu để bạn sử dụng chúng với **FastAPI**.
+
+### Kiểu dữ liệu đơn giản
+
+Bạn có thể khai báo tất cả các kiểu dữ liệu chuẩn của Python, không chỉ là `str`.
+
+Bạn có thể sử dụng, ví dụ:
+
+* `int`
+* `float`
+* `bool`
+* `bytes`
+
+```Python hl_lines="1"
+{!../../../docs_src/python_types/tutorial005.py!}
+```
+
+### Các kiểu dữ liệu tổng quát với tham số kiểu dữ liệu
+
+Có một vài cấu trúc dữ liệu có thể chứa các giá trị khác nhau như `dict`, `list`, `set` và `tuple`. Và những giá trị nội tại cũng có thể có kiểu dữ liệu của chúng.
+
+Những kiểu dữ liệu nội bộ này được gọi là những kiểu dữ liệu "**tổng quát**". Và có khả năng khai báo chúng, thậm chí với các kiểu dữ liệu nội bộ của chúng.
+
+Để khai báo những kiểu dữ liệu và những kiểu dữ liệu nội bộ đó, bạn có thể sử dụng mô đun chuẩn của Python là `typing`. Nó có hỗ trợ những gợi ý kiểu dữ liệu này.
+
+#### Những phiên bản mới hơn của Python
+
+Cú pháp sử dụng `typing` **tương thích** với tất cả các phiên bản, từ Python 3.6 tới những phiên bản cuối cùng, bao gồm Python 3.9, Python 3.10,...
+
+As Python advances, **những phiên bản mới** mang tới sự hỗ trợ được cải tiến cho những chú thích kiểu dữ liệu và trong nhiều trường hợp bạn thậm chí sẽ không cần import và sử dụng mô đun `typing` để khai báo chú thích kiểu dữ liệu.
+
+Nếu bạn có thể chọn một phiên bản Python gần đây hơn cho dự án của bạn, ban sẽ có được những ưu điểm của những cải tiến đơn giản đó.
+
+Trong tất cả các tài liệu tồn tại những ví dụ tương thích với mỗi phiên bản Python (khi có một sự khác nhau).
+
+Cho ví dụ "**Python 3.6+**" có nghĩa là nó tương thích với Python 3.7 hoặc lớn hơn (bao gồm 3.7, 3.8, 3.9, 3.10,...). và "**Python 3.9+**" nghĩa là nó tương thích với Python 3.9 trở lên (bao gồm 3.10,...).
+
+Nếu bạn có thể sử dụng **phiên bản cuối cùng của Python**, sử dụng những ví dụ cho phiên bản cuối, những cái đó sẽ có **cú pháp đơn giản và tốt nhât**, ví dụ, "**Python 3.10+**".
+
+#### List
+
+Ví dụ, hãy định nghĩa một biến là `list` các `str`.
+
+=== "Python 3.9+"
+
+ Khai báo biến với cùng dấu hai chấm (`:`).
+
+ Tương tự kiểu dữ liệu `list`.
+
+ Như danh sách là một kiểu dữ liệu chứa một vài kiểu dữ liệu có sẵn, bạn đặt chúng trong các dấu ngoặc vuông:
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/python_types/tutorial006_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ Từ `typing`, import `List` (với chữ cái `L` viết hoa):
+
+ ``` Python hl_lines="1"
+ {!> ../../../docs_src/python_types/tutorial006.py!}
+ ```
+
+ Khai báo biến với cùng dấu hai chấm (`:`).
+
+ Tương tự như kiểu dữ liệu, `List` bạn import từ `typing`.
+
+ Như danh sách là một kiểu dữ liệu chứa các kiểu dữ liệu có sẵn, bạn đặt chúng bên trong dấu ngoặc vuông:
+
+ ```Python hl_lines="4"
+ {!> ../../../docs_src/python_types/tutorial006.py!}
+ ```
+
+!!! info
+ Các kiểu dữ liệu có sẵn bên trong dấu ngoặc vuông được gọi là "tham số kiểu dữ liệu".
+
+ Trong trường hợp này, `str` là tham số kiểu dữ liệu được truyền tới `List` (hoặc `list` trong Python 3.9 trở lên).
+
+Có nghĩa là: "biến `items` là một `list`, và mỗi phần tử trong danh sách này là một `str`".
+
+!!! tip
+ Nếu bạn sử dụng Python 3.9 hoặc lớn hơn, bạn không phải import `List` từ `typing`, bạn có thể sử dụng `list` để thay thế.
+
+Bằng cách này, trình soạn thảo của bạn có thể hỗ trợ trong khi xử lí các phần tử trong danh sách:
+
+
+
+Đa phần đều không thể đạt được nếu không có các kiểu dữ liệu.
+
+Chú ý rằng, biến `item` là một trong các phần tử trong danh sách `items`.
+
+Và do vậy, trình soạn thảo biết nó là một `str`, và cung cấp sự hỗ trợ cho nó.
+
+#### Tuple and Set
+
+Bạn sẽ làm điều tương tự để khai báo các `tuple` và các `set`:
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/python_types/tutorial007_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="1 4"
+ {!> ../../../docs_src/python_types/tutorial007.py!}
+ ```
+
+Điều này có nghĩa là:
+
+* Biến `items_t` là một `tuple` với 3 phần tử, một `int`, một `int` nữa, và một `str`.
+* Biến `items_s` là một `set`, và mỗi phần tử của nó có kiểu `bytes`.
+
+#### Dict
+
+Để định nghĩa một `dict`, bạn truyền 2 tham số kiểu dữ liệu, phân cách bởi dấu phẩy.
+
+Tham số kiểu dữ liệu đầu tiên dành cho khóa của `dict`.
+
+Tham số kiểu dữ liệu thứ hai dành cho giá trị của `dict`.
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/python_types/tutorial008_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="1 4"
+ {!> ../../../docs_src/python_types/tutorial008.py!}
+ ```
+
+Điều này có nghĩa là:
+
+* Biến `prices` là một `dict`:
+ * Khóa của `dict` này là kiểu `str` (đó là tên của mỗi vật phẩm).
+ * Giá trị của `dict` này là kiểu `float` (đó là giá của mỗi vật phẩm).
+
+#### Union
+
+Bạn có thể khai báo rằng một biến có thể là **một vài kiểu dữ liệu" bất kì, ví dụ, một `int` hoặc một `str`.
+
+Trong Python 3.6 hoặc lớn hơn (bao gồm Python 3.10) bạn có thể sử dụng kiểu `Union` từ `typing` và đặt trong dấu ngoặc vuông những giá trị được chấp nhận.
+
+In Python 3.10 there's also a **new syntax** where you can put the possible types separated by a vertical bar (`|`).
+
+Trong Python 3.10 cũng có một **cú pháp mới** mà bạn có thể đặt những kiểu giá trị khả thi phân cách bởi một dấu sổ dọc (`|`).
+
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/python_types/tutorial008b_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="1 4"
+ {!> ../../../docs_src/python_types/tutorial008b.py!}
+ ```
+
+Trong cả hai trường hợp có nghĩa là `item` có thể là một `int` hoặc `str`.
+
+#### Khả năng `None`
+
+Bạn có thể khai báo một giá trị có thể có một kiểu dữ liệu, giống như `str`, nhưng nó cũng có thể là `None`.
+
+Trong Python 3.6 hoặc lớn hơn (bao gồm Python 3.10) bạn có thể khai báo nó bằng các import và sử dụng `Optional` từ mô đun `typing`.
+
+```Python hl_lines="1 4"
+{!../../../docs_src/python_types/tutorial009.py!}
+```
+
+Sử dụng `Optional[str]` thay cho `str` sẽ cho phép trình soạn thảo giúp bạn phát hiện các lỗi mà bạn có thể gặp như một giá trị luôn là một `str`, trong khi thực tế nó rất có thể là `None`.
+
+`Optional[Something]` là một cách viết ngắn gọn của `Union[Something, None]`, chúng là tương đương nhau.
+
+Điều này cũng có nghĩa là trong Python 3.10, bạn có thể sử dụng `Something | None`:
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/python_types/tutorial009_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="1 4"
+ {!> ../../../docs_src/python_types/tutorial009.py!}
+ ```
+
+=== "Python 3.6+ alternative"
+
+ ```Python hl_lines="1 4"
+ {!> ../../../docs_src/python_types/tutorial009b.py!}
+ ```
+
+#### Sử dụng `Union` hay `Optional`
+
+If you are using a Python version below 3.10, here's a tip from my very **subjective** point of view:
+
+Nếu bạn đang sử dụng phiên bản Python dưới 3.10, đây là một mẹo từ ý kiến rất "chủ quan" của tôi:
+
+* 🚨 Tránh sử dụng `Optional[SomeType]`
+* Thay vào đó ✨ **sử dụng `Union[SomeType, None]`** ✨.
+
+Cả hai là tương đương và bên dưới chúng giống nhau, nhưng tôi sẽ đễ xuất `Union` thay cho `Optional` vì từ "**tùy chọn**" có vẻ ngầm định giá trị là tùy chọn, và nó thực sự có nghĩa rằng "nó có thể là `None`", do đó nó không phải là tùy chọn và nó vẫn được yêu cầu.
+
+Tôi nghĩ `Union[SomeType, None]` là rõ ràng hơn về ý nghĩa của nó.
+
+Nó chỉ là về các từ và tên. Nhưng những từ đó có thể ảnh hưởng cách bạn và những đồng đội của bạn suy nghĩ về code.
+
+Cho một ví dụ, hãy để ý hàm này:
+
+```Python hl_lines="1 4"
+{!../../../docs_src/python_types/tutorial009c.py!}
+```
+
+Tham số `name` được định nghĩa là `Optional[str]`, nhưng nó **không phải là tùy chọn**, bạn không thể gọi hàm mà không có tham số:
+
+```Python
+say_hi() # Oh, no, this throws an error! 😱
+```
+
+Tham số `name` **vẫn được yêu cầu** (không phải là *tùy chọn*) vì nó không có giá trị mặc định. Trong khi đó, `name` chấp nhận `None` như là giá trị:
+
+```Python
+say_hi(name=None) # This works, None is valid 🎉
+```
+
+Tin tốt là, khi bạn sử dụng Python 3.10, bạn sẽ không phải lo lắng về điều đó, bạn sẽ có thể sử dụng `|` để định nghĩa hợp của các kiểu dữ liệu một cách đơn giản:
+
+```Python hl_lines="1 4"
+{!../../../docs_src/python_types/tutorial009c_py310.py!}
+```
+
+Và sau đó, bạn sẽ không phải lo rằng những cái tên như `Optional` và `Union`. 😎
+
+
+#### Những kiểu dữ liệu tổng quát
+
+Những kiểu dữ liệu này lấy tham số kiểu dữ liệu trong dấu ngoặc vuông được gọi là **Kiểu dữ liệu tổng quát**, cho ví dụ:
+
+=== "Python 3.10+"
+
+ Bạn có thể sử dụng các kiểu dữ liệu có sẵn như là kiểu dữ liệu tổng quát (với ngoặc vuông và kiểu dữ liệu bên trong):
+
+ * `list`
+ * `tuple`
+ * `set`
+ * `dict`
+
+ Và tương tự với Python 3.6, từ mô đun `typing`:
+
+ * `Union`
+ * `Optional` (tương tự như Python 3.6)
+ * ...và các kiểu dữ liệu khác.
+
+ Trong Python 3.10, thay vì sử dụng `Union` và `Optional`, bạn có thể sử dụng sổ dọc ('|') để khai báo hợp của các kiểu dữ liệu, điều đó tốt hơn và đơn giản hơn nhiều.
+
+=== "Python 3.9+"
+
+ Bạn có thể sử dụng các kiểu dữ liệu có sẵn tương tự như (với ngoặc vuông và kiểu dữ liệu bên trong):
+
+ * `list`
+ * `tuple`
+ * `set`
+ * `dict`
+
+ Và tương tự với Python 3.6, từ mô đun `typing`:
+
+ * `Union`
+ * `Optional`
+ * ...and others.
+
+=== "Python 3.6+"
+
+ * `List`
+ * `Tuple`
+ * `Set`
+ * `Dict`
+ * `Union`
+ * `Optional`
+ * ...và các kiểu khác.
+
+### Lớp như kiểu dữ liệu
+
+Bạn cũng có thể khai báo một lớp như là kiểu dữ liệu của một biến.
+
+Hãy nói rằng bạn muốn có một lớp `Person` với một tên:
+
+```Python hl_lines="1-3"
+{!../../../docs_src/python_types/tutorial010.py!}
+```
+
+Sau đó bạn có thể khai báo một biến có kiểu là `Person`:
+
+```Python hl_lines="6"
+{!../../../docs_src/python_types/tutorial010.py!}
+```
+
+Và lại một lần nữa, bạn có được tất cả sự hỗ trợ từ trình soạn thảo:
+
+
+
+Lưu ý rằng, điều này có nghĩa rằng "`one_person`" là một **thực thể** của lớp `Person`.
+
+Nó không có nghĩa "`one_person`" là một **lớp** gọi là `Person`.
+
+## Pydantic models
+
+Pydantic là một thư viện Python để validate dữ liệu hiệu năng cao.
+
+Bạn có thể khai báo "hình dạng" của dữa liệu như là các lớp với các thuộc tính.
+
+Và mỗi thuộc tính có một kiểu dữ liệu.
+
+Sau đó bạn tạo một thực thể của lớp đó với một vài giá trị và nó sẽ validate các giá trị, chuyển đổi chúng sang kiểu dữ liệu phù hợp (nếu đó là trường hợp) và cho bạn một object với toàn bộ dữ liệu.
+
+Và bạn nhận được tất cả sự hỗ trợ của trình soạn thảo với object kết quả đó.
+
+Một ví dụ từ tài liệu chính thức của Pydantic:
+
+=== "Python 3.10+"
+
+ ```Python
+ {!> ../../../docs_src/python_types/tutorial011_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python
+ {!> ../../../docs_src/python_types/tutorial011_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python
+ {!> ../../../docs_src/python_types/tutorial011.py!}
+ ```
+
+!!! info
+ Để học nhiều hơn về Pydantic, tham khảo tài liệu của nó.
+
+**FastAPI** được dựa hoàn toàn trên Pydantic.
+
+Bạn sẽ thấy nhiều ví dụ thực tế hơn trong [Hướng dẫn sử dụng](tutorial/index.md){.internal-link target=_blank}.
+
+!!! tip
+ Pydantic có một hành vi đặc biệt khi bạn sử dụng `Optional` hoặc `Union[Something, None]` mà không có giá trị mặc dịnh, bạn có thể đọc nhiều hơn về nó trong tài liệu của Pydantic về Required Optional fields.
+
+
+## Type Hints với Metadata Annotations
+
+Python cũng có một tính năng cho phép đặt **metadata bổ sung** trong những gợi ý kiểu dữ liệu này bằng cách sử dụng `Annotated`.
+
+=== "Python 3.9+"
+
+ Trong Python 3.9, `Annotated` là một phần của thư viện chuẩn, do đó bạn có thể import nó từ `typing`.
+
+ ```Python hl_lines="1 4"
+ {!> ../../../docs_src/python_types/tutorial013_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ Ở phiên bản dưới Python 3.9, bạn import `Annotated` từ `typing_extensions`.
+
+ Nó đã được cài đặt sẵng cùng với **FastAPI**.
+
+ ```Python hl_lines="1 4"
+ {!> ../../../docs_src/python_types/tutorial013.py!}
+ ```
+
+Python bản thân nó không làm bất kì điều gì với `Annotated`. Với các trình soạn thảo và các công cụ khác, kiểu dữ liệu vẫn là `str`.
+
+Nhưng bạn có thể sử dụng `Annotated` để cung cấp cho **FastAPI** metadata bổ sung về cách mà bạn muốn ứng dụng của bạn xử lí.
+
+Điều quan trọng cần nhớ là ***tham số kiểu dữ liệu* đầu tiên** bạn truyền tới `Annotated` là **kiểu giá trị thực sự**. Phần còn lại chỉ là metadata cho các công cụ khác.
+
+Bây giờ, bạn chỉ cần biết rằng `Annotated` tồn tại, và nó là tiêu chuẩn của Python. 😎
+
+
+Sau đó, bạn sẽ thấy sự **mạnh mẽ** mà nó có thể làm.
+
+!!! tip
+ Thực tế, cái này là **tiêu chuẩn của Python**, nghĩa là bạn vẫn sẽ có được **trải nghiệm phát triển tốt nhất có thể** với trình soạn thảo của bạn, với các công cụ bạn sử dụng để phân tích và tái cấu trúc code của bạn, etc. ✨
+
+ Và code của bạn sẽ tương thích với nhiều công cụ và thư viện khác của Python. 🚀
+
+## Các gợi ý kiểu dữ liệu trong **FastAPI**
+
+**FastAPI** lấy các ưu điểm của các gợi ý kiểu dữ liệu để thực hiện một số thứ.
+
+Với **FastAPI**, bạn khai báo các tham số với gợi ý kiểu và bạn có được:
+
+* **Sự hỗ trợ từ các trình soạn thảo**.
+* **Kiểm tra kiểu dữ liệu (type checking)**.
+
+...và **FastAPI** sử dụng các khia báo để:
+
+* **Định nghĩa các yêu cầu**: từ tham số đường dẫn của request, tham số query, headers, bodies, các phụ thuộc (dependencies),...
+* **Chuyển dổi dữ liệu*: từ request sang kiểu dữ liệu được yêu cầu.
+* **Kiểm tra tính đúng đắn của dữ liệu**: tới từ mỗi request:
+ * Sinh **lỗi tự động** để trả về máy khác khi dữ liệu không hợp lệ.
+* **Tài liệu hóa** API sử dụng OpenAPI:
+ * cái mà sau được được sử dụng bởi tài liệu tương tác người dùng.
+
+Điều này có thể nghe trừu tượng. Đừng lo lắng. Bạn sẽ thấy tất cả chúng trong [Hướng dẫn sử dụng](tutorial/index.md){.internal-link target=_blank}.
+
+Điều quan trọng là bằng việc sử dụng các kiểu dữ liệu chuẩn của Python (thay vì thêm các lớp, decorators,...), **FastAPI** sẽ thực hiện nhiều công việc cho bạn.
+
+!!! info
+ Nếu bạn đã đi qua toàn bộ các hướng dẫn và quay trở lại để tìm hiểu nhiều hơn về các kiểu dữ liệu, một tài nguyên tốt như "cheat sheet" từ `mypy`.
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 0000000000..f7ceb0c2fc
--- /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/swagger-ui-bundle.js",
+ swagger_css_url="https://unpkg.com/swagger-ui-dist@5/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/fastapi/__init__.py b/fastapi/__init__.py
index c113ac1fd0..d8abf2103e 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.0"
+__version__ = "0.101.1"
from starlette import status as status
diff --git a/fastapi/exceptions.py b/fastapi/exceptions.py
index c1692f3961..42f4709fba 100644
--- a/fastapi/exceptions.py
+++ b/fastapi/exceptions.py
@@ -47,3 +47,9 @@ class ResponseValidationError(ValidationException):
def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:
super().__init__(errors)
self.body = body
+
+ def __str__(self) -> str:
+ message = f"{len(self._errors)} validation errors:\n"
+ for err in self._errors:
+ message += f" {err}\n"
+ return message
diff --git a/requirements-docs.txt b/requirements-docs.txt
index 220d1ec3a5..2e667720e4 100644
--- a/requirements-docs.txt
+++ b/requirements-docs.txt
@@ -2,6 +2,7 @@
mkdocs-material==9.1.21
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
diff --git a/requirements-tests.txt b/requirements-tests.txt
index 0113b6f7ae..6f7f4ac235 100644
--- a/requirements-tests.txt
+++ b/requirements-tests.txt
@@ -11,7 +11,6 @@ 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/tests/test_multi_body_errors.py b/tests/test_multi_body_errors.py
index 931f08fc1c..a51ca7253f 100644
--- a/tests/test_multi_body_errors.py
+++ b/tests/test_multi_body_errors.py
@@ -51,7 +51,7 @@ def test_jsonable_encoder_requiring_error():
"loc": ["body", 0, "age"],
"msg": "Input should be greater than 0",
"input": -1.0,
- "ctx": {"gt": "0"},
+ "ctx": {"gt": 0},
"url": match_pydantic_error_url("greater_than"),
}
]
@@ -84,25 +84,12 @@ def test_put_incorrect_body_multiple():
"input": {"age": "five"},
"url": match_pydantic_error_url("missing"),
},
- {
- "ctx": {"class": "Decimal"},
- "input": "five",
- "loc": ["body", 0, "age", "is-instance[Decimal]"],
- "msg": "Input should be an instance of Decimal",
- "type": "is_instance_of",
- "url": match_pydantic_error_url("is_instance_of"),
- },
{
"type": "decimal_parsing",
- "loc": [
- "body",
- 0,
- "age",
- "function-after[to_decimal(), "
- "union[int,constrained-str,function-plain[str()]]]",
- ],
+ "loc": ["body", 0, "age"],
"msg": "Input should be a valid decimal",
"input": "five",
+ "url": match_pydantic_error_url("decimal_parsing"),
},
{
"type": "missing",
@@ -111,25 +98,12 @@ def test_put_incorrect_body_multiple():
"input": {"age": "six"},
"url": match_pydantic_error_url("missing"),
},
- {
- "ctx": {"class": "Decimal"},
- "input": "six",
- "loc": ["body", 1, "age", "is-instance[Decimal]"],
- "msg": "Input should be an instance of Decimal",
- "type": "is_instance_of",
- "url": match_pydantic_error_url("is_instance_of"),
- },
{
"type": "decimal_parsing",
- "loc": [
- "body",
- 1,
- "age",
- "function-after[to_decimal(), "
- "union[int,constrained-str,function-plain[str()]]]",
- ],
+ "loc": ["body", 1, "age"],
"msg": "Input should be a valid decimal",
"input": "six",
+ "url": match_pydantic_error_url("decimal_parsing"),
},
]
}
diff --git a/tests/test_response_model_as_return_annotation.py b/tests/test_response_model_as_return_annotation.py
index 85dd450eb0..6948430a13 100644
--- a/tests/test_response_model_as_return_annotation.py
+++ b/tests/test_response_model_as_return_annotation.py
@@ -277,13 +277,15 @@ def test_response_model_no_annotation_return_exact_dict():
def test_response_model_no_annotation_return_invalid_dict():
- with pytest.raises(ResponseValidationError):
+ with pytest.raises(ResponseValidationError) as excinfo:
client.get("/response_model-no_annotation-return_invalid_dict")
+ assert "missing" in str(excinfo.value)
def test_response_model_no_annotation_return_invalid_model():
- with pytest.raises(ResponseValidationError):
+ with pytest.raises(ResponseValidationError) as excinfo:
client.get("/response_model-no_annotation-return_invalid_model")
+ assert "missing" in str(excinfo.value)
def test_response_model_no_annotation_return_dict_with_extra_data():
@@ -313,13 +315,15 @@ def test_no_response_model_annotation_return_exact_dict():
def test_no_response_model_annotation_return_invalid_dict():
- with pytest.raises(ResponseValidationError):
+ with pytest.raises(ResponseValidationError) as excinfo:
client.get("/no_response_model-annotation-return_invalid_dict")
+ assert "missing" in str(excinfo.value)
def test_no_response_model_annotation_return_invalid_model():
- with pytest.raises(ResponseValidationError):
+ with pytest.raises(ResponseValidationError) as excinfo:
client.get("/no_response_model-annotation-return_invalid_model")
+ assert "missing" in str(excinfo.value)
def test_no_response_model_annotation_return_dict_with_extra_data():
@@ -395,13 +399,15 @@ def test_response_model_model1_annotation_model2_return_exact_dict():
def test_response_model_model1_annotation_model2_return_invalid_dict():
- with pytest.raises(ResponseValidationError):
+ with pytest.raises(ResponseValidationError) as excinfo:
client.get("/response_model_model1-annotation_model2-return_invalid_dict")
+ assert "missing" in str(excinfo.value)
def test_response_model_model1_annotation_model2_return_invalid_model():
- with pytest.raises(ResponseValidationError):
+ with pytest.raises(ResponseValidationError) as excinfo:
client.get("/response_model_model1-annotation_model2-return_invalid_model")
+ assert "missing" in str(excinfo.value)
def test_response_model_model1_annotation_model2_return_dict_with_extra_data():
diff --git a/tests/test_tutorial/test_body_updates/test_tutorial001.py b/tests/test_tutorial/test_body_updates/test_tutorial001.py
index f1a46210aa..58587885ef 100644
--- a/tests/test_tutorial/test_body_updates/test_tutorial001.py
+++ b/tests/test_tutorial/test_body_updates/test_tutorial001.py
@@ -53,7 +53,7 @@ def test_openapi_schema(client: TestClient):
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/ItemOutput"
+ "$ref": "#/components/schemas/Item-Output"
}
}
},
@@ -87,7 +87,7 @@ def test_openapi_schema(client: TestClient):
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/ItemOutput"
+ "$ref": "#/components/schemas/Item-Output"
}
}
},
@@ -116,7 +116,7 @@ def test_openapi_schema(client: TestClient):
"requestBody": {
"content": {
"application/json": {
- "schema": {"$ref": "#/components/schemas/ItemInput"}
+ "schema": {"$ref": "#/components/schemas/Item-Input"}
}
},
"required": True,
@@ -126,7 +126,7 @@ def test_openapi_schema(client: TestClient):
},
"components": {
"schemas": {
- "ItemInput": {
+ "Item-Input": {
"title": "Item",
"type": "object",
"properties": {
@@ -151,7 +151,7 @@ def test_openapi_schema(client: TestClient):
},
},
},
- "ItemOutput": {
+ "Item-Output": {
"title": "Item",
"type": "object",
"required": ["name", "description", "price", "tax", "tags"],
diff --git a/tests/test_tutorial/test_body_updates/test_tutorial001_py310.py b/tests/test_tutorial/test_body_updates/test_tutorial001_py310.py
index ab696e4c8d..d8a62502f0 100644
--- a/tests/test_tutorial/test_body_updates/test_tutorial001_py310.py
+++ b/tests/test_tutorial/test_body_updates/test_tutorial001_py310.py
@@ -56,7 +56,7 @@ def test_openapi_schema(client: TestClient):
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/ItemOutput"
+ "$ref": "#/components/schemas/Item-Output"
}
}
},
@@ -90,7 +90,7 @@ def test_openapi_schema(client: TestClient):
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/ItemOutput"
+ "$ref": "#/components/schemas/Item-Output"
}
}
},
@@ -119,7 +119,7 @@ def test_openapi_schema(client: TestClient):
"requestBody": {
"content": {
"application/json": {
- "schema": {"$ref": "#/components/schemas/ItemInput"}
+ "schema": {"$ref": "#/components/schemas/Item-Input"}
}
},
"required": True,
@@ -129,7 +129,7 @@ def test_openapi_schema(client: TestClient):
},
"components": {
"schemas": {
- "ItemInput": {
+ "Item-Input": {
"title": "Item",
"type": "object",
"properties": {
@@ -154,7 +154,7 @@ def test_openapi_schema(client: TestClient):
},
},
},
- "ItemOutput": {
+ "Item-Output": {
"title": "Item",
"type": "object",
"required": ["name", "description", "price", "tax", "tags"],
diff --git a/tests/test_tutorial/test_body_updates/test_tutorial001_py39.py b/tests/test_tutorial/test_body_updates/test_tutorial001_py39.py
index 2ee6a5cb4c..c604df6ecb 100644
--- a/tests/test_tutorial/test_body_updates/test_tutorial001_py39.py
+++ b/tests/test_tutorial/test_body_updates/test_tutorial001_py39.py
@@ -56,7 +56,7 @@ def test_openapi_schema(client: TestClient):
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/ItemOutput"
+ "$ref": "#/components/schemas/Item-Output"
}
}
},
@@ -90,7 +90,7 @@ def test_openapi_schema(client: TestClient):
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/ItemOutput"
+ "$ref": "#/components/schemas/Item-Output"
}
}
},
@@ -119,7 +119,7 @@ def test_openapi_schema(client: TestClient):
"requestBody": {
"content": {
"application/json": {
- "schema": {"$ref": "#/components/schemas/ItemInput"}
+ "schema": {"$ref": "#/components/schemas/Item-Input"}
}
},
"required": True,
@@ -129,7 +129,7 @@ def test_openapi_schema(client: TestClient):
},
"components": {
"schemas": {
- "ItemInput": {
+ "Item-Input": {
"title": "Item",
"type": "object",
"properties": {
@@ -154,7 +154,7 @@ def test_openapi_schema(client: TestClient):
},
},
},
- "ItemOutput": {
+ "Item-Output": {
"title": "Item",
"type": "object",
"required": ["name", "description", "price", "tax", "tags"],
diff --git a/docs_src/sql_databases_peewee/__init__.py b/tests/test_tutorial/test_configure_swagger_ui/__init__.py
similarity index 100%
rename from docs_src/sql_databases_peewee/__init__.py
rename to tests/test_tutorial/test_configure_swagger_ui/__init__.py
diff --git a/tests/test_tutorial/test_extending_openapi/test_tutorial003.py b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial001.py
similarity index 95%
rename from tests/test_tutorial/test_extending_openapi/test_tutorial003.py
rename to tests/test_tutorial/test_configure_swagger_ui/test_tutorial001.py
index 0184dd9f83..72db54bd20 100644
--- a/tests/test_tutorial/test_extending_openapi/test_tutorial003.py
+++ b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial001.py
@@ -1,6 +1,6 @@
from fastapi.testclient import TestClient
-from docs_src.extending_openapi.tutorial003 import app
+from docs_src.configure_swagger_ui.tutorial001 import app
client = TestClient(app)
diff --git a/tests/test_tutorial/test_extending_openapi/test_tutorial004.py b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial002.py
similarity index 96%
rename from tests/test_tutorial/test_extending_openapi/test_tutorial004.py
rename to tests/test_tutorial/test_configure_swagger_ui/test_tutorial002.py
index 4f7615126a..1669011885 100644
--- a/tests/test_tutorial/test_extending_openapi/test_tutorial004.py
+++ b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial002.py
@@ -1,6 +1,6 @@
from fastapi.testclient import TestClient
-from docs_src.extending_openapi.tutorial004 import app
+from docs_src.configure_swagger_ui.tutorial002 import app
client = TestClient(app)
diff --git a/tests/test_tutorial/test_extending_openapi/test_tutorial005.py b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial003.py
similarity index 96%
rename from tests/test_tutorial/test_extending_openapi/test_tutorial005.py
rename to tests/test_tutorial/test_configure_swagger_ui/test_tutorial003.py
index 24aeb93db3..187e89ace0 100644
--- a/tests/test_tutorial/test_extending_openapi/test_tutorial005.py
+++ b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial003.py
@@ -1,6 +1,6 @@
from fastapi.testclient import TestClient
-from docs_src.extending_openapi.tutorial005 import app
+from docs_src.configure_swagger_ui.tutorial003 import app
client = TestClient(app)
diff --git a/tests/test_tutorial/test_sql_databases_peewee/__init__.py b/tests/test_tutorial/test_custom_docs_ui/__init__.py
similarity index 100%
rename from tests/test_tutorial/test_sql_databases_peewee/__init__.py
rename to tests/test_tutorial/test_custom_docs_ui/__init__.py
diff --git a/tests/test_tutorial/test_custom_docs_ui/test_tutorial001.py b/tests/test_tutorial/test_custom_docs_ui/test_tutorial001.py
new file mode 100644
index 0000000000..aff070d747
--- /dev/null
+++ b/tests/test_tutorial/test_custom_docs_ui/test_tutorial001.py
@@ -0,0 +1,42 @@
+import os
+from pathlib import Path
+
+import pytest
+from fastapi.testclient import TestClient
+
+
+@pytest.fixture(scope="module")
+def client():
+ static_dir: Path = Path(os.getcwd()) / "static"
+ print(static_dir)
+ static_dir.mkdir(exist_ok=True)
+ from docs_src.custom_docs_ui.tutorial001 import app
+
+ with TestClient(app) as client:
+ yield client
+ static_dir.rmdir()
+
+
+def test_swagger_ui_html(client: TestClient):
+ response = client.get("/docs")
+ assert response.status_code == 200, response.text
+ assert "https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js" in response.text
+ assert "https://unpkg.com/swagger-ui-dist@5/swagger-ui.css" in response.text
+
+
+def test_swagger_ui_oauth2_redirect_html(client: TestClient):
+ response = client.get("/docs/oauth2-redirect")
+ assert response.status_code == 200, response.text
+ assert "window.opener.swaggerUIRedirectOauth2" in response.text
+
+
+def test_redoc_html(client: TestClient):
+ response = client.get("/redoc")
+ assert response.status_code == 200, response.text
+ assert "https://unpkg.com/redoc@next/bundles/redoc.standalone.js" in response.text
+
+
+def test_api(client: TestClient):
+ response = client.get("/users/john")
+ assert response.status_code == 200, response.text
+ assert response.json()["message"] == "Hello john"
diff --git a/tests/test_tutorial/test_extending_openapi/test_tutorial002.py b/tests/test_tutorial/test_custom_docs_ui/test_tutorial002.py
similarity index 95%
rename from tests/test_tutorial/test_extending_openapi/test_tutorial002.py
rename to tests/test_tutorial/test_custom_docs_ui/test_tutorial002.py
index 654db2e4c8..712618807c 100644
--- a/tests/test_tutorial/test_extending_openapi/test_tutorial002.py
+++ b/tests/test_tutorial/test_custom_docs_ui/test_tutorial002.py
@@ -10,7 +10,7 @@ def client():
static_dir: Path = Path(os.getcwd()) / "static"
print(static_dir)
static_dir.mkdir(exist_ok=True)
- from docs_src.extending_openapi.tutorial002 import app
+ from docs_src.custom_docs_ui.tutorial002 import app
with TestClient(app) as client:
yield client
diff --git a/tests/test_tutorial/test_dataclasses/test_tutorial003.py b/tests/test_tutorial/test_dataclasses/test_tutorial003.py
index 2e5809914f..f2ca858235 100644
--- a/tests/test_tutorial/test_dataclasses/test_tutorial003.py
+++ b/tests/test_tutorial/test_dataclasses/test_tutorial003.py
@@ -79,7 +79,9 @@ def test_openapi_schema():
"schema": {
"title": "Items",
"type": "array",
- "items": {"$ref": "#/components/schemas/ItemInput"},
+ "items": {
+ "$ref": "#/components/schemas/Item-Input"
+ },
}
}
},
@@ -141,7 +143,7 @@ def test_openapi_schema():
"items": {
"title": "Items",
"type": "array",
- "items": {"$ref": "#/components/schemas/ItemOutput"},
+ "items": {"$ref": "#/components/schemas/Item-Output"},
},
},
},
@@ -156,7 +158,7 @@ def test_openapi_schema():
}
},
},
- "ItemInput": {
+ "Item-Input": {
"title": "Item",
"required": ["name"],
"type": "object",
@@ -168,7 +170,7 @@ def test_openapi_schema():
},
},
},
- "ItemOutput": {
+ "Item-Output": {
"title": "Item",
"required": ["name", "description"],
"type": "object",
diff --git a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial004.py b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial004.py
index 3ffc0bca7c..c5b2fb670b 100644
--- a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial004.py
+++ b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial004.py
@@ -35,7 +35,7 @@ def test_openapi_schema():
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/ItemOutput"
+ "$ref": "#/components/schemas/Item-Output"
}
}
},
@@ -57,7 +57,7 @@ def test_openapi_schema():
"requestBody": {
"content": {
"application/json": {
- "schema": {"$ref": "#/components/schemas/ItemInput"}
+ "schema": {"$ref": "#/components/schemas/Item-Input"}
}
},
"required": True,
@@ -67,7 +67,7 @@ def test_openapi_schema():
},
"components": {
"schemas": {
- "ItemInput": {
+ "Item-Input": {
"title": "Item",
"required": ["name", "price"],
"type": "object",
@@ -91,7 +91,7 @@ def test_openapi_schema():
},
},
},
- "ItemOutput": {
+ "Item-Output": {
"title": "Item",
"required": ["name", "description", "price", "tax", "tags"],
"type": "object",
diff --git a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005.py b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005.py
index ff98295a60..458923b5a0 100644
--- a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005.py
+++ b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005.py
@@ -35,7 +35,7 @@ def test_openapi_schema():
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/ItemOutput"
+ "$ref": "#/components/schemas/Item-Output"
}
}
},
@@ -57,7 +57,7 @@ def test_openapi_schema():
"requestBody": {
"content": {
"application/json": {
- "schema": {"$ref": "#/components/schemas/ItemInput"}
+ "schema": {"$ref": "#/components/schemas/Item-Input"}
}
},
"required": True,
@@ -67,7 +67,7 @@ def test_openapi_schema():
},
"components": {
"schemas": {
- "ItemInput": {
+ "Item-Input": {
"title": "Item",
"required": ["name", "price"],
"type": "object",
@@ -91,7 +91,7 @@ def test_openapi_schema():
},
},
},
- "ItemOutput": {
+ "Item-Output": {
"title": "Item",
"required": ["name", "description", "price", "tax", "tags"],
"type": "object",
diff --git a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py310.py b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py310.py
index ad1c09eaec..1fcc5c4e0c 100644
--- a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py310.py
+++ b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py310.py
@@ -42,7 +42,7 @@ def test_openapi_schema(client: TestClient):
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/ItemOutput"
+ "$ref": "#/components/schemas/Item-Output"
}
}
},
@@ -64,7 +64,7 @@ def test_openapi_schema(client: TestClient):
"requestBody": {
"content": {
"application/json": {
- "schema": {"$ref": "#/components/schemas/ItemInput"}
+ "schema": {"$ref": "#/components/schemas/Item-Input"}
}
},
"required": True,
@@ -74,7 +74,7 @@ def test_openapi_schema(client: TestClient):
},
"components": {
"schemas": {
- "ItemInput": {
+ "Item-Input": {
"title": "Item",
"required": ["name", "price"],
"type": "object",
@@ -98,7 +98,7 @@ def test_openapi_schema(client: TestClient):
},
},
},
- "ItemOutput": {
+ "Item-Output": {
"title": "Item",
"required": ["name", "description", "price", "tax", "tags"],
"type": "object",
diff --git a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py39.py b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py39.py
index 045d1d402c..470fe032b1 100644
--- a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py39.py
+++ b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py39.py
@@ -42,7 +42,7 @@ def test_openapi_schema(client: TestClient):
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/ItemOutput"
+ "$ref": "#/components/schemas/Item-Output"
}
}
},
@@ -64,7 +64,7 @@ def test_openapi_schema(client: TestClient):
"requestBody": {
"content": {
"application/json": {
- "schema": {"$ref": "#/components/schemas/ItemInput"}
+ "schema": {"$ref": "#/components/schemas/Item-Input"}
}
},
"required": True,
@@ -74,7 +74,7 @@ def test_openapi_schema(client: TestClient):
},
"components": {
"schemas": {
- "ItemInput": {
+ "Item-Input": {
"title": "Item",
"required": ["name", "price"],
"type": "object",
@@ -98,7 +98,7 @@ def test_openapi_schema(client: TestClient):
},
},
},
- "ItemOutput": {
+ "Item-Output": {
"title": "Item",
"required": ["name", "description", "price", "tax", "tags"],
"type": "object",
diff --git a/tests/test_tutorial/test_sql_databases_peewee/test_sql_databases_peewee.py b/tests/test_tutorial/test_sql_databases_peewee/test_sql_databases_peewee.py
deleted file mode 100644
index 4350567d1a..0000000000
--- a/tests/test_tutorial/test_sql_databases_peewee/test_sql_databases_peewee.py
+++ /dev/null
@@ -1,454 +0,0 @@
-import time
-from pathlib import Path
-from unittest.mock import MagicMock
-
-import pytest
-from fastapi.testclient import TestClient
-
-from ...utils import needs_pydanticv1
-
-
-@pytest.fixture(scope="module")
-def client():
- # Import while creating the client to create the DB after starting the test session
- from docs_src.sql_databases_peewee.sql_app.main import app
-
- test_db = Path("./test.db")
- with TestClient(app) as c:
- yield c
- test_db.unlink()
-
-
-@needs_pydanticv1
-def test_create_user(client):
- test_user = {"email": "johndoe@example.com", "password": "secret"}
- response = client.post("/users/", json=test_user)
- assert response.status_code == 200, response.text
- data = response.json()
- assert test_user["email"] == data["email"]
- assert "id" in data
- response = client.post("/users/", json=test_user)
- assert response.status_code == 400, response.text
-
-
-@needs_pydanticv1
-def test_get_user(client):
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- data = response.json()
- assert "email" in data
- assert "id" in data
-
-
-@needs_pydanticv1
-def test_inexistent_user(client):
- response = client.get("/users/999")
- assert response.status_code == 404, response.text
-
-
-@needs_pydanticv1
-def test_get_users(client):
- response = client.get("/users/")
- assert response.status_code == 200, response.text
- data = response.json()
- assert "email" in data[0]
- assert "id" in data[0]
-
-
-time.sleep = MagicMock()
-
-
-@needs_pydanticv1
-def test_get_slowusers(client):
- response = client.get("/slowusers/")
- assert response.status_code == 200, response.text
- data = response.json()
- assert "email" in data[0]
- assert "id" in data[0]
-
-
-@needs_pydanticv1
-def test_create_item(client):
- item = {"title": "Foo", "description": "Something that fights"}
- response = client.post("/users/1/items/", json=item)
- assert response.status_code == 200, response.text
- item_data = response.json()
- assert item["title"] == item_data["title"]
- assert item["description"] == item_data["description"]
- assert "id" in item_data
- assert "owner_id" in item_data
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- user_data = response.json()
- item_to_check = [it for it in user_data["items"] if it["id"] == item_data["id"]][0]
- assert item_to_check["title"] == item["title"]
- assert item_to_check["description"] == item["description"]
- response = client.get("/users/1")
- assert response.status_code == 200, response.text
- user_data = response.json()
- item_to_check = [it for it in user_data["items"] if it["id"] == item_data["id"]][0]
- assert item_to_check["title"] == item["title"]
- assert item_to_check["description"] == item["description"]
-
-
-@needs_pydanticv1
-def test_read_items(client):
- response = client.get("/items/")
- assert response.status_code == 200, response.text
- data = response.json()
- assert data
- first_item = data[0]
- assert "title" in first_item
- assert "description" in first_item
-
-
-@needs_pydanticv1
-def test_openapi_schema(client):
- response = client.get("/openapi.json")
- assert response.status_code == 200, response.text
- assert response.json() == {
- "openapi": "3.1.0",
- "info": {"title": "FastAPI", "version": "0.1.0"},
- "paths": {
- "/users/": {
- "get": {
- "summary": "Read Users",
- "operationId": "read_users_users__get",
- "parameters": [
- {
- "required": False,
- "schema": {
- "title": "Skip",
- "type": "integer",
- "default": 0,
- },
- "name": "skip",
- "in": "query",
- },
- {
- "required": False,
- "schema": {
- "title": "Limit",
- "type": "integer",
- "default": 100,
- },
- "name": "limit",
- "in": "query",
- },
- ],
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {
- "title": "Response Read Users Users Get",
- "type": "array",
- "items": {"$ref": "#/components/schemas/User"},
- }
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- },
- "post": {
- "summary": "Create User",
- "operationId": "create_user_users__post",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/UserCreate"}
- }
- },
- "required": True,
- },
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/User"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- },
- },
- "/users/{user_id}": {
- "get": {
- "summary": "Read User",
- "operationId": "read_user_users__user_id__get",
- "parameters": [
- {
- "required": True,
- "schema": {"title": "User Id", "type": "integer"},
- "name": "user_id",
- "in": "path",
- }
- ],
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/User"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- }
- },
- "/users/{user_id}/items/": {
- "post": {
- "summary": "Create Item For User",
- "operationId": "create_item_for_user_users__user_id__items__post",
- "parameters": [
- {
- "required": True,
- "schema": {"title": "User Id", "type": "integer"},
- "name": "user_id",
- "in": "path",
- }
- ],
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/ItemCreate"}
- }
- },
- "required": True,
- },
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/Item"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- }
- },
- "/items/": {
- "get": {
- "summary": "Read Items",
- "operationId": "read_items_items__get",
- "parameters": [
- {
- "required": False,
- "schema": {
- "title": "Skip",
- "type": "integer",
- "default": 0,
- },
- "name": "skip",
- "in": "query",
- },
- {
- "required": False,
- "schema": {
- "title": "Limit",
- "type": "integer",
- "default": 100,
- },
- "name": "limit",
- "in": "query",
- },
- ],
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {
- "title": "Response Read Items Items Get",
- "type": "array",
- "items": {"$ref": "#/components/schemas/Item"},
- }
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- }
- },
- "/slowusers/": {
- "get": {
- "summary": "Read Slow Users",
- "operationId": "read_slow_users_slowusers__get",
- "parameters": [
- {
- "required": False,
- "schema": {
- "title": "Skip",
- "type": "integer",
- "default": 0,
- },
- "name": "skip",
- "in": "query",
- },
- {
- "required": False,
- "schema": {
- "title": "Limit",
- "type": "integer",
- "default": 100,
- },
- "name": "limit",
- "in": "query",
- },
- ],
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {
- "title": "Response Read Slow Users Slowusers Get",
- "type": "array",
- "items": {"$ref": "#/components/schemas/User"},
- }
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- }
- },
- },
- "components": {
- "schemas": {
- "HTTPValidationError": {
- "title": "HTTPValidationError",
- "type": "object",
- "properties": {
- "detail": {
- "title": "Detail",
- "type": "array",
- "items": {"$ref": "#/components/schemas/ValidationError"},
- }
- },
- },
- "Item": {
- "title": "Item",
- "required": ["title", "id", "owner_id"],
- "type": "object",
- "properties": {
- "title": {"title": "Title", "type": "string"},
- "description": {"title": "Description", "type": "string"},
- "id": {"title": "Id", "type": "integer"},
- "owner_id": {"title": "Owner Id", "type": "integer"},
- },
- },
- "ItemCreate": {
- "title": "ItemCreate",
- "required": ["title"],
- "type": "object",
- "properties": {
- "title": {"title": "Title", "type": "string"},
- "description": {"title": "Description", "type": "string"},
- },
- },
- "User": {
- "title": "User",
- "required": ["email", "id", "is_active"],
- "type": "object",
- "properties": {
- "email": {"title": "Email", "type": "string"},
- "id": {"title": "Id", "type": "integer"},
- "is_active": {"title": "Is Active", "type": "boolean"},
- "items": {
- "title": "Items",
- "type": "array",
- "items": {"$ref": "#/components/schemas/Item"},
- "default": [],
- },
- },
- },
- "UserCreate": {
- "title": "UserCreate",
- "required": ["email", "password"],
- "type": "object",
- "properties": {
- "email": {"title": "Email", "type": "string"},
- "password": {"title": "Password", "type": "string"},
- },
- },
- "ValidationError": {
- "title": "ValidationError",
- "required": ["loc", "msg", "type"],
- "type": "object",
- "properties": {
- "loc": {
- "title": "Location",
- "type": "array",
- "items": {
- "anyOf": [{"type": "string"}, {"type": "integer"}]
- },
- },
- "msg": {"title": "Message", "type": "string"},
- "type": {"title": "Error Type", "type": "string"},
- },
- },
- }
- },
- }