committed by
GitHub
1472 changed files with 33344 additions and 49447 deletions
@ -7,7 +7,8 @@ on: |
|||||
- synchronize |
- synchronize |
||||
|
|
||||
env: |
env: |
||||
IS_FORK: ${{ github.event.pull_request.head.repo.full_name != github.repository }} |
# Forks and Dependabot don't have access to secrets |
||||
|
HAS_SECRETS: ${{ secrets.PRE_COMMIT != '' }} |
||||
|
|
||||
jobs: |
jobs: |
||||
pre-commit: |
pre-commit: |
||||
@ -19,16 +20,23 @@ jobs: |
|||||
run: echo "$GITHUB_CONTEXT" |
run: echo "$GITHUB_CONTEXT" |
||||
- uses: actions/checkout@v5 |
- uses: actions/checkout@v5 |
||||
name: Checkout PR for own repo |
name: Checkout PR for own repo |
||||
if: env.IS_FORK == 'false' |
if: env.HAS_SECRETS == 'true' |
||||
with: |
with: |
||||
# To be able to commit it needs more than the last commit |
# To be able to commit it needs to fetch the head of the branch, not the |
||||
|
# merge commit |
||||
ref: ${{ github.head_ref }} |
ref: ${{ github.head_ref }} |
||||
|
# And it needs the full history to be able to compute diffs |
||||
|
fetch-depth: 0 |
||||
# A token other than the default GITHUB_TOKEN is needed to be able to trigger CI |
# A token other than the default GITHUB_TOKEN is needed to be able to trigger CI |
||||
token: ${{ secrets.PRE_COMMIT }} |
token: ${{ secrets.PRE_COMMIT }} |
||||
# pre-commit lite ci needs the default checkout configs to work |
# pre-commit lite ci needs the default checkout configs to work |
||||
- uses: actions/checkout@v5 |
- uses: actions/checkout@v5 |
||||
name: Checkout PR for fork |
name: Checkout PR for fork |
||||
if: env.IS_FORK == 'true' |
if: env.HAS_SECRETS == 'false' |
||||
|
with: |
||||
|
# To be able to commit it needs the head branch of the PR, the remote one |
||||
|
ref: ${{ github.event.pull_request.head.sha }} |
||||
|
fetch-depth: 0 |
||||
- name: Set up Python |
- name: Set up Python |
||||
uses: actions/setup-python@v6 |
uses: actions/setup-python@v6 |
||||
with: |
with: |
||||
@ -44,15 +52,12 @@ jobs: |
|||||
run: | |
run: | |
||||
uv venv |
uv venv |
||||
uv pip install -r requirements.txt |
uv pip install -r requirements.txt |
||||
- name: Run pre-commit |
- name: Run prek - pre-commit |
||||
id: precommit |
id: precommit |
||||
run: | |
run: uvx prek run --from-ref origin/${GITHUB_BASE_REF} --to-ref HEAD --show-diff-on-failure |
||||
# Fetch the base branch for comparison |
|
||||
git fetch origin ${{ github.base_ref }} |
|
||||
uvx pre-commit run --from-ref origin/${{ github.base_ref }} --to-ref HEAD --show-diff-on-failure |
|
||||
continue-on-error: true |
continue-on-error: true |
||||
- name: Commit and push changes |
- name: Commit and push changes |
||||
if: env.IS_FORK == 'false' |
if: env.HAS_SECRETS == 'true' |
||||
run: | |
run: | |
||||
git config user.name "github-actions[bot]" |
git config user.name "github-actions[bot]" |
||||
git config user.email "github-actions[bot]@users.noreply.github.com" |
git config user.email "github-actions[bot]@users.noreply.github.com" |
||||
@ -64,7 +69,7 @@ jobs: |
|||||
git push |
git push |
||||
fi |
fi |
||||
- uses: pre-commit-ci/[email protected] |
- uses: pre-commit-ci/[email protected] |
||||
if: env.IS_FORK == 'true' |
if: env.HAS_SECRETS == 'false' |
||||
with: |
with: |
||||
msg: 🎨 Auto format |
msg: 🎨 Auto format |
||||
- name: Error out on pre-commit errors |
- name: Error out on pre-commit errors |
||||
|
|||||
@ -1,3 +1,3 @@ |
|||||
# Ressourcen { #resources } |
# Ressourcen { #resources } |
||||
|
|
||||
Zusätzliche Ressourcen, externe Links, Artikel und mehr. ✈️ |
Zusätzliche Ressourcen, externe Links und mehr. ✈️ |
||||
|
|||||
@ -22,21 +22,13 @@ Hier ist eine allgemeine Idee, wie die Modelle mit ihren Passwortfeldern aussehe |
|||||
|
|
||||
{* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *} |
{* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *} |
||||
|
|
||||
/// info | Info |
### Über `**user_in.model_dump()` { #about-user-in-model-dump } |
||||
|
|
||||
In Pydantic v1 hieß die Methode `.dict()`, in Pydantic v2 wurde sie <abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr> (aber weiterhin unterstützt) und in `.model_dump()` umbenannt. |
#### Pydantics `.model_dump()` { #pydantics-model-dump } |
||||
|
|
||||
Die Beispiele hier verwenden `.dict()` für die Kompatibilität mit Pydantic v1, aber Sie sollten `.model_dump()` verwenden, wenn Sie Pydantic v2 verwenden können. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
### Über `**user_in.dict()` { #about-user-in-dict } |
|
||||
|
|
||||
#### Die `.dict()`-Methode von Pydantic { #pydantics-dict } |
|
||||
|
|
||||
`user_in` ist ein Pydantic-Modell der Klasse `UserIn`. |
`user_in` ist ein Pydantic-Modell der Klasse `UserIn`. |
||||
|
|
||||
Pydantic-Modelle haben eine `.dict()`-Methode, die ein <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> mit den Daten des Modells zurückgibt. |
Pydantic-Modelle haben eine `.model_dump()`-Methode, die ein <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> mit den Daten des Modells zurückgibt. |
||||
|
|
||||
Wenn wir also ein Pydantic-Objekt `user_in` erstellen, etwa so: |
Wenn wir also ein Pydantic-Objekt `user_in` erstellen, etwa so: |
||||
|
|
||||
@ -47,7 +39,7 @@ user_in = UserIn(username="john", password="secret", email="[email protected] |
|||||
und dann aufrufen: |
und dann aufrufen: |
||||
|
|
||||
```Python |
```Python |
||||
user_dict = user_in.dict() |
user_dict = user_in.model_dump() |
||||
``` |
``` |
||||
|
|
||||
haben wir jetzt ein `dict` mit den Daten in der Variablen `user_dict` (es ist ein `dict` statt eines Pydantic-Modellobjekts). |
haben wir jetzt ein `dict` mit den Daten in der Variablen `user_dict` (es ist ein `dict` statt eines Pydantic-Modellobjekts). |
||||
@ -103,20 +95,20 @@ UserInDB( |
|||||
|
|
||||
#### Ein Pydantic-Modell aus dem Inhalt eines anderen { #a-pydantic-model-from-the-contents-of-another } |
#### Ein Pydantic-Modell aus dem Inhalt eines anderen { #a-pydantic-model-from-the-contents-of-another } |
||||
|
|
||||
Da wir im obigen Beispiel `user_dict` von `user_in.dict()` bekommen haben, wäre dieser Code: |
Da wir im obigen Beispiel `user_dict` von `user_in.model_dump()` bekommen haben, wäre dieser Code: |
||||
|
|
||||
```Python |
```Python |
||||
user_dict = user_in.dict() |
user_dict = user_in.model_dump() |
||||
UserInDB(**user_dict) |
UserInDB(**user_dict) |
||||
``` |
``` |
||||
|
|
||||
gleichwertig zu: |
gleichwertig zu: |
||||
|
|
||||
```Python |
```Python |
||||
UserInDB(**user_in.dict()) |
UserInDB(**user_in.model_dump()) |
||||
``` |
``` |
||||
|
|
||||
... weil `user_in.dict()` ein `dict` ist, und dann lassen wir Python es „entpacken“, indem wir es an `UserInDB` mit vorangestelltem `**` übergeben. |
... weil `user_in.model_dump()` ein `dict` ist, und dann lassen wir Python es „entpacken“, indem wir es an `UserInDB` mit vorangestelltem `**` übergeben. |
||||
|
|
||||
Auf diese Weise erhalten wir ein Pydantic-Modell aus den Daten eines anderen Pydantic-Modells. |
Auf diese Weise erhalten wir ein Pydantic-Modell aus den Daten eines anderen Pydantic-Modells. |
||||
|
|
||||
@ -125,7 +117,7 @@ Auf diese Weise erhalten wir ein Pydantic-Modell aus den Daten eines anderen Pyd |
|||||
Und dann fügen wir das zusätzliche Schlüsselwort-Argument `hashed_password=hashed_password` hinzu, wie in: |
Und dann fügen wir das zusätzliche Schlüsselwort-Argument `hashed_password=hashed_password` hinzu, wie in: |
||||
|
|
||||
```Python |
```Python |
||||
UserInDB(**user_in.dict(), hashed_password=hashed_password) |
UserInDB(**user_in.model_dump(), hashed_password=hashed_password) |
||||
``` |
``` |
||||
|
|
||||
... was so ist wie: |
... was so ist wie: |
||||
@ -180,7 +172,6 @@ Wenn Sie eine <a href="https://docs.pydantic.dev/latest/concepts/types/#unions" |
|||||
|
|
||||
{* ../../docs_src/extra_models/tutorial003_py310.py hl[1,14:15,18:20,33] *} |
{* ../../docs_src/extra_models/tutorial003_py310.py hl[1,14:15,18:20,33] *} |
||||
|
|
||||
|
|
||||
### `Union` in Python 3.10 { #union-in-python-3-10 } |
### `Union` in Python 3.10 { #union-in-python-3-10 } |
||||
|
|
||||
In diesem Beispiel übergeben wir `Union[PlaneItem, CarItem]` als Wert des Arguments `response_model`. |
In diesem Beispiel übergeben wir `Union[PlaneItem, CarItem]` als Wert des Arguments `response_model`. |
||||
@ -203,7 +194,6 @@ Dafür verwenden Sie Pythons Standard-`typing.List` (oder nur `list` in Python 3 |
|||||
|
|
||||
{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *} |
{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *} |
||||
|
|
||||
|
|
||||
## Response mit beliebigem `dict` { #response-with-arbitrary-dict } |
## Response mit beliebigem `dict` { #response-with-arbitrary-dict } |
||||
|
|
||||
Sie können auch eine Response deklarieren, die ein beliebiges `dict` zurückgibt, indem Sie nur die Typen der Schlüssel und Werte ohne ein Pydantic-Modell deklarieren. |
Sie können auch eine Response deklarieren, die ein beliebiges `dict` zurückgibt, indem Sie nur die Typen der Schlüssel und Werte ohne ein Pydantic-Modell deklarieren. |
||||
@ -214,7 +204,6 @@ In diesem Fall können Sie `typing.Dict` verwenden (oder nur `dict` in Python 3. |
|||||
|
|
||||
{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *} |
{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *} |
||||
|
|
||||
|
|
||||
## Zusammenfassung { #recap } |
## Zusammenfassung { #recap } |
||||
|
|
||||
Verwenden Sie gerne mehrere Pydantic-Modelle und vererben Sie je nach Bedarf. |
Verwenden Sie gerne mehrere Pydantic-Modelle und vererben Sie je nach Bedarf. |
||||
|
|||||
@ -1,247 +0,0 @@ |
|||||
# 🌖 📨 🗄 |
|
||||
|
|
||||
/// warning |
|
||||
|
|
||||
👉 👍 🏧 ❔. |
|
||||
|
|
||||
🚥 👆 ▶️ ⏮️ **FastAPI**, 👆 💪 🚫 💪 👉. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
👆 💪 📣 🌖 📨, ⏮️ 🌖 👔 📟, 🔉 🆎, 📛, ♒️. |
|
||||
|
|
||||
👈 🌖 📨 🔜 🔌 🗄 🔗, 👫 🔜 😑 🛠️ 🩺. |
|
||||
|
|
||||
✋️ 👈 🌖 📨 👆 ✔️ ⚒ 💭 👆 📨 `Response` 💖 `JSONResponse` 🔗, ⏮️ 👆 👔 📟 & 🎚. |
|
||||
|
|
||||
## 🌖 📨 ⏮️ `model` |
|
||||
|
|
||||
👆 💪 🚶♀️ 👆 *➡ 🛠️ 👨🎨* 🔢 `responses`. |
|
||||
|
|
||||
⚫️ 📨 `dict`, 🔑 👔 📟 🔠 📨, 💖 `200`, & 💲 🎏 `dict`Ⓜ ⏮️ ℹ 🔠 👫. |
|
||||
|
|
||||
🔠 👈 📨 `dict`Ⓜ 💪 ✔️ 🔑 `model`, ⚗ Pydantic 🏷, 💖 `response_model`. |
|
||||
|
|
||||
**FastAPI** 🔜 ✊ 👈 🏷, 🏗 🚮 🎻 🔗 & 🔌 ⚫️ ☑ 🥉 🗄. |
|
||||
|
|
||||
🖼, 📣 ➕1️⃣ 📨 ⏮️ 👔 📟 `404` & Pydantic 🏷 `Message`, 👆 💪 ✍: |
|
||||
|
|
||||
{* ../../docs_src/additional_responses/tutorial001.py hl[18,22] *} |
|
||||
|
|
||||
/// note |
|
||||
|
|
||||
✔️ 🤯 👈 👆 ✔️ 📨 `JSONResponse` 🔗. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
/// info |
|
||||
|
|
||||
`model` 🔑 🚫 🍕 🗄. |
|
||||
|
|
||||
**FastAPI** 🔜 ✊ Pydantic 🏷 ⚪️➡️ 📤, 🏗 `JSON Schema`, & 🚮 ⚫️ ☑ 🥉. |
|
||||
|
|
||||
☑ 🥉: |
|
||||
|
|
||||
* 🔑 `content`, 👈 ✔️ 💲 ➕1️⃣ 🎻 🎚 (`dict`) 👈 🔌: |
|
||||
* 🔑 ⏮️ 📻 🆎, ✅ `application/json`, 👈 🔌 💲 ➕1️⃣ 🎻 🎚, 👈 🔌: |
|
||||
* 🔑 `schema`, 👈 ✔️ 💲 🎻 🔗 ⚪️➡️ 🏷, 📥 ☑ 🥉. |
|
||||
* **FastAPI** 🚮 🔗 📥 🌐 🎻 🔗 ➕1️⃣ 🥉 👆 🗄 ↩️ ✅ ⚫️ 🔗. 👉 🌌, 🎏 🈸 & 👩💻 💪 ⚙️ 👈 🎻 🔗 🔗, 🚚 👻 📟 ⚡ 🧰, ♒️. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
🏗 📨 🗄 👉 *➡ 🛠️* 🔜: |
|
||||
|
|
||||
```JSON hl_lines="3-12" |
|
||||
{ |
|
||||
"responses": { |
|
||||
"404": { |
|
||||
"description": "Additional Response", |
|
||||
"content": { |
|
||||
"application/json": { |
|
||||
"schema": { |
|
||||
"$ref": "#/components/schemas/Message" |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
"200": { |
|
||||
"description": "Successful Response", |
|
||||
"content": { |
|
||||
"application/json": { |
|
||||
"schema": { |
|
||||
"$ref": "#/components/schemas/Item" |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
"422": { |
|
||||
"description": "Validation Error", |
|
||||
"content": { |
|
||||
"application/json": { |
|
||||
"schema": { |
|
||||
"$ref": "#/components/schemas/HTTPValidationError" |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
🔗 🔗 ➕1️⃣ 🥉 🔘 🗄 🔗: |
|
||||
|
|
||||
```JSON hl_lines="4-16" |
|
||||
{ |
|
||||
"components": { |
|
||||
"schemas": { |
|
||||
"Message": { |
|
||||
"title": "Message", |
|
||||
"required": [ |
|
||||
"message" |
|
||||
], |
|
||||
"type": "object", |
|
||||
"properties": { |
|
||||
"message": { |
|
||||
"title": "Message", |
|
||||
"type": "string" |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
"Item": { |
|
||||
"title": "Item", |
|
||||
"required": [ |
|
||||
"id", |
|
||||
"value" |
|
||||
], |
|
||||
"type": "object", |
|
||||
"properties": { |
|
||||
"id": { |
|
||||
"title": "Id", |
|
||||
"type": "string" |
|
||||
}, |
|
||||
"value": { |
|
||||
"title": "Value", |
|
||||
"type": "string" |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
"ValidationError": { |
|
||||
"title": "ValidationError", |
|
||||
"required": [ |
|
||||
"loc", |
|
||||
"msg", |
|
||||
"type" |
|
||||
], |
|
||||
"type": "object", |
|
||||
"properties": { |
|
||||
"loc": { |
|
||||
"title": "Location", |
|
||||
"type": "array", |
|
||||
"items": { |
|
||||
"type": "string" |
|
||||
} |
|
||||
}, |
|
||||
"msg": { |
|
||||
"title": "Message", |
|
||||
"type": "string" |
|
||||
}, |
|
||||
"type": { |
|
||||
"title": "Error Type", |
|
||||
"type": "string" |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
"HTTPValidationError": { |
|
||||
"title": "HTTPValidationError", |
|
||||
"type": "object", |
|
||||
"properties": { |
|
||||
"detail": { |
|
||||
"title": "Detail", |
|
||||
"type": "array", |
|
||||
"items": { |
|
||||
"$ref": "#/components/schemas/ValidationError" |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
## 🌖 🔉 🆎 👑 📨 |
|
||||
|
|
||||
👆 💪 ⚙️ 👉 🎏 `responses` 🔢 🚮 🎏 🔉 🆎 🎏 👑 📨. |
|
||||
|
|
||||
🖼, 👆 💪 🚮 🌖 📻 🆎 `image/png`, 📣 👈 👆 *➡ 🛠️* 💪 📨 🎻 🎚 (⏮️ 📻 🆎 `application/json`) ⚖️ 🇩🇴 🖼: |
|
||||
|
|
||||
{* ../../docs_src/additional_responses/tutorial002.py hl[19:24,28] *} |
|
||||
|
|
||||
/// note |
|
||||
|
|
||||
👀 👈 👆 ✔️ 📨 🖼 ⚙️ `FileResponse` 🔗. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
/// info |
|
||||
|
|
||||
🚥 👆 ✔ 🎏 📻 🆎 🎯 👆 `responses` 🔢, FastAPI 🔜 🤔 📨 ✔️ 🎏 📻 🆎 👑 📨 🎓 (🔢 `application/json`). |
|
||||
|
|
||||
✋️ 🚥 👆 ✔️ ✔ 🛃 📨 🎓 ⏮️ `None` 🚮 📻 🆎, FastAPI 🔜 ⚙️ `application/json` 🙆 🌖 📨 👈 ✔️ 👨💼 🏷. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 🌀 ℹ |
|
||||
|
|
||||
👆 💪 🌀 📨 ℹ ⚪️➡️ 💗 🥉, 🔌 `response_model`, `status_code`, & `responses` 🔢. |
|
||||
|
|
||||
👆 💪 📣 `response_model`, ⚙️ 🔢 👔 📟 `200` (⚖️ 🛃 1️⃣ 🚥 👆 💪), & ⤴️ 📣 🌖 ℹ 👈 🎏 📨 `responses`, 🔗 🗄 🔗. |
|
||||
|
|
||||
**FastAPI** 🔜 🚧 🌖 ℹ ⚪️➡️ `responses`, & 🌀 ⚫️ ⏮️ 🎻 🔗 ⚪️➡️ 👆 🏷. |
|
||||
|
|
||||
🖼, 👆 💪 📣 📨 ⏮️ 👔 📟 `404` 👈 ⚙️ Pydantic 🏷 & ✔️ 🛃 `description`. |
|
||||
|
|
||||
& 📨 ⏮️ 👔 📟 `200` 👈 ⚙️ 👆 `response_model`, ✋️ 🔌 🛃 `example`: |
|
||||
|
|
||||
{* ../../docs_src/additional_responses/tutorial003.py hl[20:31] *} |
|
||||
|
|
||||
⚫️ 🔜 🌐 🌀 & 🔌 👆 🗄, & 🎦 🛠️ 🩺: |
|
||||
|
|
||||
<img src="/img/tutorial/additional-responses/image01.png"> |
|
||||
|
|
||||
## 🌀 🔢 📨 & 🛃 🕐 |
|
||||
|
|
||||
👆 💪 💚 ✔️ 🔁 📨 👈 ✔ 📚 *➡ 🛠️*, ✋️ 👆 💚 🌀 👫 ⏮️ 🛃 📨 💚 🔠 *➡ 🛠️*. |
|
||||
|
|
||||
📚 💼, 👆 💪 ⚙️ 🐍 ⚒ "🏗" `dict` ⏮️ `**dict_to_unpack`: |
|
||||
|
|
||||
```Python |
|
||||
old_dict = { |
|
||||
"old key": "old value", |
|
||||
"second old key": "second old value", |
|
||||
} |
|
||||
new_dict = {**old_dict, "new key": "new value"} |
|
||||
``` |
|
||||
|
|
||||
📥, `new_dict` 🔜 🔌 🌐 🔑-💲 👫 ⚪️➡️ `old_dict` ➕ 🆕 🔑-💲 👫: |
|
||||
|
|
||||
```Python |
|
||||
{ |
|
||||
"old key": "old value", |
|
||||
"second old key": "second old value", |
|
||||
"new key": "new value", |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
👆 💪 ⚙️ 👈 ⚒ 🏤-⚙️ 🔢 📨 👆 *➡ 🛠️* & 🌀 👫 ⏮️ 🌖 🛃 🕐. |
|
||||
|
|
||||
🖼: |
|
||||
|
|
||||
{* ../../docs_src/additional_responses/tutorial004.py hl[13:17,26] *} |
|
||||
|
|
||||
## 🌖 ℹ 🔃 🗄 📨 |
|
||||
|
|
||||
👀 ⚫️❔ ⚫️❔ 👆 💪 🔌 📨, 👆 💪 ✅ 👉 📄 🗄 🔧: |
|
||||
|
|
||||
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#responsesObject" class="external-link" target="_blank">🗄 📨 🎚</a>, ⚫️ 🔌 `Response Object`. |
|
||||
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#responseObject" class="external-link" target="_blank">🗄 📨 🎚</a>, 👆 💪 🔌 🕳 ⚪️➡️ 👉 🔗 🔠 📨 🔘 👆 `responses` 🔢. ✅ `description`, `headers`, `content` (🔘 👉 👈 👆 📣 🎏 🔉 🆎 & 🎻 🔗), & `links`. |
|
||||
@ -1,41 +0,0 @@ |
|||||
# 🌖 👔 📟 |
|
||||
|
|
||||
🔢, **FastAPI** 🔜 📨 📨 ⚙️ `JSONResponse`, 🚮 🎚 👆 📨 ⚪️➡️ 👆 *➡ 🛠️* 🔘 👈 `JSONResponse`. |
|
||||
|
|
||||
⚫️ 🔜 ⚙️ 🔢 👔 📟 ⚖️ 1️⃣ 👆 ⚒ 👆 *➡ 🛠️*. |
|
||||
|
|
||||
## 🌖 👔 📟 |
|
||||
|
|
||||
🚥 👆 💚 📨 🌖 👔 📟 ↖️ ⚪️➡️ 👑 1️⃣, 👆 💪 👈 🛬 `Response` 🔗, 💖 `JSONResponse`, & ⚒ 🌖 👔 📟 🔗. |
|
||||
|
|
||||
🖼, ➡️ 💬 👈 👆 💚 ✔️ *➡ 🛠️* 👈 ✔ ℹ 🏬, & 📨 🇺🇸🔍 👔 📟 2️⃣0️⃣0️⃣ "👌" 🕐❔ 🏆. |
|
||||
|
|
||||
✋️ 👆 💚 ⚫️ 🚫 🆕 🏬. & 🕐❔ 🏬 🚫 🔀 ⏭, ⚫️ ✍ 👫, & 📨 🇺🇸🔍 👔 📟 2️⃣0️⃣1️⃣ "✍". |
|
||||
|
|
||||
🏆 👈, 🗄 `JSONResponse`, & 📨 👆 🎚 📤 🔗, ⚒ `status_code` 👈 👆 💚: |
|
||||
|
|
||||
{* ../../docs_src/additional_status_codes/tutorial001.py hl[4,25] *} |
|
||||
|
|
||||
/// warning |
|
||||
|
|
||||
🕐❔ 👆 📨 `Response` 🔗, 💖 🖼 🔛, ⚫️ 🔜 📨 🔗. |
|
||||
|
|
||||
⚫️ 🏆 🚫 🎻 ⏮️ 🏷, ♒️. |
|
||||
|
|
||||
⚒ 💭 ⚫️ ✔️ 📊 👆 💚 ⚫️ ✔️, & 👈 💲 ☑ 🎻 (🚥 👆 ⚙️ `JSONResponse`). |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
/// note | 📡 ℹ |
|
||||
|
|
||||
👆 💪 ⚙️ `from starlette.responses import JSONResponse`. |
|
||||
|
|
||||
**FastAPI** 🚚 🎏 `starlette.responses` `fastapi.responses` 🏪 👆, 👩💻. ✋️ 🌅 💪 📨 👟 🔗 ⚪️➡️ 💃. 🎏 ⏮️ `status`. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 🗄 & 🛠️ 🩺 |
|
||||
|
|
||||
🚥 👆 📨 🌖 👔 📟 & 📨 🔗, 👫 🏆 🚫 🔌 🗄 🔗 (🛠️ 🩺), ↩️ FastAPI 🚫 ✔️ 🌌 💭 ⏪ ⚫️❔ 👆 🚶 📨. |
|
||||
|
|
||||
✋️ 👆 💪 📄 👈 👆 📟, ⚙️: [🌖 📨](additional-responses.md){.internal-link target=_blank}. |
|
||||
@ -1,65 +0,0 @@ |
|||||
# 🏧 🔗 |
|
||||
|
|
||||
## 🔗 🔗 |
|
||||
|
|
||||
🌐 🔗 👥 ✔️ 👀 🔧 🔢 ⚖️ 🎓. |
|
||||
|
|
||||
✋️ 📤 💪 💼 🌐❔ 👆 💚 💪 ⚒ 🔢 🔛 🔗, 🍵 ✔️ 📣 📚 🎏 🔢 ⚖️ 🎓. |
|
||||
|
|
||||
➡️ 🌈 👈 👥 💚 ✔️ 🔗 👈 ✅ 🚥 🔢 🔢 `q` 🔌 🔧 🎚. |
|
||||
|
|
||||
✋️ 👥 💚 💪 🔗 👈 🔧 🎚. |
|
||||
|
|
||||
## "🇧🇲" 👐 |
|
||||
|
|
||||
🐍 📤 🌌 ⚒ 👐 🎓 "🇧🇲". |
|
||||
|
|
||||
🚫 🎓 ⚫️ (❔ ⏪ 🇧🇲), ✋️ 👐 👈 🎓. |
|
||||
|
|
||||
👈, 👥 📣 👩🔬 `__call__`: |
|
||||
|
|
||||
{* ../../docs_src/dependencies/tutorial011.py hl[10] *} |
|
||||
|
|
||||
👉 💼, 👉 `__call__` ⚫️❔ **FastAPI** 🔜 ⚙️ ✅ 🌖 🔢 & 🎧-🔗, & 👉 ⚫️❔ 🔜 🤙 🚶♀️ 💲 🔢 👆 *➡ 🛠️ 🔢* ⏪. |
|
||||
|
|
||||
## 🔗 👐 |
|
||||
|
|
||||
& 🔜, 👥 💪 ⚙️ `__init__` 📣 🔢 👐 👈 👥 💪 ⚙️ "🔗" 🔗: |
|
||||
|
|
||||
{* ../../docs_src/dependencies/tutorial011.py hl[7] *} |
|
||||
|
|
||||
👉 💼, **FastAPI** 🏆 🚫 ⏱ 👆 ⚖️ 💅 🔃 `__init__`, 👥 🔜 ⚙️ ⚫️ 🔗 👆 📟. |
|
||||
|
|
||||
## ✍ 👐 |
|
||||
|
|
||||
👥 💪 ✍ 👐 👉 🎓 ⏮️: |
|
||||
|
|
||||
{* ../../docs_src/dependencies/tutorial011.py hl[16] *} |
|
||||
|
|
||||
& 👈 🌌 👥 💪 "🔗" 👆 🔗, 👈 🔜 ✔️ `"bar"` 🔘 ⚫️, 🔢 `checker.fixed_content`. |
|
||||
|
|
||||
## ⚙️ 👐 🔗 |
|
||||
|
|
||||
⤴️, 👥 💪 ⚙️ 👉 `checker` `Depends(checker)`, ↩️ `Depends(FixedContentQueryChecker)`, ↩️ 🔗 👐, `checker`, 🚫 🎓 ⚫️. |
|
||||
|
|
||||
& 🕐❔ ❎ 🔗, **FastAPI** 🔜 🤙 👉 `checker` 💖: |
|
||||
|
|
||||
```Python |
|
||||
checker(q="somequery") |
|
||||
``` |
|
||||
|
|
||||
...& 🚶♀️ ⚫️❔ 👈 📨 💲 🔗 👆 *➡ 🛠️ 🔢* 🔢 `fixed_content_included`: |
|
||||
|
|
||||
{* ../../docs_src/dependencies/tutorial011.py hl[20] *} |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
🌐 👉 💪 😑 🎭. & ⚫️ 💪 🚫 📶 🆑 ❔ ⚫️ ⚠. |
|
||||
|
|
||||
👫 🖼 😫 🙅, ✋️ 🎦 ❔ ⚫️ 🌐 👷. |
|
||||
|
|
||||
📃 🔃 💂♂, 📤 🚙 🔢 👈 🛠️ 👉 🎏 🌌. |
|
||||
|
|
||||
🚥 👆 🤔 🌐 👉, 👆 ⏪ 💭 ❔ 👈 🚙 🧰 💂♂ 👷 🔘. |
|
||||
|
|
||||
/// |
|
||||
@ -1,93 +0,0 @@ |
|||||
# 🔁 💯 |
|
||||
|
|
||||
👆 ✔️ ⏪ 👀 ❔ 💯 👆 **FastAPI** 🈸 ⚙️ 🚚 `TestClient`. 🆙 🔜, 👆 ✔️ 🕴 👀 ❔ ✍ 🔁 💯, 🍵 ⚙️ `async` 🔢. |
|
||||
|
|
||||
➖ 💪 ⚙️ 🔁 🔢 👆 💯 💪 ⚠, 🖼, 🕐❔ 👆 🔬 👆 💽 🔁. 🌈 👆 💚 💯 📨 📨 👆 FastAPI 🈸 & ⤴️ ✔ 👈 👆 👩💻 ⏪ ✍ ☑ 💽 💽, ⏪ ⚙️ 🔁 💽 🗃. |
|
||||
|
|
||||
➡️ 👀 ❔ 👥 💪 ⚒ 👈 👷. |
|
||||
|
|
||||
## pytest.mark.anyio |
|
||||
|
|
||||
🚥 👥 💚 🤙 🔁 🔢 👆 💯, 👆 💯 🔢 ✔️ 🔁. AnyIO 🚚 👌 📁 👉, 👈 ✔ 👥 ✔ 👈 💯 🔢 🤙 🔁. |
|
||||
|
|
||||
## 🇸🇲 |
|
||||
|
|
||||
🚥 👆 **FastAPI** 🈸 ⚙️ 😐 `def` 🔢 ↩️ `async def`, ⚫️ `async` 🈸 🔘. |
|
||||
|
|
||||
`TestClient` 🔨 🎱 🔘 🤙 🔁 FastAPI 🈸 👆 😐 `def` 💯 🔢, ⚙️ 🐩 ✳. ✋️ 👈 🎱 🚫 👷 🚫🔜 🕐❔ 👥 ⚙️ ⚫️ 🔘 🔁 🔢. 🏃 👆 💯 🔁, 👥 💪 🙅♂ 📏 ⚙️ `TestClient` 🔘 👆 💯 🔢. |
|
||||
|
|
||||
`TestClient` ⚓️ 🔛 <a href="https://www.python-httpx.org" class="external-link" target="_blank">🇸🇲</a>, & ↩️, 👥 💪 ⚙️ ⚫️ 🔗 💯 🛠️. |
|
||||
|
|
||||
## 🖼 |
|
||||
|
|
||||
🙅 🖼, ➡️ 🤔 📁 📊 🎏 1️⃣ 🔬 [🦏 🈸](../tutorial/bigger-applications.md){.internal-link target=_blank} & [🔬](../tutorial/testing.md){.internal-link target=_blank}: |
|
||||
|
|
||||
``` |
|
||||
. |
|
||||
├── app |
|
||||
│ ├── __init__.py |
|
||||
│ ├── main.py |
|
||||
│ └── test_main.py |
|
||||
``` |
|
||||
|
|
||||
📁 `main.py` 🔜 ✔️: |
|
||||
|
|
||||
{* ../../docs_src/async_tests/main.py *} |
|
||||
|
|
||||
📁 `test_main.py` 🔜 ✔️ 💯 `main.py`, ⚫️ 💪 👀 💖 👉 🔜: |
|
||||
|
|
||||
{* ../../docs_src/async_tests/test_main.py *} |
|
||||
|
|
||||
## 🏃 ⚫️ |
|
||||
|
|
||||
👆 💪 🏃 👆 💯 🐌 📨: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ pytest |
|
||||
|
|
||||
---> 100% |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
## ℹ |
|
||||
|
|
||||
📑 `@pytest.mark.anyio` 💬 ✳ 👈 👉 💯 🔢 🔜 🤙 🔁: |
|
||||
|
|
||||
{* ../../docs_src/async_tests/test_main.py hl[7] *} |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
🗒 👈 💯 🔢 🔜 `async def` ↩️ `def` ⏭ 🕐❔ ⚙️ `TestClient`. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
⤴️ 👥 💪 ✍ `AsyncClient` ⏮️ 📱, & 📨 🔁 📨 ⚫️, ⚙️ `await`. |
|
||||
|
|
||||
{* ../../docs_src/async_tests/test_main.py hl[9:12] *} |
|
||||
|
|
||||
👉 🌓: |
|
||||
|
|
||||
```Python |
|
||||
response = client.get('/') |
|
||||
``` |
|
||||
|
|
||||
...👈 👥 ⚙️ ⚒ 👆 📨 ⏮️ `TestClient`. |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
🗒 👈 👥 ⚙️ 🔁/⌛ ⏮️ 🆕 `AsyncClient` - 📨 🔁. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 🎏 🔁 🔢 🤙 |
|
||||
|
|
||||
🔬 🔢 🔜 🔁, 👆 💪 🔜 🤙 (& `await`) 🎏 `async` 🔢 ↖️ ⚪️➡️ 📨 📨 👆 FastAPI 🈸 👆 💯, ⚫️❔ 👆 🔜 🤙 👫 🙆 🙆 👆 📟. |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
🚥 👆 ⚔ `RuntimeError: Task attached to a different loop` 🕐❔ 🛠️ 🔁 🔢 🤙 👆 💯 (✅ 🕐❔ ⚙️ <a href="https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop" class="external-link" target="_blank">✳ MotorClient</a>) 💭 🔗 🎚 👈 💪 🎉 ➰ 🕴 🏞 🔁 🔢, ✅ `'@app.on_event("startup")` ⏲. |
|
||||
|
|
||||
/// |
|
||||
@ -1,359 +0,0 @@ |
|||||
# ⛅ 🗳 |
|
||||
|
|
||||
⚠, 👆 5️⃣📆 💪 ⚙️ **🗳** 💽 💖 Traefik ⚖️ 👌 ⏮️ 📳 👈 🚮 ➕ ➡ 🔡 👈 🚫 👀 👆 🈸. |
|
||||
|
|
||||
👫 💼 👆 💪 ⚙️ `root_path` 🔗 👆 🈸. |
|
||||
|
|
||||
`root_path` 🛠️ 🚚 🔫 🔧 (👈 FastAPI 🏗 🔛, 🔘 💃). |
|
||||
|
|
||||
`root_path` ⚙️ 🍵 👫 🎯 💼. |
|
||||
|
|
||||
& ⚫️ ⚙️ 🔘 🕐❔ 🗜 🎧-🈸. |
|
||||
|
|
||||
## 🗳 ⏮️ 🎞 ➡ 🔡 |
|
||||
|
|
||||
✔️ 🗳 ⏮️ 🎞 ➡ 🔡, 👉 💼, ⛓ 👈 👆 💪 📣 ➡ `/app` 👆 📟, ✋️ ⤴️, 👆 🚮 🧽 🔛 🔝 (🗳) 👈 🔜 🚮 👆 **FastAPI** 🈸 🔽 ➡ 💖 `/api/v1`. |
|
||||
|
|
||||
👉 💼, ⏮️ ➡ `/app` 🔜 🤙 🍦 `/api/v1/app`. |
|
||||
|
|
||||
✋️ 🌐 👆 📟 ✍ 🤔 📤 `/app`. |
|
||||
|
|
||||
& 🗳 🔜 **"❎"** **➡ 🔡** 🔛 ✈ ⏭ 📶 📨 Uvicorn, 🚧 👆 🈸 🤔 👈 ⚫️ 🍦 `/app`, 👈 👆 🚫 ✔️ ℹ 🌐 👆 📟 🔌 🔡 `/api/v1`. |
|
||||
|
|
||||
🆙 📥, 🌐 🔜 👷 🛎. |
|
||||
|
|
||||
✋️ ⤴️, 🕐❔ 👆 📂 🛠️ 🩺 🎚 (🕸), ⚫️ 🔜 ⌛ 🤚 🗄 🔗 `/openapi.json`, ↩️ `/api/v1/openapi.json`. |
|
||||
|
|
||||
, 🕸 (👈 🏃 🖥) 🔜 🔄 🏆 `/openapi.json` & 🚫🔜 💪 🤚 🗄 🔗. |
|
||||
|
|
||||
↩️ 👥 ✔️ 🗳 ⏮️ ➡ 🔡 `/api/v1` 👆 📱, 🕸 💪 ☕ 🗄 🔗 `/api/v1/openapi.json`. |
|
||||
|
|
||||
```mermaid |
|
||||
graph LR |
|
||||
|
|
||||
browser("Browser") |
|
||||
proxy["Proxy on http://0.0.0.0:9999/api/v1/app"] |
|
||||
server["Server on http://127.0.0.1:8000/app"] |
|
||||
|
|
||||
browser --> proxy |
|
||||
proxy --> server |
|
||||
``` |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
📢 `0.0.0.0` 🛎 ⚙️ ⛓ 👈 📋 👂 🔛 🌐 📢 💪 👈 🎰/💽. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
🩺 🎚 🔜 💪 🗄 🔗 📣 👈 👉 🛠️ `server` 🔎 `/api/v1` (⛅ 🗳). 🖼: |
|
||||
|
|
||||
```JSON hl_lines="4-8" |
|
||||
{ |
|
||||
"openapi": "3.0.2", |
|
||||
// More stuff here |
|
||||
"servers": [ |
|
||||
{ |
|
||||
"url": "/api/v1" |
|
||||
} |
|
||||
], |
|
||||
"paths": { |
|
||||
// More stuff here |
|
||||
} |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
👉 🖼, "🗳" 💪 🕳 💖 **Traefik**. & 💽 🔜 🕳 💖 **Uvicorn**, 🏃♂ 👆 FastAPI 🈸. |
|
||||
|
|
||||
### 🚚 `root_path` |
|
||||
|
|
||||
🏆 👉, 👆 💪 ⚙️ 📋 ⏸ 🎛 `--root-path` 💖: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ uvicorn main:app --root-path /api/v1 |
|
||||
|
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
🚥 👆 ⚙️ Hypercorn, ⚫️ ✔️ 🎛 `--root-path`. |
|
||||
|
|
||||
/// note | 📡 ℹ |
|
||||
|
|
||||
🔫 🔧 🔬 `root_path` 👉 ⚙️ 💼. |
|
||||
|
|
||||
& `--root-path` 📋 ⏸ 🎛 🚚 👈 `root_path`. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
### ✅ ⏮️ `root_path` |
|
||||
|
|
||||
👆 💪 🤚 ⏮️ `root_path` ⚙️ 👆 🈸 🔠 📨, ⚫️ 🍕 `scope` 📖 (👈 🍕 🔫 🔌). |
|
||||
|
|
||||
📥 👥 ✅ ⚫️ 📧 🎦 🎯. |
|
||||
|
|
||||
{* ../../docs_src/behind_a_proxy/tutorial001.py hl[8] *} |
|
||||
|
|
||||
⤴️, 🚥 👆 ▶️ Uvicorn ⏮️: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ uvicorn main:app --root-path /api/v1 |
|
||||
|
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
📨 🔜 🕳 💖: |
|
||||
|
|
||||
```JSON |
|
||||
{ |
|
||||
"message": "Hello World", |
|
||||
"root_path": "/api/v1" |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
### ⚒ `root_path` FastAPI 📱 |
|
||||
|
|
||||
👐, 🚥 👆 🚫 ✔️ 🌌 🚚 📋 ⏸ 🎛 💖 `--root-path` ⚖️ 🌓, 👆 💪 ⚒ `root_path` 🔢 🕐❔ 🏗 👆 FastAPI 📱: |
|
||||
|
|
||||
{* ../../docs_src/behind_a_proxy/tutorial002.py hl[3] *} |
|
||||
|
|
||||
🚶♀️ `root_path` `FastAPI` 🔜 🌓 🚶♀️ `--root-path` 📋 ⏸ 🎛 Uvicorn ⚖️ Hypercorn. |
|
||||
|
|
||||
### 🔃 `root_path` |
|
||||
|
|
||||
✔️ 🤯 👈 💽 (Uvicorn) 🏆 🚫 ⚙️ 👈 `root_path` 🕳 🙆 🌘 🚶♀️ ⚫️ 📱. |
|
||||
|
|
||||
✋️ 🚥 👆 🚶 ⏮️ 👆 🖥 <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000/app</a> 👆 🔜 👀 😐 📨: |
|
||||
|
|
||||
```JSON |
|
||||
{ |
|
||||
"message": "Hello World", |
|
||||
"root_path": "/api/v1" |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
, ⚫️ 🏆 🚫 ⌛ 🔐 `http://127.0.0.1:8000/api/v1/app`. |
|
||||
|
|
||||
Uvicorn 🔜 ⌛ 🗳 🔐 Uvicorn `http://127.0.0.1:8000/app`, & ⤴️ ⚫️ 🔜 🗳 🎯 🚮 ➕ `/api/v1` 🔡 🔛 🔝. |
|
||||
|
|
||||
## 🔃 🗳 ⏮️ 🎞 ➡ 🔡 |
|
||||
|
|
||||
✔️ 🤯 👈 🗳 ⏮️ 🎞 ➡ 🔡 🕴 1️⃣ 🌌 🔗 ⚫️. |
|
||||
|
|
||||
🎲 📚 💼 🔢 🔜 👈 🗳 🚫 ✔️ 🏚 ➡ 🔡. |
|
||||
|
|
||||
💼 💖 👈 (🍵 🎞 ➡ 🔡), 🗳 🔜 👂 🔛 🕳 💖 `https://myawesomeapp.com`, & ⤴️ 🚥 🖥 🚶 `https://myawesomeapp.com/api/v1/app` & 👆 💽 (✅ Uvicorn) 👂 🔛 `http://127.0.0.1:8000` 🗳 (🍵 🎞 ➡ 🔡) 🔜 🔐 Uvicorn 🎏 ➡: `http://127.0.0.1:8000/api/v1/app`. |
|
||||
|
|
||||
## 🔬 🌐 ⏮️ Traefik |
|
||||
|
|
||||
👆 💪 💪 🏃 🥼 🌐 ⏮️ 🎞 ➡ 🔡 ⚙️ <a href="https://docs.traefik.io/" class="external-link" target="_blank">Traefik</a>. |
|
||||
|
|
||||
<a href="https://github.com/containous/traefik/releases" class="external-link" target="_blank">⏬ Traefik</a>, ⚫️ 👁 💱, 👆 💪 ⚗ 🗜 📁 & 🏃 ⚫️ 🔗 ⚪️➡️ 📶. |
|
||||
|
|
||||
⤴️ ✍ 📁 `traefik.toml` ⏮️: |
|
||||
|
|
||||
```TOML hl_lines="3" |
|
||||
[entryPoints] |
|
||||
[entryPoints.http] |
|
||||
address = ":9999" |
|
||||
|
|
||||
[providers] |
|
||||
[providers.file] |
|
||||
filename = "routes.toml" |
|
||||
``` |
|
||||
|
|
||||
👉 💬 Traefik 👂 🔛 ⛴ 9️⃣9️⃣9️⃣9️⃣ & ⚙️ ➕1️⃣ 📁 `routes.toml`. |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
👥 ⚙️ ⛴ 9️⃣9️⃣9️⃣9️⃣ ↩️ 🐩 🇺🇸🔍 ⛴ 8️⃣0️⃣ 👈 👆 🚫 ✔️ 🏃 ⚫️ ⏮️ 📡 (`sudo`) 😌. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
🔜 ✍ 👈 🎏 📁 `routes.toml`: |
|
||||
|
|
||||
```TOML hl_lines="5 12 20" |
|
||||
[http] |
|
||||
[http.middlewares] |
|
||||
|
|
||||
[http.middlewares.api-stripprefix.stripPrefix] |
|
||||
prefixes = ["/api/v1"] |
|
||||
|
|
||||
[http.routers] |
|
||||
|
|
||||
[http.routers.app-http] |
|
||||
entryPoints = ["http"] |
|
||||
service = "app" |
|
||||
rule = "PathPrefix(`/api/v1`)" |
|
||||
middlewares = ["api-stripprefix"] |
|
||||
|
|
||||
[http.services] |
|
||||
|
|
||||
[http.services.app] |
|
||||
[http.services.app.loadBalancer] |
|
||||
[[http.services.app.loadBalancer.servers]] |
|
||||
url = "http://127.0.0.1:8000" |
|
||||
``` |
|
||||
|
|
||||
👉 📁 🔗 Traefik ⚙️ ➡ 🔡 `/api/v1`. |
|
||||
|
|
||||
& ⤴️ ⚫️ 🔜 ❎ 🚮 📨 👆 Uvicorn 🏃♂ 🔛 `http://127.0.0.1:8000`. |
|
||||
|
|
||||
🔜 ▶️ Traefik: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ ./traefik --configFile=traefik.toml |
|
||||
|
|
||||
INFO[0000] Configuration loaded from file: /home/user/awesomeapi/traefik.toml |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
& 🔜 ▶️ 👆 📱 ⏮️ Uvicorn, ⚙️ `--root-path` 🎛: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ uvicorn main:app --root-path /api/v1 |
|
||||
|
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
### ✅ 📨 |
|
||||
|
|
||||
🔜, 🚥 👆 🚶 📛 ⏮️ ⛴ Uvicorn: <a href="http://127.0.0.1:8000/app" class="external-link" target="_blank">http://127.0.0.1:8000/app</a>, 👆 🔜 👀 😐 📨: |
|
||||
|
|
||||
```JSON |
|
||||
{ |
|
||||
"message": "Hello World", |
|
||||
"root_path": "/api/v1" |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
👀 👈 ✋️ 👆 🔐 ⚫️ `http://127.0.0.1:8000/app` ⚫️ 🎦 `root_path` `/api/v1`, ✊ ⚪️➡️ 🎛 `--root-path`. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
& 🔜 📂 📛 ⏮️ ⛴ Traefik, ✅ ➡ 🔡: <a href="http://127.0.0.1:9999/api/v1/app" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/app</a>. |
|
||||
|
|
||||
👥 🤚 🎏 📨: |
|
||||
|
|
||||
```JSON |
|
||||
{ |
|
||||
"message": "Hello World", |
|
||||
"root_path": "/api/v1" |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
✋️ 👉 🕰 📛 ⏮️ 🔡 ➡ 🚚 🗳: `/api/v1`. |
|
||||
|
|
||||
↗️, 💭 📥 👈 👱 🔜 🔐 📱 🔘 🗳, ⏬ ⏮️ ➡ 🔡 `/app/v1` "☑" 1️⃣. |
|
||||
|
|
||||
& ⏬ 🍵 ➡ 🔡 (`http://127.0.0.1:8000/app`), 🚚 Uvicorn 🔗, 🔜 🎯 _🗳_ (Traefik) 🔐 ⚫️. |
|
||||
|
|
||||
👈 🎦 ❔ 🗳 (Traefik) ⚙️ ➡ 🔡 & ❔ 💽 (Uvicorn) ⚙️ `root_path` ⚪️➡️ 🎛 `--root-path`. |
|
||||
|
|
||||
### ✅ 🩺 🎚 |
|
||||
|
|
||||
✋️ 📥 🎊 🍕. 👶 |
|
||||
|
|
||||
"🛂" 🌌 🔐 📱 🔜 🔘 🗳 ⏮️ ➡ 🔡 👈 👥 🔬. , 👥 🔜 ⌛, 🚥 👆 🔄 🩺 🎚 🍦 Uvicorn 🔗, 🍵 ➡ 🔡 📛, ⚫️ 🏆 🚫 👷, ↩️ ⚫️ ⌛ 🔐 🔘 🗳. |
|
||||
|
|
||||
👆 💪 ✅ ⚫️ <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>: |
|
||||
|
|
||||
<img src="/img/tutorial/behind-a-proxy/image01.png"> |
|
||||
|
|
||||
✋️ 🚥 👥 🔐 🩺 🎚 "🛂" 📛 ⚙️ 🗳 ⏮️ ⛴ `9999`, `/api/v1/docs`, ⚫️ 👷 ☑ ❗ 👶 |
|
||||
|
|
||||
👆 💪 ✅ ⚫️ <a href="http://127.0.0.1:9999/api/v1/docs" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/docs</a>: |
|
||||
|
|
||||
<img src="/img/tutorial/behind-a-proxy/image02.png"> |
|
||||
|
|
||||
▶️️ 👥 💚 ⚫️. 👶 👶 |
|
||||
|
|
||||
👉 ↩️ FastAPI ⚙️ 👉 `root_path` ✍ 🔢 `server` 🗄 ⏮️ 📛 🚚 `root_path`. |
|
||||
|
|
||||
## 🌖 💽 |
|
||||
|
|
||||
/// warning |
|
||||
|
|
||||
👉 🌅 🏧 ⚙️ 💼. 💭 🆓 🚶 ⚫️. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
🔢, **FastAPI** 🔜 ✍ `server` 🗄 🔗 ⏮️ 📛 `root_path`. |
|
||||
|
|
||||
✋️ 👆 💪 🚚 🎏 🎛 `servers`, 🖼 🚥 👆 💚 *🎏* 🩺 🎚 🔗 ⏮️ 🏗 & 🏭 🌐. |
|
||||
|
|
||||
🚥 👆 🚶♀️ 🛃 📇 `servers` & 📤 `root_path` (↩️ 👆 🛠️ 👨❤👨 ⛅ 🗳), **FastAPI** 🔜 📩 "💽" ⏮️ 👉 `root_path` ▶️ 📇. |
|
||||
|
|
||||
🖼: |
|
||||
|
|
||||
{* ../../docs_src/behind_a_proxy/tutorial003.py hl[4:7] *} |
|
||||
|
|
||||
🔜 🏗 🗄 🔗 💖: |
|
||||
|
|
||||
```JSON hl_lines="5-7" |
|
||||
{ |
|
||||
"openapi": "3.0.2", |
|
||||
// More stuff here |
|
||||
"servers": [ |
|
||||
{ |
|
||||
"url": "/api/v1" |
|
||||
}, |
|
||||
{ |
|
||||
"url": "https://stag.example.com", |
|
||||
"description": "Staging environment" |
|
||||
}, |
|
||||
{ |
|
||||
"url": "https://prod.example.com", |
|
||||
"description": "Production environment" |
|
||||
} |
|
||||
], |
|
||||
"paths": { |
|
||||
// More stuff here |
|
||||
} |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
👀 🚘-🏗 💽 ⏮️ `url` 💲 `/api/v1`, ✊ ⚪️➡️ `root_path`. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
🩺 🎚 <a href="http://127.0.0.1:9999/api/v1/docs" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/docs</a> ⚫️ 🔜 👀 💖: |
|
||||
|
|
||||
<img src="/img/tutorial/behind-a-proxy/image03.png"> |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
🩺 🎚 🔜 🔗 ⏮️ 💽 👈 👆 🖊. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
### ❎ 🏧 💽 ⚪️➡️ `root_path` |
|
||||
|
|
||||
🚥 👆 🚫 💚 **FastAPI** 🔌 🏧 💽 ⚙️ `root_path`, 👆 💪 ⚙️ 🔢 `root_path_in_servers=False`: |
|
||||
|
|
||||
{* ../../docs_src/behind_a_proxy/tutorial004.py hl[9] *} |
|
||||
|
|
||||
& ⤴️ ⚫️ 🏆 🚫 🔌 ⚫️ 🗄 🔗. |
|
||||
|
|
||||
## 🗜 🎧-🈸 |
|
||||
|
|
||||
🚥 👆 💪 🗻 🎧-🈸 (🔬 [🎧 🈸 - 🗻](sub-applications.md){.internal-link target=_blank}) ⏪ ⚙️ 🗳 ⏮️ `root_path`, 👆 💪 ⚫️ 🛎, 👆 🔜 ⌛. |
|
||||
|
|
||||
FastAPI 🔜 🔘 ⚙️ `root_path` 🎆, ⚫️ 🔜 👷. 👶 |
|
||||
@ -1,303 +0,0 @@ |
|||||
# 🛃 📨 - 🕸, 🎏, 📁, 🎏 |
|
||||
|
|
||||
🔢, **FastAPI** 🔜 📨 📨 ⚙️ `JSONResponse`. |
|
||||
|
|
||||
👆 💪 🔐 ⚫️ 🛬 `Response` 🔗 👀 [📨 📨 🔗](response-directly.md){.internal-link target=_blank}. |
|
||||
|
|
||||
✋️ 🚥 👆 📨 `Response` 🔗, 📊 🏆 🚫 🔁 🗜, & 🧾 🏆 🚫 🔁 🏗 (🖼, 🔌 🎯 "📻 🆎", 🇺🇸🔍 🎚 `Content-Type` 🍕 🏗 🗄). |
|
||||
|
|
||||
✋️ 👆 💪 📣 `Response` 👈 👆 💚 ⚙️, *➡ 🛠️ 👨🎨*. |
|
||||
|
|
||||
🎚 👈 👆 📨 ⚪️➡️ 👆 *➡ 🛠️ 🔢* 🔜 🚮 🔘 👈 `Response`. |
|
||||
|
|
||||
& 🚥 👈 `Response` ✔️ 🎻 📻 🆎 (`application/json`), 💖 💼 ⏮️ `JSONResponse` & `UJSONResponse`, 💽 👆 📨 🔜 🔁 🗜 (& ⛽) ⏮️ 🙆 Pydantic `response_model` 👈 👆 📣 *➡ 🛠️ 👨🎨*. |
|
||||
|
|
||||
/// note |
|
||||
|
|
||||
🚥 👆 ⚙️ 📨 🎓 ⏮️ 🙅♂ 📻 🆎, FastAPI 🔜 ⌛ 👆 📨 ✔️ 🙅♂ 🎚, ⚫️ 🔜 🚫 📄 📨 📁 🚮 🏗 🗄 🩺. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## ⚙️ `ORJSONResponse` |
|
||||
|
|
||||
🖼, 🚥 👆 ✊ 🎭, 👆 💪 ❎ & ⚙️ <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a> & ⚒ 📨 `ORJSONResponse`. |
|
||||
|
|
||||
🗄 `Response` 🎓 (🎧-🎓) 👆 💚 ⚙️ & 📣 ⚫️ *➡ 🛠️ 👨🎨*. |
|
||||
|
|
||||
⭕ 📨, 📨 `Response` 🔗 🌅 ⏩ 🌘 🛬 📖. |
|
||||
|
|
||||
👉 ↩️ 🔢, FastAPI 🔜 ✔ 🔠 🏬 🔘 & ⚒ 💭 ⚫️ 🎻 ⏮️ 🎻, ⚙️ 🎏 [🎻 🔗 🔢](../tutorial/encoder.md){.internal-link target=_blank} 🔬 🔰. 👉 ⚫️❔ ✔ 👆 📨 **❌ 🎚**, 🖼 💽 🏷. |
|
||||
|
|
||||
✋️ 🚥 👆 🎯 👈 🎚 👈 👆 🛬 **🎻 ⏮️ 🎻**, 👆 💪 🚶♀️ ⚫️ 🔗 📨 🎓 & ❎ ➕ 🌥 👈 FastAPI 🔜 ✔️ 🚶♀️ 👆 📨 🎚 🔘 `jsonable_encoder` ⏭ 🚶♀️ ⚫️ 📨 🎓. |
|
||||
|
|
||||
{* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *} |
|
||||
|
|
||||
/// info |
|
||||
|
|
||||
🔢 `response_class` 🔜 ⚙️ 🔬 "📻 🆎" 📨. |
|
||||
|
|
||||
👉 💼, 🇺🇸🔍 🎚 `Content-Type` 🔜 ⚒ `application/json`. |
|
||||
|
|
||||
& ⚫️ 🔜 📄 ✅ 🗄. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
`ORJSONResponse` ⏳ 🕴 💪 FastAPI, 🚫 💃. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 🕸 📨 |
|
||||
|
|
||||
📨 📨 ⏮️ 🕸 🔗 ⚪️➡️ **FastAPI**, ⚙️ `HTMLResponse`. |
|
||||
|
|
||||
* 🗄 `HTMLResponse`. |
|
||||
* 🚶♀️ `HTMLResponse` 🔢 `response_class` 👆 *➡ 🛠️ 👨🎨*. |
|
||||
|
|
||||
{* ../../docs_src/custom_response/tutorial002.py hl[2,7] *} |
|
||||
|
|
||||
/// info |
|
||||
|
|
||||
🔢 `response_class` 🔜 ⚙️ 🔬 "📻 🆎" 📨. |
|
||||
|
|
||||
👉 💼, 🇺🇸🔍 🎚 `Content-Type` 🔜 ⚒ `text/html`. |
|
||||
|
|
||||
& ⚫️ 🔜 📄 ✅ 🗄. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
### 📨 `Response` |
|
||||
|
|
||||
👀 [📨 📨 🔗](response-directly.md){.internal-link target=_blank}, 👆 💪 🔐 📨 🔗 👆 *➡ 🛠️*, 🛬 ⚫️. |
|
||||
|
|
||||
🎏 🖼 ⚪️➡️ 🔛, 🛬 `HTMLResponse`, 💪 👀 💖: |
|
||||
|
|
||||
{* ../../docs_src/custom_response/tutorial003.py hl[2,7,19] *} |
|
||||
|
|
||||
/// warning |
|
||||
|
|
||||
`Response` 📨 🔗 👆 *➡ 🛠️ 🔢* 🏆 🚫 📄 🗄 (🖼, `Content-Type` 🏆 🚫 📄) & 🏆 🚫 ⭐ 🏧 🎓 🩺. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
/// info |
|
||||
|
|
||||
↗️, ☑ `Content-Type` 🎚, 👔 📟, ♒️, 🔜 👟 ⚪️➡️ `Response` 🎚 👆 📨. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
### 📄 🗄 & 🔐 `Response` |
|
||||
|
|
||||
🚥 👆 💚 🔐 📨 ⚪️➡️ 🔘 🔢 ✋️ 🎏 🕰 📄 "📻 🆎" 🗄, 👆 💪 ⚙️ `response_class` 🔢 & 📨 `Response` 🎚. |
|
||||
|
|
||||
`response_class` 🔜 ⤴️ ⚙️ 🕴 📄 🗄 *➡ 🛠️*, ✋️ 👆 `Response` 🔜 ⚙️. |
|
||||
|
|
||||
#### 📨 `HTMLResponse` 🔗 |
|
||||
|
|
||||
🖼, ⚫️ 💪 🕳 💖: |
|
||||
|
|
||||
{* ../../docs_src/custom_response/tutorial004.py hl[7,21,23] *} |
|
||||
|
|
||||
👉 🖼, 🔢 `generate_html_response()` ⏪ 🏗 & 📨 `Response` ↩️ 🛬 🕸 `str`. |
|
||||
|
|
||||
🛬 🏁 🤙 `generate_html_response()`, 👆 ⏪ 🛬 `Response` 👈 🔜 🔐 🔢 **FastAPI** 🎭. |
|
||||
|
|
||||
✋️ 👆 🚶♀️ `HTMLResponse` `response_class` 💁♂️, **FastAPI** 🔜 💭 ❔ 📄 ⚫️ 🗄 & 🎓 🩺 🕸 ⏮️ `text/html`: |
|
||||
|
|
||||
<img src="/img/tutorial/custom-response/image01.png"> |
|
||||
|
|
||||
## 💪 📨 |
|
||||
|
|
||||
📥 💪 📨. |
|
||||
|
|
||||
✔️ 🤯 👈 👆 💪 ⚙️ `Response` 📨 🕳 🙆, ⚖️ ✍ 🛃 🎧-🎓. |
|
||||
|
|
||||
/// note | 📡 ℹ |
|
||||
|
|
||||
👆 💪 ⚙️ `from starlette.responses import HTMLResponse`. |
|
||||
|
|
||||
**FastAPI** 🚚 🎏 `starlette.responses` `fastapi.responses` 🏪 👆, 👩💻. ✋️ 🌅 💪 📨 👟 🔗 ⚪️➡️ 💃. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
### `Response` |
|
||||
|
|
||||
👑 `Response` 🎓, 🌐 🎏 📨 😖 ⚪️➡️ ⚫️. |
|
||||
|
|
||||
👆 💪 📨 ⚫️ 🔗. |
|
||||
|
|
||||
⚫️ 🚫 📄 🔢: |
|
||||
|
|
||||
* `content` - `str` ⚖️ `bytes`. |
|
||||
* `status_code` - `int` 🇺🇸🔍 👔 📟. |
|
||||
* `headers` - `dict` 🎻. |
|
||||
* `media_type` - `str` 🤝 📻 🆎. 🤶 Ⓜ. `"text/html"`. |
|
||||
|
|
||||
FastAPI (🤙 💃) 🔜 🔁 🔌 🎚-📐 🎚. ⚫️ 🔜 🔌 🎚-🆎 🎚, ⚓️ 🔛 = & 🔁 = ✍ 🆎. |
|
||||
|
|
||||
{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *} |
|
||||
|
|
||||
### `HTMLResponse` |
|
||||
|
|
||||
✊ ✍ ⚖️ 🔢 & 📨 🕸 📨, 👆 ✍ 🔛. |
|
||||
|
|
||||
### `PlainTextResponse` |
|
||||
|
|
||||
✊ ✍ ⚖️ 🔢 & 📨 ✅ ✍ 📨. |
|
||||
|
|
||||
{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *} |
|
||||
|
|
||||
### `JSONResponse` |
|
||||
|
|
||||
✊ 💽 & 📨 `application/json` 🗜 📨. |
|
||||
|
|
||||
👉 🔢 📨 ⚙️ **FastAPI**, 👆 ✍ 🔛. |
|
||||
|
|
||||
### `ORJSONResponse` |
|
||||
|
|
||||
⏩ 🎛 🎻 📨 ⚙️ <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>, 👆 ✍ 🔛. |
|
||||
|
|
||||
### `UJSONResponse` |
|
||||
|
|
||||
🎛 🎻 📨 ⚙️ <a href="https://github.com/ultrajson/ultrajson" class="external-link" target="_blank">`ujson`</a>. |
|
||||
|
|
||||
/// warning |
|
||||
|
|
||||
`ujson` 🌘 💛 🌘 🐍 🏗-🛠️ ❔ ⚫️ 🍵 📐-💼. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *} |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
⚫️ 💪 👈 `ORJSONResponse` 💪 ⏩ 🎛. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
### `RedirectResponse` |
|
||||
|
|
||||
📨 🇺🇸🔍 ❎. ⚙️ 3️⃣0️⃣7️⃣ 👔 📟 (🍕 ❎) 🔢. |
|
||||
|
|
||||
👆 💪 📨 `RedirectResponse` 🔗: |
|
||||
|
|
||||
{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *} |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
⚖️ 👆 💪 ⚙️ ⚫️ `response_class` 🔢: |
|
||||
|
|
||||
|
|
||||
{* ../../docs_src/custom_response/tutorial006b.py hl[2,7,9] *} |
|
||||
|
|
||||
🚥 👆 👈, ⤴️ 👆 💪 📨 📛 🔗 ⚪️➡️ 👆 *➡ 🛠️* 🔢. |
|
||||
|
|
||||
👉 💼, `status_code` ⚙️ 🔜 🔢 1️⃣ `RedirectResponse`, ❔ `307`. |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
👆 💪 ⚙️ `status_code` 🔢 🌀 ⏮️ `response_class` 🔢: |
|
||||
|
|
||||
{* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *} |
|
||||
|
|
||||
### `StreamingResponse` |
|
||||
|
|
||||
✊ 🔁 🚂 ⚖️ 😐 🚂/🎻 & 🎏 📨 💪. |
|
||||
|
|
||||
{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *} |
|
||||
|
|
||||
#### ⚙️ `StreamingResponse` ⏮️ 📁-💖 🎚 |
|
||||
|
|
||||
🚥 👆 ✔️ 📁-💖 🎚 (✅ 🎚 📨 `open()`), 👆 💪 ✍ 🚂 🔢 🔁 🤭 👈 📁-💖 🎚. |
|
||||
|
|
||||
👈 🌌, 👆 🚫 ✔️ ✍ ⚫️ 🌐 🥇 💾, & 👆 💪 🚶♀️ 👈 🚂 🔢 `StreamingResponse`, & 📨 ⚫️. |
|
||||
|
|
||||
👉 🔌 📚 🗃 🔗 ⏮️ ☁ 💾, 📹 🏭, & 🎏. |
|
||||
|
|
||||
```{ .python .annotate hl_lines="2 10-12 14" } |
|
||||
{!../../docs_src/custom_response/tutorial008.py!} |
|
||||
``` |
|
||||
|
|
||||
1️⃣. 👉 🚂 🔢. ⚫️ "🚂 🔢" ↩️ ⚫️ 🔌 `yield` 📄 🔘. |
|
||||
2️⃣. ⚙️ `with` 🍫, 👥 ⚒ 💭 👈 📁-💖 🎚 📪 ⏮️ 🚂 🔢 🔨. , ⏮️ ⚫️ 🏁 📨 📨. |
|
||||
3️⃣. 👉 `yield from` 💬 🔢 🔁 🤭 👈 👜 🌟 `file_like`. & ⤴️, 🔠 🍕 🔁, 🌾 👈 🍕 👟 ⚪️➡️ 👉 🚂 🔢. |
|
||||
|
|
||||
, ⚫️ 🚂 🔢 👈 📨 "🏭" 👷 🕳 🙆 🔘. |
|
||||
|
|
||||
🔨 ⚫️ 👉 🌌, 👥 💪 🚮 ⚫️ `with` 🍫, & 👈 🌌, 🚚 👈 ⚫️ 📪 ⏮️ 🏁. |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
👀 👈 📥 👥 ⚙️ 🐩 `open()` 👈 🚫 🐕🦺 `async` & `await`, 👥 📣 ➡ 🛠️ ⏮️ 😐 `def`. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
### `FileResponse` |
|
||||
|
|
||||
🔁 🎏 📁 📨. |
|
||||
|
|
||||
✊ 🎏 ⚒ ❌ 🔗 🌘 🎏 📨 🆎: |
|
||||
|
|
||||
* `path` - 📁 📁 🎏. |
|
||||
* `headers` - 🙆 🛃 🎚 🔌, 📖. |
|
||||
* `media_type` - 🎻 🤝 📻 🆎. 🚥 🔢, 📁 ⚖️ ➡ 🔜 ⚙️ 🔑 📻 🆎. |
|
||||
* `filename` - 🚥 ⚒, 👉 🔜 🔌 📨 `Content-Disposition`. |
|
||||
|
|
||||
📁 📨 🔜 🔌 ☑ `Content-Length`, `Last-Modified` & `ETag` 🎚. |
|
||||
|
|
||||
{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *} |
|
||||
|
|
||||
👆 💪 ⚙️ `response_class` 🔢: |
|
||||
|
|
||||
{* ../../docs_src/custom_response/tutorial009b.py hl[2,8,10] *} |
|
||||
|
|
||||
👉 💼, 👆 💪 📨 📁 ➡ 🔗 ⚪️➡️ 👆 *➡ 🛠️* 🔢. |
|
||||
|
|
||||
## 🛃 📨 🎓 |
|
||||
|
|
||||
👆 💪 ✍ 👆 👍 🛃 📨 🎓, 😖 ⚪️➡️ `Response` & ⚙️ ⚫️. |
|
||||
|
|
||||
🖼, ➡️ 💬 👈 👆 💚 ⚙️ <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>, ✋️ ⏮️ 🛃 ⚒ 🚫 ⚙️ 🔌 `ORJSONResponse` 🎓. |
|
||||
|
|
||||
➡️ 💬 👆 💚 ⚫️ 📨 🔂 & 📁 🎻, 👆 💚 ⚙️ Orjson 🎛 `orjson.OPT_INDENT_2`. |
|
||||
|
|
||||
👆 💪 ✍ `CustomORJSONResponse`. 👑 👜 👆 ✔️ ✍ `Response.render(content)` 👩🔬 👈 📨 🎚 `bytes`: |
|
||||
|
|
||||
{* ../../docs_src/custom_response/tutorial009c.py hl[9:14,17] *} |
|
||||
|
|
||||
🔜 ↩️ 🛬: |
|
||||
|
|
||||
```json |
|
||||
{"message": "Hello World"} |
|
||||
``` |
|
||||
|
|
||||
...👉 📨 🔜 📨: |
|
||||
|
|
||||
```json |
|
||||
{ |
|
||||
"message": "Hello World" |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
↗️, 👆 🔜 🎲 🔎 🌅 👍 🌌 ✊ 📈 👉 🌘 ❕ 🎻. 👶 |
|
||||
|
|
||||
## 🔢 📨 🎓 |
|
||||
|
|
||||
🕐❔ 🏗 **FastAPI** 🎓 👐 ⚖️ `APIRouter` 👆 💪 ✔ ❔ 📨 🎓 ⚙️ 🔢. |
|
||||
|
|
||||
🔢 👈 🔬 👉 `default_response_class`. |
|
||||
|
|
||||
🖼 🔛, **FastAPI** 🔜 ⚙️ `ORJSONResponse` 🔢, 🌐 *➡ 🛠️*, ↩️ `JSONResponse`. |
|
||||
|
|
||||
{* ../../docs_src/custom_response/tutorial010.py hl[2,4] *} |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
👆 💪 🔐 `response_class` *➡ 🛠️* ⏭. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 🌖 🧾 |
|
||||
|
|
||||
👆 💪 📣 📻 🆎 & 📚 🎏 ℹ 🗄 ⚙️ `responses`: [🌖 📨 🗄](additional-responses.md){.internal-link target=_blank}. |
|
||||
@ -1,97 +0,0 @@ |
|||||
# ⚙️ 🎻 |
|
||||
|
|
||||
FastAPI 🏗 🔛 🔝 **Pydantic**, & 👤 ✔️ 🌏 👆 ❔ ⚙️ Pydantic 🏷 📣 📨 & 📨. |
|
||||
|
|
||||
✋️ FastAPI 🐕🦺 ⚙️ <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a> 🎏 🌌: |
|
||||
|
|
||||
{* ../../docs_src/dataclasses/tutorial001.py hl[1,7:12,19:20] *} |
|
||||
|
|
||||
👉 🐕🦺 👏 **Pydantic**, ⚫️ ✔️ <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">🔗 🐕🦺 `dataclasses`</a>. |
|
||||
|
|
||||
, ⏮️ 📟 🔛 👈 🚫 ⚙️ Pydantic 🎯, FastAPI ⚙️ Pydantic 🗜 📚 🐩 🎻 Pydantic 👍 🍛 🎻. |
|
||||
|
|
||||
& ↗️, ⚫️ 🐕🦺 🎏: |
|
||||
|
|
||||
* 💽 🔬 |
|
||||
* 💽 🛠️ |
|
||||
* 💽 🧾, ♒️. |
|
||||
|
|
||||
👉 👷 🎏 🌌 ⏮️ Pydantic 🏷. & ⚫️ 🤙 🏆 🎏 🌌 🔘, ⚙️ Pydantic. |
|
||||
|
|
||||
/// info |
|
||||
|
|
||||
✔️ 🤯 👈 🎻 💪 🚫 🌐 Pydantic 🏷 💪. |
|
||||
|
|
||||
, 👆 5️⃣📆 💪 ⚙️ Pydantic 🏷. |
|
||||
|
|
||||
✋️ 🚥 👆 ✔️ 📚 🎻 🤥 🤭, 👉 👌 🎱 ⚙️ 👫 🏋️ 🕸 🛠️ ⚙️ FastAPI. 👶 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 🎻 `response_model` |
|
||||
|
|
||||
👆 💪 ⚙️ `dataclasses` `response_model` 🔢: |
|
||||
|
|
||||
{* ../../docs_src/dataclasses/tutorial002.py hl[1,7:13,19] *} |
|
||||
|
|
||||
🎻 🔜 🔁 🗜 Pydantic 🎻. |
|
||||
|
|
||||
👉 🌌, 🚮 🔗 🔜 🎦 🆙 🛠️ 🩺 👩💻 🔢: |
|
||||
|
|
||||
<img src="/img/tutorial/dataclasses/image01.png"> |
|
||||
|
|
||||
## 🎻 🔁 📊 📊 |
|
||||
|
|
||||
👆 💪 🌀 `dataclasses` ⏮️ 🎏 🆎 ✍ ⚒ 🐦 📊 📊. |
|
||||
|
|
||||
💼, 👆 💪 ✔️ ⚙️ Pydantic ⏬ `dataclasses`. 🖼, 🚥 👆 ✔️ ❌ ⏮️ 🔁 🏗 🛠️ 🧾. |
|
||||
|
|
||||
👈 💼, 👆 💪 🎯 💱 🐩 `dataclasses` ⏮️ `pydantic.dataclasses`, ❔ 💧-♻: |
|
||||
|
|
||||
```{ .python .annotate hl_lines="1 5 8-11 14-17 23-25 28" } |
|
||||
{!../../docs_src/dataclasses/tutorial003.py!} |
|
||||
``` |
|
||||
|
|
||||
1️⃣. 👥 🗄 `field` ⚪️➡️ 🐩 `dataclasses`. |
|
||||
|
|
||||
2️⃣. `pydantic.dataclasses` 💧-♻ `dataclasses`. |
|
||||
|
|
||||
3️⃣. `Author` 🎻 🔌 📇 `Item` 🎻. |
|
||||
|
|
||||
4️⃣. `Author` 🎻 ⚙️ `response_model` 🔢. |
|
||||
|
|
||||
5️⃣. 👆 💪 ⚙️ 🎏 🐩 🆎 ✍ ⏮️ 🎻 📨 💪. |
|
||||
|
|
||||
👉 💼, ⚫️ 📇 `Item` 🎻. |
|
||||
|
|
||||
6️⃣. 📥 👥 🛬 📖 👈 🔌 `items` ❔ 📇 🎻. |
|
||||
|
|
||||
FastAPI 🎯 <abbr title="converting the data to a format that can be transmitted">✍</abbr> 💽 🎻. |
|
||||
|
|
||||
7️⃣. 📥 `response_model` ⚙️ 🆎 ✍ 📇 `Author` 🎻. |
|
||||
|
|
||||
🔄, 👆 💪 🌀 `dataclasses` ⏮️ 🐩 🆎 ✍. |
|
||||
|
|
||||
8️⃣. 👀 👈 👉 *➡ 🛠️ 🔢* ⚙️ 🥔 `def` ↩️ `async def`. |
|
||||
|
|
||||
🕧, FastAPI 👆 💪 🌀 `def` & `async def` 💪. |
|
||||
|
|
||||
🚥 👆 💪 ↗️ 🔃 🕐❔ ⚙️ ❔, ✅ 👅 📄 _"🏃 ❓" _ 🩺 🔃 <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank" class="internal-link">`async` & `await`</a>. |
|
||||
|
|
||||
9️⃣. 👉 *➡ 🛠️ 🔢* 🚫 🛬 🎻 (👐 ⚫️ 💪), ✋️ 📇 📖 ⏮️ 🔗 💽. |
|
||||
|
|
||||
FastAPI 🔜 ⚙️ `response_model` 🔢 (👈 🔌 🎻) 🗜 📨. |
|
||||
|
|
||||
👆 💪 🌀 `dataclasses` ⏮️ 🎏 🆎 ✍ 📚 🎏 🌀 📨 🏗 📊 📊. |
|
||||
|
|
||||
✅-📟 ✍ 💁♂ 🔛 👀 🌅 🎯 ℹ. |
|
||||
|
|
||||
## 💡 🌅 |
|
||||
|
|
||||
👆 💪 🌀 `dataclasses` ⏮️ 🎏 Pydantic 🏷, 😖 ⚪️➡️ 👫, 🔌 👫 👆 👍 🏷, ♒️. |
|
||||
|
|
||||
💡 🌅, ✅ <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/" class="external-link" target="_blank">Pydantic 🩺 🔃 🎻</a>. |
|
||||
|
|
||||
## ⏬ |
|
||||
|
|
||||
👉 💪 ↩️ FastAPI ⏬ `0.67.0`. 👶 |
|
||||
@ -1,163 +0,0 @@ |
|||||
# 🔆 🎉 |
|
||||
|
|
||||
👆 💪 🔬 ⚛ (📟) 👈 🔜 🛠️ ⏭ 🈸 **▶️ 🆙**. 👉 ⛓ 👈 👉 📟 🔜 🛠️ **🕐**, **⏭** 🈸 **▶️ 📨 📨**. |
|
||||
|
|
||||
🎏 🌌, 👆 💪 🔬 ⚛ (📟) 👈 🔜 🛠️ 🕐❔ 🈸 **🤫 🔽**. 👉 💼, 👉 📟 🔜 🛠️ **🕐**, **⏮️** ✔️ 🍵 🎲 **📚 📨**. |
|
||||
|
|
||||
↩️ 👉 📟 🛠️ ⏭ 🈸 **▶️** ✊ 📨, & ▶️️ ⏮️ ⚫️ **🏁** 🚚 📨, ⚫️ 📔 🎂 🈸 **🔆** (🔤 "🔆" 🔜 ⚠ 🥈 👶). |
|
||||
|
|
||||
👉 💪 📶 ⚠ ⚒ 🆙 **ℹ** 👈 👆 💪 ⚙️ 🎂 📱, & 👈 **💰** 👪 📨, &/⚖️ 👈 👆 💪 **🧹 🆙** ⏮️. 🖼, 💽 🔗 🎱, ⚖️ 🚚 🔗 🎰 🏫 🏷. |
|
||||
|
|
||||
## ⚙️ 💼 |
|
||||
|
|
||||
➡️ ▶️ ⏮️ 🖼 **⚙️ 💼** & ⤴️ 👀 ❔ ❎ ⚫️ ⏮️ 👉. |
|
||||
|
|
||||
➡️ 🌈 👈 👆 ✔️ **🎰 🏫 🏷** 👈 👆 💚 ⚙️ 🍵 📨. 👶 |
|
||||
|
|
||||
🎏 🏷 🔗 👪 📨,, ⚫️ 🚫 1️⃣ 🏷 📍 📨, ⚖️ 1️⃣ 📍 👩💻 ⚖️ 🕳 🎏. |
|
||||
|
|
||||
➡️ 🌈 👈 🚚 🏷 💪 **✊ 🕰**, ↩️ ⚫️ ✔️ ✍ 📚 **💽 ⚪️➡️ 💾**. 👆 🚫 💚 ⚫️ 🔠 📨. |
|
||||
|
|
||||
👆 💪 📐 ⚫️ 🔝 🎚 🕹/📁, ✋️ 👈 🔜 ⛓ 👈 ⚫️ 🔜 **📐 🏷** 🚥 👆 🏃♂ 🙅 🏧 💯, ⤴️ 👈 💯 🔜 **🐌** ↩️ ⚫️ 🔜 ✔️ ⌛ 🏷 📐 ⏭ 💆♂ 💪 🏃 🔬 🍕 📟. |
|
||||
|
|
||||
👈 ⚫️❔ 👥 🔜 ❎, ➡️ 📐 🏷 ⏭ 📨 🍵, ✋️ 🕴 ▶️️ ⏭ 🈸 ▶️ 📨 📨, 🚫 ⏪ 📟 ➖ 📐. |
|
||||
|
|
||||
## 🔆 |
|
||||
|
|
||||
👆 💪 🔬 👉 *🕴* & *🤫* ⚛ ⚙️ `lifespan` 🔢 `FastAPI` 📱, & "🔑 👨💼" (👤 🔜 🎦 👆 ⚫️❔ 👈 🥈). |
|
||||
|
|
||||
➡️ ▶️ ⏮️ 🖼 & ⤴️ 👀 ⚫️ ℹ. |
|
||||
|
|
||||
👥 ✍ 🔁 🔢 `lifespan()` ⏮️ `yield` 💖 👉: |
|
||||
|
|
||||
{* ../../docs_src/events/tutorial003.py hl[16,19] *} |
|
||||
|
|
||||
📥 👥 ⚖ 😥 *🕴* 🛠️ 🚚 🏷 🚮 (❌) 🏷 🔢 📖 ⏮️ 🎰 🏫 🏷 ⏭ `yield`. 👉 📟 🔜 🛠️ **⏭** 🈸 **▶️ ✊ 📨**, ⏮️ *🕴*. |
|
||||
|
|
||||
& ⤴️, ▶️️ ⏮️ `yield`, 👥 🚚 🏷. 👉 📟 🔜 🛠️ **⏮️** 🈸 **🏁 🚚 📨**, ▶️️ ⏭ *🤫*. 👉 💪, 🖼, 🚀 ℹ 💖 💾 ⚖️ 💻. |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
`shutdown` 🔜 🔨 🕐❔ 👆 **⛔️** 🈸. |
|
||||
|
|
||||
🎲 👆 💪 ▶️ 🆕 ⏬, ⚖️ 👆 🤚 🎡 🏃 ⚫️. 🤷 |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
### 🔆 🔢 |
|
||||
|
|
||||
🥇 👜 👀, 👈 👥 ⚖ 🔁 🔢 ⏮️ `yield`. 👉 📶 🎏 🔗 ⏮️ `yield`. |
|
||||
|
|
||||
{* ../../docs_src/events/tutorial003.py hl[14:19] *} |
|
||||
|
|
||||
🥇 🍕 🔢, ⏭ `yield`, 🔜 🛠️ **⏭** 🈸 ▶️. |
|
||||
|
|
||||
& 🍕 ⏮️ `yield` 🔜 🛠️ **⏮️** 🈸 ✔️ 🏁. |
|
||||
|
|
||||
### 🔁 🔑 👨💼 |
|
||||
|
|
||||
🚥 👆 ✅, 🔢 🎀 ⏮️ `@asynccontextmanager`. |
|
||||
|
|
||||
👈 🗜 🔢 🔘 🕳 🤙 "**🔁 🔑 👨💼**". |
|
||||
|
|
||||
{* ../../docs_src/events/tutorial003.py hl[1,13] *} |
|
||||
|
|
||||
**🔑 👨💼** 🐍 🕳 👈 👆 💪 ⚙️ `with` 📄, 🖼, `open()` 💪 ⚙️ 🔑 👨💼: |
|
||||
|
|
||||
```Python |
|
||||
with open("file.txt") as file: |
|
||||
file.read() |
|
||||
``` |
|
||||
|
|
||||
⏮️ ⏬ 🐍, 📤 **🔁 🔑 👨💼**. 👆 🔜 ⚙️ ⚫️ ⏮️ `async with`: |
|
||||
|
|
||||
```Python |
|
||||
async with lifespan(app): |
|
||||
await do_stuff() |
|
||||
``` |
|
||||
|
|
||||
🕐❔ 👆 ✍ 🔑 👨💼 ⚖️ 🔁 🔑 👨💼 💖 🔛, ⚫️❔ ⚫️ 🔨 👈, ⏭ 🛬 `with` 🍫, ⚫️ 🔜 🛠️ 📟 ⏭ `yield`, & ⏮️ ❎ `with` 🍫, ⚫️ 🔜 🛠️ 📟 ⏮️ `yield`. |
|
||||
|
|
||||
👆 📟 🖼 🔛, 👥 🚫 ⚙️ ⚫️ 🔗, ✋️ 👥 🚶♀️ ⚫️ FastAPI ⚫️ ⚙️ ⚫️. |
|
||||
|
|
||||
`lifespan` 🔢 `FastAPI` 📱 ✊ **🔁 🔑 👨💼**, 👥 💪 🚶♀️ 👆 🆕 `lifespan` 🔁 🔑 👨💼 ⚫️. |
|
||||
|
|
||||
{* ../../docs_src/events/tutorial003.py hl[22] *} |
|
||||
|
|
||||
## 🎛 🎉 (😢) |
|
||||
|
|
||||
/// warning |
|
||||
|
|
||||
👍 🌌 🍵 *🕴* & *🤫* ⚙️ `lifespan` 🔢 `FastAPI` 📱 🔬 🔛. |
|
||||
|
|
||||
👆 💪 🎲 🚶 👉 🍕. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
📤 🎛 🌌 🔬 👉 ⚛ 🛠️ ⏮️ *🕴* & ⏮️ *🤫*. |
|
||||
|
|
||||
👆 💪 🔬 🎉 🐕🦺 (🔢) 👈 💪 🛠️ ⏭ 🈸 ▶️ 🆙, ⚖️ 🕐❔ 🈸 🤫 🔽. |
|
||||
|
|
||||
👫 🔢 💪 📣 ⏮️ `async def` ⚖️ 😐 `def`. |
|
||||
|
|
||||
### `startup` 🎉 |
|
||||
|
|
||||
🚮 🔢 👈 🔜 🏃 ⏭ 🈸 ▶️, 📣 ⚫️ ⏮️ 🎉 `"startup"`: |
|
||||
|
|
||||
{* ../../docs_src/events/tutorial001.py hl[8] *} |
|
||||
|
|
||||
👉 💼, `startup` 🎉 🐕🦺 🔢 🔜 🔢 🏬 "💽" ( `dict`) ⏮️ 💲. |
|
||||
|
|
||||
👆 💪 🚮 🌅 🌘 1️⃣ 🎉 🐕🦺 🔢. |
|
||||
|
|
||||
& 👆 🈸 🏆 🚫 ▶️ 📨 📨 ⏭ 🌐 `startup` 🎉 🐕🦺 ✔️ 🏁. |
|
||||
|
|
||||
### `shutdown` 🎉 |
|
||||
|
|
||||
🚮 🔢 👈 🔜 🏃 🕐❔ 🈸 🤫 🔽, 📣 ⚫️ ⏮️ 🎉 `"shutdown"`: |
|
||||
|
|
||||
{* ../../docs_src/events/tutorial002.py hl[6] *} |
|
||||
|
|
||||
📥, `shutdown` 🎉 🐕🦺 🔢 🔜 ✍ ✍ ⏸ `"Application shutdown"` 📁 `log.txt`. |
|
||||
|
|
||||
/// info |
|
||||
|
|
||||
`open()` 🔢, `mode="a"` ⛓ "🎻",, ⏸ 🔜 🚮 ⏮️ ⚫️❔ 🔛 👈 📁, 🍵 📁 ⏮️ 🎚. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
👀 👈 👉 💼 👥 ⚙️ 🐩 🐍 `open()` 🔢 👈 🔗 ⏮️ 📁. |
|
||||
|
|
||||
, ⚫️ 🔌 👤/🅾 (🔢/🔢), 👈 🚚 "⌛" 👜 ✍ 💾. |
|
||||
|
|
||||
✋️ `open()` 🚫 ⚙️ `async` & `await`. |
|
||||
|
|
||||
, 👥 📣 🎉 🐕🦺 🔢 ⏮️ 🐩 `def` ↩️ `async def`. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
/// info |
|
||||
|
|
||||
👆 💪 ✍ 🌅 🔃 👫 🎉 🐕🦺 <a href="https://www.starlette.dev/events/" class="external-link" target="_blank">💃 🎉' 🩺</a>. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
### `startup` & `shutdown` 👯♂️ |
|
||||
|
|
||||
📤 ↕ 🤞 👈 ⚛ 👆 *🕴* & *🤫* 🔗, 👆 💪 💚 ▶️ 🕳 & ⤴️ 🏁 ⚫️, 📎 ℹ & ⤴️ 🚀 ⚫️, ♒️. |
|
||||
|
|
||||
🔨 👈 👽 🔢 👈 🚫 💰 ⚛ ⚖️ 🔢 👯♂️ 🌅 ⚠ 👆 🔜 💪 🏪 💲 🌐 🔢 ⚖️ 🎏 🎱. |
|
||||
|
|
||||
↩️ 👈, ⚫️ 🔜 👍 ↩️ ⚙️ `lifespan` 🔬 🔛. |
|
||||
|
|
||||
## 📡 ℹ |
|
||||
|
|
||||
📡 ℹ 😟 🤓. 👶 |
|
||||
|
|
||||
🔘, 🔫 📡 🔧, 👉 🍕 <a href="https://asgi.readthedocs.io/en/latest/specs/lifespan.html" class="external-link" target="_blank">🔆 🛠️</a>, & ⚫️ 🔬 🎉 🤙 `startup` & `shutdown`. |
|
||||
|
|
||||
## 🎧 🈸 |
|
||||
|
|
||||
👶 ✔️ 🤯 👈 👫 🔆 🎉 (🕴 & 🤫) 🔜 🕴 🛠️ 👑 🈸, 🚫 [🎧 🈸 - 🗻](sub-applications.md){.internal-link target=_blank}. |
|
||||
@ -1,238 +0,0 @@ |
|||||
# 🏗 👩💻 |
|
||||
|
|
||||
**FastAPI** ⚓️ 🔛 🗄 🔧, 👆 🤚 🏧 🔗 ⏮️ 📚 🧰, 🔌 🏧 🛠️ 🩺 (🚚 🦁 🎚). |
|
||||
|
|
||||
1️⃣ 🎯 📈 👈 🚫 🎯 ⭐ 👈 👆 💪 **🏗 👩💻** (🕣 🤙 <abbr title="Software Development Kits">**📱**</abbr> ) 👆 🛠️, 📚 🎏 **🛠️ 🇪🇸**. |
|
||||
|
|
||||
## 🗄 👩💻 🚂 |
|
||||
|
|
||||
📤 📚 🧰 🏗 👩💻 ⚪️➡️ **🗄**. |
|
||||
|
|
||||
⚠ 🧰 <a href="https://openapi-generator.tech/" class="external-link" target="_blank">🗄 🚂</a>. |
|
||||
|
|
||||
🚥 👆 🏗 **🕸**, 📶 😌 🎛 <a href="https://github.com/hey-api/openapi-ts" class="external-link" target="_blank">🗄-📕-🇦🇪</a>. |
|
||||
|
|
||||
## 🏗 📕 🕸 👩💻 |
|
||||
|
|
||||
➡️ ▶️ ⏮️ 🙅 FastAPI 🈸: |
|
||||
|
|
||||
{* ../../docs_src/generate_clients/tutorial001.py hl[9:11,14:15,18,19,23] *} |
|
||||
|
|
||||
👀 👈 *➡ 🛠️* 🔬 🏷 👫 ⚙️ 📨 🚀 & 📨 🚀, ⚙️ 🏷 `Item` & `ResponseMessage`. |
|
||||
|
|
||||
### 🛠️ 🩺 |
|
||||
|
|
||||
🚥 👆 🚶 🛠️ 🩺, 👆 🔜 👀 👈 ⚫️ ✔️ **🔗** 📊 📨 📨 & 📨 📨: |
|
||||
|
|
||||
<img src="/img/tutorial/generate-clients/image01.png"> |
|
||||
|
|
||||
👆 💪 👀 👈 🔗 ↩️ 👫 📣 ⏮️ 🏷 📱. |
|
||||
|
|
||||
👈 ℹ 💪 📱 **🗄 🔗**, & ⤴️ 🎦 🛠️ 🩺 (🦁 🎚). |
|
||||
|
|
||||
& 👈 🎏 ℹ ⚪️➡️ 🏷 👈 🔌 🗄 ⚫️❔ 💪 ⚙️ **🏗 👩💻 📟**. |
|
||||
|
|
||||
### 🏗 📕 👩💻 |
|
||||
|
|
||||
🔜 👈 👥 ✔️ 📱 ⏮️ 🏷, 👥 💪 🏗 👩💻 📟 🕸. |
|
||||
|
|
||||
#### ❎ `openapi-ts` |
|
||||
|
|
||||
👆 💪 ❎ `openapi-ts` 👆 🕸 📟 ⏮️: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ npm install @hey-api/openapi-ts --save-dev |
|
||||
|
|
||||
---> 100% |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
#### 🏗 👩💻 📟 |
|
||||
|
|
||||
🏗 👩💻 📟 👆 💪 ⚙️ 📋 ⏸ 🈸 `openapi-ts` 👈 🔜 🔜 ❎. |
|
||||
|
|
||||
↩️ ⚫️ ❎ 🇧🇿 🏗, 👆 🎲 🚫🔜 💪 🤙 👈 📋 🔗, ✋️ 👆 🔜 🚮 ⚫️ 🔛 👆 `package.json` 📁. |
|
||||
|
|
||||
⚫️ 💪 👀 💖 👉: |
|
||||
|
|
||||
```JSON hl_lines="7" |
|
||||
{ |
|
||||
"name": "frontend-app", |
|
||||
"version": "1.0.0", |
|
||||
"description": "", |
|
||||
"main": "index.js", |
|
||||
"scripts": { |
|
||||
"generate-client": "openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios" |
|
||||
}, |
|
||||
"author": "", |
|
||||
"license": "", |
|
||||
"devDependencies": { |
|
||||
"@hey-api/openapi-ts": "^0.27.38", |
|
||||
"typescript": "^4.6.2" |
|
||||
} |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
⏮️ ✔️ 👈 ☕ `generate-client` ✍ 📤, 👆 💪 🏃 ⚫️ ⏮️: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ npm run generate-client |
|
||||
|
|
||||
[email protected] generate-client /home/user/code/frontend-app |
|
||||
> openapi-ts --input http://localhost:8000/openapi.json --output ./src/client --client axios |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
👈 📋 🔜 🏗 📟 `./src/client` & 🔜 ⚙️ `axios` (🕸 🇺🇸🔍 🗃) 🔘. |
|
||||
|
|
||||
### 🔄 👅 👩💻 📟 |
|
||||
|
|
||||
🔜 👆 💪 🗄 & ⚙️ 👩💻 📟, ⚫️ 💪 👀 💖 👉, 👀 👈 👆 🤚 ✍ 👩🔬: |
|
||||
|
|
||||
<img src="/img/tutorial/generate-clients/image02.png"> |
|
||||
|
|
||||
👆 🔜 🤚 ✍ 🚀 📨: |
|
||||
|
|
||||
<img src="/img/tutorial/generate-clients/image03.png"> |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
👀 ✍ `name` & `price`, 👈 🔬 FastAPI 🈸, `Item` 🏷. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
👆 🔜 ✔️ ⏸ ❌ 📊 👈 👆 📨: |
|
||||
|
|
||||
<img src="/img/tutorial/generate-clients/image04.png"> |
|
||||
|
|
||||
📨 🎚 🔜 ✔️ ✍: |
|
||||
|
|
||||
<img src="/img/tutorial/generate-clients/image05.png"> |
|
||||
|
|
||||
## FastAPI 📱 ⏮️ 🔖 |
|
||||
|
|
||||
📚 💼 👆 FastAPI 📱 🔜 🦏, & 👆 🔜 🎲 ⚙️ 🔖 🎏 🎏 👪 *➡ 🛠️*. |
|
||||
|
|
||||
🖼, 👆 💪 ✔️ 📄 **🏬** & ➕1️⃣ 📄 **👩💻**, & 👫 💪 👽 🔖: |
|
||||
|
|
||||
|
|
||||
{* ../../docs_src/generate_clients/tutorial002.py hl[23,28,36] *} |
|
||||
|
|
||||
### 🏗 📕 👩💻 ⏮️ 🔖 |
|
||||
|
|
||||
🚥 👆 🏗 👩💻 FastAPI 📱 ⚙️ 🔖, ⚫️ 🔜 🛎 🎏 👩💻 📟 ⚓️ 🔛 🔖. |
|
||||
|
|
||||
👉 🌌 👆 🔜 💪 ✔️ 👜 ✔ & 👪 ☑ 👩💻 📟: |
|
||||
|
|
||||
<img src="/img/tutorial/generate-clients/image06.png"> |
|
||||
|
|
||||
👉 💼 👆 ✔️: |
|
||||
|
|
||||
* `ItemsService` |
|
||||
* `UsersService` |
|
||||
|
|
||||
### 👩💻 👩🔬 📛 |
|
||||
|
|
||||
▶️️ 🔜 🏗 👩🔬 📛 💖 `createItemItemsPost` 🚫 👀 📶 🧹: |
|
||||
|
|
||||
```TypeScript |
|
||||
ItemsService.createItemItemsPost({name: "Plumbus", price: 5}) |
|
||||
``` |
|
||||
|
|
||||
...👈 ↩️ 👩💻 🚂 ⚙️ 🗄 🔗 **🛠️ 🆔** 🔠 *➡ 🛠️*. |
|
||||
|
|
||||
🗄 🚚 👈 🔠 🛠️ 🆔 😍 🤭 🌐 *➡ 🛠️*, FastAPI ⚙️ **🔢 📛**, **➡**, & **🇺🇸🔍 👩🔬/🛠️** 🏗 👈 🛠️ 🆔, ↩️ 👈 🌌 ⚫️ 💪 ⚒ 💭 👈 🛠️ 🆔 😍. |
|
||||
|
|
||||
✋️ 👤 🔜 🎦 👆 ❔ 📉 👈 ⏭. 👶 |
|
||||
|
|
||||
## 🛃 🛠️ 🆔 & 👍 👩🔬 📛 |
|
||||
|
|
||||
👆 💪 **🔀** 🌌 👫 🛠️ 🆔 **🏗** ⚒ 👫 🙅 & ✔️ **🙅 👩🔬 📛** 👩💻. |
|
||||
|
|
||||
👉 💼 👆 🔜 ✔️ 🚚 👈 🔠 🛠️ 🆔 **😍** 🎏 🌌. |
|
||||
|
|
||||
🖼, 👆 💪 ⚒ 💭 👈 🔠 *➡ 🛠️* ✔️ 🔖, & ⤴️ 🏗 🛠️ 🆔 ⚓️ 🔛 **🔖** & *➡ 🛠️* **📛** (🔢 📛). |
|
||||
|
|
||||
### 🛃 🏗 😍 🆔 🔢 |
|
||||
|
|
||||
FastAPI ⚙️ **😍 🆔** 🔠 *➡ 🛠️*, ⚫️ ⚙️ **🛠️ 🆔** & 📛 🙆 💪 🛃 🏷, 📨 ⚖️ 📨. |
|
||||
|
|
||||
👆 💪 🛃 👈 🔢. ⚫️ ✊ `APIRoute` & 🔢 🎻. |
|
||||
|
|
||||
🖼, 📥 ⚫️ ⚙️ 🥇 🔖 (👆 🔜 🎲 ✔️ 🕴 1️⃣ 🔖) & *➡ 🛠️* 📛 (🔢 📛). |
|
||||
|
|
||||
👆 💪 ⤴️ 🚶♀️ 👈 🛃 🔢 **FastAPI** `generate_unique_id_function` 🔢: |
|
||||
|
|
||||
{* ../../docs_src/generate_clients/tutorial003.py hl[8:9,12] *} |
|
||||
|
|
||||
### 🏗 📕 👩💻 ⏮️ 🛃 🛠️ 🆔 |
|
||||
|
|
||||
🔜 🚥 👆 🏗 👩💻 🔄, 👆 🔜 👀 👈 ⚫️ ✔️ 📉 👩🔬 📛: |
|
||||
|
|
||||
<img src="/img/tutorial/generate-clients/image07.png"> |
|
||||
|
|
||||
👆 👀, 👩🔬 📛 🔜 ✔️ 🔖 & ⤴️ 🔢 📛, 🔜 👫 🚫 🔌 ℹ ⚪️➡️ 📛 ➡ & 🇺🇸🔍 🛠️. |
|
||||
|
|
||||
### 🗜 🗄 🔧 👩💻 🚂 |
|
||||
|
|
||||
🏗 📟 ✔️ **❎ ℹ**. |
|
||||
|
|
||||
👥 ⏪ 💭 👈 👉 👩🔬 🔗 **🏬** ↩️ 👈 🔤 `ItemsService` (✊ ⚪️➡️ 🔖), ✋️ 👥 ✔️ 📛 🔡 👩🔬 📛 💁♂️. 👶 |
|
||||
|
|
||||
👥 🔜 🎲 💚 🚧 ⚫️ 🗄 🏢, 👈 🔜 🚚 👈 🛠️ 🆔 **😍**. |
|
||||
|
|
||||
✋️ 🏗 👩💻 👥 💪 **🔀** 🗄 🛠️ 🆔 ▶️️ ⏭ 🏭 👩💻, ⚒ 👈 👩🔬 📛 👌 & **🧹**. |
|
||||
|
|
||||
👥 💪 ⏬ 🗄 🎻 📁 `openapi.json` & ⤴️ 👥 💪 **❎ 👈 🔡 🔖** ⏮️ ✍ 💖 👉: |
|
||||
|
|
||||
{* ../../docs_src/generate_clients/tutorial004.py *} |
|
||||
|
|
||||
⏮️ 👈, 🛠️ 🆔 🔜 📁 ⚪️➡️ 👜 💖 `items-get_items` `get_items`, 👈 🌌 👩💻 🚂 💪 🏗 🙅 👩🔬 📛. |
|
||||
|
|
||||
### 🏗 📕 👩💻 ⏮️ 🗜 🗄 |
|
||||
|
|
||||
🔜 🔚 🏁 📁 `openapi.json`, 👆 🔜 🔀 `package.json` ⚙️ 👈 🇧🇿 📁, 🖼: |
|
||||
|
|
||||
```JSON hl_lines="7" |
|
||||
{ |
|
||||
"name": "frontend-app", |
|
||||
"version": "1.0.0", |
|
||||
"description": "", |
|
||||
"main": "index.js", |
|
||||
"scripts": { |
|
||||
"generate-client": "openapi-ts --input ./openapi.json --output ./src/client --client axios" |
|
||||
}, |
|
||||
"author": "", |
|
||||
"license": "", |
|
||||
"devDependencies": { |
|
||||
"@hey-api/openapi-ts": "^0.27.38", |
|
||||
"typescript": "^4.6.2" |
|
||||
} |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
⏮️ 🏭 🆕 👩💻, 👆 🔜 🔜 ✔️ **🧹 👩🔬 📛**, ⏮️ 🌐 **✍**, **⏸ ❌**, ♒️: |
|
||||
|
|
||||
<img src="/img/tutorial/generate-clients/image08.png"> |
|
||||
|
|
||||
## 💰 |
|
||||
|
|
||||
🕐❔ ⚙️ 🔁 🏗 👩💻 👆 🔜 **✍** : |
|
||||
|
|
||||
* 👩🔬. |
|
||||
* 📨 🚀 💪, 🔢 🔢, ♒️. |
|
||||
* 📨 🚀. |
|
||||
|
|
||||
👆 🔜 ✔️ **⏸ ❌** 🌐. |
|
||||
|
|
||||
& 🕐❔ 👆 ℹ 👩💻 📟, & **♻** 🕸, ⚫️ 🔜 ✔️ 🙆 🆕 *➡ 🛠️* 💪 👩🔬, 🗝 🕐 ❎, & 🙆 🎏 🔀 🔜 🎨 🔛 🏗 📟. 👶 |
|
||||
|
|
||||
👉 ⛓ 👈 🚥 🕳 🔀 ⚫️ 🔜 **🎨** 🔛 👩💻 📟 🔁. & 🚥 👆 **🏗** 👩💻 ⚫️ 🔜 ❌ 👅 🚥 👆 ✔️ 🙆 **🔖** 📊 ⚙️. |
|
||||
|
|
||||
, 👆 🔜 **🔍 📚 ❌** 📶 ⏪ 🛠️ 🛵 ↩️ ✔️ ⌛ ❌ 🎦 🆙 👆 🏁 👩💻 🏭 & ⤴️ 🔄 ℹ 🌐❔ ⚠. 👶 |
|
||||
@ -1,27 +0,0 @@ |
|||||
# 🏧 👩💻 🦮 |
|
||||
|
|
||||
## 🌖 ⚒ |
|
||||
|
|
||||
👑 [🔰 - 👩💻 🦮](../tutorial/index.md){.internal-link target=_blank} 🔜 🥃 🤝 👆 🎫 🔘 🌐 👑 ⚒ **FastAPI**. |
|
||||
|
|
||||
⏭ 📄 👆 🔜 👀 🎏 🎛, 📳, & 🌖 ⚒. |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
⏭ 📄 **🚫 🎯 "🏧"**. |
|
||||
|
|
||||
& ⚫️ 💪 👈 👆 ⚙️ 💼, ⚗ 1️⃣ 👫. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## ✍ 🔰 🥇 |
|
||||
|
|
||||
👆 💪 ⚙️ 🏆 ⚒ **FastAPI** ⏮️ 💡 ⚪️➡️ 👑 [🔰 - 👩💻 🦮](../tutorial/index.md){.internal-link target=_blank}. |
|
||||
|
|
||||
& ⏭ 📄 🤔 👆 ⏪ ✍ ⚫️, & 🤔 👈 👆 💭 👈 👑 💭. |
|
||||
|
|
||||
## 🏎.🅾 ↗️ |
|
||||
|
|
||||
🚥 👆 🔜 💖 ✊ 🏧-🔰 ↗️ 🔗 👉 📄 🩺, 👆 💪 💚 ✅: <a href="https://testdriven.io/courses/tdd-fastapi/" class="external-link" target="_blank">💯-💾 🛠️ ⏮️ FastAPI & ☁</a> **🏎.🅾**. |
|
||||
|
|
||||
👫 ⏳ 🩸 1️⃣0️⃣ 💯 🌐 💰 🛠️ **FastAPI**. 👶 👶 |
|
||||
@ -1,95 +0,0 @@ |
|||||
# 🏧 🛠️ |
|
||||
|
|
||||
👑 🔰 👆 ✍ ❔ 🚮 [🛃 🛠️](../tutorial/middleware.md){.internal-link target=_blank} 👆 🈸. |
|
||||
|
|
||||
& ⤴️ 👆 ✍ ❔ 🍵 [⚜ ⏮️ `CORSMiddleware`](../tutorial/cors.md){.internal-link target=_blank}. |
|
||||
|
|
||||
👉 📄 👥 🔜 👀 ❔ ⚙️ 🎏 🛠️. |
|
||||
|
|
||||
## ❎ 🔫 🛠️ |
|
||||
|
|
||||
**FastAPI** ⚓️ 🔛 💃 & 🛠️ <abbr title="Asynchronous Server Gateway Interface">🔫</abbr> 🔧, 👆 💪 ⚙️ 🙆 🔫 🛠️. |
|
||||
|
|
||||
🛠️ 🚫 ✔️ ⚒ FastAPI ⚖️ 💃 👷, 📏 ⚫️ ⏩ 🔫 🔌. |
|
||||
|
|
||||
🏢, 🔫 🛠️ 🎓 👈 ⌛ 📨 🔫 📱 🥇 ❌. |
|
||||
|
|
||||
, 🧾 🥉-🥳 🔫 🛠️ 👫 🔜 🎲 💬 👆 🕳 💖: |
|
||||
|
|
||||
```Python |
|
||||
from unicorn import UnicornMiddleware |
|
||||
|
|
||||
app = SomeASGIApp() |
|
||||
|
|
||||
new_app = UnicornMiddleware(app, some_config="rainbow") |
|
||||
``` |
|
||||
|
|
||||
✋️ FastAPI (🤙 💃) 🚚 🙅 🌌 ⚫️ 👈 ⚒ 💭 👈 🔗 🛠️ 🍵 💽 ❌ & 🛃 ⚠ 🐕🦺 👷 ☑. |
|
||||
|
|
||||
👈, 👆 ⚙️ `app.add_middleware()` (🖼 ⚜). |
|
||||
|
|
||||
```Python |
|
||||
from fastapi import FastAPI |
|
||||
from unicorn import UnicornMiddleware |
|
||||
|
|
||||
app = FastAPI() |
|
||||
|
|
||||
app.add_middleware(UnicornMiddleware, some_config="rainbow") |
|
||||
``` |
|
||||
|
|
||||
`app.add_middleware()` 📨 🛠️ 🎓 🥇 ❌ & 🙆 🌖 ❌ 🚶♀️ 🛠️. |
|
||||
|
|
||||
## 🛠️ 🛠️ |
|
||||
|
|
||||
**FastAPI** 🔌 📚 🛠️ ⚠ ⚙️ 💼, 👥 🔜 👀 ⏭ ❔ ⚙️ 👫. |
|
||||
|
|
||||
/// note | 📡 ℹ |
|
||||
|
|
||||
⏭ 🖼, 👆 💪 ⚙️ `from starlette.middleware.something import SomethingMiddleware`. |
|
||||
|
|
||||
**FastAPI** 🚚 📚 🛠️ `fastapi.middleware` 🏪 👆, 👩💻. ✋️ 🌅 💪 🛠️ 👟 🔗 ⚪️➡️ 💃. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## `HTTPSRedirectMiddleware` |
|
||||
|
|
||||
🛠️ 👈 🌐 📨 📨 🔜 👯♂️ `https` ⚖️ `wss`. |
|
||||
|
|
||||
🙆 📨 📨 `http` ⚖️ `ws` 🔜 ❎ 🔐 ⚖ ↩️. |
|
||||
|
|
||||
{* ../../docs_src/advanced_middleware/tutorial001.py hl[2,6] *} |
|
||||
|
|
||||
## `TrustedHostMiddleware` |
|
||||
|
|
||||
🛠️ 👈 🌐 📨 📨 ✔️ ☑ ⚒ `Host` 🎚, ✔ 💂♂ 🛡 🇺🇸🔍 🦠 🎚 👊. |
|
||||
|
|
||||
{* ../../docs_src/advanced_middleware/tutorial002.py hl[2,6:8] *} |
|
||||
|
|
||||
📄 ❌ 🐕🦺: |
|
||||
|
|
||||
* `allowed_hosts` - 📇 🆔 📛 👈 🔜 ✔ 📛. 🃏 🆔 ✅ `*.example.com` 🐕🦺 🎀 📁. ✔ 🙆 📛 👯♂️ ⚙️ `allowed_hosts=["*"]` ⚖️ 🚫 🛠️. |
|
||||
|
|
||||
🚥 📨 📨 🔨 🚫 ✔ ☑ ⤴️ `400` 📨 🔜 📨. |
|
||||
|
|
||||
## `GZipMiddleware` |
|
||||
|
|
||||
🍵 🗜 📨 🙆 📨 👈 🔌 `"gzip"` `Accept-Encoding` 🎚. |
|
||||
|
|
||||
🛠️ 🔜 🍵 👯♂️ 🐩 & 🎥 📨. |
|
||||
|
|
||||
{* ../../docs_src/advanced_middleware/tutorial003.py hl[2,6] *} |
|
||||
|
|
||||
📄 ❌ 🐕🦺: |
|
||||
|
|
||||
* `minimum_size` - 🚫 🗜 📨 👈 🤪 🌘 👉 💯 📐 🔢. 🔢 `500`. |
|
||||
|
|
||||
## 🎏 🛠️ |
|
||||
|
|
||||
📤 📚 🎏 🔫 🛠️. |
|
||||
|
|
||||
🖼: |
|
||||
|
|
||||
* <a href="https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py" class="external-link" target="_blank">Uvicorn `ProxyHeadersMiddleware`</a> |
|
||||
* <a href="https://github.com/florimondmanca/msgpack-asgi" class="external-link" target="_blank">🇸🇲</a> |
|
||||
|
|
||||
👀 🎏 💪 🛠️ ✅ <a href="https://www.starlette.dev/middleware/" class="external-link" target="_blank">💃 🛠️ 🩺</a> & <a href="https://github.com/florimondmanca/awesome-asgi" class="external-link" target="_blank">🔫 👌 📇</a>. |
|
||||
@ -1,186 +0,0 @@ |
|||||
# 🗄 ⏲ |
|
||||
|
|
||||
👆 💪 ✍ 🛠️ ⏮️ *➡ 🛠️* 👈 💪 ⏲ 📨 *🔢 🛠️* ✍ 👱 🙆 (🎲 🎏 👩💻 👈 🔜 *⚙️* 👆 🛠️). |
|
||||
|
|
||||
🛠️ 👈 🔨 🕐❔ 👆 🛠️ 📱 🤙 *🔢 🛠️* 📛 "⏲". ↩️ 🖥 👈 🔢 👩💻 ✍ 📨 📨 👆 🛠️ & ⤴️ 👆 🛠️ *🤙 🔙*, 📨 📨 *🔢 🛠️* (👈 🎲 ✍ 🎏 👩💻). |
|
||||
|
|
||||
👉 💼, 👆 💪 💚 📄 ❔ 👈 🔢 🛠️ *🔜* 👀 💖. ⚫️❔ *➡ 🛠️* ⚫️ 🔜 ✔️, ⚫️❔ 💪 ⚫️ 🔜 ⌛, ⚫️❔ 📨 ⚫️ 🔜 📨, ♒️. |
|
||||
|
|
||||
## 📱 ⏮️ ⏲ |
|
||||
|
|
||||
➡️ 👀 🌐 👉 ⏮️ 🖼. |
|
||||
|
|
||||
🌈 👆 🛠️ 📱 👈 ✔ 🏗 🧾. |
|
||||
|
|
||||
👉 🧾 🔜 ✔️ `id`, `title` (📦), `customer`, & `total`. |
|
||||
|
|
||||
👩💻 👆 🛠️ (🔢 👩💻) 🔜 ✍ 🧾 👆 🛠️ ⏮️ 🏤 📨. |
|
||||
|
|
||||
⤴️ 👆 🛠️ 🔜 (➡️ 🌈): |
|
||||
|
|
||||
* 📨 🧾 🕴 🔢 👩💻. |
|
||||
* 📈 💸. |
|
||||
* 📨 📨 🔙 🛠️ 👩💻 (🔢 👩💻). |
|
||||
* 👉 🔜 🔨 📨 🏤 📨 (⚪️➡️ *👆 🛠️*) *🔢 🛠️* 🚚 👈 🔢 👩💻 (👉 "⏲"). |
|
||||
|
|
||||
## 😐 **FastAPI** 📱 |
|
||||
|
|
||||
➡️ 🥇 👀 ❔ 😐 🛠️ 📱 🔜 👀 💖 ⏭ ❎ ⏲. |
|
||||
|
|
||||
⚫️ 🔜 ✔️ *➡ 🛠️* 👈 🔜 📨 `Invoice` 💪, & 🔢 🔢 `callback_url` 👈 🔜 🔌 📛 ⏲. |
|
||||
|
|
||||
👉 🍕 📶 😐, 🌅 📟 🎲 ⏪ 😰 👆: |
|
||||
|
|
||||
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[9:13,36:53] *} |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
`callback_url` 🔢 🔢 ⚙️ Pydantic <a href="https://docs.pydantic.dev/latest/concepts/types/#urls" class="external-link" target="_blank">📛</a> 🆎. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
🕴 🆕 👜 `callbacks=messages_callback_router.routes` ❌ *➡ 🛠️ 👨🎨*. 👥 🔜 👀 ⚫️❔ 👈 ⏭. |
|
||||
|
|
||||
## 🔬 ⏲ |
|
||||
|
|
||||
☑ ⏲ 📟 🔜 🪀 🙇 🔛 👆 👍 🛠️ 📱. |
|
||||
|
|
||||
& ⚫️ 🔜 🎲 🪀 📚 ⚪️➡️ 1️⃣ 📱 ⏭. |
|
||||
|
|
||||
⚫️ 💪 1️⃣ ⚖️ 2️⃣ ⏸ 📟, 💖: |
|
||||
|
|
||||
```Python |
|
||||
callback_url = "https://example.com/api/v1/invoices/events/" |
|
||||
httpx.post(callback_url, json={"description": "Invoice paid", "paid": True}) |
|
||||
``` |
|
||||
|
|
||||
✋️ 🎲 🏆 ⚠ 🍕 ⏲ ⚒ 💭 👈 👆 🛠️ 👩💻 (🔢 👩💻) 🛠️ *🔢 🛠️* ☑, 🛄 💽 👈 *👆 🛠️* 🔜 📨 📨 💪 ⏲, ♒️. |
|
||||
|
|
||||
, ⚫️❔ 👥 🔜 ⏭ 🚮 📟 📄 ❔ 👈 *🔢 🛠️* 🔜 👀 💖 📨 ⏲ ⚪️➡️ *👆 🛠️*. |
|
||||
|
|
||||
👈 🧾 🔜 🎦 🆙 🦁 🎚 `/docs` 👆 🛠️, & ⚫️ 🔜 ➡️ 🔢 👩💻 💭 ❔ 🏗 *🔢 🛠️*. |
|
||||
|
|
||||
👉 🖼 🚫 🛠️ ⏲ ⚫️ (👈 💪 ⏸ 📟), 🕴 🧾 🍕. |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
☑ ⏲ 🇺🇸🔍 📨. |
|
||||
|
|
||||
🕐❔ 🛠️ ⏲ 👆, 👆 💪 ⚙️ 🕳 💖 <a href="https://www.python-httpx.org" class="external-link" target="_blank">🇸🇲</a> ⚖️ <a href="https://requests.readthedocs.io/" class="external-link" target="_blank">📨</a>. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## ✍ ⏲ 🧾 📟 |
|
||||
|
|
||||
👉 📟 🏆 🚫 🛠️ 👆 📱, 👥 🕴 💪 ⚫️ *📄* ❔ 👈 *🔢 🛠️* 🔜 👀 💖. |
|
||||
|
|
||||
✋️, 👆 ⏪ 💭 ❔ 💪 ✍ 🏧 🧾 🛠️ ⏮️ **FastAPI**. |
|
||||
|
|
||||
👥 🔜 ⚙️ 👈 🎏 💡 📄 ❔ *🔢 🛠️* 🔜 👀 💖... 🏗 *➡ 🛠️(Ⓜ)* 👈 🔢 🛠️ 🔜 🛠️ (🕐 👆 🛠️ 🔜 🤙). |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
🕐❔ ✍ 📟 📄 ⏲, ⚫️ 💪 ⚠ 🌈 👈 👆 👈 *🔢 👩💻*. & 👈 👆 ⏳ 🛠️ *🔢 🛠️*, 🚫 *👆 🛠️*. |
|
||||
|
|
||||
🍕 🛠️ 👉 ☝ 🎑 ( *🔢 👩💻*) 💪 ℹ 👆 💭 💖 ⚫️ 🌅 ⭐ 🌐❔ 🚮 🔢, Pydantic 🏷 💪, 📨, ♒️. 👈 *🔢 🛠️*. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
### ✍ ⏲ `APIRouter` |
|
||||
|
|
||||
🥇 ✍ 🆕 `APIRouter` 👈 🔜 🔌 1️⃣ ⚖️ 🌅 ⏲. |
|
||||
|
|
||||
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[3,25] *} |
|
||||
|
|
||||
### ✍ ⏲ *➡ 🛠️* |
|
||||
|
|
||||
✍ ⏲ *➡ 🛠️* ⚙️ 🎏 `APIRouter` 👆 ✍ 🔛. |
|
||||
|
|
||||
⚫️ 🔜 👀 💖 😐 FastAPI *➡ 🛠️*: |
|
||||
|
|
||||
* ⚫️ 🔜 🎲 ✔️ 📄 💪 ⚫️ 🔜 📨, ✅ `body: InvoiceEvent`. |
|
||||
* & ⚫️ 💪 ✔️ 📄 📨 ⚫️ 🔜 📨, ✅ `response_model=InvoiceEventReceived`. |
|
||||
|
|
||||
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[16:18,21:22,28:32] *} |
|
||||
|
|
||||
📤 2️⃣ 👑 🔺 ⚪️➡️ 😐 *➡ 🛠️*: |
|
||||
|
|
||||
* ⚫️ 🚫 💪 ✔️ 🙆 ☑ 📟, ↩️ 👆 📱 🔜 🙅 🤙 👉 📟. ⚫️ 🕴 ⚙️ 📄 *🔢 🛠️*. , 🔢 💪 ✔️ `pass`. |
|
||||
* *➡* 💪 🔌 <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#key-expression" class="external-link" target="_blank">🗄 3️⃣ 🧬</a> (👀 🌖 🔛) 🌐❔ ⚫️ 💪 ⚙️ 🔢 ⏮️ 🔢 & 🍕 ⏮️ 📨 📨 *👆 🛠️*. |
|
||||
|
|
||||
### ⏲ ➡ 🧬 |
|
||||
|
|
||||
⏲ *➡* 💪 ✔️ <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#key-expression" class="external-link" target="_blank">🗄 3️⃣ 🧬</a> 👈 💪 🔌 🍕 ⏮️ 📨 📨 *👆 🛠️*. |
|
||||
|
|
||||
👉 💼, ⚫️ `str`: |
|
||||
|
|
||||
```Python |
|
||||
"{$callback_url}/invoices/{$request.body.id}" |
|
||||
``` |
|
||||
|
|
||||
, 🚥 👆 🛠️ 👩💻 (🔢 👩💻) 📨 📨 *👆 🛠️* : |
|
||||
|
|
||||
``` |
|
||||
https://yourapi.com/invoices/?callback_url=https://www.external.org/events |
|
||||
``` |
|
||||
|
|
||||
⏮️ 🎻 💪: |
|
||||
|
|
||||
```JSON |
|
||||
{ |
|
||||
"id": "2expen51ve", |
|
||||
"customer": "Mr. Richie Rich", |
|
||||
"total": "9999" |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
⤴️ *👆 🛠️* 🔜 🛠️ 🧾, & ☝ ⏪, 📨 ⏲ 📨 `callback_url` ( *🔢 🛠️*): |
|
||||
|
|
||||
``` |
|
||||
https://www.external.org/events/invoices/2expen51ve |
|
||||
``` |
|
||||
|
|
||||
⏮️ 🎻 💪 ⚗ 🕳 💖: |
|
||||
|
|
||||
```JSON |
|
||||
{ |
|
||||
"description": "Payment celebration", |
|
||||
"paid": true |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
& ⚫️ 🔜 ⌛ 📨 ⚪️➡️ 👈 *🔢 🛠️* ⏮️ 🎻 💪 💖: |
|
||||
|
|
||||
```JSON |
|
||||
{ |
|
||||
"ok": true |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
👀 ❔ ⏲ 📛 ⚙️ 🔌 📛 📨 🔢 🔢 `callback_url` (`https://www.external.org/events`) & 🧾 `id` ⚪️➡️ 🔘 🎻 💪 (`2expen51ve`). |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
### 🚮 ⏲ 📻 |
|
||||
|
|
||||
👉 ☝ 👆 ✔️ *⏲ ➡ 🛠️(Ⓜ)* 💪 (1️⃣(Ⓜ) 👈 *🔢 👩💻* 🔜 🛠️ *🔢 🛠️*) ⏲ 📻 👆 ✍ 🔛. |
|
||||
|
|
||||
🔜 ⚙️ 🔢 `callbacks` *👆 🛠️ ➡ 🛠️ 👨🎨* 🚶♀️ 🔢 `.routes` (👈 🤙 `list` 🛣/*➡ 🛠️*) ⚪️➡️ 👈 ⏲ 📻: |
|
||||
|
|
||||
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[35] *} |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
👀 👈 👆 🚫 🚶♀️ 📻 ⚫️ (`invoices_callback_router`) `callback=`, ✋️ 🔢 `.routes`, `invoices_callback_router.routes`. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
### ✅ 🩺 |
|
||||
|
|
||||
🔜 👆 💪 ▶️ 👆 📱 ⏮️ Uvicorn & 🚶 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>. |
|
||||
|
|
||||
👆 🔜 👀 👆 🩺 ✅ "⏲" 📄 👆 *➡ 🛠️* 👈 🎦 ❔ *🔢 🛠️* 🔜 👀 💖: |
|
||||
|
|
||||
<img src="/img/tutorial/openapi-callbacks/image01.png"> |
|
||||
@ -1,172 +0,0 @@ |
|||||
# ➡ 🛠️ 🏧 📳 |
|
||||
|
|
||||
## 🗄 { |
|
||||
|
|
||||
/// warning |
|
||||
|
|
||||
🚥 👆 🚫 "🕴" 🗄, 👆 🎲 🚫 💪 👉. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
👆 💪 ⚒ 🗄 `operationId` ⚙️ 👆 *➡ 🛠️* ⏮️ 🔢 `operation_id`. |
|
||||
|
|
||||
👆 🔜 ✔️ ⚒ 💭 👈 ⚫️ 😍 🔠 🛠️. |
|
||||
|
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *} |
|
||||
|
|
||||
### ⚙️ *➡ 🛠️ 🔢* 📛 { |
|
||||
|
|
||||
🚥 👆 💚 ⚙️ 👆 🔗' 🔢 📛 `operationId`Ⓜ, 👆 💪 🔁 🤭 🌐 👫 & 🔐 🔠 *➡ 🛠️* `operation_id` ⚙️ 👫 `APIRoute.name`. |
|
||||
|
|
||||
👆 🔜 ⚫️ ⏮️ ❎ 🌐 👆 *➡ 🛠️*. |
|
||||
|
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2,12:21,24] *} |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
🚥 👆 ❎ 🤙 `app.openapi()`, 👆 🔜 ℹ `operationId`Ⓜ ⏭ 👈. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
/// warning |
|
||||
|
|
||||
🚥 👆 👉, 👆 ✔️ ⚒ 💭 🔠 1️⃣ 👆 *➡ 🛠️ 🔢* ✔️ 😍 📛. |
|
||||
|
|
||||
🚥 👫 🎏 🕹 (🐍 📁). |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 🚫 ⚪️➡️ 🗄 |
|
||||
|
|
||||
🚫 *➡ 🛠️* ⚪️➡️ 🏗 🗄 🔗 (& ➡️, ⚪️➡️ 🏧 🧾 ⚙️), ⚙️ 🔢 `include_in_schema` & ⚒ ⚫️ `False`: |
|
||||
|
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *} |
|
||||
|
|
||||
## 🏧 📛 ⚪️➡️ #️⃣ |
|
||||
|
|
||||
👆 💪 📉 ⏸ ⚙️ ⚪️➡️ #️⃣ *➡ 🛠️ 🔢* 🗄. |
|
||||
|
|
||||
❎ `\f` (😖 "📨 🍼" 🦹) 🤕 **FastAPI** 🔁 🔢 ⚙️ 🗄 👉 ☝. |
|
||||
|
|
||||
⚫️ 🏆 🚫 🎦 🆙 🧾, ✋️ 🎏 🧰 (✅ 🐉) 🔜 💪 ⚙️ 🎂. |
|
||||
|
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *} |
|
||||
|
|
||||
## 🌖 📨 |
|
||||
|
|
||||
👆 🎲 ✔️ 👀 ❔ 📣 `response_model` & `status_code` *➡ 🛠️*. |
|
||||
|
|
||||
👈 🔬 🗃 🔃 👑 📨 *➡ 🛠️*. |
|
||||
|
|
||||
👆 💪 📣 🌖 📨 ⏮️ 👫 🏷, 👔 📟, ♒️. |
|
||||
|
|
||||
📤 🎂 📃 📥 🧾 🔃 ⚫️, 👆 💪 ✍ ⚫️ [🌖 📨 🗄](additional-responses.md){.internal-link target=_blank}. |
|
||||
|
|
||||
## 🗄 ➕ |
|
||||
|
|
||||
🕐❔ 👆 📣 *➡ 🛠️* 👆 🈸, **FastAPI** 🔁 🏗 🔗 🗃 🔃 👈 *➡ 🛠️* 🔌 🗄 🔗. |
|
||||
|
|
||||
/// note | 📡 ℹ |
|
||||
|
|
||||
🗄 🔧 ⚫️ 🤙 <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object" class="external-link" target="_blank">🛠️ 🎚</a>. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
⚫️ ✔️ 🌐 ℹ 🔃 *➡ 🛠️* & ⚙️ 🏗 🏧 🧾. |
|
||||
|
|
||||
⚫️ 🔌 `tags`, `parameters`, `requestBody`, `responses`, ♒️. |
|
||||
|
|
||||
👉 *➡ 🛠️*-🎯 🗄 🔗 🛎 🏗 🔁 **FastAPI**, ✋️ 👆 💪 ↔ ⚫️. |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
👉 🔅 🎚 ↔ ☝. |
|
||||
|
|
||||
🚥 👆 🕴 💪 📣 🌖 📨, 🌅 🏪 🌌 ⚫️ ⏮️ [🌖 📨 🗄](additional-responses.md){.internal-link target=_blank}. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
👆 💪 ↔ 🗄 🔗 *➡ 🛠️* ⚙️ 🔢 `openapi_extra`. |
|
||||
|
|
||||
### 🗄 ↔ |
|
||||
|
|
||||
👉 `openapi_extra` 💪 👍, 🖼, 📣 [🗄 ↔](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions): |
|
||||
|
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial005.py hl[6] *} |
|
||||
|
|
||||
🚥 👆 📂 🏧 🛠️ 🩺, 👆 ↔ 🔜 🎦 🆙 🔝 🎯 *➡ 🛠️*. |
|
||||
|
|
||||
<img src="/img/tutorial/path-operation-advanced-configuration/image01.png"> |
|
||||
|
|
||||
& 🚥 👆 👀 📉 🗄 ( `/openapi.json` 👆 🛠️), 👆 🔜 👀 👆 ↔ 🍕 🎯 *➡ 🛠️* 💁♂️: |
|
||||
|
|
||||
```JSON hl_lines="22" |
|
||||
{ |
|
||||
"openapi": "3.0.2", |
|
||||
"info": { |
|
||||
"title": "FastAPI", |
|
||||
"version": "0.1.0" |
|
||||
}, |
|
||||
"paths": { |
|
||||
"/items/": { |
|
||||
"get": { |
|
||||
"summary": "Read Items", |
|
||||
"operationId": "read_items_items__get", |
|
||||
"responses": { |
|
||||
"200": { |
|
||||
"description": "Successful Response", |
|
||||
"content": { |
|
||||
"application/json": { |
|
||||
"schema": {} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
"x-aperture-labs-portal": "blue" |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
### 🛃 🗄 *➡ 🛠️* 🔗 |
|
||||
|
|
||||
📖 `openapi_extra` 🔜 🙇 🔗 ⏮️ 🔁 🏗 🗄 🔗 *➡ 🛠️*. |
|
||||
|
|
||||
, 👆 💪 🚮 🌖 💽 🔁 🏗 🔗. |
|
||||
|
|
||||
🖼, 👆 💪 💭 ✍ & ✔ 📨 ⏮️ 👆 👍 📟, 🍵 ⚙️ 🏧 ⚒ FastAPI ⏮️ Pydantic, ✋️ 👆 💪 💚 🔬 📨 🗄 🔗. |
|
||||
|
|
||||
👆 💪 👈 ⏮️ `openapi_extra`: |
|
||||
|
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[20:37,39:40] *} |
|
||||
|
|
||||
👉 🖼, 👥 🚫 📣 🙆 Pydantic 🏷. 👐, 📨 💪 🚫 <abbr title="converted from some plain format, like bytes, into Python objects">🎻</abbr> 🎻, ⚫️ ✍ 🔗 `bytes`, & 🔢 `magic_data_reader()` 🔜 🈚 🎻 ⚫️ 🌌. |
|
||||
|
|
||||
👐, 👥 💪 📣 📈 🔗 📨 💪. |
|
||||
|
|
||||
### 🛃 🗄 🎚 🆎 |
|
||||
|
|
||||
⚙️ 👉 🎏 🎱, 👆 💪 ⚙️ Pydantic 🏷 🔬 🎻 🔗 👈 ⤴️ 🔌 🛃 🗄 🔗 📄 *➡ 🛠️*. |
|
||||
|
|
||||
& 👆 💪 👉 🚥 💽 🆎 📨 🚫 🎻. |
|
||||
|
|
||||
🖼, 👉 🈸 👥 🚫 ⚙️ FastAPI 🛠️ 🛠️ ⚗ 🎻 🔗 ⚪️➡️ Pydantic 🏷 🚫 🏧 🔬 🎻. 👐, 👥 📣 📨 🎚 🆎 📁, 🚫 🎻: |
|
||||
|
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[17:22,24] *} |
|
||||
|
|
||||
👐, 👐 👥 🚫 ⚙️ 🔢 🛠️ 🛠️, 👥 ⚙️ Pydantic 🏷 ❎ 🏗 🎻 🔗 💽 👈 👥 💚 📨 📁. |
|
||||
|
|
||||
⤴️ 👥 ⚙️ 📨 🔗, & ⚗ 💪 `bytes`. 👉 ⛓ 👈 FastAPI 🏆 🚫 🔄 🎻 📨 🚀 🎻. |
|
||||
|
|
||||
& ⤴️ 👆 📟, 👥 🎻 👈 📁 🎚 🔗, & ⤴️ 👥 🔄 ⚙️ 🎏 Pydantic 🏷 ✔ 📁 🎚: |
|
||||
|
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[26:33] *} |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
📥 👥 🏤-⚙️ 🎏 Pydantic 🏷. |
|
||||
|
|
||||
✋️ 🎏 🌌, 👥 💪 ✔️ ✔ ⚫️ 🎏 🌌. |
|
||||
|
|
||||
/// |
|
||||
@ -1,31 +0,0 @@ |
|||||
# 📨 - 🔀 👔 📟 |
|
||||
|
|
||||
👆 🎲 ✍ ⏭ 👈 👆 💪 ⚒ 🔢 [📨 👔 📟](../tutorial/response-status-code.md){.internal-link target=_blank}. |
|
||||
|
|
||||
✋️ 💼 👆 💪 📨 🎏 👔 📟 🌘 🔢. |
|
||||
|
|
||||
## ⚙️ 💼 |
|
||||
|
|
||||
🖼, 🌈 👈 👆 💚 📨 🇺🇸🔍 👔 📟 "👌" `200` 🔢. |
|
||||
|
|
||||
✋️ 🚥 💽 🚫 🔀, 👆 💚 ✍ ⚫️, & 📨 🇺🇸🔍 👔 📟 "✍" `201`. |
|
||||
|
|
||||
✋️ 👆 💚 💪 ⛽ & 🗜 💽 👆 📨 ⏮️ `response_model`. |
|
||||
|
|
||||
📚 💼, 👆 💪 ⚙️ `Response` 🔢. |
|
||||
|
|
||||
## ⚙️ `Response` 🔢 |
|
||||
|
|
||||
👆 💪 📣 🔢 🆎 `Response` 👆 *➡ 🛠️ 🔢* (👆 💪 🍪 & 🎚). |
|
||||
|
|
||||
& ⤴️ 👆 💪 ⚒ `status_code` 👈 *🔀* 📨 🎚. |
|
||||
|
|
||||
{* ../../docs_src/response_change_status_code/tutorial001.py hl[1,9,12] *} |
|
||||
|
|
||||
& ⤴️ 👆 💪 📨 🙆 🎚 👆 💪, 👆 🛎 🔜 ( `dict`, 💽 🏷, ♒️). |
|
||||
|
|
||||
& 🚥 👆 📣 `response_model`, ⚫️ 🔜 ⚙️ ⛽ & 🗜 🎚 👆 📨. |
|
||||
|
|
||||
**FastAPI** 🔜 ⚙️ 👈 *🔀* 📨 ⚗ 👔 📟 (🍪 & 🎚), & 🔜 🚮 👫 🏁 📨 👈 🔌 💲 👆 📨, ⛽ 🙆 `response_model`. |
|
||||
|
|
||||
👆 💪 📣 `Response` 🔢 🔗, & ⚒ 👔 📟 👫. ✋️ ✔️ 🤯 👈 🏁 1️⃣ ⚒ 🔜 🏆. |
|
||||
@ -1,51 +0,0 @@ |
|||||
# 📨 🍪 |
|
||||
|
|
||||
## ⚙️ `Response` 🔢 |
|
||||
|
|
||||
👆 💪 📣 🔢 🆎 `Response` 👆 *➡ 🛠️ 🔢*. |
|
||||
|
|
||||
& ⤴️ 👆 💪 ⚒ 🍪 👈 *🔀* 📨 🎚. |
|
||||
|
|
||||
{* ../../docs_src/response_cookies/tutorial002.py hl[1,8:9] *} |
|
||||
|
|
||||
& ⤴️ 👆 💪 📨 🙆 🎚 👆 💪, 👆 🛎 🔜 ( `dict`, 💽 🏷, ♒️). |
|
||||
|
|
||||
& 🚥 👆 📣 `response_model`, ⚫️ 🔜 ⚙️ ⛽ & 🗜 🎚 👆 📨. |
|
||||
|
|
||||
**FastAPI** 🔜 ⚙️ 👈 *🔀* 📨 ⚗ 🍪 (🎚 & 👔 📟), & 🔜 🚮 👫 🏁 📨 👈 🔌 💲 👆 📨, ⛽ 🙆 `response_model`. |
|
||||
|
|
||||
👆 💪 📣 `Response` 🔢 🔗, & ⚒ 🍪 (& 🎚) 👫. |
|
||||
|
|
||||
## 📨 `Response` 🔗 |
|
||||
|
|
||||
👆 💪 ✍ 🍪 🕐❔ 🛬 `Response` 🔗 👆 📟. |
|
||||
|
|
||||
👈, 👆 💪 ✍ 📨 🔬 [📨 📨 🔗](response-directly.md){.internal-link target=_blank}. |
|
||||
|
|
||||
⤴️ ⚒ 🍪 ⚫️, & ⤴️ 📨 ⚫️: |
|
||||
|
|
||||
{* ../../docs_src/response_cookies/tutorial001.py hl[10:12] *} |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
✔️ 🤯 👈 🚥 👆 📨 📨 🔗 ↩️ ⚙️ `Response` 🔢, FastAPI 🔜 📨 ⚫️ 🔗. |
|
||||
|
|
||||
, 👆 🔜 ✔️ ⚒ 💭 👆 💽 ☑ 🆎. 🤶 Ⓜ. ⚫️ 🔗 ⏮️ 🎻, 🚥 👆 🛬 `JSONResponse`. |
|
||||
|
|
||||
& 👈 👆 🚫 📨 🙆 📊 👈 🔜 ✔️ ⛽ `response_model`. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
### 🌅 ℹ |
|
||||
|
|
||||
/// note | 📡 ℹ |
|
||||
|
|
||||
👆 💪 ⚙️ `from starlette.responses import Response` ⚖️ `from starlette.responses import JSONResponse`. |
|
||||
|
|
||||
**FastAPI** 🚚 🎏 `starlette.responses` `fastapi.responses` 🏪 👆, 👩💻. ✋️ 🌅 💪 📨 👟 🔗 ⚪️➡️ 💃. |
|
||||
|
|
||||
& `Response` 💪 ⚙️ 🛎 ⚒ 🎚 & 🍪, **FastAPI** 🚚 ⚫️ `fastapi.Response`. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
👀 🌐 💪 🔢 & 🎛, ✅ <a href="https://www.starlette.dev/responses/#set-cookie" class="external-link" target="_blank">🧾 💃</a>. |
|
||||
@ -1,65 +0,0 @@ |
|||||
# 📨 📨 🔗 |
|
||||
|
|
||||
🕐❔ 👆 ✍ **FastAPI** *➡ 🛠️* 👆 💪 🛎 📨 🙆 📊 ⚪️➡️ ⚫️: `dict`, `list`, Pydantic 🏷, 💽 🏷, ♒️. |
|
||||
|
|
||||
🔢, **FastAPI** 🔜 🔁 🗜 👈 📨 💲 🎻 ⚙️ `jsonable_encoder` 🔬 [🎻 🔗 🔢](../tutorial/encoder.md){.internal-link target=_blank}. |
|
||||
|
|
||||
⤴️, ⛅ 🎑, ⚫️ 🔜 🚮 👈 🎻-🔗 💽 (✅ `dict`) 🔘 `JSONResponse` 👈 🔜 ⚙️ 📨 📨 👩💻. |
|
||||
|
|
||||
✋️ 👆 💪 📨 `JSONResponse` 🔗 ⚪️➡️ 👆 *➡ 🛠️*. |
|
||||
|
|
||||
⚫️ 💪 ⚠, 🖼, 📨 🛃 🎚 ⚖️ 🍪. |
|
||||
|
|
||||
## 📨 `Response` |
|
||||
|
|
||||
👐, 👆 💪 📨 🙆 `Response` ⚖️ 🙆 🎧-🎓 ⚫️. |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
`JSONResponse` ⚫️ 🎧-🎓 `Response`. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
& 🕐❔ 👆 📨 `Response`, **FastAPI** 🔜 🚶♀️ ⚫️ 🔗. |
|
||||
|
|
||||
⚫️ 🏆 🚫 🙆 💽 🛠️ ⏮️ Pydantic 🏷, ⚫️ 🏆 🚫 🗜 🎚 🙆 🆎, ♒️. |
|
||||
|
|
||||
👉 🤝 👆 📚 💪. 👆 💪 📨 🙆 📊 🆎, 🔐 🙆 💽 📄 ⚖️ 🔬, ♒️. |
|
||||
|
|
||||
## ⚙️ `jsonable_encoder` `Response` |
|
||||
|
|
||||
↩️ **FastAPI** 🚫 🙆 🔀 `Response` 👆 📨, 👆 ✔️ ⚒ 💭 ⚫️ 🎚 🔜 ⚫️. |
|
||||
|
|
||||
🖼, 👆 🚫🔜 🚮 Pydantic 🏷 `JSONResponse` 🍵 🥇 🏭 ⚫️ `dict` ⏮️ 🌐 📊 🆎 (💖 `datetime`, `UUID`, ♒️) 🗜 🎻-🔗 🆎. |
|
||||
|
|
||||
📚 💼, 👆 💪 ⚙️ `jsonable_encoder` 🗜 👆 📊 ⏭ 🚶♀️ ⚫️ 📨: |
|
||||
|
|
||||
{* ../../docs_src/response_directly/tutorial001.py hl[6:7,21:22] *} |
|
||||
|
|
||||
/// note | 📡 ℹ |
|
||||
|
|
||||
👆 💪 ⚙️ `from starlette.responses import JSONResponse`. |
|
||||
|
|
||||
**FastAPI** 🚚 🎏 `starlette.responses` `fastapi.responses` 🏪 👆, 👩💻. ✋️ 🌅 💪 📨 👟 🔗 ⚪️➡️ 💃. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 🛬 🛃 `Response` |
|
||||
|
|
||||
🖼 🔛 🎦 🌐 🍕 👆 💪, ✋️ ⚫️ 🚫 📶 ⚠, 👆 💪 ✔️ 📨 `item` 🔗, & **FastAPI** 🔜 🚮 ⚫️ `JSONResponse` 👆, 🏭 ⚫️ `dict`, ♒️. 🌐 👈 🔢. |
|
||||
|
|
||||
🔜, ➡️ 👀 ❔ 👆 💪 ⚙️ 👈 📨 🛃 📨. |
|
||||
|
|
||||
➡️ 💬 👈 👆 💚 📨 <a href="https://en.wikipedia.org/wiki/XML" class="external-link" target="_blank">📂</a> 📨. |
|
||||
|
|
||||
👆 💪 🚮 👆 📂 🎚 🎻, 🚮 ⚫️ `Response`, & 📨 ⚫️: |
|
||||
|
|
||||
{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *} |
|
||||
|
|
||||
## 🗒 |
|
||||
|
|
||||
🕐❔ 👆 📨 `Response` 🔗 🚮 📊 🚫 ✔, 🗜 (🎻), 🚫 📄 🔁. |
|
||||
|
|
||||
✋️ 👆 💪 📄 ⚫️ 🔬 [🌖 📨 🗄](additional-responses.md){.internal-link target=_blank}. |
|
||||
|
|
||||
👆 💪 👀 ⏪ 📄 ❔ ⚙️/📣 👉 🛃 `Response`Ⓜ ⏪ ✔️ 🏧 💽 🛠️, 🧾, ♒️. |
|
||||
@ -1,41 +0,0 @@ |
|||||
# 📨 🎚 |
|
||||
|
|
||||
## ⚙️ `Response` 🔢 |
|
||||
|
|
||||
👆 💪 📣 🔢 🆎 `Response` 👆 *➡ 🛠️ 🔢* (👆 💪 🍪). |
|
||||
|
|
||||
& ⤴️ 👆 💪 ⚒ 🎚 👈 *🔀* 📨 🎚. |
|
||||
|
|
||||
{* ../../docs_src/response_headers/tutorial002.py hl[1,7:8] *} |
|
||||
|
|
||||
& ⤴️ 👆 💪 📨 🙆 🎚 👆 💪, 👆 🛎 🔜 ( `dict`, 💽 🏷, ♒️). |
|
||||
|
|
||||
& 🚥 👆 📣 `response_model`, ⚫️ 🔜 ⚙️ ⛽ & 🗜 🎚 👆 📨. |
|
||||
|
|
||||
**FastAPI** 🔜 ⚙️ 👈 *🔀* 📨 ⚗ 🎚 (🍪 & 👔 📟), & 🔜 🚮 👫 🏁 📨 👈 🔌 💲 👆 📨, ⛽ 🙆 `response_model`. |
|
||||
|
|
||||
👆 💪 📣 `Response` 🔢 🔗, & ⚒ 🎚 (& 🍪) 👫. |
|
||||
|
|
||||
## 📨 `Response` 🔗 |
|
||||
|
|
||||
👆 💪 🚮 🎚 🕐❔ 👆 📨 `Response` 🔗. |
|
||||
|
|
||||
✍ 📨 🔬 [📨 📨 🔗](response-directly.md){.internal-link target=_blank} & 🚶♀️ 🎚 🌖 🔢: |
|
||||
|
|
||||
{* ../../docs_src/response_headers/tutorial001.py hl[10:12] *} |
|
||||
|
|
||||
/// note | 📡 ℹ |
|
||||
|
|
||||
👆 💪 ⚙️ `from starlette.responses import Response` ⚖️ `from starlette.responses import JSONResponse`. |
|
||||
|
|
||||
**FastAPI** 🚚 🎏 `starlette.responses` `fastapi.responses` 🏪 👆, 👩💻. ✋️ 🌅 💪 📨 👟 🔗 ⚪️➡️ 💃. |
|
||||
|
|
||||
& `Response` 💪 ⚙️ 🛎 ⚒ 🎚 & 🍪, **FastAPI** 🚚 ⚫️ `fastapi.Response`. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 🛃 🎚 |
|
||||
|
|
||||
✔️ 🤯 👈 🛃 © 🎚 💪 🚮 <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">⚙️ '✖-' 🔡</a>. |
|
||||
|
|
||||
✋️ 🚥 👆 ✔️ 🛃 🎚 👈 👆 💚 👩💻 🖥 💪 👀, 👆 💪 🚮 👫 👆 ⚜ 📳 (✍ 🌅 [⚜ (✖️-🇨🇳 ℹ 🤝)](../tutorial/cors.md){.internal-link target=_blank}), ⚙️ 🔢 `expose_headers` 📄 <a href="https://www.starlette.dev/middleware/#corsmiddleware" class="external-link" target="_blank">💃 ⚜ 🩺</a>. |
|
||||
@ -1,107 +0,0 @@ |
|||||
# 🇺🇸🔍 🔰 🔐 |
|
||||
|
|
||||
🙅 💼, 👆 💪 ⚙️ 🇺🇸🔍 🔰 🔐. |
|
||||
|
|
||||
🇺🇸🔍 🔰 🔐, 🈸 ⌛ 🎚 👈 🔌 🆔 & 🔐. |
|
||||
|
|
||||
🚥 ⚫️ 🚫 📨 ⚫️, ⚫️ 📨 🇺🇸🔍 4️⃣0️⃣1️⃣ "⛔" ❌. |
|
||||
|
|
||||
& 📨 🎚 `WWW-Authenticate` ⏮️ 💲 `Basic`, & 📦 `realm` 🔢. |
|
||||
|
|
||||
👈 💬 🖥 🎦 🛠️ 📋 🆔 & 🔐. |
|
||||
|
|
||||
⤴️, 🕐❔ 👆 🆎 👈 🆔 & 🔐, 🖥 📨 👫 🎚 🔁. |
|
||||
|
|
||||
## 🙅 🇺🇸🔍 🔰 🔐 |
|
||||
|
|
||||
* 🗄 `HTTPBasic` & `HTTPBasicCredentials`. |
|
||||
* ✍ "`security` ⚖" ⚙️ `HTTPBasic`. |
|
||||
* ⚙️ 👈 `security` ⏮️ 🔗 👆 *➡ 🛠️*. |
|
||||
* ⚫️ 📨 🎚 🆎 `HTTPBasicCredentials`: |
|
||||
* ⚫️ 🔌 `username` & `password` 📨. |
|
||||
|
|
||||
{* ../../docs_src/security/tutorial006.py hl[2,6,10] *} |
|
||||
|
|
||||
🕐❔ 👆 🔄 📂 📛 🥇 🕰 (⚖️ 🖊 "🛠️" 🔼 🩺) 🖥 🔜 💭 👆 👆 🆔 & 🔐: |
|
||||
|
|
||||
<img src="/img/tutorial/security/image12.png"> |
|
||||
|
|
||||
## ✅ 🆔 |
|
||||
|
|
||||
📥 🌅 🏁 🖼. |
|
||||
|
|
||||
⚙️ 🔗 ✅ 🚥 🆔 & 🔐 ☑. |
|
||||
|
|
||||
👉, ⚙️ 🐍 🐩 🕹 <a href="https://docs.python.org/3/library/secrets.html" class="external-link" target="_blank">`secrets`</a> ✅ 🆔 & 🔐. |
|
||||
|
|
||||
`secrets.compare_digest()` 💪 ✊ `bytes` ⚖️ `str` 👈 🕴 🔌 🔠 🦹 (🕐 🇪🇸), 👉 ⛓ ⚫️ 🚫🔜 👷 ⏮️ 🦹 💖 `á`, `Sebastián`. |
|
||||
|
|
||||
🍵 👈, 👥 🥇 🗜 `username` & `password` `bytes` 🔢 👫 ⏮️ 🔠-8️⃣. |
|
||||
|
|
||||
⤴️ 👥 💪 ⚙️ `secrets.compare_digest()` 🚚 👈 `credentials.username` `"stanleyjobson"`, & 👈 `credentials.password` `"swordfish"`. |
|
||||
|
|
||||
{* ../../docs_src/security/tutorial007.py hl[1,11:21] *} |
|
||||
|
|
||||
👉 🔜 🎏: |
|
||||
|
|
||||
```Python |
|
||||
if not (credentials.username == "stanleyjobson") or not (credentials.password == "swordfish"): |
|
||||
# Return some error |
|
||||
... |
|
||||
``` |
|
||||
|
|
||||
✋️ ⚙️ `secrets.compare_digest()` ⚫️ 🔜 🔐 🛡 🆎 👊 🤙 "🕰 👊". |
|
||||
|
|
||||
### ⏲ 👊 |
|
||||
|
|
||||
✋️ ⚫️❔ "⏲ 👊"❓ |
|
||||
|
|
||||
➡️ 🌈 👊 🔄 💭 🆔 & 🔐. |
|
||||
|
|
||||
& 👫 📨 📨 ⏮️ 🆔 `johndoe` & 🔐 `love123`. |
|
||||
|
|
||||
⤴️ 🐍 📟 👆 🈸 🔜 🌓 🕳 💖: |
|
||||
|
|
||||
```Python |
|
||||
if "johndoe" == "stanleyjobson" and "love123" == "swordfish": |
|
||||
... |
|
||||
``` |
|
||||
|
|
||||
✋️ ▶️️ 🙍 🐍 🔬 🥇 `j` `johndoe` 🥇 `s` `stanleyjobson`, ⚫️ 🔜 📨 `False`, ↩️ ⚫️ ⏪ 💭 👈 📚 2️⃣ 🎻 🚫 🎏, 💭 👈 "📤 🙅♂ 💪 🗑 🌅 📊 ⚖ 🎂 🔤". & 👆 🈸 🔜 💬 "❌ 👩💻 ⚖️ 🔐". |
|
||||
|
|
||||
✋️ ⤴️ 👊 🔄 ⏮️ 🆔 `stanleyjobsox` & 🔐 `love123`. |
|
||||
|
|
||||
& 👆 🈸 📟 🔨 🕳 💖: |
|
||||
|
|
||||
```Python |
|
||||
if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish": |
|
||||
... |
|
||||
``` |
|
||||
|
|
||||
🐍 🔜 ✔️ 🔬 🎂 `stanleyjobso` 👯♂️ `stanleyjobsox` & `stanleyjobson` ⏭ 🤔 👈 👯♂️ 🎻 🚫 🎏. ⚫️ 🔜 ✊ ➕ ⏲ 📨 🔙 "❌ 👩💻 ⚖️ 🔐". |
|
||||
|
|
||||
#### 🕰 ❔ ℹ 👊 |
|
||||
|
|
||||
👈 ☝, 👀 👈 💽 ✊ ⏲ 📏 📨 "❌ 👩💻 ⚖️ 🔐" 📨, 👊 🔜 💭 👈 👫 🤚 _🕳_ ▶️️, ▶️ 🔤 ▶️️. |
|
||||
|
|
||||
& ⤴️ 👫 💪 🔄 🔄 🤔 👈 ⚫️ 🎲 🕳 🌖 🎏 `stanleyjobsox` 🌘 `johndoe`. |
|
||||
|
|
||||
#### "🕴" 👊 |
|
||||
|
|
||||
↗️, 👊 🔜 🚫 🔄 🌐 👉 ✋, 👫 🔜 ✍ 📋 ⚫️, 🎲 ⏮️ 💯 ⚖️ 💯 💯 📍 🥈. & 🔜 🤚 1️⃣ ➕ ☑ 🔤 🕰. |
|
||||
|
|
||||
✋️ 🔨 👈, ⏲ ⚖️ 📆 👊 🔜 ✔️ 💭 ☑ 🆔 & 🔐, ⏮️ "ℹ" 👆 🈸, ⚙️ 🕰 ✊ ❔. |
|
||||
|
|
||||
#### 🔧 ⚫️ ⏮️ `secrets.compare_digest()` |
|
||||
|
|
||||
✋️ 👆 📟 👥 🤙 ⚙️ `secrets.compare_digest()`. |
|
||||
|
|
||||
📏, ⚫️ 🔜 ✊ 🎏 🕰 🔬 `stanleyjobsox` `stanleyjobson` 🌘 ⚫️ ✊ 🔬 `johndoe` `stanleyjobson`. & 🎏 🔐. |
|
||||
|
|
||||
👈 🌌, ⚙️ `secrets.compare_digest()` 👆 🈸 📟, ⚫️ 🔜 🔒 🛡 👉 🎂 ↔ 💂♂ 👊. |
|
||||
|
|
||||
### 📨 ❌ |
|
||||
|
|
||||
⏮️ 🔍 👈 🎓 ❌, 📨 `HTTPException` ⏮️ 👔 📟 4️⃣0️⃣1️⃣ (🎏 📨 🕐❔ 🙅♂ 🎓 🚚) & 🚮 🎚 `WWW-Authenticate` ⚒ 🖥 🎦 💳 📋 🔄: |
|
||||
|
|
||||
{* ../../docs_src/security/tutorial007.py hl[23:27] *} |
|
||||
@ -1,19 +0,0 @@ |
|||||
# 🏧 💂♂ |
|
||||
|
|
||||
## 🌖 ⚒ |
|
||||
|
|
||||
📤 ➕ ⚒ 🍵 💂♂ ↖️ ⚪️➡️ 🕐 📔 [🔰 - 👩💻 🦮: 💂♂](../../tutorial/security/index.md){.internal-link target=_blank}. |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
⏭ 📄 **🚫 🎯 "🏧"**. |
|
||||
|
|
||||
& ⚫️ 💪 👈 👆 ⚙️ 💼, ⚗ 1️⃣ 👫. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## ✍ 🔰 🥇 |
|
||||
|
|
||||
⏭ 📄 🤔 👆 ⏪ ✍ 👑 [🔰 - 👩💻 🦮: 💂♂](../../tutorial/security/index.md){.internal-link target=_blank}. |
|
||||
|
|
||||
👫 🌐 ⚓️ 🔛 🎏 🔧, ✋️ ✔ ➕ 🛠️. |
|
||||
@ -1,274 +0,0 @@ |
|||||
# Oauth2️⃣ ↔ |
|
||||
|
|
||||
👆 💪 ⚙️ Oauth2️⃣ ↔ 🔗 ⏮️ **FastAPI**, 👫 🛠️ 👷 💎. |
|
||||
|
|
||||
👉 🔜 ✔ 👆 ✔️ 🌖 👌-🧽 ✔ ⚙️, 📄 Oauth2️⃣ 🐩, 🛠️ 🔘 👆 🗄 🈸 (& 🛠️ 🩺). |
|
||||
|
|
||||
Oauth2️⃣ ⏮️ ↔ 🛠️ ⚙️ 📚 🦏 🤝 🐕🦺, 💖 👱📔, 🇺🇸🔍, 📂, 🤸♂, 👱📔, ♒️. 👫 ⚙️ ⚫️ 🚚 🎯 ✔ 👩💻 & 🈸. |
|
||||
|
|
||||
🔠 🕰 👆 "🕹 ⏮️" 👱📔, 🇺🇸🔍, 📂, 🤸♂, 👱📔, 👈 🈸 ⚙️ Oauth2️⃣ ⏮️ ↔. |
|
||||
|
|
||||
👉 📄 👆 🔜 👀 ❔ 🛠️ 🤝 & ✔ ⏮️ 🎏 Oauth2️⃣ ⏮️ ↔ 👆 **FastAPI** 🈸. |
|
||||
|
|
||||
/// warning |
|
||||
|
|
||||
👉 🌅 ⚖️ 🌘 🏧 📄. 🚥 👆 ▶️, 👆 💪 🚶 ⚫️. |
|
||||
|
|
||||
👆 🚫 🎯 💪 Oauth2️⃣ ↔, & 👆 💪 🍵 🤝 & ✔ 👐 👆 💚. |
|
||||
|
|
||||
✋️ Oauth2️⃣ ⏮️ ↔ 💪 🎆 🛠️ 🔘 👆 🛠️ (⏮️ 🗄) & 👆 🛠️ 🩺. |
|
||||
|
|
||||
👐, 👆 🛠️ 📚 ↔, ⚖️ 🙆 🎏 💂♂/✔ 📄, 👐 👆 💪, 👆 📟. |
|
||||
|
|
||||
📚 💼, Oauth2️⃣ ⏮️ ↔ 💪 👹. |
|
||||
|
|
||||
✋️ 🚥 👆 💭 👆 💪 ⚫️, ⚖️ 👆 😟, 🚧 👂. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## Oauth2️⃣ ↔ & 🗄 |
|
||||
|
|
||||
Oauth2️⃣ 🔧 🔬 "↔" 📇 🎻 🎏 🚀. |
|
||||
|
|
||||
🎚 🔠 👉 🎻 💪 ✔️ 🙆 📁, ✋️ 🔜 🚫 🔌 🚀. |
|
||||
|
|
||||
👫 ↔ 🎨 "✔". |
|
||||
|
|
||||
🗄 (✅ 🛠️ 🩺), 👆 💪 🔬 "💂♂ ⚖". |
|
||||
|
|
||||
🕐❔ 1️⃣ 👫 💂♂ ⚖ ⚙️ Oauth2️⃣, 👆 💪 📣 & ⚙️ ↔. |
|
||||
|
|
||||
🔠 "↔" 🎻 (🍵 🚀). |
|
||||
|
|
||||
👫 🛎 ⚙️ 📣 🎯 💂♂ ✔, 🖼: |
|
||||
|
|
||||
* `users:read` ⚖️ `users:write` ⚠ 🖼. |
|
||||
* `instagram_basic` ⚙️ 👱📔 / 👱📔. |
|
||||
* `https://www.googleapis.com/auth/drive` ⚙️ 🇺🇸🔍. |
|
||||
|
|
||||
/// info |
|
||||
|
|
||||
Oauth2️⃣ "↔" 🎻 👈 📣 🎯 ✔ ✔. |
|
||||
|
|
||||
⚫️ 🚫 🤔 🚥 ⚫️ ✔️ 🎏 🦹 💖 `:` ⚖️ 🚥 ⚫️ 📛. |
|
||||
|
|
||||
👈 ℹ 🛠️ 🎯. |
|
||||
|
|
||||
Oauth2️⃣ 👫 🎻. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 🌐 🎑 |
|
||||
|
|
||||
🥇, ➡️ 🔜 👀 🍕 👈 🔀 ⚪️➡️ 🖼 👑 **🔰 - 👩💻 🦮** [Oauth2️⃣ ⏮️ 🔐 (& 🔁), 📨 ⏮️ 🥙 🤝](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. 🔜 ⚙️ Oauth2️⃣ ↔: |
|
||||
|
|
||||
{* ../../docs_src/security/tutorial005.py hl[2,4,8,12,46,64,105,107:115,121:125,129:135,140,156] *} |
|
||||
|
|
||||
🔜 ➡️ 📄 👈 🔀 🔁 🔁. |
|
||||
|
|
||||
## Oauth2️⃣ 💂♂ ⚖ |
|
||||
|
|
||||
🥇 🔀 👈 🔜 👥 📣 Oauth2️⃣ 💂♂ ⚖ ⏮️ 2️⃣ 💪 ↔, `me` & `items`. |
|
||||
|
|
||||
`scopes` 🔢 📨 `dict` ⏮️ 🔠 ↔ 🔑 & 📛 💲: |
|
||||
|
|
||||
{* ../../docs_src/security/tutorial005.py hl[62:65] *} |
|
||||
|
|
||||
↩️ 👥 🔜 📣 📚 ↔, 👫 🔜 🎦 🆙 🛠️ 🩺 🕐❔ 👆 🕹-/✔. |
|
||||
|
|
||||
& 👆 🔜 💪 🖊 ❔ ↔ 👆 💚 🤝 🔐: `me` & `items`. |
|
||||
|
|
||||
👉 🎏 🛠️ ⚙️ 🕐❔ 👆 🤝 ✔ ⏪ 🚨 ⏮️ 👱📔, 🇺🇸🔍, 📂, ♒️: |
|
||||
|
|
||||
<img src="/img/tutorial/security/image11.png"> |
|
||||
|
|
||||
## 🥙 🤝 ⏮️ ↔ |
|
||||
|
|
||||
🔜, 🔀 🤝 *➡ 🛠️* 📨 ↔ 📨. |
|
||||
|
|
||||
👥 ⚙️ 🎏 `OAuth2PasswordRequestForm`. ⚫️ 🔌 🏠 `scopes` ⏮️ `list` `str`, ⏮️ 🔠 ↔ ⚫️ 📨 📨. |
|
||||
|
|
||||
& 👥 📨 ↔ 🍕 🥙 🤝. |
|
||||
|
|
||||
/// danger |
|
||||
|
|
||||
🦁, 📥 👥 ❎ ↔ 📨 🔗 🤝. |
|
||||
|
|
||||
✋️ 👆 🈸, 💂♂, 👆 🔜 ⚒ 💭 👆 🕴 🚮 ↔ 👈 👩💻 🤙 💪 ✔️, ⚖️ 🕐 👆 ✔️ 🔁. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
{* ../../docs_src/security/tutorial005.py hl[156] *} |
|
||||
|
|
||||
## 📣 ↔ *➡ 🛠️* & 🔗 |
|
||||
|
|
||||
🔜 👥 📣 👈 *➡ 🛠️* `/users/me/items/` 🚚 ↔ `items`. |
|
||||
|
|
||||
👉, 👥 🗄 & ⚙️ `Security` ⚪️➡️ `fastapi`. |
|
||||
|
|
||||
👆 💪 ⚙️ `Security` 📣 🔗 (💖 `Depends`), ✋️ `Security` 📨 🔢 `scopes` ⏮️ 📇 ↔ (🎻). |
|
||||
|
|
||||
👉 💼, 👥 🚶♀️ 🔗 🔢 `get_current_active_user` `Security` (🎏 🌌 👥 🔜 ⏮️ `Depends`). |
|
||||
|
|
||||
✋️ 👥 🚶♀️ `list` ↔, 👉 💼 ⏮️ 1️⃣ ↔: `items` (⚫️ 💪 ✔️ 🌅). |
|
||||
|
|
||||
& 🔗 🔢 `get_current_active_user` 💪 📣 🎧-🔗, 🚫 🕴 ⏮️ `Depends` ✋️ ⏮️ `Security`. 📣 🚮 👍 🎧-🔗 🔢 (`get_current_user`), & 🌖 ↔ 📄. |
|
||||
|
|
||||
👉 💼, ⚫️ 🚚 ↔ `me` (⚫️ 💪 🚚 🌅 🌘 1️⃣ ↔). |
|
||||
|
|
||||
/// note |
|
||||
|
|
||||
👆 🚫 🎯 💪 🚮 🎏 ↔ 🎏 🥉. |
|
||||
|
|
||||
👥 🔨 ⚫️ 📥 🎦 ❔ **FastAPI** 🍵 ↔ 📣 🎏 🎚. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
{* ../../docs_src/security/tutorial005.py hl[4,140,169] *} |
|
||||
|
|
||||
/// info | 📡 ℹ |
|
||||
|
|
||||
`Security` 🤙 🏿 `Depends`, & ⚫️ ✔️ 1️⃣ ➕ 🔢 👈 👥 🔜 👀 ⏪. |
|
||||
|
|
||||
✋️ ⚙️ `Security` ↩️ `Depends`, **FastAPI** 🔜 💭 👈 ⚫️ 💪 📣 💂♂ ↔, ⚙️ 👫 🔘, & 📄 🛠️ ⏮️ 🗄. |
|
||||
|
|
||||
✋️ 🕐❔ 👆 🗄 `Query`, `Path`, `Depends`, `Security` & 🎏 ⚪️➡️ `fastapi`, 👈 🤙 🔢 👈 📨 🎁 🎓. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## ⚙️ `SecurityScopes` |
|
||||
|
|
||||
🔜 ℹ 🔗 `get_current_user`. |
|
||||
|
|
||||
👉 1️⃣ ⚙️ 🔗 🔛. |
|
||||
|
|
||||
📥 👥 ⚙️ 🎏 Oauth2️⃣ ⚖ 👥 ✍ ⏭, 📣 ⚫️ 🔗: `oauth2_scheme`. |
|
||||
|
|
||||
↩️ 👉 🔗 🔢 🚫 ✔️ 🙆 ↔ 📄 ⚫️, 👥 💪 ⚙️ `Depends` ⏮️ `oauth2_scheme`, 👥 🚫 ✔️ ⚙️ `Security` 🕐❔ 👥 🚫 💪 ✔ 💂♂ ↔. |
|
||||
|
|
||||
👥 📣 🎁 🔢 🆎 `SecurityScopes`, 🗄 ⚪️➡️ `fastapi.security`. |
|
||||
|
|
||||
👉 `SecurityScopes` 🎓 🎏 `Request` (`Request` ⚙️ 🤚 📨 🎚 🔗). |
|
||||
|
|
||||
{* ../../docs_src/security/tutorial005.py hl[8,105] *} |
|
||||
|
|
||||
## ⚙️ `scopes` |
|
||||
|
|
||||
🔢 `security_scopes` 🔜 🆎 `SecurityScopes`. |
|
||||
|
|
||||
⚫️ 🔜 ✔️ 🏠 `scopes` ⏮️ 📇 ⚗ 🌐 ↔ ✔ ⚫️ & 🌐 🔗 👈 ⚙️ 👉 🎧-🔗. 👈 ⛓, 🌐 "⚓️"... 👉 💪 🔊 😨, ⚫️ 🔬 🔄 ⏪ 🔛. |
|
||||
|
|
||||
`security_scopes` 🎚 (🎓 `SecurityScopes`) 🚚 `scope_str` 🔢 ⏮️ 👁 🎻, 🔌 👈 ↔ 👽 🚀 (👥 🔜 ⚙️ ⚫️). |
|
||||
|
|
||||
👥 ✍ `HTTPException` 👈 👥 💪 🏤-⚙️ (`raise`) ⏪ 📚 ☝. |
|
||||
|
|
||||
👉 ⚠, 👥 🔌 ↔ 🚚 (🚥 🙆) 🎻 👽 🚀 (⚙️ `scope_str`). 👥 🚮 👈 🎻 ⚗ ↔ `WWW-Authenticate` 🎚 (👉 🍕 🔌). |
|
||||
|
|
||||
{* ../../docs_src/security/tutorial005.py hl[105,107:115] *} |
|
||||
|
|
||||
## ✔ `username` & 💽 💠 |
|
||||
|
|
||||
👥 ✔ 👈 👥 🤚 `username`, & ⚗ ↔. |
|
||||
|
|
||||
& ⤴️ 👥 ✔ 👈 📊 ⏮️ Pydantic 🏷 (✊ `ValidationError` ⚠), & 🚥 👥 🤚 ❌ 👂 🥙 🤝 ⚖️ ⚖ 📊 ⏮️ Pydantic, 👥 🤚 `HTTPException` 👥 ✍ ⏭. |
|
||||
|
|
||||
👈, 👥 ℹ Pydantic 🏷 `TokenData` ⏮️ 🆕 🏠 `scopes`. |
|
||||
|
|
||||
⚖ 📊 ⏮️ Pydantic 👥 💪 ⚒ 💭 👈 👥 ✔️, 🖼, ⚫️❔ `list` `str` ⏮️ ↔ & `str` ⏮️ `username`. |
|
||||
|
|
||||
↩️, 🖼, `dict`, ⚖️ 🕳 🙆, ⚫️ 💪 💔 🈸 ☝ ⏪, ⚒ ⚫️ 💂♂ ⚠. |
|
||||
|
|
||||
👥 ✔ 👈 👥 ✔️ 👩💻 ⏮️ 👈 🆔, & 🚥 🚫, 👥 🤚 👈 🎏 ⚠ 👥 ✍ ⏭. |
|
||||
|
|
||||
{* ../../docs_src/security/tutorial005.py hl[46,116:128] *} |
|
||||
|
|
||||
## ✔ `scopes` |
|
||||
|
|
||||
👥 🔜 ✔ 👈 🌐 ↔ ✔, 👉 🔗 & 🌐 ⚓️ (🔌 *➡ 🛠️*), 🔌 ↔ 🚚 🤝 📨, ⏪ 🤚 `HTTPException`. |
|
||||
|
|
||||
👉, 👥 ⚙️ `security_scopes.scopes`, 👈 🔌 `list` ⏮️ 🌐 👫 ↔ `str`. |
|
||||
|
|
||||
{* ../../docs_src/security/tutorial005.py hl[129:135] *} |
|
||||
|
|
||||
## 🔗 🌲 & ↔ |
|
||||
|
|
||||
➡️ 📄 🔄 👉 🔗 🌲 & ↔. |
|
||||
|
|
||||
`get_current_active_user` 🔗 ✔️ 🎧-🔗 🔛 `get_current_user`, ↔ `"me"` 📣 `get_current_active_user` 🔜 🔌 📇 ✔ ↔ `security_scopes.scopes` 🚶♀️ `get_current_user`. |
|
||||
|
|
||||
*➡ 🛠️* ⚫️ 📣 ↔, `"items"`, 👉 🔜 📇 `security_scopes.scopes` 🚶♀️ `get_current_user`. |
|
||||
|
|
||||
📥 ❔ 🔗 🔗 & ↔ 👀 💖: |
|
||||
|
|
||||
* *➡ 🛠️* `read_own_items` ✔️: |
|
||||
* ✔ ↔ `["items"]` ⏮️ 🔗: |
|
||||
* `get_current_active_user`: |
|
||||
* 🔗 🔢 `get_current_active_user` ✔️: |
|
||||
* ✔ ↔ `["me"]` ⏮️ 🔗: |
|
||||
* `get_current_user`: |
|
||||
* 🔗 🔢 `get_current_user` ✔️: |
|
||||
* 🙅♂ ↔ ✔ ⚫️. |
|
||||
* 🔗 ⚙️ `oauth2_scheme`. |
|
||||
* `security_scopes` 🔢 🆎 `SecurityScopes`: |
|
||||
* 👉 `security_scopes` 🔢 ✔️ 🏠 `scopes` ⏮️ `list` ⚗ 🌐 👫 ↔ 📣 🔛,: |
|
||||
* `security_scopes.scopes` 🔜 🔌 `["me", "items"]` *➡ 🛠️* `read_own_items`. |
|
||||
* `security_scopes.scopes` 🔜 🔌 `["me"]` *➡ 🛠️* `read_users_me`, ↩️ ⚫️ 📣 🔗 `get_current_active_user`. |
|
||||
* `security_scopes.scopes` 🔜 🔌 `[]` (🕳) *➡ 🛠️* `read_system_status`, ↩️ ⚫️ 🚫 📣 🙆 `Security` ⏮️ `scopes`, & 🚮 🔗, `get_current_user`, 🚫 📣 🙆 `scope` 👯♂️. |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
⚠ & "🎱" 👜 📥 👈 `get_current_user` 🔜 ✔️ 🎏 📇 `scopes` ✅ 🔠 *➡ 🛠️*. |
|
||||
|
|
||||
🌐 ⚓️ 🔛 `scopes` 📣 🔠 *➡ 🛠️* & 🔠 🔗 🔗 🌲 👈 🎯 *➡ 🛠️*. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 🌖 ℹ 🔃 `SecurityScopes` |
|
||||
|
|
||||
👆 💪 ⚙️ `SecurityScopes` 🙆 ☝, & 💗 🥉, ⚫️ 🚫 ✔️ "🌱" 🔗. |
|
||||
|
|
||||
⚫️ 🔜 🕧 ✔️ 💂♂ ↔ 📣 ⏮️ `Security` 🔗 & 🌐 ⚓️ **👈 🎯** *➡ 🛠️* & **👈 🎯** 🔗 🌲. |
|
||||
|
|
||||
↩️ `SecurityScopes` 🔜 ✔️ 🌐 ↔ 📣 ⚓️, 👆 💪 ⚙️ ⚫️ ✔ 👈 🤝 ✔️ 🚚 ↔ 🇨🇫 🔗 🔢, & ⤴️ 📣 🎏 ↔ 📄 🎏 *➡ 🛠️*. |
|
||||
|
|
||||
👫 🔜 ✅ ➡ 🔠 *➡ 🛠️*. |
|
||||
|
|
||||
## ✅ ⚫️ |
|
||||
|
|
||||
🚥 👆 📂 🛠️ 🩺, 👆 💪 🔓 & ✔ ❔ ↔ 👆 💚 ✔. |
|
||||
|
|
||||
<img src="/img/tutorial/security/image11.png"> |
|
||||
|
|
||||
🚥 👆 🚫 🖊 🙆 ↔, 👆 🔜 "🔓", ✋️ 🕐❔ 👆 🔄 🔐 `/users/me/` ⚖️ `/users/me/items/` 👆 🔜 🤚 ❌ 💬 👈 👆 🚫 ✔️ 🥃 ✔. 👆 🔜 💪 🔐 `/status/`. |
|
||||
|
|
||||
& 🚥 👆 🖊 ↔ `me` ✋️ 🚫 ↔ `items`, 👆 🔜 💪 🔐 `/users/me/` ✋️ 🚫 `/users/me/items/`. |
|
||||
|
|
||||
👈 ⚫️❔ 🔜 🔨 🥉 🥳 🈸 👈 🔄 🔐 1️⃣ 👫 *➡ 🛠️* ⏮️ 🤝 🚚 👩💻, ⚓️ 🔛 ❔ 📚 ✔ 👩💻 🤝 🈸. |
|
||||
|
|
||||
## 🔃 🥉 🥳 🛠️ |
|
||||
|
|
||||
👉 🖼 👥 ⚙️ Oauth2️⃣ "🔐" 💧. |
|
||||
|
|
||||
👉 ☑ 🕐❔ 👥 🚨 👆 👍 🈸, 🎲 ⏮️ 👆 👍 🕸. |
|
||||
|
|
||||
↩️ 👥 💪 💙 ⚫️ 📨 `username` & `password`, 👥 🎛 ⚫️. |
|
||||
|
|
||||
✋️ 🚥 👆 🏗 Oauth2️⃣ 🈸 👈 🎏 🔜 🔗 (➡, 🚥 👆 🏗 🤝 🐕🦺 🌓 👱📔, 🇺🇸🔍, 📂, ♒️.) 👆 🔜 ⚙️ 1️⃣ 🎏 💧. |
|
||||
|
|
||||
🌅 ⚠ 🔑 💧. |
|
||||
|
|
||||
🏆 🔐 📟 💧, ✋️ 🌖 🏗 🛠️ ⚫️ 🚚 🌅 📶. ⚫️ 🌅 🏗, 📚 🐕🦺 🔚 🆙 ✔ 🔑 💧. |
|
||||
|
|
||||
/// note |
|
||||
|
|
||||
⚫️ ⚠ 👈 🔠 🤝 🐕🦺 📛 👫 💧 🎏 🌌, ⚒ ⚫️ 🍕 👫 🏷. |
|
||||
|
|
||||
✋️ 🔚, 👫 🛠️ 🎏 Oauth2️⃣ 🐩. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
**FastAPI** 🔌 🚙 🌐 👫 Oauth2️⃣ 🤝 💧 `fastapi.security.oauth2`. |
|
||||
|
|
||||
## `Security` 👨🎨 `dependencies` |
|
||||
|
|
||||
🎏 🌌 👆 💪 🔬 `list` `Depends` 👨🎨 `dependencies` 🔢 (🔬 [🔗 ➡ 🛠️ 👨🎨](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), 👆 💪 ⚙️ `Security` ⏮️ `scopes` 📤. |
|
||||
@ -1,396 +0,0 @@ |
|||||
# ⚒ & 🌐 🔢 |
|
||||
|
|
||||
📚 💼 👆 🈸 💪 💪 🔢 ⚒ ⚖️ 📳, 🖼 ㊙ 🔑, 💽 🎓, 🎓 📧 🐕🦺, ♒️. |
|
||||
|
|
||||
🏆 👫 ⚒ 🔢 (💪 🔀), 💖 💽 📛. & 📚 💪 🚿, 💖 ㊙. |
|
||||
|
|
||||
👉 🤔 ⚫️ ⚠ 🚚 👫 🌐 🔢 👈 ✍ 🈸. |
|
||||
|
|
||||
## 🌐 🔢 |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
🚥 👆 ⏪ 💭 ⚫️❔ "🌐 🔢" & ❔ ⚙️ 👫, 💭 🆓 🚶 ⏭ 📄 🔛. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
<a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">🌐 🔢</a> (💭 "🇨🇻 {") 🔢 👈 🖖 🏞 🐍 📟, 🏃♂ ⚙️, & 💪 ✍ 👆 🐍 📟 (⚖️ 🎏 📋 👍). |
|
||||
|
|
||||
👆 💪 ✍ & ⚙️ 🌐 🔢 🐚, 🍵 💆♂ 🐍: |
|
||||
|
|
||||
//// tab | 💾, 🇸🇻, 🚪 🎉 |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
// You could create an env var MY_NAME with |
|
||||
$ export MY_NAME="Wade Wilson" |
|
||||
|
|
||||
// Then you could use it with other programs, like |
|
||||
$ echo "Hello $MY_NAME" |
|
||||
|
|
||||
Hello Wade Wilson |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
//// tab | 🚪 📋 |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
// Create an env var MY_NAME |
|
||||
$ $Env:MY_NAME = "Wade Wilson" |
|
||||
|
|
||||
// Use it with other programs, like |
|
||||
$ echo "Hello $Env:MY_NAME" |
|
||||
|
|
||||
Hello Wade Wilson |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
//// |
|
||||
|
|
||||
### ✍ 🇨🇻 {🐍 |
|
||||
|
|
||||
👆 💪 ✍ 🌐 🔢 🏞 🐍, 📶 (⚖️ ⏮️ 🙆 🎏 👩🔬), & ⤴️ ✍ 👫 🐍. |
|
||||
|
|
||||
🖼 👆 💪 ✔️ 📁 `main.py` ⏮️: |
|
||||
|
|
||||
```Python hl_lines="3" |
|
||||
import os |
|
||||
|
|
||||
name = os.getenv("MY_NAME", "World") |
|
||||
print(f"Hello {name} from Python") |
|
||||
``` |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
🥈 ❌ <a href="https://docs.python.org/3.8/library/os.html#os.getenv" class="external-link" target="_blank">`os.getenv()`</a> 🔢 💲 📨. |
|
||||
|
|
||||
🚥 🚫 🚚, ⚫️ `None` 🔢, 📥 👥 🚚 `"World"` 🔢 💲 ⚙️. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
⤴️ 👆 💪 🤙 👈 🐍 📋: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
// Here we don't set the env var yet |
|
||||
$ python main.py |
|
||||
|
|
||||
// As we didn't set the env var, we get the default value |
|
||||
|
|
||||
Hello World from Python |
|
||||
|
|
||||
// But if we create an environment variable first |
|
||||
$ export MY_NAME="Wade Wilson" |
|
||||
|
|
||||
// And then call the program again |
|
||||
$ python main.py |
|
||||
|
|
||||
// Now it can read the environment variable |
|
||||
|
|
||||
Hello Wade Wilson from Python |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
🌐 🔢 💪 ⚒ 🏞 📟, ✋️ 💪 ✍ 📟, & 🚫 ✔️ 🏪 (💕 `git`) ⏮️ 🎂 📁, ⚫️ ⚠ ⚙️ 👫 📳 ⚖️ ⚒. |
|
||||
|
|
||||
👆 💪 ✍ 🌐 🔢 🕴 🎯 📋 👼, 👈 🕴 💪 👈 📋, & 🕴 🚮 📐. |
|
||||
|
|
||||
👈, ✍ ⚫️ ▶️️ ⏭ 📋 ⚫️, 🔛 🎏 ⏸: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
// Create an env var MY_NAME in line for this program call |
|
||||
$ MY_NAME="Wade Wilson" python main.py |
|
||||
|
|
||||
// Now it can read the environment variable |
|
||||
|
|
||||
Hello Wade Wilson from Python |
|
||||
|
|
||||
// The env var no longer exists afterwards |
|
||||
$ python main.py |
|
||||
|
|
||||
Hello World from Python |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
👆 💪 ✍ 🌅 🔃 ⚫️ <a href="https://12factor.net/config" class="external-link" target="_blank">1️⃣2️⃣-⚖ 📱: 📁</a>. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
### 🆎 & 🔬 |
|
||||
|
|
||||
👫 🌐 🔢 💪 🕴 🍵 ✍ 🎻, 👫 🔢 🐍 & ✔️ 🔗 ⏮️ 🎏 📋 & 🎂 ⚙️ (& ⏮️ 🎏 🏃♂ ⚙️, 💾, 🚪, 🇸🇻). |
|
||||
|
|
||||
👈 ⛓ 👈 🙆 💲 ✍ 🐍 ⚪️➡️ 🌐 🔢 🔜 `str`, & 🙆 🛠️ 🎏 🆎 ⚖️ 🔬 ✔️ 🔨 📟. |
|
||||
|
|
||||
## Pydantic `Settings` |
|
||||
|
|
||||
👐, Pydantic 🚚 👑 🚙 🍵 👫 ⚒ 👟 ⚪️➡️ 🌐 🔢 ⏮️ <a href="https://docs.pydantic.dev/latest/concepts/pydantic_settings/" class="external-link" target="_blank">Pydantic: ⚒ 🧾</a>. |
|
||||
|
|
||||
### ✍ `Settings` 🎚 |
|
||||
|
|
||||
🗄 `BaseSettings` ⚪️➡️ Pydantic & ✍ 🎧-🎓, 📶 🌅 💖 ⏮️ Pydantic 🏷. |
|
||||
|
|
||||
🎏 🌌 ⏮️ Pydantic 🏷, 👆 📣 🎓 🔢 ⏮️ 🆎 ✍, & 🎲 🔢 💲. |
|
||||
|
|
||||
👆 💪 ⚙️ 🌐 🎏 🔬 ⚒ & 🧰 👆 ⚙️ Pydantic 🏷, 💖 🎏 📊 🆎 & 🌖 🔬 ⏮️ `Field()`. |
|
||||
|
|
||||
{* ../../docs_src/settings/tutorial001.py hl[2,5:8,11] *} |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
🚥 👆 💚 🕳 ⏩ 📁 & 📋, 🚫 ⚙️ 👉 🖼, ⚙️ 🏁 1️⃣ 🔛. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
⤴️, 🕐❔ 👆 ✍ 👐 👈 `Settings` 🎓 (👉 💼, `settings` 🎚), Pydantic 🔜 ✍ 🌐 🔢 💼-😛 🌌,, ↖-💼 🔢 `APP_NAME` 🔜 ✍ 🔢 `app_name`. |
|
||||
|
|
||||
⏭ ⚫️ 🔜 🗜 & ✔ 💽. , 🕐❔ 👆 ⚙️ 👈 `settings` 🎚, 👆 🔜 ✔️ 📊 🆎 👆 📣 (✅ `items_per_user` 🔜 `int`). |
|
||||
|
|
||||
### ⚙️ `settings` |
|
||||
|
|
||||
⤴️ 👆 💪 ⚙️ 🆕 `settings` 🎚 👆 🈸: |
|
||||
|
|
||||
{* ../../docs_src/settings/tutorial001.py hl[18:20] *} |
|
||||
|
|
||||
### 🏃 💽 |
|
||||
|
|
||||
⏭, 👆 🔜 🏃 💽 🚶♀️ 📳 🌐 🔢, 🖼 👆 💪 ⚒ `ADMIN_EMAIL` & `APP_NAME` ⏮️: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ ADMIN_EMAIL="[email protected]" APP_NAME="ChimichangApp" uvicorn main:app |
|
||||
|
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
⚒ 💗 🇨🇻 {👁 📋 🎏 👫 ⏮️ 🚀, & 🚮 👫 🌐 ⏭ 📋. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
& ⤴️ `admin_email` ⚒ 🔜 ⚒ `"[email protected]"`. |
|
||||
|
|
||||
`app_name` 🔜 `"ChimichangApp"`. |
|
||||
|
|
||||
& `items_per_user` 🔜 🚧 🚮 🔢 💲 `50`. |
|
||||
|
|
||||
## ⚒ ➕1️⃣ 🕹 |
|
||||
|
|
||||
👆 💪 🚮 👈 ⚒ ➕1️⃣ 🕹 📁 👆 👀 [🦏 🈸 - 💗 📁](../tutorial/bigger-applications.md){.internal-link target=_blank}. |
|
||||
|
|
||||
🖼, 👆 💪 ✔️ 📁 `config.py` ⏮️: |
|
||||
|
|
||||
{* ../../docs_src/settings/app01/config.py *} |
|
||||
|
|
||||
& ⤴️ ⚙️ ⚫️ 📁 `main.py`: |
|
||||
|
|
||||
{* ../../docs_src/settings/app01/main.py hl[3,11:13] *} |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
👆 🔜 💪 📁 `__init__.py` 👆 👀 🔛 [🦏 🈸 - 💗 📁](../tutorial/bigger-applications.md){.internal-link target=_blank}. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## ⚒ 🔗 |
|
||||
|
|
||||
🍾 ⚫️ 5️⃣📆 ⚠ 🚚 ⚒ ⚪️➡️ 🔗, ↩️ ✔️ 🌐 🎚 ⏮️ `settings` 👈 ⚙️ 🌐. |
|
||||
|
|
||||
👉 💪 ✴️ ⚠ ⏮️ 🔬, ⚫️ 📶 ⏩ 🔐 🔗 ⏮️ 👆 👍 🛃 ⚒. |
|
||||
|
|
||||
### 📁 📁 |
|
||||
|
|
||||
👟 ⚪️➡️ ⏮️ 🖼, 👆 `config.py` 📁 💪 👀 💖: |
|
||||
|
|
||||
{* ../../docs_src/settings/app02/config.py hl[10] *} |
|
||||
|
|
||||
👀 👈 🔜 👥 🚫 ✍ 🔢 👐 `settings = Settings()`. |
|
||||
|
|
||||
### 👑 📱 📁 |
|
||||
|
|
||||
🔜 👥 ✍ 🔗 👈 📨 🆕 `config.Settings()`. |
|
||||
|
|
||||
{* ../../docs_src/settings/app02/main.py hl[5,11:12] *} |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
👥 🔜 🔬 `@lru_cache` 🍖. |
|
||||
|
|
||||
🔜 👆 💪 🤔 `get_settings()` 😐 🔢. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
& ⤴️ 👥 💪 🚚 ⚫️ ⚪️➡️ *➡ 🛠️ 🔢* 🔗 & ⚙️ ⚫️ 🙆 👥 💪 ⚫️. |
|
||||
|
|
||||
{* ../../docs_src/settings/app02/main.py hl[16,18:20] *} |
|
||||
|
|
||||
### ⚒ & 🔬 |
|
||||
|
|
||||
⤴️ ⚫️ 🔜 📶 ⏩ 🚚 🎏 ⚒ 🎚 ⏮️ 🔬 🏗 🔗 🔐 `get_settings`: |
|
||||
|
|
||||
{* ../../docs_src/settings/app02/test_main.py hl[9:10,13,21] *} |
|
||||
|
|
||||
🔗 🔐 👥 ⚒ 🆕 💲 `admin_email` 🕐❔ 🏗 🆕 `Settings` 🎚, & ⤴️ 👥 📨 👈 🆕 🎚. |
|
||||
|
|
||||
⤴️ 👥 💪 💯 👈 ⚫️ ⚙️. |
|
||||
|
|
||||
## 👂 `.env` 📁 |
|
||||
|
|
||||
🚥 👆 ✔️ 📚 ⚒ 👈 🎲 🔀 📚, 🎲 🎏 🌐, ⚫️ 5️⃣📆 ⚠ 🚮 👫 🔛 📁 & ⤴️ ✍ 👫 ⚪️➡️ ⚫️ 🚥 👫 🌐 🔢. |
|
||||
|
|
||||
👉 💡 ⚠ 🥃 👈 ⚫️ ✔️ 📛, 👫 🌐 🔢 🛎 🥉 📁 `.env`, & 📁 🤙 "🇨🇻". |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
📁 ▶️ ⏮️ ❣ (`.`) 🕵♂ 📁 🖥-💖 ⚙️, 💖 💾 & 🇸🇻. |
|
||||
|
|
||||
✋️ 🇨🇻 📁 🚫 🤙 ✔️ ✔️ 👈 ☑ 📁. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
Pydantic ✔️ 🐕🦺 👂 ⚪️➡️ 👉 🆎 📁 ⚙️ 🔢 🗃. 👆 💪 ✍ 🌖 <a href="https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support" class="external-link" target="_blank">Pydantic ⚒: 🇨🇻 (.🇨🇻) 🐕🦺</a>. |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
👉 👷, 👆 💪 `pip install python-dotenv`. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
### `.env` 📁 |
|
||||
|
|
||||
👆 💪 ✔️ `.env` 📁 ⏮️: |
|
||||
|
|
||||
```bash |
|
||||
ADMIN_EMAIL="[email protected]" |
|
||||
APP_NAME="ChimichangApp" |
|
||||
``` |
|
||||
|
|
||||
### ✍ ⚒ ⚪️➡️ `.env` |
|
||||
|
|
||||
& ⤴️ ℹ 👆 `config.py` ⏮️: |
|
||||
|
|
||||
{* ../../docs_src/settings/app03/config.py hl[9:10] *} |
|
||||
|
|
||||
📥 👥 ✍ 🎓 `Config` 🔘 👆 Pydantic `Settings` 🎓, & ⚒ `env_file` 📁 ⏮️ 🇨🇻 📁 👥 💚 ⚙️. |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
`Config` 🎓 ⚙️ Pydantic 📳. 👆 💪 ✍ 🌖 <a href="https://docs.pydantic.dev/latest/api/config/" class="external-link" target="_blank">Pydantic 🏷 📁</a> |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
### 🏗 `Settings` 🕴 🕐 ⏮️ `lru_cache` |
|
||||
|
|
||||
👂 📁 ⚪️➡️ 💾 🛎 ⚠ (🐌) 🛠️, 👆 🎲 💚 ⚫️ 🕴 🕐 & ⤴️ 🏤-⚙️ 🎏 ⚒ 🎚, ↩️ 👂 ⚫️ 🔠 📨. |
|
||||
|
|
||||
✋️ 🔠 🕰 👥: |
|
||||
|
|
||||
```Python |
|
||||
Settings() |
|
||||
``` |
|
||||
|
|
||||
🆕 `Settings` 🎚 🔜 ✍, & 🏗 ⚫️ 🔜 ✍ `.env` 📁 🔄. |
|
||||
|
|
||||
🚥 🔗 🔢 💖: |
|
||||
|
|
||||
```Python |
|
||||
def get_settings(): |
|
||||
return Settings() |
|
||||
``` |
|
||||
|
|
||||
👥 🔜 ✍ 👈 🎚 🔠 📨, & 👥 🔜 👂 `.env` 📁 🔠 📨. 👶 👶 |
|
||||
|
|
||||
✋️ 👥 ⚙️ `@lru_cache` 👨🎨 🔛 🔝, `Settings` 🎚 🔜 ✍ 🕴 🕐, 🥇 🕰 ⚫️ 🤙. 👶 👶 |
|
||||
|
|
||||
{* ../../docs_src/settings/app03/main.py hl[1,10] *} |
|
||||
|
|
||||
⤴️ 🙆 🏁 🤙 `get_settings()` 🔗 ⏭ 📨, ↩️ 🛠️ 🔗 📟 `get_settings()` & 🏗 🆕 `Settings` 🎚, ⚫️ 🔜 📨 🎏 🎚 👈 📨 🔛 🥇 🤙, 🔄 & 🔄. |
|
||||
|
|
||||
#### `lru_cache` 📡 ℹ |
|
||||
|
|
||||
`@lru_cache` 🔀 🔢 ⚫️ 🎀 📨 🎏 💲 👈 📨 🥇 🕰, ↩️ 💻 ⚫️ 🔄, 🛠️ 📟 🔢 🔠 🕰. |
|
||||
|
|
||||
, 🔢 🔛 ⚫️ 🔜 🛠️ 🕐 🔠 🌀 ❌. & ⤴️ 💲 📨 🔠 👈 🌀 ❌ 🔜 ⚙️ 🔄 & 🔄 🕐❔ 🔢 🤙 ⏮️ ⚫️❔ 🎏 🌀 ❌. |
|
||||
|
|
||||
🖼, 🚥 👆 ✔️ 🔢: |
|
||||
|
|
||||
```Python |
|
||||
@lru_cache |
|
||||
def say_hi(name: str, salutation: str = "Ms."): |
|
||||
return f"Hello {salutation} {name}" |
|
||||
``` |
|
||||
|
|
||||
👆 📋 💪 🛠️ 💖 👉: |
|
||||
|
|
||||
```mermaid |
|
||||
sequenceDiagram |
|
||||
|
|
||||
participant code as Code |
|
||||
participant function as say_hi() |
|
||||
participant execute as Execute function |
|
||||
|
|
||||
rect rgba(0, 255, 0, .1) |
|
||||
code ->> function: say_hi(name="Camila") |
|
||||
function ->> execute: execute function code |
|
||||
execute ->> code: return the result |
|
||||
end |
|
||||
|
|
||||
rect rgba(0, 255, 255, .1) |
|
||||
code ->> function: say_hi(name="Camila") |
|
||||
function ->> code: return stored result |
|
||||
end |
|
||||
|
|
||||
rect rgba(0, 255, 0, .1) |
|
||||
code ->> function: say_hi(name="Rick") |
|
||||
function ->> execute: execute function code |
|
||||
execute ->> code: return the result |
|
||||
end |
|
||||
|
|
||||
rect rgba(0, 255, 0, .1) |
|
||||
code ->> function: say_hi(name="Rick", salutation="Mr.") |
|
||||
function ->> execute: execute function code |
|
||||
execute ->> code: return the result |
|
||||
end |
|
||||
|
|
||||
rect rgba(0, 255, 255, .1) |
|
||||
code ->> function: say_hi(name="Rick") |
|
||||
function ->> code: return stored result |
|
||||
end |
|
||||
|
|
||||
rect rgba(0, 255, 255, .1) |
|
||||
code ->> function: say_hi(name="Camila") |
|
||||
function ->> code: return stored result |
|
||||
end |
|
||||
``` |
|
||||
|
|
||||
💼 👆 🔗 `get_settings()`, 🔢 🚫 ✊ 🙆 ❌, ⚫️ 🕧 📨 🎏 💲. |
|
||||
|
|
||||
👈 🌌, ⚫️ 🎭 🌖 🚥 ⚫️ 🌐 🔢. ✋️ ⚫️ ⚙️ 🔗 🔢, ⤴️ 👥 💪 🔐 ⚫️ 💪 🔬. |
|
||||
|
|
||||
`@lru_cache` 🍕 `functools` ❔ 🍕 🐍 🐩 🗃, 👆 💪 ✍ 🌅 🔃 ⚫️ <a href="https://docs.python.org/3/library/functools.html#functools.lru_cache" class="external-link" target="_blank">🐍 🩺 `@lru_cache`</a>. |
|
||||
|
|
||||
## 🌃 |
|
||||
|
|
||||
👆 💪 ⚙️ Pydantic ⚒ 🍵 ⚒ ⚖️ 📳 👆 🈸, ⏮️ 🌐 🏋️ Pydantic 🏷. |
|
||||
|
|
||||
* ⚙️ 🔗 👆 💪 📉 🔬. |
|
||||
* 👆 💪 ⚙️ `.env` 📁 ⏮️ ⚫️. |
|
||||
* ⚙️ `@lru_cache` ➡️ 👆 ❎ 👂 🇨🇻 📁 🔄 & 🔄 🔠 📨, ⏪ 🤝 👆 🔐 ⚫️ ⏮️ 🔬. |
|
||||
@ -1,67 +0,0 @@ |
|||||
# 🎧 🈸 - 🗻 |
|
||||
|
|
||||
🚥 👆 💪 ✔️ 2️⃣ 🔬 FastAPI 🈸, ⏮️ 👫 👍 🔬 🗄 & 👫 👍 🩺 ⚜, 👆 💪 ✔️ 👑 📱 & "🗻" 1️⃣ (⚖️ 🌅) 🎧-🈸(Ⓜ). |
|
||||
|
|
||||
## 🗜 **FastAPI** 🈸 |
|
||||
|
|
||||
"🗜" ⛓ ❎ 🍕 "🔬" 🈸 🎯 ➡, 👈 ⤴️ ✊ 💅 🚚 🌐 🔽 👈 ➡, ⏮️ _➡ 🛠️_ 📣 👈 🎧-🈸. |
|
||||
|
|
||||
### 🔝-🎚 🈸 |
|
||||
|
|
||||
🥇, ✍ 👑, 🔝-🎚, **FastAPI** 🈸, & 🚮 *➡ 🛠️*: |
|
||||
|
|
||||
{* ../../docs_src/sub_applications/tutorial001.py hl[3,6:8] *} |
|
||||
|
|
||||
### 🎧-🈸 |
|
||||
|
|
||||
⤴️, ✍ 👆 🎧-🈸, & 🚮 *➡ 🛠️*. |
|
||||
|
|
||||
👉 🎧-🈸 ➕1️⃣ 🐩 FastAPI 🈸, ✋️ 👉 1️⃣ 👈 🔜 "🗻": |
|
||||
|
|
||||
{* ../../docs_src/sub_applications/tutorial001.py hl[11,14:16] *} |
|
||||
|
|
||||
### 🗻 🎧-🈸 |
|
||||
|
|
||||
👆 🔝-🎚 🈸, `app`, 🗻 🎧-🈸, `subapi`. |
|
||||
|
|
||||
👉 💼, ⚫️ 🔜 📌 ➡ `/subapi`: |
|
||||
|
|
||||
{* ../../docs_src/sub_applications/tutorial001.py hl[11,19] *} |
|
||||
|
|
||||
### ✅ 🏧 🛠️ 🩺 |
|
||||
|
|
||||
🔜, 🏃 `uvicorn` ⏮️ 👑 📱, 🚥 👆 📁 `main.py`, ⚫️ 🔜: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ uvicorn main:app --reload |
|
||||
|
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
& 📂 🩺 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>. |
|
||||
|
|
||||
👆 🔜 👀 🏧 🛠️ 🩺 👑 📱, 🔌 🕴 🚮 👍 _➡ 🛠️_: |
|
||||
|
|
||||
<img src="/img/tutorial/sub-applications/image01.png"> |
|
||||
|
|
||||
& ⤴️, 📂 🩺 🎧-🈸, <a href="http://127.0.0.1:8000/subapi/docs" class="external-link" target="_blank">http://127.0.0.1:8000/subapi/docs</a>. |
|
||||
|
|
||||
👆 🔜 👀 🏧 🛠️ 🩺 🎧-🈸, ✅ 🕴 🚮 👍 _➡ 🛠️_, 🌐 🔽 ☑ 🎧-➡ 🔡 `/subapi`: |
|
||||
|
|
||||
<img src="/img/tutorial/sub-applications/image02.png"> |
|
||||
|
|
||||
🚥 👆 🔄 🔗 ⏮️ 🙆 2️⃣ 👩💻 🔢, 👫 🔜 👷 ☑, ↩️ 🖥 🔜 💪 💬 🔠 🎯 📱 ⚖️ 🎧-📱. |
|
||||
|
|
||||
### 📡 ℹ: `root_path` |
|
||||
|
|
||||
🕐❔ 👆 🗻 🎧-🈸 🔬 🔛, FastAPI 🔜 ✊ 💅 🔗 🗻 ➡ 🎧-🈸 ⚙️ 🛠️ ⚪️➡️ 🔫 🔧 🤙 `root_path`. |
|
||||
|
|
||||
👈 🌌, 🎧-🈸 🔜 💭 ⚙️ 👈 ➡ 🔡 🩺 🎚. |
|
||||
|
|
||||
& 🎧-🈸 💪 ✔️ 🚮 👍 📌 🎧-🈸 & 🌐 🔜 👷 ☑, ↩️ FastAPI 🍵 🌐 👉 `root_path`Ⓜ 🔁. |
|
||||
|
|
||||
👆 🔜 💡 🌅 🔃 `root_path` & ❔ ⚙️ ⚫️ 🎯 📄 🔃 [⛅ 🗳](behind-a-proxy.md){.internal-link target=_blank}. |
|
||||
@ -1,84 +0,0 @@ |
|||||
# 📄 |
|
||||
|
|
||||
👆 💪 ⚙️ 🙆 📄 🚒 👆 💚 ⏮️ **FastAPI**. |
|
||||
|
|
||||
⚠ ⚒ Jinja2️⃣, 🎏 1️⃣ ⚙️ 🏺 & 🎏 🧰. |
|
||||
|
|
||||
📤 🚙 🔗 ⚫️ 💪 👈 👆 💪 ⚙️ 🔗 👆 **FastAPI** 🈸 (🚚 💃). |
|
||||
|
|
||||
## ❎ 🔗 |
|
||||
|
|
||||
❎ `jinja2`: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ pip install jinja2 |
|
||||
|
|
||||
---> 100% |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
## ⚙️ `Jinja2Templates` |
|
||||
|
|
||||
* 🗄 `Jinja2Templates`. |
|
||||
* ✍ `templates` 🎚 👈 👆 💪 🏤-⚙️ ⏪. |
|
||||
* 📣 `Request` 🔢 *➡ 🛠️* 👈 🔜 📨 📄. |
|
||||
* ⚙️ `templates` 👆 ✍ ✍ & 📨 `TemplateResponse`, 🚶♀️ `request` 1️⃣ 🔑-💲 👫 Jinja2️⃣ "🔑". |
|
||||
|
|
||||
{* ../../docs_src/templates/tutorial001.py hl[4,11,15:18] *} |
|
||||
|
|
||||
/// note |
|
||||
|
|
||||
👀 👈 👆 ✔️ 🚶♀️ `request` 🍕 🔑-💲 👫 🔑 Jinja2️⃣. , 👆 ✔️ 📣 ⚫️ 👆 *➡ 🛠️*. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
📣 `response_class=HTMLResponse` 🩺 🎚 🔜 💪 💭 👈 📨 🔜 🕸. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
/// note | 📡 ℹ |
|
||||
|
|
||||
👆 💪 ⚙️ `from starlette.templating import Jinja2Templates`. |
|
||||
|
|
||||
**FastAPI** 🚚 🎏 `starlette.templating` `fastapi.templating` 🏪 👆, 👩💻. ✋️ 🌅 💪 📨 👟 🔗 ⚪️➡️ 💃. 🎏 ⏮️ `Request` & `StaticFiles`. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## ✍ 📄 |
|
||||
|
|
||||
⤴️ 👆 💪 ✍ 📄 `templates/item.html` ⏮️: |
|
||||
|
|
||||
```jinja hl_lines="7" |
|
||||
{!../../docs_src/templates/templates/item.html!} |
|
||||
``` |
|
||||
|
|
||||
⚫️ 🔜 🎦 `id` ✊ ⚪️➡️ "🔑" `dict` 👆 🚶♀️: |
|
||||
|
|
||||
```Python |
|
||||
{"request": request, "id": id} |
|
||||
``` |
|
||||
|
|
||||
## 📄 & 🎻 📁 |
|
||||
|
|
||||
& 👆 💪 ⚙️ `url_for()` 🔘 📄, & ⚙️ ⚫️, 🖼, ⏮️ `StaticFiles` 👆 📌. |
|
||||
|
|
||||
```jinja hl_lines="4" |
|
||||
{!../../docs_src/templates/templates/item.html!} |
|
||||
``` |
|
||||
|
|
||||
👉 🖼, ⚫️ 🔜 🔗 🎚 📁 `static/styles.css` ⏮️: |
|
||||
|
|
||||
```CSS hl_lines="4" |
|
||||
{!../../docs_src/templates/static/styles.css!} |
|
||||
``` |
|
||||
|
|
||||
& ↩️ 👆 ⚙️ `StaticFiles`, 👈 🎚 📁 🔜 🍦 🔁 👆 **FastAPI** 🈸 📛 `/static/styles.css`. |
|
||||
|
|
||||
## 🌅 ℹ |
|
||||
|
|
||||
🌅 ℹ, 🔌 ❔ 💯 📄, ✅ <a href="https://www.starlette.dev/templates/" class="external-link" target="_blank">💃 🩺 🔛 📄</a>. |
|
||||
@ -1,53 +0,0 @@ |
|||||
# 🔬 🔗 ⏮️ 🔐 |
|
||||
|
|
||||
## 🔑 🔗 ⏮️ 🔬 |
|
||||
|
|
||||
📤 😐 🌐❔ 👆 💪 💚 🔐 🔗 ⏮️ 🔬. |
|
||||
|
|
||||
👆 🚫 💚 ⏮️ 🔗 🏃 (🚫 🙆 🎧-🔗 ⚫️ 💪 ✔️). |
|
||||
|
|
||||
↩️, 👆 💚 🚚 🎏 🔗 👈 🔜 ⚙️ 🕴 ⏮️ 💯 (🎲 🕴 🎯 💯), & 🔜 🚚 💲 👈 💪 ⚙️ 🌐❔ 💲 ⏮️ 🔗 ⚙️. |
|
||||
|
|
||||
### ⚙️ 💼: 🔢 🐕🦺 |
|
||||
|
|
||||
🖼 💪 👈 👆 ✔️ 🔢 🤝 🐕🦺 👈 👆 💪 🤙. |
|
||||
|
|
||||
👆 📨 ⚫️ 🤝 & ⚫️ 📨 🔓 👩💻. |
|
||||
|
|
||||
👉 🐕🦺 5️⃣📆 🔌 👆 📍 📨, & 🤙 ⚫️ 💪 ✊ ➕ 🕰 🌘 🚥 👆 ✔️ 🔧 🎁 👩💻 💯. |
|
||||
|
|
||||
👆 🎲 💚 💯 🔢 🐕🦺 🕐, ✋️ 🚫 🎯 🤙 ⚫️ 🔠 💯 👈 🏃. |
|
||||
|
|
||||
👉 💼, 👆 💪 🔐 🔗 👈 🤙 👈 🐕🦺, & ⚙️ 🛃 🔗 👈 📨 🎁 👩💻, 🕴 👆 💯. |
|
||||
|
|
||||
### ⚙️ `app.dependency_overrides` 🔢 |
|
||||
|
|
||||
👫 💼, 👆 **FastAPI** 🈸 ✔️ 🔢 `app.dependency_overrides`, ⚫️ 🙅 `dict`. |
|
||||
|
|
||||
🔐 🔗 🔬, 👆 🚮 🔑 ⏮️ 🔗 (🔢), & 💲, 👆 🔗 🔐 (➕1️⃣ 🔢). |
|
||||
|
|
||||
& ⤴️ **FastAPI** 🔜 🤙 👈 🔐 ↩️ ⏮️ 🔗. |
|
||||
|
|
||||
{* ../../docs_src/dependency_testing/tutorial001.py hl[28:29,32] *} |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
👆 💪 ⚒ 🔗 🔐 🔗 ⚙️ 🙆 👆 **FastAPI** 🈸. |
|
||||
|
|
||||
⏮️ 🔗 💪 ⚙️ *➡ 🛠️ 🔢*, *➡ 🛠️ 👨🎨* (🕐❔ 👆 🚫 ⚙️ 📨 💲), `.include_router()` 🤙, ♒️. |
|
||||
|
|
||||
FastAPI 🔜 💪 🔐 ⚫️. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
⤴️ 👆 💪 ⏲ 👆 🔐 (❎ 👫) ⚒ `app.dependency_overrides` 🛁 `dict`: |
|
||||
|
|
||||
```Python |
|
||||
app.dependency_overrides = {} |
|
||||
``` |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
🚥 👆 💚 🔐 🔗 🕴 ⏮️ 💯, 👆 💪 ⚒ 🔐 ▶️ 💯 (🔘 💯 🔢) & ⏲ ⚫️ 🔚 (🔚 💯 🔢). |
|
||||
|
|
||||
/// |
|
||||
@ -1,5 +0,0 @@ |
|||||
# 🔬 🎉: 🕴 - 🤫 |
|
||||
|
|
||||
🕐❔ 👆 💪 👆 🎉 🐕🦺 (`startup` & `shutdown`) 🏃 👆 💯, 👆 💪 ⚙️ `TestClient` ⏮️ `with` 📄: |
|
||||
|
|
||||
{* ../../docs_src/app_testing/tutorial003.py hl[9:12,20:24] *} |
|
||||
@ -1,13 +0,0 @@ |
|||||
# 🔬 *️⃣ |
|
||||
|
|
||||
👆 💪 ⚙️ 🎏 `TestClient` 💯*️⃣. |
|
||||
|
|
||||
👉, 👆 ⚙️ `TestClient` `with` 📄, 🔗*️⃣: |
|
||||
|
|
||||
{* ../../docs_src/app_testing/tutorial002.py hl[27:31] *} |
|
||||
|
|
||||
/// note |
|
||||
|
|
||||
🌅 ℹ, ✅ 💃 🧾 <a href="https://www.starlette.dev/testclient/#testing-websocket-sessions" class="external-link" target="_blank">🔬 *️⃣ </a>. |
|
||||
|
|
||||
/// |
|
||||
@ -1,56 +0,0 @@ |
|||||
# ⚙️ 📨 🔗 |
|
||||
|
|
||||
🆙 🔜, 👆 ✔️ 📣 🍕 📨 👈 👆 💪 ⏮️ 👫 🆎. |
|
||||
|
|
||||
✊ 📊 ⚪️➡️: |
|
||||
|
|
||||
* ➡ 🔢. |
|
||||
* 🎚. |
|
||||
* 🍪. |
|
||||
* ♒️. |
|
||||
|
|
||||
& 🔨, **FastAPI** ⚖ 👈 💽, 🏭 ⚫️ & 🏭 🧾 👆 🛠️ 🔁. |
|
||||
|
|
||||
✋️ 📤 ⚠ 🌐❔ 👆 💪 💪 🔐 `Request` 🎚 🔗. |
|
||||
|
|
||||
## ℹ 🔃 `Request` 🎚 |
|
||||
|
|
||||
**FastAPI** 🤙 **💃** 🔘, ⏮️ 🧽 📚 🧰 🔛 🔝, 👆 💪 ⚙️ 💃 <a href="https://www.starlette.dev/requests/" class="external-link" target="_blank">`Request`</a> 🎚 🔗 🕐❔ 👆 💪. |
|
||||
|
|
||||
⚫️ 🔜 ⛓ 👈 🚥 👆 🤚 📊 ⚪️➡️ `Request` 🎚 🔗 (🖼, ✍ 💪) ⚫️ 🏆 🚫 ✔, 🗜 ⚖️ 📄 (⏮️ 🗄, 🏧 🛠️ 👩💻 🔢) FastAPI. |
|
||||
|
|
||||
👐 🙆 🎏 🔢 📣 🛎 (🖼, 💪 ⏮️ Pydantic 🏷) 🔜 ✔, 🗜, ✍, ♒️. |
|
||||
|
|
||||
✋️ 📤 🎯 💼 🌐❔ ⚫️ ⚠ 🤚 `Request` 🎚. |
|
||||
|
|
||||
## ⚙️ `Request` 🎚 🔗 |
|
||||
|
|
||||
➡️ 🌈 👆 💚 🤚 👩💻 📢 📢/🦠 🔘 👆 *➡ 🛠️ 🔢*. |
|
||||
|
|
||||
👈 👆 💪 🔐 📨 🔗. |
|
||||
|
|
||||
{* ../../docs_src/using_request_directly/tutorial001.py hl[1,7:8] *} |
|
||||
|
|
||||
📣 *➡ 🛠️ 🔢* 🔢 ⏮️ 🆎 ➖ `Request` **FastAPI** 🔜 💭 🚶♀️ `Request` 👈 🔢. |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
🗒 👈 👉 💼, 👥 📣 ➡ 🔢 ⤴️ 📨 🔢. |
|
||||
|
|
||||
, ➡ 🔢 🔜 ⚗, ✔, 🗜 ✔ 🆎 & ✍ ⏮️ 🗄. |
|
||||
|
|
||||
🎏 🌌, 👆 💪 📣 🙆 🎏 🔢 🛎, & ➡, 🤚 `Request` 💁♂️. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## `Request` 🧾 |
|
||||
|
|
||||
👆 💪 ✍ 🌅 ℹ 🔃 <a href="https://www.starlette.dev/requests/" class="external-link" target="_blank">`Request` 🎚 🛂 💃 🧾 🕸</a>. |
|
||||
|
|
||||
/// note | 📡 ℹ |
|
||||
|
|
||||
👆 💪 ⚙️ `from starlette.requests import Request`. |
|
||||
|
|
||||
**FastAPI** 🚚 ⚫️ 🔗 🏪 👆, 👩💻. ✋️ ⚫️ 👟 🔗 ⚪️➡️ 💃. |
|
||||
|
|
||||
/// |
|
||||
@ -1,186 +0,0 @@ |
|||||
# *️⃣ |
|
||||
|
|
||||
👆 💪 ⚙️ <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API" class="external-link" target="_blank"> *️⃣ </a> ⏮️ **FastAPI**. |
|
||||
|
|
||||
## ❎ `WebSockets` |
|
||||
|
|
||||
🥇 👆 💪 ❎ `WebSockets`: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ pip install websockets |
|
||||
|
|
||||
---> 100% |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
## *️⃣ 👩💻 |
|
||||
|
|
||||
### 🏭 |
|
||||
|
|
||||
👆 🏭 ⚙️, 👆 🎲 ✔️ 🕸 ✍ ⏮️ 🏛 🛠️ 💖 😥, Vue.js ⚖️ 📐. |
|
||||
|
|
||||
& 🔗 ⚙️ *️⃣ ⏮️ 👆 👩💻 👆 🔜 🎲 ⚙️ 👆 🕸 🚙. |
|
||||
|
|
||||
⚖️ 👆 💪 ✔️ 🇦🇸 📱 🈸 👈 🔗 ⏮️ 👆 *️⃣ 👩💻 🔗, 🇦🇸 📟. |
|
||||
|
|
||||
⚖️ 👆 5️⃣📆 ✔️ 🙆 🎏 🌌 🔗 ⏮️ *️⃣ 🔗. |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
✋️ 👉 🖼, 👥 🔜 ⚙️ 📶 🙅 🕸 📄 ⏮️ 🕸, 🌐 🔘 📏 🎻. |
|
||||
|
|
||||
👉, ↗️, 🚫 ⚖ & 👆 🚫🔜 ⚙️ ⚫️ 🏭. |
|
||||
|
|
||||
🏭 👆 🔜 ✔️ 1️⃣ 🎛 🔛. |
|
||||
|
|
||||
✋️ ⚫️ 🙅 🌌 🎯 🔛 💽-🚄 *️⃣ & ✔️ 👷 🖼: |
|
||||
|
|
||||
{* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *} |
|
||||
|
|
||||
## ✍ `websocket` |
|
||||
|
|
||||
👆 **FastAPI** 🈸, ✍ `websocket`: |
|
||||
|
|
||||
{* ../../docs_src/websockets/tutorial001.py hl[1,46:47] *} |
|
||||
|
|
||||
/// note | 📡 ℹ |
|
||||
|
|
||||
👆 💪 ⚙️ `from starlette.websockets import WebSocket`. |
|
||||
|
|
||||
**FastAPI** 🚚 🎏 `WebSocket` 🔗 🏪 👆, 👩💻. ✋️ ⚫️ 👟 🔗 ⚪️➡️ 💃. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## ⌛ 📧 & 📨 📧 |
|
||||
|
|
||||
👆 *️⃣ 🛣 👆 💪 `await` 📧 & 📨 📧. |
|
||||
|
|
||||
{* ../../docs_src/websockets/tutorial001.py hl[48:52] *} |
|
||||
|
|
||||
👆 💪 📨 & 📨 💱, ✍, & 🎻 💽. |
|
||||
|
|
||||
## 🔄 ⚫️ |
|
||||
|
|
||||
🚥 👆 📁 📛 `main.py`, 🏃 👆 🈸 ⏮️: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ uvicorn main:app --reload |
|
||||
|
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
📂 👆 🖥 <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>. |
|
||||
|
|
||||
👆 🔜 👀 🙅 📃 💖: |
|
||||
|
|
||||
<img src="/img/tutorial/websockets/image01.png"> |
|
||||
|
|
||||
👆 💪 🆎 📧 🔢 📦, & 📨 👫: |
|
||||
|
|
||||
<img src="/img/tutorial/websockets/image02.png"> |
|
||||
|
|
||||
& 👆 **FastAPI** 🈸 ⏮️ *️⃣ 🔜 📨 🔙: |
|
||||
|
|
||||
<img src="/img/tutorial/websockets/image03.png"> |
|
||||
|
|
||||
👆 💪 📨 (& 📨) 📚 📧: |
|
||||
|
|
||||
<img src="/img/tutorial/websockets/image04.png"> |
|
||||
|
|
||||
& 🌐 👫 🔜 ⚙️ 🎏 *️⃣ 🔗. |
|
||||
|
|
||||
## ⚙️ `Depends` & 🎏 |
|
||||
|
|
||||
*️⃣ 🔗 👆 💪 🗄 ⚪️➡️ `fastapi` & ⚙️: |
|
||||
|
|
||||
* `Depends` |
|
||||
* `Security` |
|
||||
* `Cookie` |
|
||||
* `Header` |
|
||||
* `Path` |
|
||||
* `Query` |
|
||||
|
|
||||
👫 👷 🎏 🌌 🎏 FastAPI 🔗/*➡ 🛠️*: |
|
||||
|
|
||||
{* ../../docs_src/websockets/tutorial002.py hl[66:77,76:91] *} |
|
||||
|
|
||||
/// info |
|
||||
|
|
||||
👉 *️⃣ ⚫️ 🚫 🤙 ⚒ 🔑 🤚 `HTTPException`, ↩️ 👥 🤚 `WebSocketException`. |
|
||||
|
|
||||
👆 💪 ⚙️ 📪 📟 ⚪️➡️ <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1" class="external-link" target="_blank">☑ 📟 🔬 🔧</a>. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
### 🔄 *️⃣ ⏮️ 🔗 |
|
||||
|
|
||||
🚥 👆 📁 📛 `main.py`, 🏃 👆 🈸 ⏮️: |
|
||||
|
|
||||
<div class="termy"> |
|
||||
|
|
||||
```console |
|
||||
$ uvicorn main:app --reload |
|
||||
|
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) |
|
||||
``` |
|
||||
|
|
||||
</div> |
|
||||
|
|
||||
📂 👆 🖥 <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>. |
|
||||
|
|
||||
📤 👆 💪 ⚒: |
|
||||
|
|
||||
* "🏬 🆔", ⚙️ ➡. |
|
||||
* "🤝" ⚙️ 🔢 🔢. |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
👀 👈 🔢 `token` 🔜 🍵 🔗. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
⏮️ 👈 👆 💪 🔗 *️⃣ & ⤴️ 📨 & 📨 📧: |
|
||||
|
|
||||
<img src="/img/tutorial/websockets/image05.png"> |
|
||||
|
|
||||
## 🚚 🔀 & 💗 👩💻 |
|
||||
|
|
||||
🕐❔ *️⃣ 🔗 📪, `await websocket.receive_text()` 🔜 🤚 `WebSocketDisconnect` ⚠, ❔ 👆 💪 ⤴️ ✊ & 🍵 💖 👉 🖼. |
|
||||
|
|
||||
{* ../../docs_src/websockets/tutorial003.py hl[81:83] *} |
|
||||
|
|
||||
🔄 ⚫️ 👅: |
|
||||
|
|
||||
* 📂 📱 ⏮️ 📚 🖥 📑. |
|
||||
* ✍ 📧 ⚪️➡️ 👫. |
|
||||
* ⤴️ 🔐 1️⃣ 📑. |
|
||||
|
|
||||
👈 🔜 🤚 `WebSocketDisconnect` ⚠, & 🌐 🎏 👩💻 🔜 📨 📧 💖: |
|
||||
|
|
||||
``` |
|
||||
Client #1596980209979 left the chat |
|
||||
``` |
|
||||
|
|
||||
/// tip |
|
||||
|
|
||||
📱 🔛 ⭐ & 🙅 🖼 🎦 ❔ 🍵 & 📻 📧 📚 *️⃣ 🔗. |
|
||||
|
|
||||
✋️ ✔️ 🤯 👈, 🌐 🍵 💾, 👁 📇, ⚫️ 🔜 🕴 👷 ⏪ 🛠️ 🏃, & 🔜 🕴 👷 ⏮️ 👁 🛠️. |
|
||||
|
|
||||
🚥 👆 💪 🕳 ⏩ 🛠️ ⏮️ FastAPI ✋️ 👈 🌖 🏋️, 🐕🦺 ✳, ✳ ⚖️ 🎏, ✅ <a href="https://github.com/encode/broadcaster" class="external-link" target="_blank">🗜/📻</a>. |
|
||||
|
|
||||
/// |
|
||||
|
|
||||
## 🌅 ℹ |
|
||||
|
|
||||
💡 🌅 🔃 🎛, ✅ 💃 🧾: |
|
||||
|
|
||||
* <a href="https://www.starlette.dev/websockets/" class="external-link" target="_blank"> `WebSocket` 🎓</a>. |
|
||||
* <a href="https://www.starlette.dev/endpoints/#websocketendpoint" class="external-link" target="_blank">🎓-⚓️ *️⃣ 🚚</a>. |
|
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue