diff --git a/.github/workflows/latest-changes.yml b/.github/workflows/latest-changes.yml
index 1f7ac7b286..0461f3dd3e 100644
--- a/.github/workflows/latest-changes.yml
+++ b/.github/workflows/latest-changes.yml
@@ -14,7 +14,7 @@ on:
debug_enabled:
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
required: false
- default: false
+ default: 'false'
jobs:
latest-changes:
@@ -22,12 +22,12 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
- # To allow latest-changes to commit to master
+ # To allow latest-changes to commit to the main branch
token: ${{ secrets.FASTAPI_LATEST_CHANGES }}
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
- if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
+ if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
with:
limit-access-to-actor: true
- uses: docker://tiangolo/latest-changes:0.0.3
diff --git a/.github/workflows/notify-translations.yml b/.github/workflows/notify-translations.yml
index 0926486e9b..cd7affbc39 100644
--- a/.github/workflows/notify-translations.yml
+++ b/.github/workflows/notify-translations.yml
@@ -5,6 +5,15 @@ on:
types:
- labeled
- closed
+ workflow_dispatch:
+ inputs:
+ number:
+ description: PR number
+ required: true
+ debug_enabled:
+ description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
+ required: false
+ default: 'false'
jobs:
notify-translations:
@@ -14,7 +23,7 @@ jobs:
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
- if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
+ if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
with:
limit-access-to-actor: true
- uses: ./.github/actions/notify-translations
diff --git a/.github/workflows/people.yml b/.github/workflows/people.yml
index dac526a6c7..aa7f34464e 100644
--- a/.github/workflows/people.yml
+++ b/.github/workflows/people.yml
@@ -8,7 +8,7 @@ on:
debug_enabled:
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
required: false
- default: false
+ default: 'false'
jobs:
fastapi-people:
@@ -22,7 +22,7 @@ jobs:
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
- if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
+ if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
with:
limit-access-to-actor: true
- uses: ./.github/actions/people
diff --git a/README.md b/README.md
index 36c71081ee..50f80ded67 100644
--- a/README.md
+++ b/README.md
@@ -48,6 +48,7 @@ The key features are:
+
diff --git a/docs/en/data/sponsors.yml b/docs/en/data/sponsors.yml
index 1b5240b5e3..53cdb9bad1 100644
--- a/docs/en/data/sponsors.yml
+++ b/docs/en/data/sponsors.yml
@@ -5,6 +5,9 @@ gold:
- url: https://platform.sh/try-it-now/?utm_source=fastapi-signup&utm_medium=banner&utm_campaign=FastAPI-signup-June-2023
title: "Build, run and scale your apps on a modern, reliable, and secure PaaS."
img: https://fastapi.tiangolo.com/img/sponsors/platform-sh.png
+ - url: https://www.buildwithfern.com/?utm_source=tiangolo&utm_medium=website&utm_campaign=main-badge
+ title: Fern | SDKs and API docs
+ img: https://fastapi.tiangolo.com/img/sponsors/fern.svg
silver:
- url: https://www.deta.sh/?ref=fastapi
title: The launchpad for all your (team's) ideas
diff --git a/docs/en/docs/advanced/generate-clients.md b/docs/en/docs/advanced/generate-clients.md
index f62c0b57c1..3fed48b0bc 100644
--- a/docs/en/docs/advanced/generate-clients.md
+++ b/docs/en/docs/advanced/generate-clients.md
@@ -12,6 +12,11 @@ A common tool is openapi-typescript-codegen.
+Another option you could consider for several languages is Fern.
+
+!!! info
+ Fern is also a FastAPI sponsor. 😎🎉
+
## Generate a TypeScript Frontend Client
Let's start with a simple FastAPI application:
diff --git a/docs/en/docs/alternatives.md b/docs/en/docs/alternatives.md
index 0f074ccf32..a777ddb98e 100644
--- a/docs/en/docs/alternatives.md
+++ b/docs/en/docs/alternatives.md
@@ -119,6 +119,8 @@ That's why when talking about version 2.0 it's common to say "Swagger", and for
These two were chosen for being fairly popular and stable, but doing a quick search, you could find dozens of additional alternative user interfaces for OpenAPI (that you can use with **FastAPI**).
+ For example, you could try Fern which is also a FastAPI sponsor. 😎🎉
+
### Flask REST frameworks
There are several Flask REST frameworks, but after investing the time and work into investigating them, I found that many are discontinued or abandoned, with several standing issues that made them unfit.
diff --git a/docs/en/docs/img/sponsors/fern-banner.png b/docs/en/docs/img/sponsors/fern-banner.png
new file mode 100644
index 0000000000..1b70ab96d9
Binary files /dev/null and b/docs/en/docs/img/sponsors/fern-banner.png differ
diff --git a/docs/en/docs/img/sponsors/fern-banner.svg b/docs/en/docs/img/sponsors/fern-banner.svg
new file mode 100644
index 0000000000..bb3a389f31
--- /dev/null
+++ b/docs/en/docs/img/sponsors/fern-banner.svg
@@ -0,0 +1 @@
+
diff --git a/docs/en/docs/img/sponsors/fern.png b/docs/en/docs/img/sponsors/fern.png
new file mode 100644
index 0000000000..4c6e54b0d5
Binary files /dev/null and b/docs/en/docs/img/sponsors/fern.png differ
diff --git a/docs/en/docs/img/sponsors/fern.svg b/docs/en/docs/img/sponsors/fern.svg
new file mode 100644
index 0000000000..ad3842fe03
--- /dev/null
+++ b/docs/en/docs/img/sponsors/fern.svg
@@ -0,0 +1 @@
+
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index 72fa346d13..ead095d8d6 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -2,11 +2,41 @@
## Latest Changes
+* 🔧 Update sponsor Fern. PR [#9979](https://github.com/tiangolo/fastapi/pull/9979) by [@tiangolo](https://github.com/tiangolo).
+* 👷 Update CI debug mode with Tmate. PR [#9977](https://github.com/tiangolo/fastapi/pull/9977) by [@tiangolo](https://github.com/tiangolo).
+* 🌐 Remove Vietnamese note about missing translation. PR [#9957](https://github.com/tiangolo/fastapi/pull/9957) by [@tiangolo](https://github.com/tiangolo).
+
+## 0.100.1
+
+### Fixes
+
+* 🐛 Replace `MultHostUrl` to `AnyUrl` for compatibility with older versions of Pydantic v1. PR [#9852](https://github.com/tiangolo/fastapi/pull/9852) by [@Kludex](https://github.com/Kludex).
+
+### Docs
+
+* 📝 Update links for self-hosted Swagger UI, point to v5, for OpenAPI 31.0. PR [#9834](https://github.com/tiangolo/fastapi/pull/9834) by [@tiangolo](https://github.com/tiangolo).
+
+### Translations
+
+* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/body.md`. PR [#4574](https://github.com/tiangolo/fastapi/pull/4574) by [@ss-o-furda](https://github.com/ss-o-furda).
+* 🌐 Add Vietnamese translation for `docs/vi/docs/features.md` and `docs/vi/docs/index.md`. PR [#3006](https://github.com/tiangolo/fastapi/pull/3006) by [@magiskboy](https://github.com/magiskboy).
+* 🌐 Add Korean translation for `docs/ko/docs/async.md`. PR [#4179](https://github.com/tiangolo/fastapi/pull/4179) by [@NinaHwang](https://github.com/NinaHwang).
+* 🌐 Add Chinese translation for `docs/zh/docs/tutorial/background-tasks.md`. PR [#9812](https://github.com/tiangolo/fastapi/pull/9812) by [@wdh99](https://github.com/wdh99).
+* 🌐 Add French translation for `docs/fr/docs/tutorial/query-params-str-validations.md`. PR [#4075](https://github.com/tiangolo/fastapi/pull/4075) by [@Smlep](https://github.com/Smlep).
+* 🌐 Add French translation for `docs/fr/docs/tutorial/index.md`. PR [#2234](https://github.com/tiangolo/fastapi/pull/2234) by [@JulianMaurin](https://github.com/JulianMaurin).
+* 🌐 Add French translation for `docs/fr/docs/contributing.md`. PR [#2132](https://github.com/tiangolo/fastapi/pull/2132) by [@JulianMaurin](https://github.com/JulianMaurin).
+* 🌐 Add French translation for `docs/fr/docs/benchmarks.md`. PR [#2155](https://github.com/tiangolo/fastapi/pull/2155) by [@clemsau](https://github.com/clemsau).
+* 🌐 Update Chinese translations with new source files. PR [#9738](https://github.com/tiangolo/fastapi/pull/9738) by [@mahone3297](https://github.com/mahone3297).
+* 🌐 Add Russian translation for `docs/ru/docs/tutorial/request-forms.md`. PR [#9841](https://github.com/tiangolo/fastapi/pull/9841) by [@dedkot01](https://github.com/dedkot01).
+* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/handling-errors.md`. PR [#9485](https://github.com/tiangolo/fastapi/pull/9485) by [@Creat55](https://github.com/Creat55).
+
+### Internal
+
+* 🔧 Update sponsors, add Fern. PR [#9956](https://github.com/tiangolo/fastapi/pull/9956) by [@tiangolo](https://github.com/tiangolo).
* 👷 Update FastAPI People token. PR [#9844](https://github.com/tiangolo/fastapi/pull/9844) by [@tiangolo](https://github.com/tiangolo).
* 👥 Update FastAPI People. PR [#9775](https://github.com/tiangolo/fastapi/pull/9775) by [@tiangolo](https://github.com/tiangolo).
* 👷 Update MkDocs Material token. PR [#9843](https://github.com/tiangolo/fastapi/pull/9843) by [@tiangolo](https://github.com/tiangolo).
* 👷 Update token for latest changes. PR [#9842](https://github.com/tiangolo/fastapi/pull/9842) by [@tiangolo](https://github.com/tiangolo).
-* 📝 Update links for self-hosted Swagger UI, point to v5, for OpenAPI 31.0. PR [#9834](https://github.com/tiangolo/fastapi/pull/9834) by [@tiangolo](https://github.com/tiangolo).
## 0.100.0
diff --git a/docs/en/mkdocs.yml b/docs/en/mkdocs.yml
index 030bbe5d3e..a186131858 100644
--- a/docs/en/mkdocs.yml
+++ b/docs/en/mkdocs.yml
@@ -59,6 +59,8 @@ nav:
- pt: /pt/
- ru: /ru/
- tr: /tr/
+ - uk: /uk/
+ - vi: /vi/
- zh: /zh/
- features.md
- fastapi-people.md
@@ -236,6 +238,10 @@ extra:
name: ru - русский язык
- link: /tr/
name: tr - Türkçe
+ - link: /uk/
+ name: uk
+ - link: /vi/
+ name: vi
- link: /zh/
name: zh - 汉语
extra_css:
diff --git a/docs/en/overrides/main.html b/docs/en/overrides/main.html
index 4608880f21..7e6c0f7634 100644
--- a/docs/en/overrides/main.html
+++ b/docs/en/overrides/main.html
@@ -34,6 +34,12 @@
+
+
+### Combiner liste de paramètres et valeurs par défaut
+
+Et l'on peut aussi définir une liste de valeurs par défaut si aucune n'est fournie :
+
+```Python hl_lines="9"
+{!../../../docs_src/query_params_str_validations/tutorial012.py!}
+```
+
+Si vous allez à :
+
+```
+http://localhost:8000/items/
+```
+
+la valeur par défaut de `q` sera : `["foo", "bar"]`
+
+et la réponse sera :
+
+```JSON
+{
+ "q": [
+ "foo",
+ "bar"
+ ]
+}
+```
+
+#### Utiliser `list`
+
+Il est aussi possible d'utiliser directement `list` plutôt que `List[str]` :
+
+```Python hl_lines="7"
+{!../../../docs_src/query_params_str_validations/tutorial013.py!}
+```
+
+!!! note
+ Dans ce cas-là, **FastAPI** ne vérifiera pas le contenu de la liste.
+
+ Par exemple, `List[int]` vérifiera (et documentera) que la liste est bien entièrement composée d'entiers. Alors qu'un simple `list` ne ferait pas cette vérification.
+
+## Déclarer des métadonnées supplémentaires
+
+On peut aussi ajouter plus d'informations sur le paramètre.
+
+Ces informations seront incluses dans le schéma `OpenAPI` généré et utilisées par la documentation interactive ou les outils externes utilisés.
+
+!!! note
+ Gardez en tête que les outils externes utilisés ne supportent pas forcément tous parfaitement OpenAPI.
+
+ Il se peut donc que certains d'entre eux n'utilisent pas toutes les métadonnées que vous avez déclarées pour le moment, bien que dans la plupart des cas, les fonctionnalités manquantes ont prévu d'être implémentées.
+
+Vous pouvez ajouter un `title` :
+
+```Python hl_lines="10"
+{!../../../docs_src/query_params_str_validations/tutorial007.py!}
+```
+
+Et une `description` :
+
+```Python hl_lines="13"
+{!../../../docs_src/query_params_str_validations/tutorial008.py!}
+```
+
+## Alias de paramètres
+
+Imaginez que vous vouliez que votre paramètre se nomme `item-query`.
+
+Comme dans la requête :
+
+```
+http://127.0.0.1:8000/items/?item-query=foobaritems
+```
+
+Mais `item-query` n'est pas un nom de variable valide en Python.
+
+Le nom le plus proche serait `item_query`.
+
+Mais vous avez vraiment envie que ce soit exactement `item-query`...
+
+Pour cela vous pouvez déclarer un `alias`, et cet alias est ce qui sera utilisé pour trouver la valeur du paramètre :
+
+```Python hl_lines="9"
+{!../../../docs_src/query_params_str_validations/tutorial009.py!}
+```
+
+## Déprécier des paramètres
+
+Disons que vous ne vouliez plus utiliser ce paramètre désormais.
+
+Il faut qu'il continue à exister pendant un certain temps car vos clients l'utilisent, mais vous voulez que la documentation mentionne clairement que ce paramètre est déprécié.
+
+On utilise alors l'argument `deprecated=True` de `Query` :
+
+```Python hl_lines="18"
+{!../../../docs_src/query_params_str_validations/tutorial010.py!}
+```
+
+La documentation le présentera comme il suit :
+
+
+
+## Pour résumer
+
+Il est possible d'ajouter des validateurs et métadonnées pour vos paramètres.
+
+Validateurs et métadonnées génériques:
+
+* `alias`
+* `title`
+* `description`
+* `deprecated`
+
+Validateurs spécifiques aux chaînes de caractères :
+
+* `min_length`
+* `max_length`
+* `regex`
+
+Parmi ces exemples, vous avez pu voir comment déclarer des validateurs pour les chaînes de caractères.
+
+Dans les prochains chapitres, vous verrez comment déclarer des validateurs pour d'autres types, comme les nombres.
diff --git a/docs/ko/docs/async.md b/docs/ko/docs/async.md
new file mode 100644
index 0000000000..47dbaa1b01
--- /dev/null
+++ b/docs/ko/docs/async.md
@@ -0,0 +1,404 @@
+# 동시성과 async / await
+
+*경로 작동 함수*에서의 `async def` 문법에 대한 세부사항과 비동기 코드, 동시성 및 병렬성에 대한 배경
+
+## 바쁘신 경우
+
+요약
+
+다음과 같이 `await`를 사용해 호출하는 제3의 라이브러리를 사용하는 경우:
+
+```Python
+results = await some_library()
+```
+
+다음처럼 *경로 작동 함수*를 `async def`를 사용해 선언하십시오:
+
+```Python hl_lines="2"
+@app.get('/')
+async def read_results():
+ results = await some_library()
+ return results
+```
+
+!!! note "참고"
+ `async def`로 생성된 함수 내부에서만 `await`를 사용할 수 있습니다.
+
+---
+
+데이터베이스, API, 파일시스템 등과 의사소통하는 제3의 라이브러리를 사용하고, 그것이 `await`를 지원하지 않는 경우(현재 거의 모든 데이터베이스 라이브러리가 그러합니다), *경로 작동 함수*를 일반적인 `def`를 사용해 선언하십시오:
+
+```Python hl_lines="2"
+@app.get('/')
+def results():
+ results = some_library()
+ return results
+```
+
+---
+
+만약 당신의 응용프로그램이 (어째서인지) 다른 무엇과 의사소통하고 그것이 응답하기를 기다릴 필요가 없다면 `async def`를 사용하십시오.
+
+---
+
+모르겠다면, 그냥 `def`를 사용하십시오.
+
+---
+
+**참고**: *경로 작동 함수*에서 필요한만큼 `def`와 `async def`를 혼용할 수 있고, 가장 알맞은 것을 선택해서 정의할 수 있습니다. FastAPI가 자체적으로 알맞은 작업을 수행할 것입니다.
+
+어찌되었든, 상기 어떠한 경우라도, FastAPI는 여전히 비동기적으로 작동하고 매우 빠릅니다.
+
+그러나 상기 작업을 수행함으로써 어느 정도의 성능 최적화가 가능합니다.
+
+## 기술적 세부사항
+
+최신 파이썬 버전은 `async`와 `await` 문법과 함께 **“코루틴”**이라고 하는 것을 사용하는 **“비동기 코드”**를 지원합니다.
+
+아래 섹션들에서 해당 문장을 부분별로 살펴보겠습니다:
+
+* **비동기 코드**
+* **`async`와 `await`**
+* **코루틴**
+
+## 비동기 코드
+
+비동기 코드란 언어 💬 가 코드의 어느 한 부분에서, 컴퓨터 / 프로그램🤖에게 *다른 무언가*가 어딘가에서 끝날 때까지 기다려야한다고 말하는 방식입니다. *다른 무언가*가 “느린-파일" 📝 이라고 불린다고 가정해봅시다.
+
+따라서 “느린-파일” 📝이 끝날때까지 컴퓨터는 다른 작업을 수행할 수 있습니다.
+
+그 다음 컴퓨터 / 프로그램 🤖 은 다시 기다리고 있기 때문에 기회가 있을 때마다 다시 돌아오거나, 혹은 당시에 수행해야하는 작업들이 완료될 때마다 다시 돌아옵니다. 그리고 그것 🤖 은 기다리고 있던 작업 중 어느 것이 이미 완료되었는지, 그것 🤖 이 해야하는 모든 작업을 수행하면서 확인합니다.
+
+다음으로, 그것 🤖 은 완료할 첫번째 작업에 착수하고(우리의 "느린-파일" 📝 이라고 가정합시다) 그에 대해 수행해야하는 작업을 계속합니다.
+
+"다른 무언가를 기다리는 것"은 일반적으로 비교적 "느린" (프로세서와 RAM 메모리 속도에 비해) I/O 작업을 의미합니다. 예를 들면 다음의 것들을 기다리는 것입니다:
+
+* 네트워크를 통해 클라이언트로부터 전송되는 데이터
+* 네트워크를 통해 클라이언트가 수신할, 당신의 프로그램으로부터 전송되는 데이터
+* 시스템이 읽고 프로그램에 전달할 디스크 내의 파일 내용
+* 당신의 프로그램이 시스템에 전달하는, 디스크에 작성될 내용
+* 원격 API 작업
+* 완료될 데이터베이스 작업
+* 결과를 반환하는 데이터베이스 쿼리
+* 기타
+
+수행 시간의 대부분이 I/O 작업을 기다리는데에 소요되기 때문에, "I/O에 묶인" 작업이라고 불립니다.
+
+이것은 "비동기"라고 불리는데 컴퓨터 / 프로그램이 작업 결과를 가지고 일을 수행할 수 있도록, 느린 작업에 "동기화"되어 아무것도 하지 않으면서 작업이 완료될 정확한 시점만을 기다릴 필요가 없기 때문입니다.
+
+이 대신에, "비동기" 시스템에서는, 작업은 일단 완료되면, 컴퓨터 / 프로그램이 수행하고 있는 일을 완료하고 이후 다시 돌아와서 그것의 결과를 받아 이를 사용해 작업을 지속할 때까지 잠시 (몇 마이크로초) 대기할 수 있습니다.
+
+"동기"("비동기"의 반대)는 컴퓨터 / 프로그램이 상이한 작업들간 전환을 하기 전에 그것이 대기를 동반하게 될지라도 모든 순서를 따르기 때문에 "순차"라는 용어로도 흔히 불립니다.
+
+### 동시성과 버거
+
+위에서 설명한 **비동기** 코드에 대한 개념은 종종 **"동시성"**이라고도 불립니다. 이것은 **"병렬성"**과는 다릅니다.
+
+**동시성**과 **병렬성**은 모두 "동시에 일어나는 서로 다른 일들"과 관련이 있습니다.
+
+하지만 *동시성*과 *병렬성*의 세부적인 개념에는 꽤 차이가 있습니다.
+
+차이를 확인하기 위해, 다음의 버거에 대한 이야기를 상상해보십시오:
+
+### 동시 버거
+
+당신은 짝사랑 상대 😍 와 패스트푸드 🍔 를 먹으러 갔습니다. 당신은 점원 💁 이 당신 앞에 있는 사람들의 주문을 받을 동안 줄을 서서 기다리고 있습니다.
+
+이제 당신의 순서가 되어서, 당신은 당신과 짝사랑 상대 😍 를 위한 두 개의 고급스러운 버거 🍔 를 주문합니다.
+
+당신이 돈을 냅니다 💸.
+
+점원 💁 은 주방 👨🍳 에 요리를 하라고 전달하고, 따라서 그들은 당신의 버거 🍔 를 준비해야한다는 사실을 알게됩니다(그들이 지금은 당신 앞 고객들의 주문을 준비하고 있을지라도 말입니다).
+
+점원 💁 은 당신의 순서가 적힌 번호표를 줍니다.
+
+기다리는 동안, 당신은 짝사랑 상대 😍 와 함께 테이블을 고르고, 자리에 앉아 오랫동안 (당신이 주문한 버거는 꽤나 고급스럽기 때문에 준비하는데 시간이 조금 걸립니다 ✨🍔✨) 대화를 나눕니다.
+
+짝사랑 상대 😍 와 테이블에 앉아서 버거 🍔 를 기다리는 동안, 그 사람 😍 이 얼마나 멋지고, 사랑스럽고, 똑똑한지 감탄하며 시간을 보냅니다 ✨😍✨.
+
+짝사랑 상대 😍 와 기다리면서 얘기하는 동안, 때때로, 당신은 당신의 차례가 되었는지 보기 위해 카운터의 번호를 확인합니다.
+
+그러다 어느 순간, 당신의 차례가 됩니다. 카운터에 가서, 버거 🍔 를 받고, 테이블로 다시 돌아옵니다.
+
+당신과 짝사랑 상대 😍 는 버거 🍔 를 먹으며 좋은 시간을 보냅니다 ✨.
+
+---
+
+당신이 이 이야기에서 컴퓨터 / 프로그램 🤖 이라고 상상해보십시오.
+
+줄을 서서 기다리는 동안, 당신은 아무것도 하지 않고 😴 당신의 차례를 기다리며, 어떠한 "생산적인" 일도 하지 않습니다. 하지만 점원 💁 이 (음식을 준비하지는 않고) 주문을 받기만 하기 때문에 줄이 빨리 줄어들어서 괜찮습니다.
+
+그다음, 당신이 차례가 오면, 당신은 실제로 "생산적인" 일 🤓 을 합니다. 당신은 메뉴를 보고, 무엇을 먹을지 결정하고, 짝사랑 상대 😍 의 선택을 묻고, 돈을 내고 💸 , 맞는 카드를 냈는지 확인하고, 비용이 제대로 지불되었는지 확인하고, 주문이 제대로 들어갔는지 확인을 하는 작업 등등을 수행합니다.
+
+하지만 이후에는, 버거 🍔 를 아직 받지 못했음에도, 버거가 준비될 때까지 기다려야 🕙 하기 때문에 점원 💁 과의 작업은 "일시정지" ⏸ 상태입니다.
+
+하지만 번호표를 받고 카운터에서 나와 테이블에 앉으면, 당신은 짝사랑 상대 😍 와 그 "작업" ⏯ 🤓 에 번갈아가며 🔀 집중합니다. 그러면 당신은 다시 짝사랑 상대 😍 에게 작업을 거는 매우 "생산적인" 일 🤓 을 합니다.
+
+점원 💁 이 카운터 화면에 당신의 번호를 표시함으로써 "버거 🍔 가 준비되었습니다"라고 해도, 당신은 즉시 뛰쳐나가지는 않을 것입니다. 당신은 당신의 번호를 갖고있고, 다른 사람들은 그들의 번호를 갖고있기 때문에, 아무도 당신의 버거 🍔 를 훔쳐가지 않는다는 사실을 알기 때문입니다.
+
+그래서 당신은 짝사랑 상대 😍 가 이야기를 끝낼 때까지 기다린 후 (현재 작업 완료 ⏯ / 진행 중인 작업 처리 🤓 ), 정중하게 미소짓고 버거를 가지러 가겠다고 말합니다 ⏸.
+
+그다음 당신은 카운터에 가서 🔀 , 초기 작업을 이제 완료하고 ⏯ , 버거 🍔 를 받고, 감사하다고 말하고 테이블로 가져옵니다. 이로써 카운터와의 상호작용 단계 / 작업이 종료됩니다 ⏹.
+
+이전 작업인 "버거 받기"가 종료되면 ⏹ "버거 먹기"라는 새로운 작업이 생성됩니다 🔀 ⏯.
+
+### 병렬 버거
+
+이제 "동시 버거"가 아닌 "병렬 버거"를 상상해보십시오.
+
+당신은 짝사랑 상대 😍 와 함께 병렬 패스트푸드 🍔 를 먹으러 갔습니다.
+
+당신은 여러명(8명이라고 가정합니다)의 점원이 당신 앞 사람들의 주문을 받으며 동시에 요리 👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳 도 하는 동안 줄을 서서 기다립니다.
+
+당신 앞 모든 사람들이 버거가 준비될 때까지 카운터에서 떠나지 않고 기다립니다 🕙 . 왜냐하면 8명의 직원들이 다음 주문을 받기 전에 버거를 준비하러 가기 때문입니다.
+
+마침내 당신의 차례가 왔고, 당신은 당신과 짝사랑 상대 😍 를 위한 두 개의 고급스러운 버거 🍔 를 주문합니다.
+
+당신이 비용을 지불합니다 💸 .
+
+점원이 주방에 갑니다 👨🍳 .
+
+당신은 번호표가 없기 때문에 누구도 당신의 버거 🍔 를 대신 가져갈 수 없도록 카운터에 서서 기다립니다 🕙 .
+
+당신과 짝사랑 상대 😍 는 다른 사람이 새치기해서 버거를 가져가지 못하게 하느라 바쁘기 때문에 🕙 , 짝사랑 상대에게 주의를 기울일 수 없습니다 😞 .
+
+이것은 "동기" 작업이고, 당신은 점원/요리사 👨🍳 와 "동기화" 되었습니다. 당신은 기다리고 🕙 , 점원/요리사 👨🍳 가 버거 🍔 준비를 완료한 후 당신에게 주거나, 누군가가 그것을 가져가는 그 순간에 그 곳에 있어야합니다.
+
+카운터 앞에서 오랫동안 기다린 후에 🕙 , 점원/요리사 👨🍳 가 당신의 버거 🍔 를 가지고 돌아옵니다.
+
+당신은 버거를 받고 짝사랑 상대와 함께 테이블로 돌아옵니다.
+
+단지 먹기만 하다가, 다 먹었습니다 🍔 ⏹.
+
+카운터 앞에서 기다리면서 🕙 너무 많은 시간을 허비했기 때문에 대화를 하거나 작업을 걸 시간이 거의 없었습니다 😞 .
+
+---
+
+이 병렬 버거 시나리오에서, 당신은 기다리고 🕙 , 오랜 시간동안 "카운터에서 기다리는" 🕙 데에 주의를 기울이는 ⏯ 두 개의 프로세서(당신과 짝사랑 상대😍)를 가진 컴퓨터 / 프로그램 🤖 입니다.
+
+패스트푸드점에는 8개의 프로세서(점원/요리사) 👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳 가 있습니다. 동시 버거는 단 두 개(한 명의 직원과 한 명의 요리사) 💁 👨🍳 만을 가지고 있었습니다.
+
+하지만 여전히, 병렬 버거 예시가 최선은 아닙니다 😞 .
+
+---
+
+이 예시는 버거🍔 이야기와 결이 같습니다.
+
+더 "현실적인" 예시로, 은행을 상상해보십시오.
+
+최근까지, 대다수의 은행에는 다수의 은행원들 👨💼👨💼👨💼👨💼 과 긴 줄 🕙🕙🕙🕙🕙🕙🕙🕙 이 있습니다.
+
+모든 은행원들은 한 명 한 명의 고객들을 차례로 상대합니다 👨💼⏯ .
+
+그리고 당신은 오랫동안 줄에서 기다려야하고 🕙 , 그렇지 않으면 당신의 차례를 잃게 됩니다.
+
+아마 당신은 은행 🏦 심부름에 짝사랑 상대 😍 를 데려가고 싶지는 않을 것입니다.
+
+### 버거 예시의 결론
+
+"짝사랑 상대와의 패스트푸드점 버거" 시나리오에서, 오랜 기다림 🕙 이 있기 때문에 동시 시스템 ⏸🔀⏯ 을 사용하는 것이 더 합리적입니다.
+
+대다수의 웹 응용프로그램의 경우가 그러합니다.
+
+매우 많은 수의 유저가 있지만, 서버는 그들의 요청을 전송하기 위해 그닥-좋지-않은 연결을 기다려야 합니다 🕙 .
+
+그리고 응답이 돌아올 때까지 다시 기다려야 합니다 🕙 .
+
+이 "기다림" 🕙 은 마이크로초 단위이지만, 모두 더해지면, 결국에는 매우 긴 대기시간이 됩니다.
+
+따라서 웹 API를 위해 비동기 ⏸🔀⏯ 코드를 사용하는 것이 합리적입니다.
+
+대부분의 존재하는 유명한 파이썬 프레임워크 (Flask와 Django 등)은 새로운 비동기 기능들이 파이썬에 존재하기 전에 만들어졌습니다. 그래서, 그들의 배포 방식은 병렬 실행과 새로운 기능만큼 강력하지는 않은 예전 버전의 비동기 실행을 지원합니다.
+
+비동기 웹 파이썬(ASGI)에 대한 주요 명세가 웹소켓을 지원하기 위해 Django에서 개발 되었음에도 그렇습니다.
+
+이러한 종류의 비동기성은 (NodeJS는 병렬적이지 않음에도) NodeJS가 사랑받는 이유이고, 프로그래밍 언어로서의 Go의 강점입니다.
+
+그리고 **FastAPI**를 사용함으로써 동일한 성능을 낼 수 있습니다.
+
+또한 병렬성과 비동기성을 동시에 사용할 수 있기 때문에, 대부분의 테스트가 완료된 NodeJS 프레임워크보다 더 높은 성능을 얻고 C에 더 가까운 컴파일 언어인 Go와 동등한 성능을 얻을 수 있습니다(모두 Starlette 덕분입니다).
+
+### 동시성이 병렬성보다 더 나은가?
+
+그렇지 않습니다! 그것이 이야기의 교훈은 아닙니다.
+
+동시성은 병렬성과 다릅니다. 그리고 그것은 많은 대기를 필요로하는 **특정한** 시나리오에서는 더 낫습니다. 이로 인해, 웹 응용프로그램 개발에서 동시성이 병렬성보다 일반적으로 훨씬 낫습니다. 하지만 모든 경우에 그런 것은 아닙니다.
+
+따라서, 균형을 맞추기 위해, 다음의 짧은 이야기를 상상해보십시오:
+
+> 당신은 크고, 더러운 집을 청소해야합니다.
+
+*네, 이게 전부입니다*.
+
+---
+
+어디에도 대기 🕙 는 없고, 집안 곳곳에서 해야하는 많은 작업들만 있습니다.
+
+버거 예시처럼 처음에는 거실, 그 다음은 부엌과 같은 식으로 순서를 정할 수도 있으나, 무엇도 기다리지 🕙 않고 계속해서 청소 작업만 수행하기 때문에, 순서는 아무런 영향을 미치지 않습니다.
+
+순서가 있든 없든 동일한 시간이 소요될 것이고(동시성) 동일한 양의 작업을 하게 될 것입니다.
+
+하지만 이 경우에서, 8명의 전(前)-점원/요리사이면서-현(現)-청소부 👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳 를 고용할 수 있고, 그들 각자(그리고 당신)가 집의 한 부분씩 맡아 청소를 한다면, 당신은 **병렬적**으로 작업을 수행할 수 있고, 조금의 도움이 있다면, 훨씬 더 빨리 끝낼 수 있습니다.
+
+이 시나리오에서, (당신을 포함한) 각각의 청소부들은 프로세서가 될 것이고, 각자의 역할을 수행합니다.
+
+실행 시간의 대부분이 대기가 아닌 실제 작업에 소요되고, 컴퓨터에서 작업은 CPU에서 이루어지므로, 이러한 문제를 "CPU에 묶였"다고 합니다.
+
+---
+
+CPU에 묶인 연산에 관한 흔한 예시는 복잡한 수학 처리를 필요로 하는 경우입니다.
+
+예를 들어:
+
+* **오디오** 또는 **이미지** 처리.
+* **컴퓨터 비전**: 하나의 이미지는 수백개의 픽셀로 구성되어있고, 각 픽셀은 3개의 값 / 색을 갖고 있으며, 일반적으로 해당 픽셀들에 대해 동시에 무언가를 계산해야하는 처리.
+* **머신러닝**: 일반적으로 많은 "행렬"과 "벡터" 곱셈이 필요합니다. 거대한 스프레드 시트에 수들이 있고 그 수들을 동시에 곱해야 한다고 생각해보십시오.
+* **딥러닝**: 머신러닝의 하위영역으로, 동일한 예시가 적용됩니다. 단지 이 경우에는 하나의 스프레드 시트에 곱해야할 수들이 있는 것이 아니라, 거대한 세트의 스프레드 시트들이 있고, 많은 경우에, 이 모델들을 만들고 사용하기 위해 특수한 프로세서를 사용합니다.
+
+### 동시성 + 병렬성: 웹 + 머신러닝
+
+**FastAPI**를 사용하면 웹 개발에서는 매우 흔한 동시성의 이점을 (NodeJS의 주된 매력만큼) 얻을 수 있습니다.
+
+뿐만 아니라 머신러닝 시스템과 같이 **CPU에 묶인** 작업을 위해 병렬성과 멀티프로세싱(다수의 프로세스를 병렬적으로 동작시키는 것)을 이용하는 것도 가능합니다.
+
+파이썬이 **데이터 사이언스**, 머신러닝과 특히 딥러닝에 의 주된 언어라는 간단한 사실에 더해서, 이것은 FastAPI를 데이터 사이언스 / 머신러닝 웹 API와 응용프로그램에 (다른 것들보다) 좋은 선택지가 되게 합니다.
+
+배포시 병렬을 어떻게 가능하게 하는지 알고싶다면, [배포](/ko/deployment){.internal-link target=_blank}문서를 참고하십시오.
+
+## `async`와 `await`
+
+최신 파이썬 버전에는 비동기 코드를 정의하는 매우 직관적인 방법이 있습니다. 이는 이것을 평범한 "순차적" 코드로 보이게 하고, 적절한 순간에 당신을 위해 "대기"합니다.
+
+연산이 결과를 전달하기 전에 대기를 해야하고 새로운 파이썬 기능들을 지원한다면, 이렇게 코드를 작성할 수 있습니다:
+
+```Python
+burgers = await get_burgers(2)
+```
+
+여기서 핵심은 `await`입니다. 이것은 파이썬에게 `burgers` 결과를 저장하기 이전에 `get_burgers(2)`의 작업이 완료되기를 🕙 기다리라고 ⏸ 말합니다. 이로 인해, 파이썬은 그동안 (다른 요청을 받는 것과 같은) 다른 작업을 수행해도 된다는 것을 🔀 ⏯ 알게될 것입니다.
+
+`await`가 동작하기 위해, 이것은 비동기를 지원하는 함수 내부에 있어야 합니다. 이를 위해서 함수를 `async def`를 사용해 정의하기만 하면 됩니다:
+
+```Python hl_lines="1"
+async def get_burgers(number: int):
+ # Do some asynchronous stuff to create the burgers
+ return burgers
+```
+
+...`def`를 사용하는 대신:
+
+```Python hl_lines="2"
+# This is not asynchronous
+def get_sequential_burgers(number: int):
+ # Do some sequential stuff to create the burgers
+ return burgers
+```
+
+`async def`를 사용하면, 파이썬은 해당 함수 내에서 `await` 표현에 주의해야한다는 사실과, 해당 함수의 실행을 "일시정지"⏸하고 다시 돌아오기 전까지 다른 작업을 수행🔀할 수 있다는 것을 알게됩니다.
+
+`async def`f 함수를 호출하고자 할 때, "대기"해야합니다. 따라서, 아래는 동작하지 않습니다.
+
+```Python
+# This won't work, because get_burgers was defined with: async def
+burgers = get_burgers(2)
+```
+
+---
+
+따라서, `await`f를 사용해서 호출할 수 있는 라이브러리를 사용한다면, 다음과 같이 `async def`를 사용하는 *경로 작동 함수*를 생성해야 합니다:
+
+```Python hl_lines="2-3"
+@app.get('/burgers')
+async def read_burgers():
+ burgers = await get_burgers(2)
+ return burgers
+```
+
+### 더 세부적인 기술적 사항
+
+`await`가 `async def`를 사용하는 함수 내부에서만 사용이 가능하다는 것을 눈치채셨을 것입니다.
+
+하지만 동시에, `async def`로 정의된 함수들은 "대기"되어야만 합니다. 따라서, `async def`를 사용한 함수들은 역시 `async def`를 사용한 함수 내부에서만 호출될 수 있습니다.
+
+그렇다면 닭이 먼저냐, 달걀이 먼저냐, 첫 `async` 함수를 어떻게 호출할 수 있겠습니까?
+
+**FastAPI**를 사용해 작업한다면 이것을 걱정하지 않아도 됩니다. 왜냐하면 그 "첫" 함수는 당신의 *경로 작동 함수*가 될 것이고, FastAPI는 어떻게 올바르게 처리할지 알고있기 때문입니다.
+
+하지만 FastAPI를 사용하지 않고 `async` / `await`를 사용하고 싶다면, 이 역시 가능합니다.
+
+### 당신만의 비동기 코드 작성하기
+
+Starlette(그리고 FastAPI)는 AnyIO를 기반으로 하고있고, 따라서 파이썬 표준 라이브러리인 asyncio 및 Trio와 호환됩니다.
+
+특히, 코드에서 고급 패턴이 필요한 고급 동시성을 사용하는 경우 직접적으로 AnyIO를 사용할 수 있습니다.
+
+FastAPI를 사용하지 않더라도, 높은 호환성 및 AnyIO의 이점(예: *구조화된 동시성*)을 취하기 위해 AnyIO를 사용해 비동기 응용프로그램을 작성할 수 있습니다.
+
+### 비동기 코드의 다른 형태
+
+파이썬에서 `async`와 `await`를 사용하게 된 것은 비교적 최근의 일입니다.
+
+하지만 이로 인해 비동기 코드 작업이 훨씬 간단해졌습니다.
+
+같은 (또는 거의 유사한) 문법은 최신 버전의 자바스크립트(브라우저와 NodeJS)에도 추가되었습니다.
+
+하지만 그 이전에, 비동기 코드를 처리하는 것은 꽤 복잡하고 어려운 일이었습니다.
+
+파이썬의 예전 버전이라면, 스레드 또는 Gevent를 사용할 수 있을 것입니다. 하지만 코드를 이해하고, 디버깅하고, 이에 대해 생각하는게 훨씬 복잡합니다.
+
+예전 버전의 NodeJS / 브라우저 자바스크립트라면, "콜백 함수"를 사용했을 것입니다. 그리고 이로 인해 콜백 지옥에 빠지게 될 수 있습니다.
+
+## 코루틴
+
+**코루틴**은 `async def` 함수가 반환하는 것을 칭하는 매우 고급스러운 용어일 뿐입니다. 파이썬은 그것이 시작되고 어느 시점에서 완료되지만 내부에 `await`가 있을 때마다 내부적으로 일시정지⏸될 수도 있는 함수와 유사한 것이라는 사실을 알고있습니다.
+
+그러나 `async` 및 `await`와 함께 비동기 코드를 사용하는 이 모든 기능들은 "코루틴"으로 간단히 요약됩니다. 이것은 Go의 주된 핵심 기능인 "고루틴"에 견줄 수 있습니다.
+
+## 결론
+
+상기 문장을 다시 한 번 봅시다:
+
+> 최신 파이썬 버전은 **`async` 및 `await`** 문법과 함께 **“코루틴”**이라고 하는 것을 사용하는 **“비동기 코드”**를 지원합니다.
+
+이제 이 말을 조금 더 이해할 수 있을 것입니다. ✨
+
+이것이 (Starlette을 통해) FastAPI를 강하게 하면서 그것이 인상적인 성능을 낼 수 있게 합니다.
+
+## 매우 세부적인 기술적 사항
+
+!!! warning "경고"
+ 이 부분은 넘어가도 됩니다.
+
+ 이것들은 **FastAPI**가 내부적으로 어떻게 동작하는지에 대한 매우 세부적인 기술사항입니다.
+
+ 만약 기술적 지식(코루틴, 스레드, 블록킹 등)이 있고 FastAPI가 어떻게 `async def` vs `def`를 다루는지 궁금하다면, 계속하십시오.
+
+### 경로 작동 함수
+
+경로 작동 함수를 `async def` 대신 일반적인 `def`로 선언하는 경우, (서버를 차단하는 것처럼) 그것을 직접 호출하는 대신 대기중인 외부 스레드풀에서 실행됩니다.
+
+만약 상기에 묘사된대로 동작하지 않는 비동기 프로그램을 사용해왔고 약간의 성능 향상 (약 100 나노초)을 위해 `def`를 사용해서 계산만을 위한 사소한 *경로 작동 함수*를 정의해왔다면, **FastAPI**는 이와는 반대라는 것에 주의하십시오. 이러한 경우에, *경로 작동 함수*가 블로킹 I/O를 수행하는 코드를 사용하지 않는 한 `async def`를 사용하는 편이 더 낫습니다.
+
+하지만 두 경우 모두, FastAPI가 당신이 전에 사용하던 프레임워크보다 [더 빠를](/#performance){.internal-link target=_blank} (최소한 비견될) 확률이 높습니다.
+
+### 의존성
+
+의존성에도 동일하게 적용됩니다. 의존성이 `async def`가 아닌 표준 `def` 함수라면, 외부 스레드풀에서 실행됩니다.
+
+### 하위-의존성
+
+함수 정의시 매개변수로 서로를 필요로하는 다수의 의존성과 하위-의존성을 가질 수 있고, 그 중 일부는 `async def`로, 다른 일부는 일반적인 `def`로 생성되었을 수 있습니다. 이것은 여전히 잘 동작하고, 일반적인 `def`로 생성된 것들은 "대기"되는 대신에 (스레드풀로부터) 외부 스레드에서 호출됩니다.
+
+### 다른 유틸리티 함수
+
+직접 호출되는 다른 모든 유틸리티 함수는 일반적인 `def`나 `async def`로 생성될 수 있고 FastAPI는 이를 호출하는 방식에 영향을 미치지 않습니다.
+
+이것은 FastAPI가 당신을 위해 호출하는 함수와는 반대입니다: *경로 작동 함수*와 의존성
+
+만약 당신의 유틸리티 함수가 `def`를 사용한 일반적인 함수라면, 스레드풀에서가 아니라 직접 호출(당신이 코드에 작성한 대로)될 것이고, `async def`로 생성된 함수라면 코드에서 호출할 때 그 함수를 `await` 해야 합니다.
+
+---
+
+다시 말하지만, 이것은 당신이 이것에 대해 찾고있던 경우에 한해 유용할 매우 세부적인 기술사항입니다.
+
+그렇지 않은 경우, 상기의 가이드라인만으로도 충분할 것입니다: [바쁘신 경우](#in-a-hurry).
diff --git a/docs/ru/docs/tutorial/request-forms.md b/docs/ru/docs/tutorial/request-forms.md
new file mode 100644
index 0000000000..a20cf78e0a
--- /dev/null
+++ b/docs/ru/docs/tutorial/request-forms.md
@@ -0,0 +1,92 @@
+# Данные формы
+
+Когда вам нужно получить поля формы вместо JSON, вы можете использовать `Form`.
+
+!!! info "Дополнительная информация"
+ Чтобы использовать формы, сначала установите `python-multipart`.
+
+ Например, выполните команду `pip install python-multipart`.
+
+## Импорт `Form`
+
+Импортируйте `Form` из `fastapi`:
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="3"
+ {!> ../../../docs_src/request_forms/tutorial001_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/request_forms/tutorial001_an.py!}
+ ```
+
+=== "Python 3.6+ без Annotated"
+
+ !!! tip "Подсказка"
+ Рекомендуется использовать 'Annotated' версию, если это возможно.
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/request_forms/tutorial001.py!}
+ ```
+
+## Определение параметров `Form`
+
+Создайте параметры формы так же, как это делается для `Body` или `Query`:
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/request_forms/tutorial001_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="8"
+ {!> ../../../docs_src/request_forms/tutorial001_an.py!}
+ ```
+
+=== "Python 3.6+ без Annotated"
+
+ !!! tip "Подсказка"
+ Рекомендуется использовать 'Annotated' версию, если это возможно.
+
+ ```Python hl_lines="7"
+ {!> ../../../docs_src/request_forms/tutorial001.py!}
+ ```
+
+Например, в одном из способов использования спецификации OAuth2 (называемом "потоком пароля") требуется отправить `username` и `password` в виде полей формы.
+
+Данный способ требует отправку данных для авторизации посредством формы (а не JSON) и обязательного наличия в форме строго именованных полей `username` и `password`.
+
+Вы можете настроить `Form` точно так же, как настраиваете и `Body` ( `Query`, `Path`, `Cookie`), включая валидации, примеры, псевдонимы (например, `user-name` вместо `username`) и т.д.
+
+!!! info "Дополнительная информация"
+ `Form` - это класс, который наследуется непосредственно от `Body`.
+
+!!! tip "Подсказка"
+ Вам необходимо явно указывать параметр `Form` при объявлении каждого поля, иначе поля будут интерпретироваться как параметры запроса или параметры тела (JSON).
+
+## О "полях формы"
+
+Обычно способ, которым HTML-формы (``) отправляют данные на сервер, использует "специальное" кодирование для этих данных, отличное от JSON.
+
+**FastAPI** гарантирует правильное чтение этих данных из соответствующего места, а не из JSON.
+
+!!! note "Технические детали"
+ Данные из форм обычно кодируются с использованием "типа медиа" `application/x-www-form-urlencoded`.
+
+ Но когда форма содержит файлы, она кодируется как `multipart/form-data`. Вы узнаете о работе с файлами в следующей главе.
+
+ Если вы хотите узнать больше про кодировки и поля формы, ознакомьтесь с документацией MDN для `POST` на веб-сайте.
+
+!!! warning "Предупреждение"
+ Вы можете объявлять несколько параметров `Form` в *операции пути*, но вы не можете одновременно с этим объявлять поля `Body`, которые вы ожидаете получить в виде JSON, так как запрос будет иметь тело, закодированное с использованием `application/x-www-form-urlencoded`, а не `application/json`.
+
+ Это не ограничение **FastAPI**, это часть протокола HTTP.
+
+## Резюме
+
+Используйте `Form` для объявления входных параметров данных формы.
diff --git a/docs/uk/docs/tutorial/body.md b/docs/uk/docs/tutorial/body.md
new file mode 100644
index 0000000000..e78c5de0e3
--- /dev/null
+++ b/docs/uk/docs/tutorial/body.md
@@ -0,0 +1,213 @@
+# Тіло запиту
+
+Коли вам потрібно надіслати дані з клієнта (скажімо, браузера) до вашого API, ви надсилаєте їх як **тіло запиту**.
+
+Тіло **запиту** — це дані, надіслані клієнтом до вашого API. Тіло **відповіді** — це дані, які ваш API надсилає клієнту.
+
+Ваш API майже завжди має надсилати тіло **відповіді**. Але клієнтам не обов’язково потрібно постійно надсилати тіла **запитів**.
+
+Щоб оголосити тіло **запиту**, ви використовуєте Pydantic моделі з усією їх потужністю та перевагами.
+
+!!! info
+ Щоб надіслати дані, ви повинні використовувати один із: `POST` (більш поширений), `PUT`, `DELETE` або `PATCH`.
+
+ Надсилання тіла із запитом `GET` має невизначену поведінку в специфікаціях, проте воно підтримується FastAPI лише для дуже складних/екстремальних випадків використання.
+
+ Оскільки це не рекомендується, інтерактивна документація з Swagger UI не відображатиме документацію для тіла запиту під час використання `GET`, і проксі-сервери в середині можуть не підтримувати її.
+
+## Імпортуйте `BaseModel` від Pydantic
+
+Спочатку вам потрібно імпортувати `BaseModel` з `pydantic`:
+
+=== "Python 3.6 і вище"
+
+ ```Python hl_lines="4"
+ {!> ../../../docs_src/body/tutorial001.py!}
+ ```
+
+=== "Python 3.10 і вище"
+
+ ```Python hl_lines="2"
+ {!> ../../../docs_src/body/tutorial001_py310.py!}
+ ```
+
+## Створіть свою модель даних
+
+Потім ви оголошуєте свою модель даних як клас, який успадковується від `BaseModel`.
+
+Використовуйте стандартні типи Python для всіх атрибутів:
+
+=== "Python 3.6 і вище"
+
+ ```Python hl_lines="7-11"
+ {!> ../../../docs_src/body/tutorial001.py!}
+ ```
+
+=== "Python 3.10 і вище"
+
+ ```Python hl_lines="5-9"
+ {!> ../../../docs_src/body/tutorial001_py310.py!}
+ ```
+
+Так само, як і при оголошенні параметрів запиту, коли атрибут моделі має значення за замовчуванням, він не є обов’язковим. В іншому випадку це потрібно. Використовуйте `None`, щоб зробити його необов'язковим.
+
+Наприклад, ця модель вище оголошує JSON "`об'єкт`" (або Python `dict`), як:
+
+```JSON
+{
+ "name": "Foo",
+ "description": "An optional description",
+ "price": 45.2,
+ "tax": 3.5
+}
+```
+
+...оскільки `description` і `tax` є необов'язковими (зі значенням за замовчуванням `None`), цей JSON "`об'єкт`" також буде дійсним:
+
+```JSON
+{
+ "name": "Foo",
+ "price": 45.2
+}
+```
+
+## Оголоси її як параметр
+
+Щоб додати модель даних до вашої *операції шляху*, оголосіть її так само, як ви оголосили параметри шляху та запиту:
+
+=== "Python 3.6 і вище"
+
+ ```Python hl_lines="18"
+ {!> ../../../docs_src/body/tutorial001.py!}
+ ```
+
+=== "Python 3.10 і вище"
+
+ ```Python hl_lines="16"
+ {!> ../../../docs_src/body/tutorial001_py310.py!}
+ ```
+
+...і вкажіть її тип як модель, яку ви створили, `Item`.
+
+## Результати
+
+Лише з цим оголошенням типу Python **FastAPI** буде:
+
+* Читати тіло запиту як JSON.
+* Перетворювати відповідні типи (якщо потрібно).
+* Валідувати дані.
+ * Якщо дані недійсні, він поверне гарну та чітку помилку, вказуючи, де саме і які дані були неправильними.
+* Надавати отримані дані у параметрі `item`.
+ * Оскільки ви оголосили його у функції як тип `Item`, ви також матимете всю підтримку редактора (автозаповнення, тощо) для всіх атрибутів та їх типів.
+* Генерувати JSON Schema визначення для вашої моделі, ви також можете використовувати їх де завгодно, якщо це має сенс для вашого проекту.
+* Ці схеми будуть частиною згенерованої схеми OpenAPI і використовуватимуться автоматичною документацією інтерфейсу користувача.
+
+## Автоматична документація
+
+Схеми JSON ваших моделей будуть частиною вашої схеми, згенерованої OpenAPI, і будуть показані в інтерактивній API документації:
+
+
+
+А також використовуватимуться в API документації всередині кожної *операції шляху*, якій вони потрібні:
+
+
+
+## Підтримка редактора
+
+У вашому редакторі, всередині вашої функції, ви будете отримувати підказки типу та завершення скрізь (це б не сталося, якби ви отримали `dict` замість моделі Pydantic):
+
+
+
+Ви також отримуєте перевірку помилок на наявність операцій з неправильним типом:
+
+
+
+Це не випадково, весь каркас був побудований навколо цього дизайну.
+
+І він був ретельно перевірений на етапі проектування, перед будь-яким впровадженням, щоб переконатися, що він працюватиме з усіма редакторами.
+
+Були навіть деякі зміни в самому Pydantic, щоб підтримати це.
+
+Попередні скріншоти були зроблені у Visual Studio Code.
+
+Але ви отримаєте ту саму підтримку редактора у PyCharm та більшість інших редакторів Python:
+
+
+
+!!! tip
+ Якщо ви використовуєте PyCharm як ваш редактор, ви можете використати Pydantic PyCharm Plugin.
+
+ Він покращує підтримку редакторів для моделей Pydantic за допомогою:
+
+ * автозаповнення
+ * перевірки типу
+ * рефакторингу
+ * пошуку
+ * інспекції
+
+## Використовуйте модель
+
+Усередині функції ви можете отримати прямий доступ до всіх атрибутів об’єкта моделі:
+
+=== "Python 3.6 і вище"
+
+ ```Python hl_lines="21"
+ {!> ../../../docs_src/body/tutorial002.py!}
+ ```
+
+=== "Python 3.10 і вище"
+
+ ```Python hl_lines="19"
+ {!> ../../../docs_src/body/tutorial002_py310.py!}
+ ```
+
+## Тіло запиту + параметри шляху
+
+Ви можете одночасно оголошувати параметри шляху та тіло запиту.
+
+**FastAPI** розпізнає, що параметри функції, які відповідають параметрам шляху, мають бути **взяті з шляху**, а параметри функції, які оголошуються як моделі Pydantic, **взяті з тіла запиту**.
+
+=== "Python 3.6 і вище"
+
+ ```Python hl_lines="17-18"
+ {!> ../../../docs_src/body/tutorial003.py!}
+ ```
+
+=== "Python 3.10 і вище"
+
+ ```Python hl_lines="15-16"
+ {!> ../../../docs_src/body/tutorial003_py310.py!}
+ ```
+
+## Тіло запиту + шлях + параметри запиту
+
+Ви також можете оголосити параметри **тіло**, **шлях** і **запит** одночасно.
+
+**FastAPI** розпізнає кожен з них і візьме дані з потрібного місця.
+
+=== "Python 3.6 і вище"
+
+ ```Python hl_lines="18"
+ {!> ../../../docs_src/body/tutorial004.py!}
+ ```
+
+=== "Python 3.10 і вище"
+
+ ```Python hl_lines="16"
+ {!> ../../../docs_src/body/tutorial004_py310.py!}
+ ```
+
+Параметри функції будуть розпізнаватися наступним чином:
+
+* Якщо параметр також оголошено в **шляху**, він використовуватиметься як параметр шляху.
+* Якщо параметр має **сингулярний тип** (наприклад, `int`, `float`, `str`, `bool` тощо), він буде інтерпретуватися як параметр **запиту**.
+* Якщо параметр оголошується як тип **Pydantic моделі**, він інтерпретується як **тіло** запиту.
+
+!!! note
+ FastAPI буде знати, що значення "q" не є обов'язковим через значення за замовчуванням "= None".
+
+ `Optional` у `Optional[str]` не використовується FastAPI, але дозволить вашому редактору надати вам кращу підтримку та виявляти помилки.
+
+## Без Pydantic
+
+Якщо ви не хочете використовувати моделі Pydantic, ви також можете використовувати параметри **Body**. Перегляньте документацію для [Тіло – Кілька параметрів: сингулярні значення в тілі](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}.
diff --git a/docs/uk/mkdocs.yml b/docs/uk/mkdocs.yml
new file mode 100644
index 0000000000..de18856f44
--- /dev/null
+++ b/docs/uk/mkdocs.yml
@@ -0,0 +1 @@
+INHERIT: ../en/mkdocs.yml
diff --git a/docs/vi/docs/features.md b/docs/vi/docs/features.md
new file mode 100644
index 0000000000..0599530e8c
--- /dev/null
+++ b/docs/vi/docs/features.md
@@ -0,0 +1,197 @@
+# Tính năng
+
+## Tính năng của FastAPI
+
+**FastAPI** cho bạn những tính năng sau:
+
+### Dựa trên những tiêu chuẩn mở
+
+* OpenAPI cho việc tạo API, bao gồm những khai báo về đường dẫn các toán tử, tham số, body requests, cơ chế bảo mật, etc.
+* Tự động tài liệu hóa data model theo JSON Schema (OpenAPI bản thân nó được dựa trên JSON Schema).
+* Được thiết kế xung quanh các tiêu chuẩn này sau khi nghiên cứu tỉ mỉ thay vì chỉ suy nghĩ đơn giản và sơ xài.
+* Điều này cho phép tự động hóa **trình sinh code client** cho nhiều ngôn ngữ lập trình khác nhau.
+
+### Tự động hóa tài liệu
+
+
+Tài liệu tương tác API và web giao diện người dùng. Là một framework được dựa trên OpenAPI do đó có nhiều tùy chọn giao diện cho tài liệu API, 2 giao diện bên dưới là mặc định.
+
+* Swagger UI, với giao diện khám phá, gọi và kiểm thử API trực tiếp từ trình duyệt.
+
+
+
+* Thay thế với tài liệu API với ReDoc.
+
+
+
+### Chỉ cần phiên bản Python hiện đại
+
+Tất cả được dựa trên khai báo kiểu dữ liệu chuẩn của **Python 3.6** (cảm ơn Pydantic). Bạn không cần học cú pháp mới, chỉ cần biết chuẩn Python hiện đại.
+
+Nếu bạn cần 2 phút để làm mới lại cách sử dụng các kiểu dữ liệu mới của Python (thậm chí nếu bạn không sử dụng FastAPI), xem hướng dẫn ngắn: [Kiểu dữ liệu Python](python-types.md){.internal-link target=_blank}.
+
+Bạn viết chuẩn Python với kiểu dữ liệu như sau:
+
+```Python
+from datetime import date
+
+from pydantic import BaseModel
+
+# Declare a variable as a str
+# and get editor support inside the function
+def main(user_id: str):
+ return user_id
+
+
+# A Pydantic model
+class User(BaseModel):
+ id: int
+ name: str
+ joined: date
+```
+
+Sau đó có thể được sử dụng:
+
+```Python
+my_user: User = User(id=3, name="John Doe", joined="2018-07-19")
+
+second_user_data = {
+ "id": 4,
+ "name": "Mary",
+ "joined": "2018-11-30",
+}
+
+my_second_user: User = User(**second_user_data)
+```
+
+!!! info
+ `**second_user_data` nghĩa là:
+
+ Truyền các khóa và giá trị của dict `second_user_data` trực tiếp như các tham số kiểu key-value, tương đương với: `User(id=4, name="Mary", joined="2018-11-30")`
+
+### Được hỗ trợ từ các trình soạn thảo
+
+
+Toàn bộ framework được thiết kế để sử dụng dễ dàng và trực quan, toàn bộ quyết định đã được kiểm thử trên nhiều trình soạn thảo thậm chí trước khi bắt đầu quá trình phát triển, để chắc chắn trải nghiệm phát triển là tốt nhất.
+
+Trong lần khảo sát cuối cùng dành cho các lập trình viên Python, đã rõ ràng rằng đa số các lập trình viên sử dụng tính năng "autocompletion".
+
+Toàn bộ framework "FastAPI" phải đảm bảo rằng: autocompletion hoạt động ở mọi nơi. Bạn sẽ hiếm khi cần quay lại để đọc tài liệu.
+
+Đây là các trình soạn thảo có thể giúp bạn:
+
+* trong Visual Studio Code:
+
+
+
+* trong PyCharm:
+
+
+
+Bạn sẽ có được auto-completion trong code, thậm chí trước đó là không thể. Như trong ví dụ, khóa `price` bên trong một JSON (đó có thể được lồng nhau) đến từ một request.
+
+Không còn nhập sai tên khóa, quay đi quay lại giữa các tài liệu hoặc cuộn lên cuộn xuống để tìm xem cuối cùng bạn đã sử dụng `username` hay `user_name`.
+
+### Ngắn gọn
+
+FastAPI có các giá trị mặc định hợp lý cho mọi thứ, với các cấu hình tùy chọn ở mọi nơi. Tất cả các tham số có thể được tinh chỉnh để thực hiện những gì bạn cần và để định nghĩa API bạn cần.
+
+Nhưng mặc định, tất cả **đều hoạt động**.
+
+### Validation
+
+* Validation cho đa số (hoặc tất cả?) **các kiểu dữ liệu** Python, bao gồm:
+ * JSON objects (`dict`).
+ * Mảng JSON (`list`) định nghĩa kiểu dữ liệu từng phần tử.
+ * Xâu (`str`), định nghĩa độ dài lớn nhất, nhỏ nhất.
+ * Số (`int`, `float`) với các giá trị lớn nhất, nhỏ nhất, etc.
+
+* Validation cho nhiều kiểu dữ liệu bên ngoài như:
+ * URL.
+ * Email.
+ * UUID.
+ * ...và nhiều cái khác.
+
+Tất cả validation được xử lí bằng những thiết lập tốt và mạnh mẽ của **Pydantic**.
+
+### Bảo mật và xác thực
+
+Bảo mật và xác thực đã tích hợp mà không làm tổn hại tới cơ sở dữ liệu hoặc data models.
+
+Tất cả cơ chế bảo mật định nghĩa trong OpenAPI, bao gồm:
+
+* HTTP Basic.
+* **OAuth2** (với **JWT tokens**). Xem hướng dẫn [OAuth2 with JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}.
+* API keys in:
+ * Headers.
+ * Các tham số trong query string.
+ * Cookies, etc.
+
+Cộng với tất cả các tính năng bảo mật từ Starlette (bao gồm **session cookies**).
+
+Tất cả được xây dựng dưới dạng các công cụ và thành phần có thể tái sử dụng, dễ dàng tích hợp với hệ thống, kho lưu trữ dữ liệu, cơ sở dữ liệu quan hệ và NoSQL của bạn,...
+
+### Dependency Injection
+
+FastAPI bao gồm một hệ thống Dependency Injection vô cùng dễ sử dụng nhưng vô cùng mạnh mẽ.
+
+* Thậm chí, các dependency có thể có các dependency khác, tạo thành một phân cấp hoặc **"một đồ thị" của các dependency**.
+* Tất cả **được xử lí tự động** bởi framework.
+* Tất cả các dependency có thể yêu cầu dữ liệu từ request và **tăng cường các ràng buộc từ đường dẫn** và tự động tài liệu hóa.
+* **Tự động hóa validation**, thậm chí với các tham số *đường dẫn* định nghĩa trong các dependency.
+* Hỗ trợ hệ thống xác thực người dùng phức tạp, **các kết nối cơ sở dữ liệu**,...
+* **Không làm tổn hại** cơ sở dữ liệu, frontends,... Nhưng dễ dàng tích hợp với tất cả chúng.
+
+### Không giới hạn "plug-ins"
+
+Hoặc theo một cách nào khác, không cần chúng, import và sử dụng code bạn cần.
+
+Bất kì tích hợp nào được thiết kế để sử dụng đơn giản (với các dependency), đến nỗi bạn có thể tạo một "plug-in" cho ứng dụng của mình trong 2 dòng code bằng cách sử dụng cùng một cấu trúc và cú pháp được sử dụng cho *path operations* của bạn.
+
+### Đã được kiểm thử
+
+* 100% test coverage.
+* 100% type annotated code base.
+* Được sử dụng cho các ứng dụng sản phẩm.
+
+## Tính năng của Starlette
+
+`FastAPI` is thực sự là một sub-class của `Starlette`. Do đó, nếu bạn đã biết hoặc đã sử dụng Starlette, đa số các chức năng sẽ làm việc giống như vậy.
+
+Với **FastAPI**, bạn có được tất cả những tính năng của **Starlette**:
+
+* Hiệu năng thực sự ấn tượng. Nó là một trong nhưng framework Python nhanh nhất, khi so sánh với **NodeJS** và **Go**.
+* Hỗ trợ **WebSocket**.
+* In-process background tasks.
+* Startup and shutdown events.
+* Client cho kiểm thử xây dựng trên HTTPX.
+* **CORS**, GZip, Static Files, Streaming responses.
+* Hỗ trợ **Session and Cookie**.
+* 100% test coverage.
+* 100% type annotated codebase.
+
+## Tính năng của Pydantic
+
+**FastAPI** tương thích đầy đủ với (và dựa trên) Pydantic. Do đó, bất kì code Pydantic nào bạn thêm vào cũng sẽ hoạt động.
+
+Bao gồm các thư viện bên ngoài cũng dựa trên Pydantic, như ORMs, ODMs cho cơ sở dữ liệu.
+
+Nó cũng có nghĩa là trong nhiều trường hợp, bạn có thể truyền cùng object bạn có từ một request **trực tiếp cho cơ sở dữ liệu**, vì mọi thứ được validate tự động.
+
+Điều tương tự áp dụng cho các cách khác nhau, trong nhiều trường hợp, bạn có thể chỉ truyền object từ cơ sở dữ liêu **trực tiếp tới client**.
+
+Với **FastAPI**, bạn có tất cả những tính năng của **Pydantic** (FastAPI dựa trên Pydantic cho tất cả những xử lí về dữ liệu):
+
+* **Không gây rối não**:
+ * Không cần học ngôn ngữ mô tả cấu trúc mới.
+ * Nếu bạn biết kiểu dữ liệu Python, bạn biết cách sử dụng Pydantic.
+* Sử dụng tốt với **IDE/linter/não của bạn**:
+
+ * Bởi vì các cấu trúc dữ liệu của Pydantic chỉ là các instances của class bạn định nghĩa; auto-completion, linting, mypy và trực giác của bạn nên làm việc riêng biệt với những dữ liệu mà bạn đã validate.
+* Validate **các cấu trúc phức tạp**:
+ * Sử dụng các models Pydantic phân tầng, `List` và `Dict` của Python `typing`,...
+ * Và các validators cho phép các cấu trúc dữ liệu phức tạp trở nên rõ ràng và dễ dàng để định nghĩa, kiểm tra và tài liệu hóa thành JSON Schema.
+ * Bạn có thể có các object **JSON lồng nhau** và tất cả chúng đã validate và annotated.
+* **Có khả năng mở rộng**:
+ * Pydantic cho phép bạn tùy chỉnh kiểu dữ liệu bằng việc định nghĩa hoặc bạn có thể mở rộng validation với các decorator trong model.
+* 100% test coverage.
diff --git a/docs/vi/docs/index.md b/docs/vi/docs/index.md
new file mode 100644
index 0000000000..0e773a0110
--- /dev/null
+++ b/docs/vi/docs/index.md
@@ -0,0 +1,472 @@
+
++ FastAPI framework, hiệu năng cao, dễ học, dễ code, sẵn sàng để tạo ra sản phẩm +
+ + +--- + +**Tài liệu**: https://fastapi.tiangolo.com + +**Mã nguồn**: https://github.com/tiangolo/fastapi + +--- + +FastAPI là một web framework hiện đại, hiệu năng cao để xây dựng web APIs với Python 3.7+ dựa trên tiêu chuẩn Python type hints. + +Những tính năng như: + +* **Nhanh**: Hiệu năng rất cao khi so sánh với **NodeJS** và **Go** (cảm ơn Starlette và Pydantic). [Một trong những Python framework nhanh nhất](#performance). +* **Code nhanh**: Tăng tốc độ phát triển tính năng từ 200% tới 300%. * +* **Ít lỗi hơn**: Giảm khoảng 40% những lỗi phát sinh bởi con người (nhà phát triển). * +* **Trực giác tốt hơn**: Được các trình soạn thảo hỗ tuyệt vời. Completion mọi nơi. Ít thời gian gỡ lỗi. +* **Dễ dàng**: Được thiết kế để dễ dàng học và sử dụng. Ít thời gian đọc tài liệu. +* **Ngắn**: Tối thiểu code bị trùng lặp. Nhiều tính năng được tích hợp khi định nghĩa tham số. Ít lỗi hơn. +* **Tăng tốc**: Có được sản phẩm cùng với tài liệu (được tự động tạo) có thể tương tác. +* **Được dựa trên các tiêu chuẩn**: Dựa trên (và hoàn toàn tương thích với) các tiêu chuẩn mở cho APIs : OpenAPI (trước đó được biết đến là Swagger) và JSON Schema. + +* ước tính được dựa trên những kiểm chứng trong nhóm phát triển nội bộ, xây dựng các ứng dụng sản phẩm. + +## Nhà tài trợ + + + +{% if sponsors %} +{% for sponsor in sponsors.gold -%} +async def...uvicorn main:app --reload...ujson - "Parse" JSON nhanh hơn.
+* email_validator - cho email validation.
+
+Sử dụng Starlette:
+
+* httpx - Bắt buộc nếu bạn muốn sử dụng `TestClient`.
+* jinja2 - Bắt buộc nếu bạn muốn sử dụng cấu hình template engine mặc định.
+* python-multipart - Bắt buộc nếu bạn muốn hỗ trợ "parsing", form với `request.form()`.
+* itsdangerous - Bắt buộc để hỗ trợ `SessionMiddleware`.
+* pyyaml - Bắt buộc để hỗ trợ `SchemaGenerator` cho Starlette (bạn có thể không cần nó trong FastAPI).
+* ujson - Bắt buộc nếu bạn muốn sử dụng `UJSONResponse`.
+
+Sử dụng bởi FastAPI / Starlette:
+
+* uvicorn - Server để chạy ứng dụng của bạn.
+* orjson - Bắt buộc nếu bạn muốn sử dụng `ORJSONResponse`.
+
+Bạn có thể cài đặt tất cả những dependency trên với `pip install "fastapi[all]"`.
+
+## Giấy phép
+
+Dự án này được cấp phép dưới những điều lệ của giấy phép MIT.
diff --git a/docs/vi/mkdocs.yml b/docs/vi/mkdocs.yml
new file mode 100644
index 0000000000..de18856f44
--- /dev/null
+++ b/docs/vi/mkdocs.yml
@@ -0,0 +1 @@
+INHERIT: ../en/mkdocs.yml
diff --git a/docs/zh/docs/tutorial/background-tasks.md b/docs/zh/docs/tutorial/background-tasks.md
new file mode 100644
index 0000000000..c8568298b1
--- /dev/null
+++ b/docs/zh/docs/tutorial/background-tasks.md
@@ -0,0 +1,126 @@
+# 后台任务
+
+你可以定义在返回响应后运行的后台任务。
+
+这对需要在请求之后执行的操作很有用,但客户端不必在接收响应之前等待操作完成。
+
+包括这些例子:
+
+* 执行操作后发送的电子邮件通知:
+ * 由于连接到电子邮件服务器并发送电子邮件往往很“慢”(几秒钟),您可以立即返回响应并在后台发送电子邮件通知。
+* 处理数据:
+ * 例如,假设您收到的文件必须经过一个缓慢的过程,您可以返回一个"Accepted"(HTTP 202)响应并在后台处理它。
+
+## 使用 `BackgroundTasks`
+
+首先导入 `BackgroundTasks` 并在 *路径操作函数* 中使用类型声明 `BackgroundTasks` 定义一个参数:
+
+```Python hl_lines="1 13"
+{!../../../docs_src/background_tasks/tutorial001.py!}
+```
+
+**FastAPI** 会创建一个 `BackgroundTasks` 类型的对象并作为该参数传入。
+
+## 创建一个任务函数
+
+创建要作为后台任务运行的函数。
+
+它只是一个可以接收参数的标准函数。
+
+它可以是 `async def` 或普通的 `def` 函数,**FastAPI** 知道如何正确处理。
+
+在这种情况下,任务函数将写入一个文件(模拟发送电子邮件)。
+
+由于写操作不使用 `async` 和 `await`,我们用普通的 `def` 定义函数:
+
+```Python hl_lines="6-9"
+{!../../../docs_src/background_tasks/tutorial001.py!}
+```
+
+## 添加后台任务
+
+在你的 *路径操作函数* 里,用 `.add_task()` 方法将任务函数传到 *后台任务* 对象中:
+
+```Python hl_lines="14"
+{!../../../docs_src/background_tasks/tutorial001.py!}
+```
+
+`.add_task()` 接收以下参数:
+
+* 在后台运行的任务函数(`write_notification`)。
+* 应按顺序传递给任务函数的任意参数序列(`email`)。
+* 应传递给任务函数的任意关键字参数(`message="some notification"`)。
+
+## 依赖注入
+
+使用 `BackgroundTasks` 也适用于依赖注入系统,你可以在多个级别声明 `BackgroundTasks` 类型的参数:在 *路径操作函数* 里,在依赖中(可依赖),在子依赖中,等等。
+
+**FastAPI** 知道在每种情况下该做什么以及如何复用同一对象,因此所有后台任务被合并在一起并且随后在后台运行:
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="13 15 22 25"
+ {!> ../../../docs_src/background_tasks/tutorial002_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="13 15 22 25"
+ {!> ../../../docs_src/background_tasks/tutorial002_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="14 16 23 26"
+ {!> ../../../docs_src/background_tasks/tutorial002_an.py!}
+ ```
+
+=== "Python 3.10+ 没Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="11 13 20 23"
+ {!> ../../../docs_src/background_tasks/tutorial002_py310.py!}
+ ```
+
+=== "Python 3.6+ 没Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="13 15 22 25"
+ {!> ../../../docs_src/background_tasks/tutorial002.py!}
+ ```
+
+该示例中,信息会在响应发出 *之后* 被写到 `log.txt` 文件。
+
+如果请求中有查询,它将在后台任务中写入日志。
+
+然后另一个在 *路径操作函数* 生成的后台任务会使用路径参数 `email` 写入一条信息。
+
+## 技术细节
+
+`BackgroundTasks` 类直接来自 `starlette.background`。
+
+它被直接导入/包含到FastAPI以便你可以从 `fastapi` 导入,并避免意外从 `starlette.background` 导入备用的 `BackgroundTask` (后面没有 `s`)。
+
+通过仅使用 `BackgroundTasks` (而不是 `BackgroundTask`),使得能将它作为 *路径操作函数* 的参数 ,并让**FastAPI**为您处理其余部分, 就像直接使用 `Request` 对象。
+
+在FastAPI中仍然可以单独使用 `BackgroundTask`,但您必须在代码中创建对象,并返回包含它的Starlette `Response`。
+
+更多细节查看 Starlette's official docs for Background Tasks.
+
+## 告诫
+
+如果您需要执行繁重的后台计算,并且不一定需要由同一进程运行(例如,您不需要共享内存、变量等),那么使用其他更大的工具(如 Celery)可能更好。
+
+它们往往需要更复杂的配置,即消息/作业队列管理器,如RabbitMQ或Redis,但它们允许您在多个进程中运行后台任务,甚至是在多个服务器中。
+
+要查看示例,查阅 [Project Generators](../project-generation.md){.internal-link target=_blank},它们都包括已经配置的Celery。
+
+但是,如果您需要从同一个**FastAPI**应用程序访问变量和对象,或者您需要执行小型后台任务(如发送电子邮件通知),您只需使用 `BackgroundTasks` 即可。
+
+## 回顾
+
+导入并使用 `BackgroundTasks` 通过 *路径操作函数* 中的参数和依赖项来添加后台任务。
diff --git a/docs/zh/docs/tutorial/body-fields.md b/docs/zh/docs/tutorial/body-fields.md
index 053cae71c7..c153784dcd 100644
--- a/docs/zh/docs/tutorial/body-fields.md
+++ b/docs/zh/docs/tutorial/body-fields.md
@@ -6,9 +6,41 @@
首先,你必须导入它:
-```Python hl_lines="2"
-{!../../../docs_src/body_fields/tutorial001.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="4"
+ {!> ../../../docs_src/body_fields/tutorial001_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="4"
+ {!> ../../../docs_src/body_fields/tutorial001_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="4"
+ {!> ../../../docs_src/body_fields/tutorial001_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="2"
+ {!> ../../../docs_src/body_fields/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="4"
+ {!> ../../../docs_src/body_fields/tutorial001.py!}
+ ```
!!! warning
注意,`Field` 是直接从 `pydantic` 导入的,而不是像其他的(`Query`,`Path`,`Body` 等)都从 `fastapi` 导入。
@@ -17,9 +49,41 @@
然后,你可以对模型属性使用 `Field`:
-```Python hl_lines="9-10"
-{!../../../docs_src/body_fields/tutorial001.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="11-14"
+ {!> ../../../docs_src/body_fields/tutorial001_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="11-14"
+ {!> ../../../docs_src/body_fields/tutorial001_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="12-15"
+ {!> ../../../docs_src/body_fields/tutorial001_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip
+ Prefer to use the `Annotated` version if possible.
+
+ ```Python hl_lines="9-12"
+ {!> ../../../docs_src/body_fields/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ Prefer to use the `Annotated` version if possible.
+
+ ```Python hl_lines="11-14"
+ {!> ../../../docs_src/body_fields/tutorial001.py!}
+ ```
`Field` 的工作方式和 `Query`、`Path` 和 `Body` 相同,包括它们的参数等等也完全相同。
diff --git a/docs/zh/docs/tutorial/body-multiple-params.md b/docs/zh/docs/tutorial/body-multiple-params.md
index 34fa5b638f..ee2cba6df7 100644
--- a/docs/zh/docs/tutorial/body-multiple-params.md
+++ b/docs/zh/docs/tutorial/body-multiple-params.md
@@ -8,9 +8,41 @@
你还可以通过将默认值设置为 `None` 来将请求体参数声明为可选参数:
-```Python hl_lines="17-19"
-{!../../../docs_src/body_multiple_params/tutorial001.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="18-20"
+ {!> ../../../docs_src/body_multiple_params/tutorial001_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="18-20"
+ {!> ../../../docs_src/body_multiple_params/tutorial001_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="19-21"
+ {!> ../../../docs_src/body_multiple_params/tutorial001_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="17-19"
+ {!> ../../../docs_src/body_multiple_params/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="19-21"
+ {!> ../../../docs_src/body_multiple_params/tutorial001.py!}
+ ```
!!! note
请注意,在这种情况下,将从请求体获取的 `item` 是可选的。因为它的默认值为 `None`。
@@ -30,9 +62,17 @@
但是你也可以声明多个请求体参数,例如 `item` 和 `user`:
-```Python hl_lines="20"
-{!../../../docs_src/body_multiple_params/tutorial002.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="20"
+ {!> ../../../docs_src/body_multiple_params/tutorial002_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="22"
+ {!> ../../../docs_src/body_multiple_params/tutorial002.py!}
+ ```
在这种情况下,**FastAPI** 将注意到该函数中有多个请求体参数(两个 Pydantic 模型参数)。
@@ -72,9 +112,41 @@
但是你可以使用 `Body` 指示 **FastAPI** 将其作为请求体的另一个键进行处理。
-```Python hl_lines="22"
-{!../../../docs_src/body_multiple_params/tutorial003.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="23"
+ {!> ../../../docs_src/body_multiple_params/tutorial003_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="23"
+ {!> ../../../docs_src/body_multiple_params/tutorial003_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="24"
+ {!> ../../../docs_src/body_multiple_params/tutorial003_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="20"
+ {!> ../../../docs_src/body_multiple_params/tutorial003_py310.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="22"
+ {!> ../../../docs_src/body_multiple_params/tutorial003.py!}
+ ```
在这种情况下,**FastAPI** 将期望像这样的请求体:
@@ -109,9 +181,41 @@ q: str = None
比如:
-```Python hl_lines="25"
-{!../../../docs_src/body_multiple_params/tutorial004.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="27"
+ {!> ../../../docs_src/body_multiple_params/tutorial004_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="27"
+ {!> ../../../docs_src/body_multiple_params/tutorial004_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="28"
+ {!> ../../../docs_src/body_multiple_params/tutorial004_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="25"
+ {!> ../../../docs_src/body_multiple_params/tutorial004_py310.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="27"
+ {!> ../../../docs_src/body_multiple_params/tutorial004.py!}
+ ```
!!! info
`Body` 同样具有与 `Query`、`Path` 以及其他后面将看到的类完全相同的额外校验和元数据参数。
@@ -131,9 +235,41 @@ item: Item = Body(embed=True)
比如:
-```Python hl_lines="15"
-{!../../../docs_src/body_multiple_params/tutorial005.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="17"
+ {!> ../../../docs_src/body_multiple_params/tutorial005_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="17"
+ {!> ../../../docs_src/body_multiple_params/tutorial005_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="18"
+ {!> ../../../docs_src/body_multiple_params/tutorial005_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="15"
+ {!> ../../../docs_src/body_multiple_params/tutorial005_py310.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="17"
+ {!> ../../../docs_src/body_multiple_params/tutorial005.py!}
+ ```
在这种情况下,**FastAPI** 将期望像这样的请求体:
diff --git a/docs/zh/docs/tutorial/body-nested-models.md b/docs/zh/docs/tutorial/body-nested-models.md
index 7649ee6fea..7704d26248 100644
--- a/docs/zh/docs/tutorial/body-nested-models.md
+++ b/docs/zh/docs/tutorial/body-nested-models.md
@@ -6,9 +6,17 @@
你可以将一个属性定义为拥有子元素的类型。例如 Python `list`:
-```Python hl_lines="12"
-{!../../../docs_src/body_nested_models/tutorial001.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="12"
+ {!> ../../../docs_src/body_nested_models/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="14"
+ {!> ../../../docs_src/body_nested_models/tutorial001.py!}
+ ```
这将使 `tags` 成为一个由元素组成的列表。不过它没有声明每个元素的类型。
@@ -21,7 +29,7 @@
首先,从 Python 的标准库 `typing` 模块中导入 `List`:
```Python hl_lines="1"
-{!../../../docs_src/body_nested_models/tutorial002.py!}
+{!> ../../../docs_src/body_nested_models/tutorial002.py!}
```
### 声明具有子类型的 List
@@ -43,9 +51,23 @@ my_list: List[str]
因此,在我们的示例中,我们可以将 `tags` 明确地指定为一个「字符串列表」:
-```Python hl_lines="14"
-{!../../../docs_src/body_nested_models/tutorial002.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="12"
+ {!> ../../../docs_src/body_nested_models/tutorial002_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="14"
+ {!> ../../../docs_src/body_nested_models/tutorial002_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="14"
+ {!> ../../../docs_src/body_nested_models/tutorial002.py!}
+ ```
## Set 类型
@@ -55,9 +77,23 @@ Python 具有一种特殊的数据类型来保存一组唯一的元素,即 `se
然后我们可以导入 `Set` 并将 `tag` 声明为一个由 `str` 组成的 `set`:
-```Python hl_lines="1 14"
-{!../../../docs_src/body_nested_models/tutorial003.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="12"
+ {!> ../../../docs_src/body_nested_models/tutorial003_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="14"
+ {!> ../../../docs_src/body_nested_models/tutorial003_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="1 14"
+ {!> ../../../docs_src/body_nested_models/tutorial003.py!}
+ ```
这样,即使你收到带有重复数据的请求,这些数据也会被转换为一组唯一项。
@@ -79,17 +115,45 @@ Pydantic 模型的每个属性都具有类型。
例如,我们可以定义一个 `Image` 模型:
-```Python hl_lines="9 10 11"
-{!../../../docs_src/body_nested_models/tutorial004.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="7-9"
+ {!> ../../../docs_src/body_nested_models/tutorial004_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="9-11"
+ {!> ../../../docs_src/body_nested_models/tutorial004_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="9-11"
+ {!> ../../../docs_src/body_nested_models/tutorial004.py!}
+ ```
### 将子模型用作类型
然后我们可以将其用作一个属性的类型:
-```Python hl_lines="20"
-{!../../../docs_src/body_nested_models/tutorial004.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="18"
+ {!> ../../../docs_src/body_nested_models/tutorial004_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="20"
+ {!> ../../../docs_src/body_nested_models/tutorial004_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="20"
+ {!> ../../../docs_src/body_nested_models/tutorial004.py!}
+ ```
这意味着 **FastAPI** 将期望类似于以下内容的请求体:
@@ -122,9 +186,23 @@ Pydantic 模型的每个属性都具有类型。
例如,在 `Image` 模型中我们有一个 `url` 字段,我们可以把它声明为 Pydantic 的 `HttpUrl`,而不是 `str`:
-```Python hl_lines="4 10"
-{!../../../docs_src/body_nested_models/tutorial005.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="2 8"
+ {!> ../../../docs_src/body_nested_models/tutorial005_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="4 10"
+ {!> ../../../docs_src/body_nested_models/tutorial005_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="4 10"
+ {!> ../../../docs_src/body_nested_models/tutorial005.py!}
+ ```
该字符串将被检查是否为有效的 URL,并在 JSON Schema / OpenAPI 文档中进行记录。
@@ -132,9 +210,23 @@ Pydantic 模型的每个属性都具有类型。
你还可以将 Pydantic 模型用作 `list`、`set` 等的子类型:
-```Python hl_lines="20"
-{!../../../docs_src/body_nested_models/tutorial006.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="18"
+ {!> ../../../docs_src/body_nested_models/tutorial006_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="20"
+ {!> ../../../docs_src/body_nested_models/tutorial006_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="20"
+ {!> ../../../docs_src/body_nested_models/tutorial006.py!}
+ ```
这将期望(转换,校验,记录文档等)下面这样的 JSON 请求体:
@@ -169,9 +261,23 @@ Pydantic 模型的每个属性都具有类型。
你可以定义任意深度的嵌套模型:
-```Python hl_lines="9 14 20 23 27"
-{!../../../docs_src/body_nested_models/tutorial007.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="7 12 18 21 25"
+ {!> ../../../docs_src/body_nested_models/tutorial007_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="9 14 20 23 27"
+ {!> ../../../docs_src/body_nested_models/tutorial007_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="9 14 20 23 27"
+ {!> ../../../docs_src/body_nested_models/tutorial007.py!}
+ ```
!!! info
请注意 `Offer` 拥有一组 `Item` 而反过来 `Item` 又是一个可选的 `Image` 列表是如何发生的。
@@ -186,9 +292,17 @@ images: List[Image]
例如:
-```Python hl_lines="15"
-{!../../../docs_src/body_nested_models/tutorial008.py!}
-```
+=== "Python 3.9+"
+
+ ```Python hl_lines="13"
+ {!> ../../../docs_src/body_nested_models/tutorial008_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="15"
+ {!> ../../../docs_src/body_nested_models/tutorial008.py!}
+ ```
## 无处不在的编辑器支持
@@ -218,9 +332,17 @@ images: List[Image]
在下面的例子中,你将接受任意键为 `int` 类型并且值为 `float` 类型的 `dict`:
-```Python hl_lines="15"
-{!../../../docs_src/body_nested_models/tutorial009.py!}
-```
+=== "Python 3.9+"
+
+ ```Python hl_lines="7"
+ {!> ../../../docs_src/body_nested_models/tutorial009_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/body_nested_models/tutorial009.py!}
+ ```
!!! tip
请记住 JSON 仅支持将 `str` 作为键。
diff --git a/docs/zh/docs/tutorial/body.md b/docs/zh/docs/tutorial/body.md
index f80ab5bf59..d00c96dc3a 100644
--- a/docs/zh/docs/tutorial/body.md
+++ b/docs/zh/docs/tutorial/body.md
@@ -17,9 +17,17 @@
首先,你需要从 `pydantic` 中导入 `BaseModel`:
-```Python hl_lines="2"
-{!../../../docs_src/body/tutorial001.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="2"
+ {!> ../../../docs_src/body/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="4"
+ {!> ../../../docs_src/body/tutorial001.py!}
+ ```
## 创建数据模型
@@ -27,9 +35,17 @@
使用标准的 Python 类型来声明所有属性:
-```Python hl_lines="5-9"
-{!../../../docs_src/body/tutorial001.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="5-9"
+ {!> ../../../docs_src/body/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="7-11"
+ {!> ../../../docs_src/body/tutorial001.py!}
+ ```
和声明查询参数时一样,当一个模型属性具有默认值时,它不是必需的。否则它是一个必需属性。将默认值设为 `None` 可使其成为可选属性。
@@ -57,9 +73,17 @@
使用与声明路径和查询参数的相同方式声明请求体,即可将其添加到「路径操作」中:
-```Python hl_lines="16"
-{!../../../docs_src/body/tutorial001.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="16"
+ {!> ../../../docs_src/body/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="18"
+ {!> ../../../docs_src/body/tutorial001.py!}
+ ```
...并且将它的类型声明为你创建的 `Item` 模型。
@@ -112,9 +136,17 @@ Pydantic 本身甚至也进行了一些更改以支持此功能。
在函数内部,你可以直接访问模型对象的所有属性:
-```Python hl_lines="19"
-{!../../../docs_src/body/tutorial002.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="19"
+ {!> ../../../docs_src/body/tutorial002_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="21"
+ {!> ../../../docs_src/body/tutorial002.py!}
+ ```
## 请求体 + 路径参数
@@ -122,9 +154,17 @@ Pydantic 本身甚至也进行了一些更改以支持此功能。
**FastAPI** 将识别出与路径参数匹配的函数参数应**从路径中获取**,而声明为 Pydantic 模型的函数参数应**从请求体中获取**。
-```Python hl_lines="15-16"
-{!../../../docs_src/body/tutorial003.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="15-16"
+ {!> ../../../docs_src/body/tutorial003_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="17-18"
+ {!> ../../../docs_src/body/tutorial003.py!}
+ ```
## 请求体 + 路径参数 + 查询参数
@@ -132,9 +172,17 @@ Pydantic 本身甚至也进行了一些更改以支持此功能。
**FastAPI** 会识别它们中的每一个,并从正确的位置获取数据。
-```Python hl_lines="16"
-{!../../../docs_src/body/tutorial004.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="16"
+ {!> ../../../docs_src/body/tutorial004_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="18"
+ {!> ../../../docs_src/body/tutorial004.py!}
+ ```
函数参数将依次按如下规则进行识别:
diff --git a/docs/zh/docs/tutorial/cookie-params.md b/docs/zh/docs/tutorial/cookie-params.md
index d67daf0f90..470fd8e825 100644
--- a/docs/zh/docs/tutorial/cookie-params.md
+++ b/docs/zh/docs/tutorial/cookie-params.md
@@ -6,9 +6,41 @@
首先,导入 `Cookie`:
-```Python hl_lines="3"
-{!../../../docs_src/cookie_params/tutorial001.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="3"
+ {!> ../../../docs_src/cookie_params/tutorial001_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="3"
+ {!> ../../../docs_src/cookie_params/tutorial001_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="3"
+ {!> ../../../docs_src/cookie_params/tutorial001_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="3"
+ {!> ../../../docs_src/cookie_params/tutorial001.py!}
+ ```
## 声明 `Cookie` 参数
@@ -17,9 +49,41 @@
第一个值是参数的默认值,同时也可以传递所有验证参数或注释参数,来校验参数:
-```Python hl_lines="9"
-{!../../../docs_src/cookie_params/tutorial001.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/cookie_params/tutorial001_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/cookie_params/tutorial001_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="10"
+ {!> ../../../docs_src/cookie_params/tutorial001_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="7"
+ {!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/cookie_params/tutorial001.py!}
+ ```
!!! note "技术细节"
`Cookie` 、`Path` 、`Query`是兄弟类,它们都继承自公共的 `Param` 类
diff --git a/docs/zh/docs/tutorial/extra-data-types.md b/docs/zh/docs/tutorial/extra-data-types.md
index ac3e076545..76d606903a 100644
--- a/docs/zh/docs/tutorial/extra-data-types.md
+++ b/docs/zh/docs/tutorial/extra-data-types.md
@@ -55,12 +55,76 @@
下面是一个*路径操作*的示例,其中的参数使用了上面的一些类型。
-```Python hl_lines="1 3 12-16"
-{!../../../docs_src/extra_data_types/tutorial001.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="1 3 12-16"
+ {!> ../../../docs_src/extra_data_types/tutorial001_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="1 3 12-16"
+ {!> ../../../docs_src/extra_data_types/tutorial001_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="1 3 13-17"
+ {!> ../../../docs_src/extra_data_types/tutorial001_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="1 2 11-15"
+ {!> ../../../docs_src/extra_data_types/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="1 2 12-16"
+ {!> ../../../docs_src/extra_data_types/tutorial001.py!}
+ ```
注意,函数内的参数有原生的数据类型,你可以,例如,执行正常的日期操作,如:
-```Python hl_lines="18-19"
-{!../../../docs_src/extra_data_types/tutorial001.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="18-19"
+ {!> ../../../docs_src/extra_data_types/tutorial001_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="18-19"
+ {!> ../../../docs_src/extra_data_types/tutorial001_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="19-20"
+ {!> ../../../docs_src/extra_data_types/tutorial001_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="17-18"
+ {!> ../../../docs_src/extra_data_types/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="18-19"
+ {!> ../../../docs_src/extra_data_types/tutorial001.py!}
+ ```
diff --git a/docs/zh/docs/tutorial/extra-models.md b/docs/zh/docs/tutorial/extra-models.md
index 1fbe77be8d..32f8f9df12 100644
--- a/docs/zh/docs/tutorial/extra-models.md
+++ b/docs/zh/docs/tutorial/extra-models.md
@@ -17,9 +17,17 @@
下面是应该如何根据它们的密码字段以及使用位置去定义模型的大概思路:
-```Python hl_lines="9 11 16 22 24 29-30 33-35 40-41"
-{!../../../docs_src/extra_models/tutorial001.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="7 9 14 20 22 27-28 31-33 38-39"
+ {!> ../../../docs_src/extra_models/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="9 11 16 22 24 29-30 33-35 40-41"
+ {!> ../../../docs_src/extra_models/tutorial001.py!}
+ ```
### 关于 `**user_in.dict()`
@@ -150,9 +158,17 @@ UserInDB(
这样,我们可以仅声明模型之间的差异部分(具有明文的 `password`、具有 `hashed_password` 以及不包括密码)。
-```Python hl_lines="9 15-16 19-20 23-24"
-{!../../../docs_src/extra_models/tutorial002.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="7 13-14 17-18 21-22"
+ {!> ../../../docs_src/extra_models/tutorial002_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="9 15-16 19-20 23-24"
+ {!> ../../../docs_src/extra_models/tutorial002.py!}
+ ```
## `Union` 或者 `anyOf`
@@ -166,9 +182,17 @@ UserInDB(
!!! note
定义一个 `Union` 类型时,首先包括最详细的类型,然后是不太详细的类型。在下面的示例中,更详细的 `PlaneItem` 位于 `Union[PlaneItem,CarItem]` 中的 `CarItem` 之前。
-```Python hl_lines="1 14-15 18-20 33"
-{!../../../docs_src/extra_models/tutorial003.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="1 14-15 18-20 33"
+ {!> ../../../docs_src/extra_models/tutorial003_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="1 14-15 18-20 33"
+ {!> ../../../docs_src/extra_models/tutorial003.py!}
+ ```
## 模型列表
@@ -176,9 +200,17 @@ UserInDB(
为此,请使用标准的 Python `typing.List`:
-```Python hl_lines="1 20"
-{!../../../docs_src/extra_models/tutorial004.py!}
-```
+=== "Python 3.9+"
+
+ ```Python hl_lines="18"
+ {!> ../../../docs_src/extra_models/tutorial004_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="1 20"
+ {!> ../../../docs_src/extra_models/tutorial004.py!}
+ ```
## 任意 `dict` 构成的响应
@@ -188,9 +220,17 @@ UserInDB(
在这种情况下,你可以使用 `typing.Dict`:
-```Python hl_lines="1 8"
-{!../../../docs_src/extra_models/tutorial005.py!}
-```
+=== "Python 3.9+"
+
+ ```Python hl_lines="6"
+ {!> ../../../docs_src/extra_models/tutorial005_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="1 8"
+ {!> ../../../docs_src/extra_models/tutorial005.py!}
+ ```
## 总结
diff --git a/docs/zh/docs/tutorial/handling-errors.md b/docs/zh/docs/tutorial/handling-errors.md
index 9b066bc2ce..a0d66e557c 100644
--- a/docs/zh/docs/tutorial/handling-errors.md
+++ b/docs/zh/docs/tutorial/handling-errors.md
@@ -145,7 +145,7 @@
```
-访问 `/items/foo`,可以看到以下内容替换了默认 JSON 错误信息:
+访问 `/items/foo`,可以看到默认的 JSON 错误信息:
```JSON
{
@@ -163,7 +163,7 @@
```
-以下是文本格式的错误信息:
+被替换为了以下文本格式的错误信息:
```
1 validation error
diff --git a/docs/zh/docs/tutorial/header-params.md b/docs/zh/docs/tutorial/header-params.md
index c4b1c38cee..22ff6dc270 100644
--- a/docs/zh/docs/tutorial/header-params.md
+++ b/docs/zh/docs/tutorial/header-params.md
@@ -6,9 +6,41 @@
首先导入 `Header`:
-```Python hl_lines="3"
-{!../../../docs_src/header_params/tutorial001.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="3"
+ {!> ../../../docs_src/header_params/tutorial001_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="3"
+ {!> ../../../docs_src/header_params/tutorial001_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="3"
+ {!> ../../../docs_src/header_params/tutorial001_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/header_params/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="3"
+ {!> ../../../docs_src/header_params/tutorial001.py!}
+ ```
## 声明 `Header` 参数
@@ -16,9 +48,41 @@
第一个值是默认值,你可以传递所有的额外验证或注释参数:
-```Python hl_lines="9"
-{!../../../docs_src/header_params/tutorial001.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/header_params/tutorial001_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/header_params/tutorial001_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="10"
+ {!> ../../../docs_src/header_params/tutorial001_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="7"
+ {!> ../../../docs_src/header_params/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/header_params/tutorial001.py!}
+ ```
!!! note "技术细节"
`Header` 是 `Path`, `Query` 和 `Cookie` 的兄弟类型。它也继承自通用的 `Param` 类.
@@ -44,9 +108,41 @@
如果出于某些原因,你需要禁用下划线到连字符的自动转换,设置`Header`的参数 `convert_underscores` 为 `False`:
-```Python hl_lines="10"
-{!../../../docs_src/header_params/tutorial002.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="10"
+ {!> ../../../docs_src/header_params/tutorial002_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="11"
+ {!> ../../../docs_src/header_params/tutorial002_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="12"
+ {!> ../../../docs_src/header_params/tutorial002_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="8"
+ {!> ../../../docs_src/header_params/tutorial002_py310.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="10"
+ {!> ../../../docs_src/header_params/tutorial002.py!}
+ ```
!!! warning
在设置 `convert_underscores` 为 `False` 之前,请记住,一些HTTP代理和服务器不允许使用带有下划线的headers。
@@ -62,9 +158,50 @@
比如, 为了声明一个 `X-Token` header 可以出现多次,你可以这样写:
-```Python hl_lines="9"
-{!../../../docs_src/header_params/tutorial003.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/header_params/tutorial003_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/header_params/tutorial003_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="10"
+ {!> ../../../docs_src/header_params/tutorial003_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip
+ Prefer to use the `Annotated` version if possible.
+
+ ```Python hl_lines="7"
+ {!> ../../../docs_src/header_params/tutorial003_py310.py!}
+ ```
+
+=== "Python 3.9+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/header_params/tutorial003_py39.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/header_params/tutorial003.py!}
+ ```
如果你与*路径操作*通信时发送两个HTTP headers,就像:
diff --git a/docs/zh/docs/tutorial/path-params-numeric-validations.md b/docs/zh/docs/tutorial/path-params-numeric-validations.md
index 13512a08ed..78fa922b49 100644
--- a/docs/zh/docs/tutorial/path-params-numeric-validations.md
+++ b/docs/zh/docs/tutorial/path-params-numeric-validations.md
@@ -6,9 +6,41 @@
首先,从 `fastapi` 导入 `Path`:
-```Python hl_lines="1"
-{!../../../docs_src/path_params_numeric_validations/tutorial001.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="1 3"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="1 3"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="3-4"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="1"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="3"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
+ ```
## 声明元数据
@@ -16,9 +48,41 @@
例如,要声明路径参数 `item_id`的 `title` 元数据值,你可以输入:
-```Python hl_lines="8"
-{!../../../docs_src/path_params_numeric_validations/tutorial001.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="10"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="10"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="11"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="8"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="10"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
+ ```
!!! note
路径参数总是必需的,因为它必须是路径的一部分。
@@ -43,9 +107,14 @@
因此,你可以将函数声明为:
-```Python hl_lines="7"
-{!../../../docs_src/path_params_numeric_validations/tutorial002.py!}
-```
+=== "Python 3.6 non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="7"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial002.py!}
+ ```
## 按需对参数排序的技巧
diff --git a/docs/zh/docs/tutorial/query-params-str-validations.md b/docs/zh/docs/tutorial/query-params-str-validations.md
index 070074839f..7244aeadef 100644
--- a/docs/zh/docs/tutorial/query-params-str-validations.md
+++ b/docs/zh/docs/tutorial/query-params-str-validations.md
@@ -4,9 +4,17 @@
让我们以下面的应用程序为例:
-```Python hl_lines="7"
-{!../../../docs_src/query_params_str_validations/tutorial001.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="7"
+ {!> ../../../docs_src/query_params_str_validations/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/query_params_str_validations/tutorial001.py!}
+ ```
查询参数 `q` 的类型为 `str`,默认值为 `None`,因此它是可选的。
diff --git a/docs/zh/docs/tutorial/response-model.md b/docs/zh/docs/tutorial/response-model.md
index ea3d0666de..f529cb0d8b 100644
--- a/docs/zh/docs/tutorial/response-model.md
+++ b/docs/zh/docs/tutorial/response-model.md
@@ -8,9 +8,23 @@
* `@app.delete()`
* 等等。
-```Python hl_lines="17"
-{!../../../docs_src/response_model/tutorial001.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="17 22 24-27"
+ {!> ../../../docs_src/response_model/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="17 22 24-27"
+ {!> ../../../docs_src/response_model/tutorial001_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="17 22 24-27"
+ {!> ../../../docs_src/response_model/tutorial001.py!}
+ ```
!!! note
注意,`response_model`是「装饰器」方法(`get`,`post` 等)的一个参数。不像之前的所有参数和请求体,它不属于*路径操作函数*。
@@ -58,21 +72,45 @@ FastAPI 将使用此 `response_model` 来:
相反,我们可以创建一个有明文密码的输入模型和一个没有明文密码的输出模型:
-```Python hl_lines="9 11 16"
-{!../../../docs_src/response_model/tutorial003.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="9 11 16"
+ {!> ../../../docs_src/response_model/tutorial003_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="9 11 16"
+ {!> ../../../docs_src/response_model/tutorial003.py!}
+ ```
这样,即便我们的*路径操作函数*将会返回包含密码的相同输入用户:
-```Python hl_lines="24"
-{!../../../docs_src/response_model/tutorial003.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="24"
+ {!> ../../../docs_src/response_model/tutorial003_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="24"
+ {!> ../../../docs_src/response_model/tutorial003.py!}
+ ```
...我们已经将 `response_model` 声明为了不包含密码的 `UserOut` 模型:
-```Python hl_lines="22"
-{!../../../docs_src/response_model/tutorial003.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="22"
+ {!> ../../../docs_src/response_model/tutorial003_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="22"
+ {!> ../../../docs_src/response_model/tutorial003.py!}
+ ```
因此,**FastAPI** 将会负责过滤掉未在输出模型中声明的所有数据(使用 Pydantic)。
diff --git a/docs/zh/docs/tutorial/schema-extra-example.md b/docs/zh/docs/tutorial/schema-extra-example.md
index 8f5fbfe70b..816e8f68ef 100644
--- a/docs/zh/docs/tutorial/schema-extra-example.md
+++ b/docs/zh/docs/tutorial/schema-extra-example.md
@@ -10,9 +10,17 @@
您可以使用 `Config` 和 `schema_extra` 为Pydantic模型声明一个示例,如Pydantic 文档:定制 Schema 中所述:
-```Python hl_lines="15-23"
-{!../../../docs_src/schema_extra_example/tutorial001.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="13-21"
+ {!> ../../../docs_src/schema_extra_example/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="15-23"
+ {!> ../../../docs_src/schema_extra_example/tutorial001.py!}
+ ```
这些额外的信息将按原样添加到输出的JSON模式中。
@@ -20,9 +28,17 @@
在 `Field`, `Path`, `Query`, `Body` 和其他你之后将会看到的工厂函数,你可以为JSON 模式声明额外信息,你也可以通过给工厂函数传递其他的任意参数来给JSON 模式声明额外信息,比如增加 `example`:
-```Python hl_lines="4 10-13"
-{!../../../docs_src/schema_extra_example/tutorial002.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="2 8-11"
+ {!> ../../../docs_src/schema_extra_example/tutorial002_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="4 10-13"
+ {!> ../../../docs_src/schema_extra_example/tutorial002.py!}
+ ```
!!! warning
请记住,传递的那些额外参数不会添加任何验证,只会添加注释,用于文档的目的。
@@ -33,9 +49,41 @@
比如,你可以将请求体的一个 `example` 传递给 `Body`:
-```Python hl_lines="20-25"
-{!../../../docs_src/schema_extra_example/tutorial003.py!}
-```
+=== "Python 3.10+"
+
+ ```Python hl_lines="22-27"
+ {!> ../../../docs_src/schema_extra_example/tutorial003_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="22-27"
+ {!> ../../../docs_src/schema_extra_example/tutorial003_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="23-28"
+ {!> ../../../docs_src/schema_extra_example/tutorial003_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="18-23"
+ {!> ../../../docs_src/schema_extra_example/tutorial003_py310.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python hl_lines="20-25"
+ {!> ../../../docs_src/schema_extra_example/tutorial003.py!}
+ ```
## 文档 UI 中的例子
diff --git a/docs/zh/docs/tutorial/security/first-steps.md b/docs/zh/docs/tutorial/security/first-steps.md
index 86c3320ce1..7b1052e12a 100644
--- a/docs/zh/docs/tutorial/security/first-steps.md
+++ b/docs/zh/docs/tutorial/security/first-steps.md
@@ -20,9 +20,26 @@
把下面的示例代码复制到 `main.py`:
-```Python
-{!../../../docs_src/security/tutorial001.py!}
-```
+=== "Python 3.9+"
+
+ ```Python
+ {!> ../../../docs_src/security/tutorial001_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python
+ {!> ../../../docs_src/security/tutorial001_an.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ 尽可能选择使用 `Annotated` 的版本。
+
+ ```Python
+ {!> ../../../docs_src/security/tutorial001.py!}
+ ```
## 运行
diff --git a/fastapi/__init__.py b/fastapi/__init__.py
index e9c3abe012..7dfeca0d48 100644
--- a/fastapi/__init__.py
+++ b/fastapi/__init__.py
@@ -1,6 +1,6 @@
"""FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
-__version__ = "0.100.0"
+__version__ = "0.100.1"
from starlette import status as status
diff --git a/fastapi/_compat.py b/fastapi/_compat.py
index 2233fe33c7..9ffcaf4092 100644
--- a/fastapi/_compat.py
+++ b/fastapi/_compat.py
@@ -56,7 +56,6 @@ if PYDANTIC_V2:
from pydantic.json_schema import GenerateJsonSchema as GenerateJsonSchema
from pydantic.json_schema import JsonSchemaValue as JsonSchemaValue
from pydantic_core import CoreSchema as CoreSchema
- from pydantic_core import MultiHostUrl as MultiHostUrl
from pydantic_core import PydanticUndefined, PydanticUndefinedType
from pydantic_core import Url as Url
from pydantic_core.core_schema import (
@@ -294,9 +293,6 @@ else:
from pydantic.fields import ( # type: ignore[no-redef, attr-defined]
UndefinedType as UndefinedType, # noqa: F401
)
- from pydantic.networks import ( # type: ignore[no-redef]
- MultiHostDsn as MultiHostUrl, # noqa: F401
- )
from pydantic.schema import (
field_schema,
get_flat_models_from_fields,
diff --git a/fastapi/encoders.py b/fastapi/encoders.py
index b542749f25..30493697e0 100644
--- a/fastapi/encoders.py
+++ b/fastapi/encoders.py
@@ -20,10 +20,10 @@ from uuid import UUID
from fastapi.types import IncEx
from pydantic import BaseModel
from pydantic.color import Color
-from pydantic.networks import NameEmail
+from pydantic.networks import AnyUrl, NameEmail
from pydantic.types import SecretBytes, SecretStr
-from ._compat import PYDANTIC_V2, MultiHostUrl, Url, _model_dump
+from ._compat import PYDANTIC_V2, Url, _model_dump
# Taken from Pydantic v1 as is
@@ -80,7 +80,7 @@ ENCODERS_BY_TYPE: Dict[Type[Any], Callable[[Any], Any]] = {
set: list,
UUID: str,
Url: str,
- MultiHostUrl: str,
+ AnyUrl: str,
}