diff --git a/.github/actions/notify-translations/app/main.py b/.github/actions/notify-translations/app/main.py
index 494fe6ad8e..8ac1f233d6 100644
--- a/.github/actions/notify-translations/app/main.py
+++ b/.github/actions/notify-translations/app/main.py
@@ -9,7 +9,7 @@ import httpx
from github import Github
from pydantic import BaseModel, BaseSettings, SecretStr
-awaiting_label = "awaiting review"
+awaiting_label = "awaiting-review"
lang_all_label = "lang-all"
approved_label = "approved-2"
translations_path = Path(__file__).parent / "translations.yml"
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index c9723b25bb..4ebc64a14d 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -29,7 +29,7 @@ jobs:
id: cache
with:
path: ${{ env.pythonLocation }}
- key: ${{ runner.os }}-python-${{ env.pythonLocation }}-pydantic-v2-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v05
+ key: ${{ runner.os }}-python-${{ env.pythonLocation }}-pydantic-v2-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v06
- name: Install Dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: pip install -r requirements-tests.txt
@@ -62,7 +62,7 @@ jobs:
id: cache
with:
path: ${{ env.pythonLocation }}
- key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ matrix.pydantic-version }}-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v05
+ key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ matrix.pydantic-version }}-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v06
- name: Install Dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: pip install -r requirements-tests.txt
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index 58eb8ece0d..a8b9bba03d 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -2,6 +2,11 @@
## Latest Changes
+* ⬆️ Upgrade compatibility with Pydantic v2.4, new renamed functions and JSON Schema input/output models with default values. PR [#10344](https://github.com/tiangolo/fastapi/pull/10344) by [@tiangolo](https://github.com/tiangolo).
+* 🔧 Rename label "awaiting review" to "awaiting-review" to simplify search queries. PR [#10343](https://github.com/tiangolo/fastapi/pull/10343) by [@tiangolo](https://github.com/tiangolo).
+* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/extra-data-types.md`. PR [#10132](https://github.com/tiangolo/fastapi/pull/10132) by [@ArtemKhymenko](https://github.com/ArtemKhymenko).
+* 🌐 Fix typos in French translations for `docs/fr/docs/advanced/path-operation-advanced-configuration.md`, `docs/fr/docs/alternatives.md`, `docs/fr/docs/async.md`, `docs/fr/docs/features.md`, `docs/fr/docs/help-fastapi.md`, `docs/fr/docs/index.md`, `docs/fr/docs/python-types.md`, `docs/fr/docs/tutorial/body.md`, `docs/fr/docs/tutorial/first-steps.md`, `docs/fr/docs/tutorial/query-params.md`. PR [#10154](https://github.com/tiangolo/fastapi/pull/10154) by [@s-rigaud](https://github.com/s-rigaud).
+* 🌐 Add Chinese translation for `docs/zh/docs/async.md`. PR [#5591](https://github.com/tiangolo/fastapi/pull/5591) by [@mkdir700](https://github.com/mkdir700).
* 🌐 Update Chinese translation for `docs/tutorial/security/simple-oauth2.md`. PR [#3844](https://github.com/tiangolo/fastapi/pull/3844) by [@jaystone776](https://github.com/jaystone776).
* 🌐 Add Korean translation for `docs/ko/docs/deployment/cloud.md`. PR [#10191](https://github.com/tiangolo/fastapi/pull/10191) by [@Sion99](https://github.com/Sion99).
* 🌐 Add Japanese translation for `docs/ja/docs/deployment/https.md`. PR [#10298](https://github.com/tiangolo/fastapi/pull/10298) by [@tamtam-fitness](https://github.com/tamtam-fitness).
diff --git a/docs/fr/docs/advanced/path-operation-advanced-configuration.md b/docs/fr/docs/advanced/path-operation-advanced-configuration.md
index ace9f19f93..7ded97ce17 100644
--- a/docs/fr/docs/advanced/path-operation-advanced-configuration.md
+++ b/docs/fr/docs/advanced/path-operation-advanced-configuration.md
@@ -66,7 +66,7 @@ Il y a un chapitre entier ici dans la documentation à ce sujet, vous pouvez le
Lorsque vous déclarez un *chemin* dans votre application, **FastAPI** génère automatiquement les métadonnées concernant ce *chemin* à inclure dans le schéma OpenAPI.
!!! note "Détails techniques"
- La spécification OpenAPI appelle ces métaonnées des Objets d'opération.
+ La spécification OpenAPI appelle ces métadonnées des Objets d'opération.
Il contient toutes les informations sur le *chemin* et est utilisé pour générer automatiquement la documentation.
diff --git a/docs/fr/docs/alternatives.md b/docs/fr/docs/alternatives.md
index ee20438c3d..8e58a3dfa9 100644
--- a/docs/fr/docs/alternatives.md
+++ b/docs/fr/docs/alternatives.md
@@ -387,7 +387,7 @@ Gérer toute la validation des données, leur sérialisation et la documentation
### Starlette
-Starlette est un framework/toolkit léger ASGI, qui est idéal pour construire des services asyncio performants.
+Starlette est un framework/toolkit léger ASGI, qui est idéal pour construire des services asyncio performants.
Il est très simple et intuitif. Il est conçu pour être facilement extensible et avoir des composants modulaires.
diff --git a/docs/fr/docs/async.md b/docs/fr/docs/async.md
index db88c4663c..af4d6ca060 100644
--- a/docs/fr/docs/async.md
+++ b/docs/fr/docs/async.md
@@ -250,7 +250,7 @@ Par exemple :
### Concurrence + Parallélisme : Web + Machine Learning
-Avec **FastAPI** vous pouvez bénéficier de la concurrence qui est très courante en developement web (c'est l'attrait principal de NodeJS).
+Avec **FastAPI** vous pouvez bénéficier de la concurrence qui est très courante en développement web (c'est l'attrait principal de NodeJS).
Mais vous pouvez aussi profiter du parallélisme et multiprocessing afin de gérer des charges **CPU bound** qui sont récurrentes dans les systèmes de *Machine Learning*.
diff --git a/docs/fr/docs/features.md b/docs/fr/docs/features.md
index dcc0e39ed7..f5faa46b6d 100644
--- a/docs/fr/docs/features.md
+++ b/docs/fr/docs/features.md
@@ -71,9 +71,9 @@ my_second_user: User = User(**second_user_data)
Tout le framework a été conçu pour être facile et intuitif d'utilisation, toutes les décisions de design ont été testées sur de nombreux éditeurs avant même de commencer le développement final afin d'assurer la meilleure expérience de développement possible.
-Dans le dernier sondage effectué auprès de développeurs python il était clair que la fonctionnalité la plus utilisée est "l'autocomplètion".
+Dans le dernier sondage effectué auprès de développeurs python il était clair que la fonctionnalité la plus utilisée est "l’autocomplétion".
-Tout le framwork **FastAPI** a été conçu avec cela en tête. L'autocomplétion fonctionne partout.
+Tout le framework **FastAPI** a été conçu avec cela en tête. L'autocomplétion fonctionne partout.
Vous devrez rarement revenir à la documentation.
@@ -136,7 +136,7 @@ FastAPI contient un système simple mais extrêmement puissant d'Starlette. Le code utilisant Starlette que vous ajouterez fonctionnera donc aussi.
-En fait, `FastAPI` est un sous compposant de `Starlette`. Donc, si vous savez déjà comment utiliser Starlette, la plupart des fonctionnalités fonctionneront de la même manière.
+En fait, `FastAPI` est un sous composant de `Starlette`. Donc, si vous savez déjà comment utiliser Starlette, la plupart des fonctionnalités fonctionneront de la même manière.
Avec **FastAPI** vous aurez toutes les fonctionnalités de **Starlette** (FastAPI est juste Starlette sous stéroïdes):
-* Des performances vraiments impressionnantes. C'est l'un des framework Python les plus rapide, à égalité avec **NodeJS** et **GO**.
+* Des performances vraiment impressionnantes. C'est l'un des framework Python les plus rapide, à égalité avec **NodeJS** et **GO**.
* Le support des **WebSockets**.
* Le support de **GraphQL**.
* Les tâches d'arrière-plan.
@@ -180,7 +180,7 @@ Inclus des librairies externes basées, aussi, sur Pydantic, servent d' décorateur de validation
* 100% de couverture de test.
diff --git a/docs/fr/docs/help-fastapi.md b/docs/fr/docs/help-fastapi.md
index 0995721e1e..3bc3c3a8a7 100644
--- a/docs/fr/docs/help-fastapi.md
+++ b/docs/fr/docs/help-fastapi.md
@@ -36,8 +36,8 @@ Vous pouvez :
* Me suivre sur **Twitter**.
* Dites-moi comment vous utilisez FastAPI (j'adore entendre ça).
* Entendre quand je fais des annonces ou que je lance de nouveaux outils.
-* Vous connectez à moi sur **Linkedin**.
- * Etre notifié quand je fais des annonces ou que je lance de nouveaux outils (bien que j'utilise plus souvent Twitte 🤷♂).
+* Vous connectez à moi sur **LinkedIn**.
+ * Etre notifié quand je fais des annonces ou que je lance de nouveaux outils (bien que j'utilise plus souvent Twitter 🤷♂).
* Lire ce que j’écris (ou me suivre) sur **Dev.to** ou **Medium**.
* Lire d'autres idées, articles, et sur les outils que j'ai créés.
* Suivez-moi pour lire quand je publie quelque chose de nouveau.
diff --git a/docs/fr/docs/index.md b/docs/fr/docs/index.md
index 7c7547be1c..4ac9864ec0 100644
--- a/docs/fr/docs/index.md
+++ b/docs/fr/docs/index.md
@@ -424,7 +424,7 @@ Pour un exemple plus complet comprenant plus de fonctionnalités, voir le en-têtes.**, **cookies**, **champs de formulaire** et **fichiers**.
* L'utilisation de **contraintes de validation** comme `maximum_length` ou `regex`.
-* Un **systéme d'injection de dépendance ** très puissant et facile à utiliser .
+* Un **système d'injection de dépendance ** très puissant et facile à utiliser .
* Sécurité et authentification, y compris la prise en charge de **OAuth2** avec les **jetons JWT** et l'authentification **HTTP Basic**.
* Des techniques plus avancées (mais tout aussi faciles) pour déclarer les **modèles JSON profondément imbriqués** (grâce à Pydantic).
* Intégration de **GraphQL** avec Strawberry et d'autres bibliothèques.
@@ -450,7 +450,7 @@ Utilisées par Pydantic:
Utilisées par Starlette :
* requests - Obligatoire si vous souhaitez utiliser `TestClient`.
-* jinja2 - Obligatoire si vous souhaitez utiliser la configuration de template par defaut.
+* jinja2 - Obligatoire si vous souhaitez utiliser la configuration de template par défaut.
* python-multipart - Obligatoire si vous souhaitez supporter le "décodage" de formulaire avec `request.form()`.
* itsdangerous - Obligatoire pour la prise en charge de `SessionMiddleware`.
* pyyaml - Obligatoire pour le support `SchemaGenerator` de Starlette (vous n'en avez probablement pas besoin avec FastAPI).
diff --git a/docs/fr/docs/python-types.md b/docs/fr/docs/python-types.md
index 4008ed96fc..f49fbafd36 100644
--- a/docs/fr/docs/python-types.md
+++ b/docs/fr/docs/python-types.md
@@ -119,7 +119,7 @@ Comme l'éditeur connaît le type des variables, vous n'avez pas seulement l'aut
-Maintenant que vous avez connaissance du problème, convertissez `age` en chaine de caractères grâce à `str(age)` :
+Maintenant que vous avez connaissance du problème, convertissez `age` en chaîne de caractères grâce à `str(age)` :
```Python hl_lines="2"
{!../../../docs_src/python_types/tutorial004.py!}
diff --git a/docs/fr/docs/tutorial/body.md b/docs/fr/docs/tutorial/body.md
index 1e732d3364..89720c973a 100644
--- a/docs/fr/docs/tutorial/body.md
+++ b/docs/fr/docs/tutorial/body.md
@@ -98,7 +98,7 @@ Et vous obtenez aussi de la vérification d'erreur pour les opérations incorrec
-Ce n'est pas un hasard, ce framework entier a été bati avec ce design comme objectif.
+Ce n'est pas un hasard, ce framework entier a été bâti avec ce design comme objectif.
Et cela a été rigoureusement testé durant la phase de design, avant toute implémentation, pour s'assurer que cela fonctionnerait avec tous les éditeurs.
diff --git a/docs/fr/docs/tutorial/first-steps.md b/docs/fr/docs/tutorial/first-steps.md
index 224c340c66..e98283f1e2 100644
--- a/docs/fr/docs/tutorial/first-steps.md
+++ b/docs/fr/docs/tutorial/first-steps.md
@@ -170,7 +170,7 @@ Si vous créez votre app avec :
{!../../../docs_src/first_steps/tutorial002.py!}
```
-Et la mettez dans un fichier `main.py`, alors vous appeleriez `uvicorn` avec :
+Et la mettez dans un fichier `main.py`, alors vous appelleriez `uvicorn` avec :
+
+然后轮到你了,你为你的恋人和你选了两个非常豪华的汉堡。🍔🍔
+
+
+
+收银员对厨房里的厨师说了一些话,让他们知道他们必须为你准备汉堡(尽管他们目前正在为之前的顾客准备汉堡)。
+
+
+
+你付钱了。 💸
+
+收银员给你轮到的号码。
+
+
+
+当你在等待的时候,你和你的恋人一起去挑选一张桌子,然后你们坐下来聊了很长时间(因为汉堡很豪华,需要一些时间来准备)。
+
+当你和你的恋人坐在桌子旁,等待汉堡的时候,你可以用这段时间来欣赏你的恋人是多么的棒、可爱和聪明✨😍✨。
+
+
+
+在等待中和你的恋人交谈时,你会不时地查看柜台上显示的号码,看看是否已经轮到你了。
+
+然后在某个时刻,终于轮到你了。你去柜台拿汉堡然后回到桌子上。
+
+
+
+你们享用了汉堡,整个过程都很开心。✨
+
+
+
+!!! info
+ 漂亮的插画来自 Ketrina Thompson. 🎨
+
+---
+
+在那个故事里,假设你是计算机程序 🤖 。
+
+当你在排队时,你只是闲着😴, 轮到你前不做任何事情(仅排队)。但排队很快,因为收银员只接订单(不准备订单),所以这一切都还好。
+
+然后,当轮到你时,需要你做一些实际性的工作,比如查看菜单,决定你想要什么,让你的恋人选择,支付,检查你是否提供了正确的账单或卡,检查你的收费是否正确,检查订单是否有正确的项目,等等。
+
+此时,即使你仍然没有汉堡,你和收银员的工作也"暂停"了⏸, 因为你必须等待一段时间 🕙 让你的汉堡做好。
+
+但是,当你离开柜台并坐在桌子旁,在轮到你的号码前的这段时间,你可以将焦点切换到 🔀 你的恋人上,并做一些"工作"⏯ 🤓。你可以做一些非常"有成效"的事情,比如和你的恋人调情😍.
+
+之后,收银员 💁 把号码显示在显示屏上,并说到 "汉堡做好了",而当显示的号码是你的号码时,你不会立刻疯狂地跳起来。因为你知道没有人会偷你的汉堡,因为你有你的号码,而其他人又有他们自己的号码。
+
+所以你要等待你的恋人完成故事(完成当前的工作⏯ /正在做的事🤓), 轻轻微笑,说你要吃汉堡⏸.
+
+然后你去柜台🔀, 到现在初始任务已经完成⏯, 拿起汉堡,说声谢谢,然后把它们送到桌上。这就完成了与计数器交互的步骤/任务⏹. 这反过来又产生了一项新任务,即"吃汉堡"🔀 ⏯, 上一个"拿汉堡"的任务已经结束了⏹.
+
+### 并行汉堡
+
+现在让我们假设不是"并发汉堡",而是"并行汉堡"。
+
+你和你的恋人一起去吃并行快餐。
+
+你站在队伍中,同时是厨师的几个收银员(比方说8个)从前面的人那里接单。
+
+你之前的每个人都在等待他们的汉堡准备好后才离开柜台,因为8名收银员都会在下一份订单前马上准备好汉堡。
+
+
+
+然后,终于轮到你了,你为你的恋人和你订购了两个非常精美的汉堡。
+
+你付钱了 💸。
+
+
+
+收银员去厨房。
+
+你站在柜台前 🕙等待着,这样就不会有人在你之前抢走你的汉堡,因为没有轮流的号码。
+
+
+
+当你和你的恋人忙于不让任何人出现在你面前,并且在他们到来的时候拿走你的汉堡时,你无法关注到你的恋人。😞
+
+这是"同步"的工作,你被迫与服务员/厨师 👨🍳"同步"。你在此必须等待 🕙 ,在收银员/厨师 👨🍳 完成汉堡并将它们交给你的确切时间到达之前一直等待,否则其他人可能会拿走它们。
+
+
+
+你经过长时间的等待 🕙 ,收银员/厨师 👨🍳终于带着汉堡回到了柜台。
+
+
+
+你拿着汉堡,和你的情人一起上桌。
+
+你们仅仅是吃了它们,就结束了。⏹
+
+
+
+没有太多的交谈或调情,因为大部分时间 🕙 都在柜台前等待😞。
+
+!!! info
+ 漂亮的插画来自 Ketrina Thompson. 🎨
+
+---
+
+在这个并行汉堡的场景中,你是一个计算机程序 🤖 且有两个处理器(你和你的恋人),都在等待 🕙 ,并投入他们的注意力 ⏯ 在柜台上等待了很长一段时间。
+
+这家快餐店有 8 个处理器(收银员/厨师)。而并发汉堡店可能只有 2 个(一个收银员和一个厨师)。
+
+但最终的体验仍然不是最好的。😞
+
+---
+
+这将是与汉堡的类似故事。🍔
+
+一种更"贴近生活"的例子,想象一家银行。
+
+直到最近,大多数银行都有多个出纳员 👨💼👨💼👨💼👨💼 还有一条长长排队队伍🕙🕙🕙🕙🕙🕙🕙🕙。
+
+所有收银员都是一个接一个的在客户面前做完所有的工作👨💼⏯.
+
+你必须经过 🕙 较长时间排队,否则你就没机会了。
+
+你可不会想带你的恋人 😍 和你一起去银行办事🏦.
+
+### 汉堡结论
+
+在"你与恋人一起吃汉堡"的这个场景中,因为有很多人在等待🕙, 使用并发系统更有意义⏸🔀⏯.
+
+大多数 Web 应用都是这样的。
+
+你的服务器正在等待很多很多用户通过他们不太好的网络发送来的请求。
+
+然后再次等待 🕙 响应回来。
+
+这个"等待" 🕙 是以微秒为单位测量的,但总的来说,最后还是等待很久。
+
+这就是为什么使用异步对于 Web API 很有意义的原因 ⏸🔀⏯。
+
+这种异步机制正是 NodeJS 受到欢迎的原因(尽管 NodeJS 不是并行的),以及 Go 作为编程语言的优势所在。
+
+这与 **FastAPI** 的性能水平相同。
+
+您可以同时拥有并行性和异步性,您可以获得比大多数经过测试的 NodeJS 框架更高的性能,并且与 Go 不相上下, Go 是一种更接近于 C 的编译语言(全部归功于 Starlette)。
+
+### 并发比并行好吗?
+
+不!这不是故事的本意。
+
+并发不同于并行。而是在需要大量等待的特定场景下效果更好。因此,在 Web 应用程序开发中,它通常比并行要好得多,但这并不意味着全部。
+
+因此,为了平衡这一点,想象一下下面的短篇故事:
+
+> 你必须打扫一个又大又脏的房子。
+
+*是的,这就是完整的故事。*
+
+---
+
+在任何地方, 都不需要等待 🕙 ,只需要在房子的多个地方做着很多工作。
+
+你可以像汉堡的例子那样轮流执行,先是客厅,然后是厨房,但因为你不需要等待 🕙 ,对于任何事情都是清洁,清洁,还是清洁,轮流不会影响任何事情。
+
+无论是否轮流执行(并发),都需要相同的时间来完成,而你也会完成相同的工作量。
+
+但在这种情况下,如果你能带上 8 名前收银员/厨师,现在是清洁工一起清扫,他们中的每一个人(加上你)都能占据房子的一个区域来清扫,你就可以在额外的帮助下并行的更快地完成所有工作。
+
+在这个场景中,每个清洁工(包括您)都将是一个处理器,完成这个工作的一部分。
+
+由于大多数执行时间是由实际工作(而不是等待)占用的,并且计算机中的工作是由 CPU 完成的,所以他们称这些问题为"CPU 密集型"。
+
+---
+
+CPU 密集型操作的常见示例是需要复杂的数学处理。
+
+例如:
+
+* **音频**或**图像**处理;
+* **计算机视觉**: 一幅图像由数百万像素组成,每个像素有3种颜色值,处理通常需要同时对这些像素进行计算;
+* **机器学习**: 它通常需要大量的"矩阵"和"向量"乘法。想象一个包含数字的巨大电子表格,并同时将所有数字相乘;
+* **深度学习**: 这是机器学习的一个子领域,同样适用。只是没有一个数字的电子表格可以相乘,而是一个庞大的数字集合,在很多情况下,你需要使用一个特殊的处理器来构建和使用这些模型。
+
+### 并发 + 并行: Web + 机器学习
+
+使用 **FastAPI**,您可以利用 Web 开发中常见的并发机制的优势(NodeJS 的主要吸引力)。
+
+并且,您也可以利用并行和多进程(让多个进程并行运行)的优点来处理与机器学习系统中类似的 **CPU 密集型** 工作。
+
+这一点,再加上 Python 是**数据科学**、机器学习(尤其是深度学习)的主要语言这一简单事实,使得 **FastAPI** 与数据科学/机器学习 Web API 和应用程序(以及其他许多应用程序)非常匹配。
+
+了解如何在生产环境中实现这种并行性,可查看此文 [Deployment](deployment/index.md){.internal-link target=_blank}。
+
+## `async` 和 `await`
+
+现代版本的 Python 有一种非常直观的方式来定义异步代码。这使它看起来就像正常的"顺序"代码,并在适当的时候"等待"。
+
+当有一个操作需要等待才能给出结果,且支持这个新的 Python 特性时,您可以编写如下代码:
+
+```Python
+burgers = await get_burgers(2)
+```
+
+这里的关键是 `await`。它告诉 Python 它必须等待 ⏸ `get_burgers(2)` 完成它的工作 🕙 ,然后将结果存储在 `burgers` 中。这样,Python 就会知道此时它可以去做其他事情 🔀 ⏯ (比如接收另一个请求)。
+
+要使 `await` 工作,它必须位于支持这种异步机制的函数内。因此,只需使用 `async def` 声明它:
+
+```Python hl_lines="1"
+async def get_burgers(number: int):
+ # Do some asynchronous stuff to create the burgers
+ return burgers
+```
+
+...而不是 `def`:
+
+```Python hl_lines="2"
+# This is not asynchronous
+def get_sequential_burgers(number: int):
+ # Do some sequential stuff to create the burgers
+ return burgers
+```
+
+使用 `async def`,Python 就知道在该函数中,它将遇上 `await`,并且它可以"暂停" ⏸ 执行该函数,直至执行其他操作 🔀 后回来。
+
+当你想调用一个 `async def` 函数时,你必须"等待"它。因此,这不会起作用:
+
+```Python
+# This won't work, because get_burgers was defined with: async def
+burgers = get_burgers(2)
+```
+
+---
+
+因此,如果您使用的库告诉您可以使用 `await` 调用它,则需要使用 `async def` 创建路径操作函数 ,如:
+
+```Python hl_lines="2-3"
+@app.get('/burgers')
+async def read_burgers():
+ burgers = await get_burgers(2)
+ return burgers
+```
+
+### 更多技术细节
+
+您可能已经注意到,`await` 只能在 `async def` 定义的函数内部使用。
+
+但与此同时,必须"等待"通过 `async def` 定义的函数。因此,带 `async def` 的函数也只能在 `async def` 定义的函数内部调用。
+
+那么,这关于先有鸡还是先有蛋的问题,如何调用第一个 `async` 函数?
+
+如果您使用 **FastAPI**,你不必担心这一点,因为"第一个"函数将是你的路径操作函数,FastAPI 将知道如何做正确的事情。
+
+但如果您想在没有 FastAPI 的情况下使用 `async` / `await`,则可以这样做。
+
+### 编写自己的异步代码
+
+Starlette (和 **FastAPI**) 是基于 AnyIO 实现的,这使得它们可以兼容 Python 的标准库 asyncio 和 Trio。
+
+特别是,你可以直接使用 AnyIO 来处理高级的并发用例,这些用例需要在自己的代码中使用更高级的模式。
+
+即使您没有使用 **FastAPI**,您也可以使用 AnyIO 编写自己的异步程序,使其拥有较高的兼容性并获得一些好处(例如, 结构化并发)。
+
+### 其他形式的异步代码
+
+这种使用 `async` 和 `await` 的风格在语言中相对较新。
+
+但它使处理异步代码变得容易很多。
+
+这种相同的语法(或几乎相同)最近也包含在现代版本的 JavaScript 中(在浏览器和 NodeJS 中)。
+
+但在此之前,处理异步代码非常复杂和困难。
+
+在以前版本的 Python,你可以使用多线程或者 Gevent。但代码的理解、调试和思考都要复杂许多。
+
+在以前版本的 NodeJS / 浏览器 JavaScript 中,你会使用"回调",因此也可能导致回调地狱。
+
+## 协程
+
+**协程**只是 `async def` 函数返回的一个非常奇特的东西的称呼。Python 知道它有点像一个函数,它可以启动,也会在某个时刻结束,而且它可能会在内部暂停 ⏸ ,只要内部有一个 `await`。
+
+通过使用 `async` 和 `await` 的异步代码的所有功能大多数被概括为"协程"。它可以与 Go 的主要关键特性 "Goroutines" 相媲美。
+
+## 结论
+
+让我们再来回顾下上文所说的:
+
+> Python 的现代版本可以通过使用 `async` 和 `await` 语法创建**协程**,并用于支持**异步代码**。
+
+现在应该能明白其含义了。✨
+
+所有这些使得 FastAPI(通过 Starlette)如此强大,也是它拥有如此令人印象深刻的性能的原因。
+
+## 非常技术性的细节
+
+!!! warning
+ 你可以跳过这里。
+
+ 这些都是 FastAPI 如何在内部工作的技术细节。
+
+ 如果您有相当多的技术知识(协程、线程、阻塞等),并且对 FastAPI 如何处理 `async def` 与常规 `def` 感到好奇,请继续。
+
+### 路径操作函数
+
+当你使用 `def` 而不是 `async def` 来声明一个*路径操作函数*时,它运行在外部的线程池中并等待其结果,而不是直接调用(因为它会阻塞服务器)。
+
+如果您使用过另一个不以上述方式工作的异步框架,并且您习惯于用普通的 `def` 定义普通的仅计算路径操作函数,以获得微小的性能增益(大约100纳秒),请注意,在 FastAPI 中,效果将完全相反。在这些情况下,最好使用 `async def`,除非路径操作函数内使用执行阻塞 I/O 的代码。
+
+在这两种情况下,与您之前的框架相比,**FastAPI** 可能[仍然很快](/#performance){.internal-link target=_blank}。
+
+### 依赖
+
+这同样适用于[依赖](/tutorial/dependencies/index.md){.internal-link target=_blank}。如果一个依赖是标准的 `def` 函数而不是 `async def`,它将被运行在外部线程池中。
+
+### 子依赖
+
+你可以拥有多个相互依赖的依赖以及[子依赖](/tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank} (作为函数的参数),它们中的一些可能是通过 `async def` 声明,也可能是通过 `def` 声明。它们仍然可以正常工作,这些通过 `def` 声明的函数将会在外部线程中调用(来自线程池),而不是"被等待"。
+
+### 其他函数
+
+您可直接调用通过 `def` 或 `async def` 创建的任何其他函数,FastAPI 不会影响您调用它们的方式。
+
+这与 FastAPI 为您调用*路径操作函数*和依赖项的逻辑相反。
+
+如果你的函数是通过 `def` 声明的,它将被直接调用(在代码中编写的地方),而不会在线程池中,如果这个函数通过 `async def` 声明,当在代码中调用时,你就应该使用 `await` 等待函数的结果。
+
+---
+
+再次提醒,这些是非常技术性的细节,如果你来搜索它可能对你有用。
+
+否则,您最好应该遵守的指导原则赶时间吗?.
diff --git a/fastapi/_compat.py b/fastapi/_compat.py
index eb55b08f2e..a4b305d429 100644
--- a/fastapi/_compat.py
+++ b/fastapi/_compat.py
@@ -58,9 +58,15 @@ if PYDANTIC_V2:
from pydantic_core import CoreSchema as CoreSchema
from pydantic_core import PydanticUndefined, PydanticUndefinedType
from pydantic_core import Url as Url
- from pydantic_core.core_schema import (
- general_plain_validator_function as general_plain_validator_function,
- )
+
+ try:
+ from pydantic_core.core_schema import (
+ with_info_plain_validator_function as with_info_plain_validator_function,
+ )
+ except ImportError: # pragma: no cover
+ from pydantic_core.core_schema import (
+ general_plain_validator_function as with_info_plain_validator_function, # noqa: F401
+ )
Required = PydanticUndefined
Undefined = PydanticUndefined
@@ -345,7 +351,7 @@ else:
class PydanticSchemaGenerationError(Exception): # type: ignore[no-redef]
pass
- def general_plain_validator_function( # type: ignore[misc]
+ def with_info_plain_validator_function( # type: ignore[misc]
function: Callable[..., Any],
*,
ref: Union[str, None] = None,
diff --git a/fastapi/datastructures.py b/fastapi/datastructures.py
index 3c96c56c70..b2865cd405 100644
--- a/fastapi/datastructures.py
+++ b/fastapi/datastructures.py
@@ -5,7 +5,7 @@ from fastapi._compat import (
CoreSchema,
GetJsonSchemaHandler,
JsonSchemaValue,
- general_plain_validator_function,
+ with_info_plain_validator_function,
)
from starlette.datastructures import URL as URL # noqa: F401
from starlette.datastructures import Address as Address # noqa: F401
@@ -49,7 +49,7 @@ class UploadFile(StarletteUploadFile):
def __get_pydantic_core_schema__(
cls, source: Type[Any], handler: Callable[[Any], CoreSchema]
) -> CoreSchema:
- return general_plain_validator_function(cls._validate)
+ return with_info_plain_validator_function(cls._validate)
class DefaultPlaceholder:
diff --git a/fastapi/openapi/models.py b/fastapi/openapi/models.py
index 3d982eb9ae..5f3bdbb206 100644
--- a/fastapi/openapi/models.py
+++ b/fastapi/openapi/models.py
@@ -7,7 +7,7 @@ from fastapi._compat import (
GetJsonSchemaHandler,
JsonSchemaValue,
_model_rebuild,
- general_plain_validator_function,
+ with_info_plain_validator_function,
)
from fastapi.logger import logger
from pydantic import AnyUrl, BaseModel, Field
@@ -52,7 +52,7 @@ except ImportError: # pragma: no cover
def __get_pydantic_core_schema__(
cls, source: Type[Any], handler: Callable[[Any], CoreSchema]
) -> CoreSchema:
- return general_plain_validator_function(cls._validate)
+ return with_info_plain_validator_function(cls._validate)
class Contact(BaseModel):
diff --git a/tests/test_compat.py b/tests/test_compat.py
index 47160ee76f..bf268b860b 100644
--- a/tests/test_compat.py
+++ b/tests/test_compat.py
@@ -24,7 +24,7 @@ def test_model_field_default_required():
@needs_pydanticv1
-def test_upload_file_dummy_general_plain_validator_function():
+def test_upload_file_dummy_with_info_plain_validator_function():
# For coverage
assert UploadFile.__get_pydantic_core_schema__(str, lambda x: None) == {}
diff --git a/tests/test_filter_pydantic_sub_model_pv2.py b/tests/test_filter_pydantic_sub_model_pv2.py
index 9f5e6b08fb..9097d2ce52 100644
--- a/tests/test_filter_pydantic_sub_model_pv2.py
+++ b/tests/test_filter_pydantic_sub_model_pv2.py
@@ -12,7 +12,7 @@ from .utils import needs_pydanticv2
@pytest.fixture(name="client")
def get_client():
- from pydantic import BaseModel, FieldValidationInfo, field_validator
+ from pydantic import BaseModel, ValidationInfo, field_validator
app = FastAPI()
@@ -28,7 +28,7 @@ def get_client():
foo: ModelB
@field_validator("name")
- def lower_username(cls, name: str, info: FieldValidationInfo):
+ def lower_username(cls, name: str, info: ValidationInfo):
if not name.endswith("A"):
raise ValueError("name must end in A")
return name
diff --git a/tests/test_openapi_separate_input_output_schemas.py b/tests/test_openapi_separate_input_output_schemas.py
index 70f4b90d75..aeb85f735b 100644
--- a/tests/test_openapi_separate_input_output_schemas.py
+++ b/tests/test_openapi_separate_input_output_schemas.py
@@ -4,19 +4,23 @@ from fastapi import FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel
-from .utils import needs_pydanticv2
+from .utils import PYDANTIC_V2, needs_pydanticv2
class SubItem(BaseModel):
subname: str
sub_description: Optional[str] = None
tags: List[str] = []
+ if PYDANTIC_V2:
+ model_config = {"json_schema_serialization_defaults_required": True}
class Item(BaseModel):
name: str
description: Optional[str] = None
sub: Optional[SubItem] = None
+ if PYDANTIC_V2:
+ model_config = {"json_schema_serialization_defaults_required": True}
def get_app_client(separate_input_output_schemas: bool = True) -> TestClient:
diff --git a/tests/test_tutorial/test_body_updates/test_tutorial001.py b/tests/test_tutorial/test_body_updates/test_tutorial001.py
index 58587885ef..e586534a07 100644
--- a/tests/test_tutorial/test_body_updates/test_tutorial001.py
+++ b/tests/test_tutorial/test_body_updates/test_tutorial001.py
@@ -52,9 +52,7 @@ def test_openapi_schema(client: TestClient):
"description": "Successful Response",
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Item-Output"
- }
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
},
@@ -86,9 +84,7 @@ def test_openapi_schema(client: TestClient):
"description": "Successful Response",
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Item-Output"
- }
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
},
@@ -116,7 +112,7 @@ def test_openapi_schema(client: TestClient):
"requestBody": {
"content": {
"application/json": {
- "schema": {"$ref": "#/components/schemas/Item-Input"}
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
"required": True,
@@ -126,35 +122,9 @@ def test_openapi_schema(client: TestClient):
},
"components": {
"schemas": {
- "Item-Input": {
- "title": "Item",
+ "Item": {
"type": "object",
- "properties": {
- "name": {
- "title": "Name",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- },
- "description": {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- },
- "price": {
- "title": "Price",
- "anyOf": [{"type": "number"}, {"type": "null"}],
- },
- "tax": {"title": "Tax", "type": "number", "default": 10.5},
- "tags": {
- "title": "Tags",
- "type": "array",
- "items": {"type": "string"},
- "default": [],
- },
- },
- },
- "Item-Output": {
"title": "Item",
- "type": "object",
- "required": ["name", "description", "price", "tax", "tags"],
"properties": {
"name": {
"anyOf": [{"type": "string"}, {"type": "null"}],
diff --git a/tests/test_tutorial/test_body_updates/test_tutorial001_py310.py b/tests/test_tutorial/test_body_updates/test_tutorial001_py310.py
index d8a62502f0..6bc969d43a 100644
--- a/tests/test_tutorial/test_body_updates/test_tutorial001_py310.py
+++ b/tests/test_tutorial/test_body_updates/test_tutorial001_py310.py
@@ -55,9 +55,7 @@ def test_openapi_schema(client: TestClient):
"description": "Successful Response",
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Item-Output"
- }
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
},
@@ -89,9 +87,7 @@ def test_openapi_schema(client: TestClient):
"description": "Successful Response",
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Item-Output"
- }
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
},
@@ -119,7 +115,7 @@ def test_openapi_schema(client: TestClient):
"requestBody": {
"content": {
"application/json": {
- "schema": {"$ref": "#/components/schemas/Item-Input"}
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
"required": True,
@@ -129,35 +125,9 @@ def test_openapi_schema(client: TestClient):
},
"components": {
"schemas": {
- "Item-Input": {
- "title": "Item",
+ "Item": {
"type": "object",
- "properties": {
- "name": {
- "title": "Name",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- },
- "description": {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- },
- "price": {
- "title": "Price",
- "anyOf": [{"type": "number"}, {"type": "null"}],
- },
- "tax": {"title": "Tax", "type": "number", "default": 10.5},
- "tags": {
- "title": "Tags",
- "type": "array",
- "items": {"type": "string"},
- "default": [],
- },
- },
- },
- "Item-Output": {
"title": "Item",
- "type": "object",
- "required": ["name", "description", "price", "tax", "tags"],
"properties": {
"name": {
"anyOf": [{"type": "string"}, {"type": "null"}],
diff --git a/tests/test_tutorial/test_body_updates/test_tutorial001_py39.py b/tests/test_tutorial/test_body_updates/test_tutorial001_py39.py
index c604df6ecb..a1edb33707 100644
--- a/tests/test_tutorial/test_body_updates/test_tutorial001_py39.py
+++ b/tests/test_tutorial/test_body_updates/test_tutorial001_py39.py
@@ -55,9 +55,7 @@ def test_openapi_schema(client: TestClient):
"description": "Successful Response",
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Item-Output"
- }
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
},
@@ -89,9 +87,7 @@ def test_openapi_schema(client: TestClient):
"description": "Successful Response",
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Item-Output"
- }
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
},
@@ -119,7 +115,7 @@ def test_openapi_schema(client: TestClient):
"requestBody": {
"content": {
"application/json": {
- "schema": {"$ref": "#/components/schemas/Item-Input"}
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
"required": True,
@@ -129,35 +125,9 @@ def test_openapi_schema(client: TestClient):
},
"components": {
"schemas": {
- "Item-Input": {
- "title": "Item",
+ "Item": {
"type": "object",
- "properties": {
- "name": {
- "title": "Name",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- },
- "description": {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- },
- "price": {
- "title": "Price",
- "anyOf": [{"type": "number"}, {"type": "null"}],
- },
- "tax": {"title": "Tax", "type": "number", "default": 10.5},
- "tags": {
- "title": "Tags",
- "type": "array",
- "items": {"type": "string"},
- "default": [],
- },
- },
- },
- "Item-Output": {
"title": "Item",
- "type": "object",
- "required": ["name", "description", "price", "tax", "tags"],
"properties": {
"name": {
"anyOf": [{"type": "string"}, {"type": "null"}],
diff --git a/tests/test_tutorial/test_dataclasses/test_tutorial003.py b/tests/test_tutorial/test_dataclasses/test_tutorial003.py
index f2ca858235..dd0e36735e 100644
--- a/tests/test_tutorial/test_dataclasses/test_tutorial003.py
+++ b/tests/test_tutorial/test_dataclasses/test_tutorial003.py
@@ -79,9 +79,7 @@ def test_openapi_schema():
"schema": {
"title": "Items",
"type": "array",
- "items": {
- "$ref": "#/components/schemas/Item-Input"
- },
+ "items": {"$ref": "#/components/schemas/Item"},
}
}
},
@@ -136,14 +134,14 @@ def test_openapi_schema():
"schemas": {
"Author": {
"title": "Author",
- "required": ["name", "items"],
+ "required": ["name"],
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"items": {
"title": "Items",
"type": "array",
- "items": {"$ref": "#/components/schemas/Item-Output"},
+ "items": {"$ref": "#/components/schemas/Item"},
},
},
},
@@ -158,27 +156,15 @@ def test_openapi_schema():
}
},
},
- "Item-Input": {
+ "Item": {
"title": "Item",
"required": ["name"],
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"description": {
- "title": "Description",
"anyOf": [{"type": "string"}, {"type": "null"}],
- },
- },
- },
- "Item-Output": {
- "title": "Item",
- "required": ["name", "description"],
- "type": "object",
- "properties": {
- "name": {"title": "Name", "type": "string"},
- "description": {
"title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
},
},
},
diff --git a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial004.py b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial004.py
index c5b2fb670b..4f69e4646c 100644
--- a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial004.py
+++ b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial004.py
@@ -34,9 +34,7 @@ def test_openapi_schema():
"description": "Successful Response",
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Item-Output"
- }
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
},
@@ -57,7 +55,7 @@ def test_openapi_schema():
"requestBody": {
"content": {
"application/json": {
- "schema": {"$ref": "#/components/schemas/Item-Input"}
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
"required": True,
@@ -67,7 +65,7 @@ def test_openapi_schema():
},
"components": {
"schemas": {
- "Item-Input": {
+ "Item": {
"title": "Item",
"required": ["name", "price"],
"type": "object",
@@ -91,30 +89,6 @@ def test_openapi_schema():
},
},
},
- "Item-Output": {
- "title": "Item",
- "required": ["name", "description", "price", "tax", "tags"],
- "type": "object",
- "properties": {
- "name": {"title": "Name", "type": "string"},
- "description": {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- },
- "price": {"title": "Price", "type": "number"},
- "tax": {
- "title": "Tax",
- "anyOf": [{"type": "number"}, {"type": "null"}],
- },
- "tags": {
- "title": "Tags",
- "uniqueItems": True,
- "type": "array",
- "items": {"type": "string"},
- "default": [],
- },
- },
- },
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
diff --git a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005.py b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005.py
index 458923b5a0..d3792e701f 100644
--- a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005.py
+++ b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005.py
@@ -34,9 +34,7 @@ def test_openapi_schema():
"description": "The created item",
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Item-Output"
- }
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
},
@@ -57,7 +55,7 @@ def test_openapi_schema():
"requestBody": {
"content": {
"application/json": {
- "schema": {"$ref": "#/components/schemas/Item-Input"}
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
"required": True,
@@ -67,7 +65,7 @@ def test_openapi_schema():
},
"components": {
"schemas": {
- "Item-Input": {
+ "Item": {
"title": "Item",
"required": ["name", "price"],
"type": "object",
@@ -91,30 +89,6 @@ def test_openapi_schema():
},
},
},
- "Item-Output": {
- "title": "Item",
- "required": ["name", "description", "price", "tax", "tags"],
- "type": "object",
- "properties": {
- "name": {"title": "Name", "type": "string"},
- "description": {
- "anyOf": [{"type": "string"}, {"type": "null"}],
- "title": "Description",
- },
- "price": {"title": "Price", "type": "number"},
- "tax": {
- "title": "Tax",
- "anyOf": [{"type": "number"}, {"type": "null"}],
- },
- "tags": {
- "title": "Tags",
- "uniqueItems": True,
- "type": "array",
- "items": {"type": "string"},
- "default": [],
- },
- },
- },
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
diff --git a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py310.py b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py310.py
index 1fcc5c4e0c..a68deb3df5 100644
--- a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py310.py
+++ b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py310.py
@@ -41,9 +41,7 @@ def test_openapi_schema(client: TestClient):
"description": "The created item",
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Item-Output"
- }
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
},
@@ -64,7 +62,7 @@ def test_openapi_schema(client: TestClient):
"requestBody": {
"content": {
"application/json": {
- "schema": {"$ref": "#/components/schemas/Item-Input"}
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
"required": True,
@@ -74,7 +72,7 @@ def test_openapi_schema(client: TestClient):
},
"components": {
"schemas": {
- "Item-Input": {
+ "Item": {
"title": "Item",
"required": ["name", "price"],
"type": "object",
@@ -98,30 +96,6 @@ def test_openapi_schema(client: TestClient):
},
},
},
- "Item-Output": {
- "title": "Item",
- "required": ["name", "description", "price", "tax", "tags"],
- "type": "object",
- "properties": {
- "name": {"title": "Name", "type": "string"},
- "description": {
- "anyOf": [{"type": "string"}, {"type": "null"}],
- "title": "Description",
- },
- "price": {"title": "Price", "type": "number"},
- "tax": {
- "title": "Tax",
- "anyOf": [{"type": "number"}, {"type": "null"}],
- },
- "tags": {
- "title": "Tags",
- "uniqueItems": True,
- "type": "array",
- "items": {"type": "string"},
- "default": [],
- },
- },
- },
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
diff --git a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py39.py b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py39.py
index 470fe032b1..e17f2592dc 100644
--- a/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py39.py
+++ b/tests/test_tutorial/test_path_operation_configurations/test_tutorial005_py39.py
@@ -41,9 +41,7 @@ def test_openapi_schema(client: TestClient):
"description": "The created item",
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Item-Output"
- }
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
},
@@ -64,7 +62,7 @@ def test_openapi_schema(client: TestClient):
"requestBody": {
"content": {
"application/json": {
- "schema": {"$ref": "#/components/schemas/Item-Input"}
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
"required": True,
@@ -74,7 +72,7 @@ def test_openapi_schema(client: TestClient):
},
"components": {
"schemas": {
- "Item-Input": {
+ "Item": {
"title": "Item",
"required": ["name", "price"],
"type": "object",
@@ -98,30 +96,6 @@ def test_openapi_schema(client: TestClient):
},
},
},
- "Item-Output": {
- "title": "Item",
- "required": ["name", "description", "price", "tax", "tags"],
- "type": "object",
- "properties": {
- "name": {"title": "Name", "type": "string"},
- "description": {
- "anyOf": [{"type": "string"}, {"type": "null"}],
- "title": "Description",
- },
- "price": {"title": "Price", "type": "number"},
- "tax": {
- "title": "Tax",
- "anyOf": [{"type": "number"}, {"type": "null"}],
- },
- "tags": {
- "title": "Tags",
- "uniqueItems": True,
- "type": "array",
- "items": {"type": "string"},
- "default": [],
- },
- },
- },
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
diff --git a/tests/test_tutorial/test_path_params/test_tutorial005.py b/tests/test_tutorial/test_path_params/test_tutorial005.py
index 90fa6adaf7..2e4b0146be 100644
--- a/tests/test_tutorial/test_path_params/test_tutorial005.py
+++ b/tests/test_tutorial/test_path_params/test_tutorial005.py
@@ -33,9 +33,9 @@ def test_get_enums_invalid():
{
"type": "enum",
"loc": ["path", "model_name"],
- "msg": "Input should be 'alexnet','resnet' or 'lenet'",
+ "msg": "Input should be 'alexnet', 'resnet' or 'lenet'",
"input": "foo",
- "ctx": {"expected": "'alexnet','resnet' or 'lenet'"},
+ "ctx": {"expected": "'alexnet', 'resnet' or 'lenet'"},
}
]
}
diff --git a/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial001.py b/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial001.py
index 8079c11343..cdfae9f8c1 100644
--- a/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial001.py
+++ b/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial001.py
@@ -48,9 +48,7 @@ def test_openapi_schema(client: TestClient) -> None:
"content": {
"application/json": {
"schema": {
- "items": {
- "$ref": "#/components/schemas/Item-Output"
- },
+ "items": {"$ref": "#/components/schemas/Item"},
"type": "array",
"title": "Response Read Items Items Get",
}
@@ -65,7 +63,7 @@ def test_openapi_schema(client: TestClient) -> None:
"requestBody": {
"content": {
"application/json": {
- "schema": {"$ref": "#/components/schemas/Item-Input"}
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
"required": True,
@@ -102,7 +100,7 @@ def test_openapi_schema(client: TestClient) -> None:
"type": "object",
"title": "HTTPValidationError",
},
- "Item-Input": {
+ "Item": {
"properties": {
"name": {"type": "string", "title": "Name"},
"description": {
@@ -114,18 +112,6 @@ def test_openapi_schema(client: TestClient) -> None:
"required": ["name"],
"title": "Item",
},
- "Item-Output": {
- "properties": {
- "name": {"type": "string", "title": "Name"},
- "description": {
- "anyOf": [{"type": "string"}, {"type": "null"}],
- "title": "Description",
- },
- },
- "type": "object",
- "required": ["name", "description"],
- "title": "Item",
- },
"ValidationError": {
"properties": {
"loc": {
diff --git a/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial001_py310.py b/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial001_py310.py
index 4fa98ccbef..3b22146f63 100644
--- a/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial001_py310.py
+++ b/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial001_py310.py
@@ -51,9 +51,7 @@ def test_openapi_schema(client: TestClient) -> None:
"content": {
"application/json": {
"schema": {
- "items": {
- "$ref": "#/components/schemas/Item-Output"
- },
+ "items": {"$ref": "#/components/schemas/Item"},
"type": "array",
"title": "Response Read Items Items Get",
}
@@ -68,7 +66,7 @@ def test_openapi_schema(client: TestClient) -> None:
"requestBody": {
"content": {
"application/json": {
- "schema": {"$ref": "#/components/schemas/Item-Input"}
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
"required": True,
@@ -105,7 +103,7 @@ def test_openapi_schema(client: TestClient) -> None:
"type": "object",
"title": "HTTPValidationError",
},
- "Item-Input": {
+ "Item": {
"properties": {
"name": {"type": "string", "title": "Name"},
"description": {
@@ -117,18 +115,6 @@ def test_openapi_schema(client: TestClient) -> None:
"required": ["name"],
"title": "Item",
},
- "Item-Output": {
- "properties": {
- "name": {"type": "string", "title": "Name"},
- "description": {
- "anyOf": [{"type": "string"}, {"type": "null"}],
- "title": "Description",
- },
- },
- "type": "object",
- "required": ["name", "description"],
- "title": "Item",
- },
"ValidationError": {
"properties": {
"loc": {
diff --git a/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial001_py39.py b/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial001_py39.py
index ad36582ed5..991abe8113 100644
--- a/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial001_py39.py
+++ b/tests/test_tutorial/test_separate_openapi_schemas/test_tutorial001_py39.py
@@ -51,9 +51,7 @@ def test_openapi_schema(client: TestClient) -> None:
"content": {
"application/json": {
"schema": {
- "items": {
- "$ref": "#/components/schemas/Item-Output"
- },
+ "items": {"$ref": "#/components/schemas/Item"},
"type": "array",
"title": "Response Read Items Items Get",
}
@@ -68,7 +66,7 @@ def test_openapi_schema(client: TestClient) -> None:
"requestBody": {
"content": {
"application/json": {
- "schema": {"$ref": "#/components/schemas/Item-Input"}
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
"required": True,
@@ -105,7 +103,7 @@ def test_openapi_schema(client: TestClient) -> None:
"type": "object",
"title": "HTTPValidationError",
},
- "Item-Input": {
+ "Item": {
"properties": {
"name": {"type": "string", "title": "Name"},
"description": {
@@ -117,18 +115,6 @@ def test_openapi_schema(client: TestClient) -> None:
"required": ["name"],
"title": "Item",
},
- "Item-Output": {
- "properties": {
- "name": {"type": "string", "title": "Name"},
- "description": {
- "anyOf": [{"type": "string"}, {"type": "null"}],
- "title": "Description",
- },
- },
- "type": "object",
- "required": ["name", "description"],
- "title": "Item",
- },
"ValidationError": {
"properties": {
"loc": {