]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
🌐 Update translations for fr (update-outdated) (#14826)
authorSebastiĂĄn RamĂ­rez <tiangolo@gmail.com>
Thu, 5 Feb 2026 15:34:19 +0000 (07:34 -0800)
committerGitHub <noreply@github.com>
Thu, 5 Feb 2026 15:34:19 +0000 (16:34 +0100)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
24 files changed:
docs/fr/docs/advanced/additional-responses.md
docs/fr/docs/advanced/additional-status-codes.md
docs/fr/docs/advanced/index.md
docs/fr/docs/advanced/path-operation-advanced-configuration.md
docs/fr/docs/advanced/response-directly.md
docs/fr/docs/benchmarks.md
docs/fr/docs/deployment/docker.md
docs/fr/docs/deployment/https.md
docs/fr/docs/deployment/index.md
docs/fr/docs/deployment/versions.md
docs/fr/docs/index.md
docs/fr/docs/learn/index.md
docs/fr/docs/project-generation.md
docs/fr/docs/python-types.md
docs/fr/docs/tutorial/background-tasks.md
docs/fr/docs/tutorial/body-multiple-params.md
docs/fr/docs/tutorial/body.md
docs/fr/docs/tutorial/debugging.md
docs/fr/docs/tutorial/first-steps.md
docs/fr/docs/tutorial/index.md
docs/fr/docs/tutorial/path-params-numeric-validations.md
docs/fr/docs/tutorial/path-params.md
docs/fr/docs/tutorial/query-params-str-validations.md
docs/fr/docs/tutorial/query-params.md

index 38527aad3c09ed6d25e5024023f092861d1cfdd1..dabcded52e16459d128152f11c7deb9c9a070d6d 100644 (file)
@@ -1,6 +1,6 @@
-# RĂ©ponses supplĂ©mentaires dans OpenAPI
+# RĂ©ponses supplĂ©mentaires dans OpenAPI { #additional-responses-in-openapi }
 
-/// warning | Attention
+/// warning | Alertes
 
 Ceci concerne un sujet plutĂŽt avancĂ©.
 
@@ -14,9 +14,9 @@ Ces rĂ©ponses supplĂ©mentaires seront incluses dans le schĂ©ma OpenAPI, elles ap
 
 Mais pour ces rĂ©ponses supplĂ©mentaires, vous devez vous assurer de renvoyer directement une `Response` comme `JSONResponse`, avec votre code HTTP et votre contenu.
 
-## RĂ©ponse supplĂ©mentaire avec `model`
+## RĂ©ponse supplĂ©mentaire avec `model` { #additional-response-with-model }
 
-Vous pouvez ajouter Ă  votre dĂ©corateur de *paramĂštre de chemin* un paramĂštre `responses`.
+Vous pouvez passer Ă  vos dĂ©corateurs de *chemin d'accĂšs* un paramĂštre `responses`.
 
 Il prend comme valeur un `dict` dont les clĂ©s sont des codes HTTP pour chaque rĂ©ponse, comme `200`, et la valeur de ces clĂ©s sont d'autres `dict` avec des informations pour chacun d'eux.
 
@@ -26,7 +26,7 @@ Chacun de ces `dict` de rĂ©ponse peut avoir une clĂ© `model`, contenant un modĂš
 
 Par exemple, pour dĂ©clarer une autre rĂ©ponse avec un code HTTP `404` et un modĂšle Pydantic `Message`, vous pouvez Ă©crire :
 
-{* ../../docs_src/additional_responses/tutorial001.py hl[18,22] *}
+{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *}
 
 /// note | Remarque
 
@@ -49,7 +49,7 @@ Le bon endroit est :
 
 ///
 
-Les rĂ©ponses gĂ©nĂ©rĂ©es au format OpenAPI pour cette *opĂ©ration de chemin* seront :
+Les rĂ©ponses gĂ©nĂ©rĂ©es au format OpenAPI pour ce *chemin d'accĂšs* seront :
 
 ```JSON hl_lines="3-12"
 {
@@ -169,13 +169,13 @@ Les schĂ©mas sont rĂ©fĂ©rencĂ©s Ă  un autre endroit du modĂšle OpenAPI :
 }
 ```
 
-## Types de mĂ©dias supplĂ©mentaires pour la rĂ©ponse principale
+## Types de mĂ©dias supplĂ©mentaires pour la rĂ©ponse principale { #additional-media-types-for-the-main-response }
 
 Vous pouvez utiliser ce mĂȘme paramĂštre `responses` pour ajouter diffĂ©rents types de mĂ©dias pour la mĂȘme rĂ©ponse principale.
 
-Par exemple, vous pouvez ajouter un type de mĂ©dia supplĂ©mentaire `image/png`, en dĂ©clarant que votre *opĂ©ration de chemin* peut renvoyer un objet JSON (avec le type de mĂ©dia `application/json`) ou une image PNG :
+Par exemple, vous pouvez ajouter un type de mĂ©dia supplĂ©mentaire `image/png`, en dĂ©clarant que votre *chemin d'accĂšs* peut renvoyer un objet JSON (avec le type de mĂ©dia `application/json`) ou une image PNG :
 
-{* ../../docs_src/additional_responses/tutorial002.py hl[19:24,28] *}
+{* ../../docs_src/additional_responses/tutorial002_py310.py hl[17:22,26] *}
 
 /// note | Remarque
 
@@ -191,7 +191,7 @@ Mais si vous avez spĂ©cifiĂ© une classe de rĂ©ponse personnalisĂ©e avec `None` c
 
 ///
 
-## Combinaison d'informations
+## Combiner les informations { #combining-information }
 
 Vous pouvez Ă©galement combiner des informations de rĂ©ponse provenant de plusieurs endroits, y compris les paramĂštres `response_model`, `status_code` et `responses`.
 
@@ -203,17 +203,17 @@ Par exemple, vous pouvez dĂ©clarer une rĂ©ponse avec un code HTTP `404` qui util
 
 Et une rĂ©ponse avec un code HTTP `200` qui utilise votre `response_model`, mais inclut un `example` personnalisé :
 
-{* ../../docs_src/additional_responses/tutorial003.py hl[20:31] *}
+{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *}
 
 Tout sera combinĂ© et inclus dans votre OpenAPI, et affichĂ© dans la documentation de l'API :
 
 <img src="/img/tutorial/additional-responses/image01.png">
 
-## Combinez les rĂ©ponses prĂ©dĂ©finies et les rĂ©ponses personnalisĂ©es
+## Combinez les rĂ©ponses prĂ©dĂ©finies et les rĂ©ponses personnalisĂ©es { #combine-predefined-responses-and-custom-ones }
 
-Vous voulez peut-ĂȘtre avoir des rĂ©ponses prĂ©dĂ©finies qui s'appliquent Ă  de nombreux *paramĂštre de chemin*, mais vous souhaitez les combiner avec des rĂ©ponses personnalisĂ©es nĂ©cessaires Ă  chaque *opĂ©ration de chemin*.
+Vous voulez peut-ĂȘtre avoir des rĂ©ponses prĂ©dĂ©finies qui s'appliquent Ă  de nombreux *chemins d'accĂšs*, mais vous souhaitez les combiner avec des rĂ©ponses personnalisĂ©es nĂ©cessaires Ă  chaque *chemin d'accĂšs*.
 
-Dans ces cas, vous pouvez utiliser la technique Python "d'affection par dĂ©composition" (appelĂ© _unpacking_ en anglais) d'un `dict` avec `**dict_to_unpack` :
+Dans ces cas, vous pouvez utiliser la technique Python Â« unpacking Â» d'un `dict` avec `**dict_to_unpack` :
 
 ```Python
 old_dict = {
@@ -233,15 +233,15 @@ Ici, `new_dict` contiendra toutes les paires clĂ©-valeur de `old_dict` plus la n
 }
 ```
 
-Vous pouvez utiliser cette technique pour rĂ©utiliser certaines rĂ©ponses prĂ©dĂ©finies dans vos *paramĂštres de chemin* et les combiner avec des rĂ©ponses personnalisĂ©es supplĂ©mentaires.
+Vous pouvez utiliser cette technique pour rĂ©utiliser certaines rĂ©ponses prĂ©dĂ©finies dans vos *chemins d'accĂšs* et les combiner avec des rĂ©ponses personnalisĂ©es supplĂ©mentaires.
 
 Par exemple:
 
-{* ../../docs_src/additional_responses/tutorial004.py hl[13:17,26] *}
+{* ../../docs_src/additional_responses/tutorial004_py310.py hl[11:15,24] *}
 
-## Plus d'informations sur les rĂ©ponses OpenAPI
+## Plus d'informations sur les rĂ©ponses OpenAPI { #more-information-about-openapi-responses }
 
 Pour voir exactement ce que vous pouvez inclure dans les rĂ©ponses, vous pouvez consulter ces sections dans la spĂ©cification OpenAPI :
 
-* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#responsesObject" class="external-link" target="_blank">Objet Responses de OpenAPI </a>, il inclut le `Response Object`.
-* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#responseObject" class="external-link" target="_blank">Objet Response de OpenAPI </a>, vous pouvez inclure n'importe quoi directement dans chaque rĂ©ponse Ă  l'intĂ©rieur de votre paramĂštre `responses`. Y compris `description`, `headers`, `content` (Ă  l'intĂ©rieur de cela, vous dĂ©clarez diffĂ©rents types de mĂ©dias et schĂ©mas JSON) et `links`.
+* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responses-object" class="external-link" target="_blank">Objet Responses de OpenAPI</a>, il inclut le `Response Object`.
+* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#response-object" class="external-link" target="_blank">Objet Response de OpenAPI</a>, vous pouvez inclure n'importe quoi directement dans chaque rĂ©ponse Ă  l'intĂ©rieur de votre paramĂštre `responses`. Y compris `description`, `headers`, `content` (Ă  l'intĂ©rieur de cela, vous dĂ©clarez diffĂ©rents types de mĂ©dias et schĂ©mas JSON) et `links`.
index dde6b9a63fab336d26d68d52f2ce379074b9082f..b2befffa8dfeb14425872ab0e9c2678fe79f9ec3 100644 (file)
@@ -1,28 +1,28 @@
-# Codes HTTP supplĂ©mentaires
+# Codes HTTP supplĂ©mentaires { #additional-status-codes }
 
 Par dĂ©faut, **FastAPI** renverra les rĂ©ponses Ă  l'aide d'une structure de donnĂ©es `JSONResponse`, en plaçant la rĂ©ponse de votre  *chemin d'accĂšs* Ă  l'intĂ©rieur de cette `JSONResponse`.
 
 Il utilisera le code HTTP par dĂ©faut ou celui que vous avez dĂ©fini dans votre *chemin d'accĂšs*.
 
-## Codes HTTP supplĂ©mentaires
+## Codes HTTP supplĂ©mentaires { #additional-status-codes_1 }
 
 Si vous souhaitez renvoyer des codes HTTP supplĂ©mentaires en plus du code principal, vous pouvez le faire en renvoyant directement une `Response`, comme une `JSONResponse`, et en dĂ©finissant directement le code HTTP supplĂ©mentaire.
 
-Par exemple, disons que vous voulez avoir un *chemin d'accĂšs* qui permet de mettre Ă  jour les Ă©lĂ©ments et renvoie les codes HTTP 200 "OK" en cas de succĂšs.
+Par exemple, disons que vous voulez avoir un *chemin d'accĂšs* qui permet de mettre Ă  jour les Ă©lĂ©ments et renvoie les codes HTTP 200 Â« OK Â» en cas de succĂšs.
 
-Mais vous voulez aussi qu'il accepte de nouveaux Ă©lĂ©ments. Et lorsque les Ă©lĂ©ments n'existaient pas auparavant, il les crĂ©e et renvoie un code HTTP de 201 "Créé".
+Mais vous voulez aussi qu'il accepte de nouveaux Ă©lĂ©ments. Et lorsque les Ă©lĂ©ments n'existaient pas auparavant, il les crĂ©e et renvoie un code HTTP de 201 Â« Créé Â».
 
 Pour y parvenir, importez `JSONResponse` et renvoyez-y directement votre contenu, en dĂ©finissant le `status_code` que vous souhaitez :
 
-{* ../../docs_src/additional_status_codes/tutorial001.py hl[4,25] *}
+{* ../../docs_src/additional_status_codes/tutorial001_an_py310.py hl[4,25] *}
 
-/// warning | Attention
+/// warning | Alertes
 
 Lorsque vous renvoyez une `Response` directement, comme dans l'exemple ci-dessus, elle sera renvoyĂ©e directement.
 
 Elle ne sera pas sĂ©rialisĂ©e avec un modĂšle.
 
-Assurez-vous qu'il contient les donnĂ©es souhaitĂ©es et que les valeurs soient dans un format JSON valides (si vous utilisez une `JSONResponse`).
+Assurez-vous qu'il contient les donnĂ©es souhaitĂ©es et que les valeurs sont dans un format JSON valide (si vous utilisez une `JSONResponse`).
 
 ///
 
@@ -30,12 +30,12 @@ Assurez-vous qu'il contient les donnĂ©es souhaitĂ©es et que les valeurs soient d
 
 Vous pouvez Ă©galement utiliser `from starlette.responses import JSONResponse`.
 
-Pour plus de commoditĂ©s, **FastAPI** fournit les objets `starlette.responses` sous forme d'un alias accessible par `fastapi.responses`. Mais la plupart des rĂ©ponses disponibles proviennent directement de Starlette. Il en est de mĂȘme avec l'objet `statut`.
+Pour plus de commoditĂ©s, **FastAPI** fournit les objets `starlette.responses` sous forme d'un alias accessible par `fastapi.responses`. Mais la plupart des rĂ©ponses disponibles proviennent directement de Starlette. Il en est de mĂȘme avec `status`.
 
 ///
 
-## Documents OpenAPI et API
+## Documents OpenAPI et API { #openapi-and-api-docs }
 
 Si vous renvoyez directement des codes HTTP et des rĂ©ponses supplĂ©mentaires, ils ne seront pas inclus dans le schĂ©ma OpenAPI (la documentation de l'API), car FastAPI n'a aucun moyen de savoir Ă  l'avance ce que vous allez renvoyer.
 
-Mais vous pouvez documenter cela dans votre code, en utilisant : [RĂ©ponses supplĂ©mentaires dans OpenAPI](additional-responses.md){.internal-link target=_blank}.
+Mais vous pouvez documenter cela dans votre code, en utilisant : [RĂ©ponses supplĂ©mentaires](additional-responses.md){.internal-link target=_blank}.
index d9d8ad8e60ffa8e7c0996ae157eec0dcdab3b773..a2f9d3b1bba69edea5aa2bd0c1a44039769ea311 100644 (file)
@@ -1,27 +1,21 @@
-# Guide de l'utilisateur avancĂ©
+# Guide de l'utilisateur avancĂ© { #advanced-user-guide }
 
-## CaractĂ©ristiques supplĂ©mentaires
+## CaractĂ©ristiques supplĂ©mentaires { #additional-features }
 
 Le [Tutoriel - Guide de l'utilisateur](../tutorial/index.md){.internal-link target=_blank} devrait suffire Ă  vous faire dĂ©couvrir toutes les fonctionnalitĂ©s principales de **FastAPI**.
 
 Dans les sections suivantes, vous verrez des options, configurations et fonctionnalitĂ©s supplĂ©mentaires.
 
-/// note | Remarque
+/// tip | Astuce
 
-Les sections de ce chapitre ne sont **pas nĂ©cessairement "avancĂ©es"**.
+Les sections suivantes ne sont **pas nĂ©cessairement Â« avancĂ©es Â»**.
 
-Et il est possible que pour votre cas d'utilisation, la solution se trouve dans l'un d'entre eux.
+Et il est possible que, pour votre cas d'utilisation, la solution se trouve dans l'une d'entre elles.
 
 ///
 
-## Lisez d'abord le didacticiel
+## Lire d'abord le tutoriel { #read-the-tutorial-first }
 
 Vous pouvez utiliser la plupart des fonctionnalitĂ©s de **FastAPI** grĂące aux connaissances du [Tutoriel - Guide de l'utilisateur](../tutorial/index.md){.internal-link target=_blank}.
 
 Et les sections suivantes supposent que vous l'avez lu et que vous en connaissez les idĂ©es principales.
-
-## Cours TestDriven.io
-
-Si vous souhaitez suivre un cours pour dĂ©butants avancĂ©s pour complĂ©ter cette section de la documentation, vous pouvez consulter : <a href="https://testdrive.io/courses/tdd-fastapi/" class="external- link" target="_blank">DĂ©veloppement pilotĂ© par les tests avec FastAPI et Docker</a> par **TestDriven.io**.
-
-10 % de tous les bĂ©nĂ©fices de ce cours sont reversĂ©s au dĂ©veloppement de **FastAPI**. đŸŽ‰ đŸ˜„
index 7daf0fc65f6e90c9ab7c84f834f69109b2458bcf..fc88f33633bd8b7985a3d4d4da315aaffd71e34b 100644 (file)
-# Configuration avancĂ©e des paramĂštres de chemin
+# Configuration avancĂ©e des chemins d'accĂšs { #path-operation-advanced-configuration }
 
-## ID d'opĂ©ration OpenAPI
+## ID d’opĂ©ration OpenAPI { #openapi-operationid }
 
-/// warning | Attention
+/// warning | Alertes
 
-Si vous n'ĂȘtes pas un "expert" en OpenAPI, vous n'en avez probablement pas besoin.
+Si vous n’ĂȘtes pas un Â« expert Â» d’OpenAPI, vous n’en avez probablement pas besoin.
 
 ///
 
-Dans OpenAPI, les chemins sont des ressources, tels que /users/ ou /items/, exposĂ©es par votre API, et les opĂ©rations sont les mĂ©thodes HTTP utilisĂ©es pour manipuler ces chemins, telles que GET, POST ou DELETE. Les operationId sont des chaĂźnes uniques facultatives utilisĂ©es pour identifier une opĂ©ration d'un chemin. Vous pouvez dĂ©finir l'OpenAPI `operationId` Ă  utiliser dans votre *opĂ©ration de chemin* avec le paramĂštre `operation_id`.
+Vous pouvez dĂ©finir l’OpenAPI `operationId` Ă  utiliser dans votre chemin d’accĂšs avec le paramĂštre `operation_id`.
 
-Vous devez vous assurer qu'il est unique pour chaque opĂ©ration.
+Vous devez vous assurer qu’il est unique pour chaque opĂ©ration.
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
 
-### Utilisation du nom *path operation function* comme operationId
+### Utiliser le nom de la fonction de chemin d’accĂšs comme operationId { #using-the-path-operation-function-name-as-the-operationid }
 
-Si vous souhaitez utiliser les noms de fonction de vos API comme `operationId`, vous pouvez les parcourir tous et remplacer chaque `operation_id` de l'*opĂ©ration de chemin* en utilisant leur `APIRoute.name`.
+Si vous souhaitez utiliser les noms de fonction de vos API comme `operationId`, vous pouvez les parcourir tous et remplacer l’`operation_id` de chaque chemin d’accĂšs en utilisant leur `APIRoute.name`.
 
-Vous devriez le faire aprĂšs avoir ajoutĂ© toutes vos *paramĂštres de chemin*.
+Vous devez le faire aprĂšs avoir ajoutĂ© tous vos chemins d’accĂšs.
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2,12:21,24] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
 
 /// tip | Astuce
 
-Si vous appelez manuellement `app.openapi()`, vous devez mettre Ă  jour les `operationId` avant.
+Si vous appelez manuellement `app.openapi()`, vous devez mettre Ă  jour les `operationId` avant cela.
 
 ///
 
-/// warning | Attention
+/// warning | Alertes
 
-Pour faire cela, vous devez vous assurer que chacun de vos *chemin* ait un nom unique.
+Si vous faites cela, vous devez vous assurer que chacune de vos fonctions de chemin d’accĂšs a un nom unique.
 
-MĂȘme s'ils se trouvent dans des modules diffĂ©rents (fichiers Python).
+MĂȘme si elles se trouvent dans des modules diffĂ©rents (fichiers Python).
 
 ///
 
-## Exclusion d'OpenAPI
+## Exclusion d’OpenAPI { #exclude-from-openapi }
 
-Pour exclure un *chemin* du schĂ©ma OpenAPI gĂ©nĂ©rĂ© (et donc des systĂšmes de documentation automatiques), utilisez le paramĂštre `include_in_schema` et assignez-lui la valeur `False` :
+Pour exclure un chemin d’accĂšs du schĂ©ma OpenAPI gĂ©nĂ©rĂ© (et donc des systĂšmes de documentation automatiques), utilisez le paramĂštre `include_in_schema` et dĂ©finissez-le Ă  `False` :
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
 
-## Description avancĂ©e de docstring
+## Description avancĂ©e depuis la docstring { #advanced-description-from-docstring }
 
-Vous pouvez limiter le texte utilisĂ© de la docstring d'une *fonction de chemin* qui sera affichĂ© sur OpenAPI.
+Vous pouvez limiter les lignes utilisĂ©es de la docstring d’une fonction de chemin d’accĂšs pour OpenAPI.
 
-L'ajout d'un `\f` (un caractĂšre d'Ă©chappement "form feed") va permettre Ă  **FastAPI** de tronquer la sortie utilisĂ©e pour OpenAPI Ă  ce stade.
+L’ajout d’un `\f` (un caractĂšre Â« saut de page Â» Ă©chappĂ©) amĂšne **FastAPI** Ă  tronquer la sortie utilisĂ©e pour OpenAPI Ă  cet endroit.
 
-Il n'apparaĂźtra pas dans la documentation, mais d'autres outils (tel que Sphinx) pourront utiliser le reste.
+Cela n’apparaĂźtra pas dans la documentation, mais d’autres outils (comme Sphinx) pourront utiliser le reste.
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *}
 
-## RĂ©ponses supplĂ©mentaires
+## RĂ©ponses supplĂ©mentaires { #additional-responses }
 
-Vous avez probablement vu comment dĂ©clarer le `response_model` et le `status_code` pour une *opĂ©ration de chemin*.
+Vous avez probablement vu comment dĂ©clarer le `response_model` et le `status_code` pour un chemin d’accĂšs.
 
-Cela dĂ©finit les mĂ©tadonnĂ©es sur la rĂ©ponse principale d'une *opĂ©ration de chemin*.
+Cela dĂ©finit les mĂ©tadonnĂ©es sur la rĂ©ponse principale d’un chemin d’accĂšs.
 
 Vous pouvez Ă©galement dĂ©clarer des rĂ©ponses supplĂ©mentaires avec leurs modĂšles, codes de statut, etc.
 
-Il y a un chapitre entier ici dans la documentation Ă  ce sujet, vous pouvez le lire sur [RĂ©ponses supplĂ©mentaires dans OpenAPI](additional-responses.md){.internal-link target=_blank}.
+Il y a un chapitre entier dans la documentation Ă  ce sujet, vous pouvez le lire dans [RĂ©ponses supplĂ©mentaires dans OpenAPI](additional-responses.md){.internal-link target=_blank}.
 
-## OpenAPI supplĂ©mentaire
+## OpenAPI supplĂ©mentaire { #openapi-extra }
 
-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.
+Lorsque vous dĂ©clarez un chemin d’accĂšs dans votre application, **FastAPI** gĂ©nĂšre automatiquement les mĂ©tadonnĂ©es pertinentes Ă  propos de ce chemin d’accĂšs Ă  inclure dans le schĂ©ma OpenAPI.
 
 /// note | DĂ©tails techniques
 
-La spĂ©cification OpenAPI appelle ces mĂ©tadonnĂ©es des <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object" class="external-link" target="_blank">Objets d'opĂ©ration</a>.
+Dans la spĂ©cification OpenAPI, cela s’appelle l’<a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object" class="external-link" target="_blank">objet Operation</a>.
 
 ///
 
-Il contient toutes les informations sur le *chemin* et est utilisĂ© pour gĂ©nĂ©rer automatiquement la documentation.
+Il contient toutes les informations sur le chemin d’accĂšs et est utilisĂ© pour gĂ©nĂ©rer la documentation automatique.
 
 Il inclut les `tags`, `parameters`, `requestBody`, `responses`, etc.
 
-Ce schĂ©ma OpenAPI spĂ©cifique aux *operations* est normalement gĂ©nĂ©rĂ© automatiquement par **FastAPI**, mais vous pouvez Ă©galement l'Ă©tendre.
+Ce schĂ©ma OpenAPI spĂ©cifique Ă  un chemin d’accĂšs est normalement gĂ©nĂ©rĂ© automatiquement par **FastAPI**, mais vous pouvez Ă©galement l’étendre.
 
 /// tip | Astuce
 
-Si vous avez seulement besoin de dĂ©clarer des rĂ©ponses supplĂ©mentaires, un moyen plus pratique de le faire est d'utiliser les [rĂ©ponses supplĂ©mentaires dans OpenAPI](additional-responses.md){.internal-link target=_blank}.
+Ceci est un point d’extension de bas niveau.
+
+Si vous avez seulement besoin de dĂ©clarer des rĂ©ponses supplĂ©mentaires, un moyen plus pratique de le faire est d’utiliser [RĂ©ponses supplĂ©mentaires dans OpenAPI](additional-responses.md){.internal-link target=_blank}.
 
 ///
 
-Vous pouvez Ă©tendre le schĂ©ma OpenAPI pour une *opĂ©ration de chemin* en utilisant le paramĂštre `openapi_extra`.
+Vous pouvez Ă©tendre le schĂ©ma OpenAPI pour un chemin d’accĂšs en utilisant le paramĂštre `openapi_extra`.
 
-### Extensions OpenAPI
+### Extensions OpenAPI { #openapi-extensions }
 
-Cet `openapi_extra` peut ĂȘtre utile, par exemple, pour dĂ©clarer [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions) :
+Cet `openapi_extra` peut ĂȘtre utile, par exemple, pour dĂ©clarer des [Extensions OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions) :
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial005.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *}
 
-Si vous ouvrez la documentation automatique de l'API, votre extension apparaĂźtra au bas du *chemin* spĂ©cifique.
+Si vous ouvrez la documentation automatique de l’API, votre extension apparaĂźtra en bas du chemin d’accĂšs spĂ©cifique.
 
 <img src="/img/tutorial/path-operation-advanced-configuration/image01.png">
 
-Et dans le fichier openapi gĂ©nĂ©rĂ© (`/openapi.json`), vous verrez Ă©galement votre extension dans le cadre du *chemin* spĂ©cifique :
+Et si vous consultez l’OpenAPI rĂ©sultant (Ă  `/openapi.json` dans votre API), vous verrez Ă©galement votre extension comme partie du chemin d’accĂšs spĂ©cifique :
 
 ```JSON hl_lines="22"
 {
-    "openapi": "3.0.2",
+    "openapi": "3.1.0",
     "info": {
         "title": "FastAPI",
         "version": "0.1.0"
@@ -127,44 +129,44 @@ Et dans le fichier openapi gĂ©nĂ©rĂ© (`/openapi.json`), vous verrez Ă©galement v
 }
 ```
 
-### Personnalisation du SchĂ©ma OpenAPI pour un chemin
+### Personnaliser le schĂ©ma OpenAPI d’un chemin d’accĂšs { #custom-openapi-path-operation-schema }
 
-Le dictionnaire contenu dans la variable `openapi_extra` sera fusionnĂ© avec le schĂ©ma OpenAPI gĂ©nĂ©rĂ© automatiquement pour l'*opĂ©ration de chemin*.
+Le dictionnaire dans `openapi_extra` sera fusionnĂ© en profondeur avec le schĂ©ma OpenAPI gĂ©nĂ©rĂ© automatiquement pour le chemin d’accĂšs.
 
 Ainsi, vous pouvez ajouter des donnĂ©es supplĂ©mentaires au schĂ©ma gĂ©nĂ©rĂ© automatiquement.
 
-Par exemple, vous pouvez dĂ©cider de lire et de valider la requĂȘte avec votre propre code, sans utiliser les fonctionnalitĂ©s automatiques de validation proposĂ©e par Pydantic, mais vous pouvez toujours dĂ©finir la requĂȘte dans le schĂ©ma OpenAPI.
+Par exemple, vous pourriez dĂ©cider de lire et de valider la requĂȘte avec votre propre code, sans utiliser les fonctionnalitĂ©s automatiques de FastAPI avec Pydantic, mais vous pourriez tout de mĂȘme vouloir dĂ©finir la requĂȘte dans le schĂ©ma OpenAPI.
 
-Vous pouvez le faire avec `openapi_extra` :
+Vous pourriez le faire avec `openapi_extra` :
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[20:37,39:40] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
 
-Dans cet exemple, nous n'avons dĂ©clarĂ© aucun modĂšle Pydantic. En fait, le corps de la requĂȘte n'est mĂȘme pas <abbr title="converti d'un format simple, comme des octets, en objets Python">parsĂ©</abbr> en tant que JSON, il est lu directement en tant que `bytes`, et la fonction `magic_data_reader()` serait chargĂ© de l'analyser d'une maniĂšre ou d'une autre.
+Dans cet exemple, nous n’avons dĂ©clarĂ© aucun modĂšle Pydantic. En fait, le corps de la requĂȘte n’est mĂȘme pas <abbr title="converti d'un format simple, comme des octets, en objets Python">parsĂ©</abbr> en JSON, il est lu directement en tant que `bytes`, et la fonction `magic_data_reader()` serait chargĂ©e de l’analyser d’une maniĂšre ou d’une autre.
 
 NĂ©anmoins, nous pouvons dĂ©clarer le schĂ©ma attendu pour le corps de la requĂȘte.
 
-### Type de contenu OpenAPI personnalisĂ©
+### Type de contenu OpenAPI personnalisĂ© { #custom-openapi-content-type }
 
-En utilisant cette mĂȘme astuce, vous pouvez utiliser un modĂšle Pydantic pour dĂ©finir le schĂ©ma JSON qui est ensuite inclus dans la section de schĂ©ma OpenAPI personnalisĂ©e pour le *chemin* concernĂ©.
+En utilisant cette mĂȘme astuce, vous pourriez utiliser un modĂšle Pydantic pour dĂ©finir le JSON Schema qui est ensuite inclus dans la section de schĂ©ma OpenAPI personnalisĂ©e pour le chemin d’accĂšs.
 
-Et vous pouvez le faire mĂȘme si le type de donnĂ©es dans la requĂȘte n'est pas au format JSON.
+Et vous pourriez le faire mĂȘme si le type de donnĂ©es dans la requĂȘte n’est pas du JSON.
 
-Dans cet exemple, nous n'utilisons pas les fonctionnalitĂ©s de FastAPI pour extraire le schĂ©ma JSON des modĂšles Pydantic ni la validation automatique pour JSON. En fait, nous dĂ©clarons le type de contenu de la requĂȘte en tant que YAML, et non JSON :
+Par exemple, dans cette application nous n’utilisons pas la fonctionnalitĂ© intĂ©grĂ©e de FastAPI pour extraire le JSON Schema des modĂšles Pydantic ni la validation automatique pour le JSON. En fait, nous dĂ©clarons le type de contenu de la requĂȘte comme YAML, pas JSON :
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[17:22,24] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
 
-NĂ©anmoins, bien que nous n'utilisions pas la fonctionnalitĂ© par dĂ©faut, nous utilisons toujours un modĂšle Pydantic pour gĂ©nĂ©rer manuellement le schĂ©ma JSON pour les donnĂ©es que nous souhaitons recevoir en YAML.
+NĂ©anmoins, bien que nous n’utilisions pas la fonctionnalitĂ© intĂ©grĂ©e par dĂ©faut, nous utilisons toujours un modĂšle Pydantic pour gĂ©nĂ©rer manuellement le JSON Schema pour les donnĂ©es que nous souhaitons recevoir en YAML.
 
-Ensuite, nous utilisons directement la requĂȘte et extrayons son contenu en tant qu'octets. Cela signifie que FastAPI n'essaiera mĂȘme pas d'analyser le payload de la requĂȘte en tant que JSON.
+Ensuite, nous utilisons directement la requĂȘte et extrayons le corps en tant que `bytes`. Cela signifie que FastAPI n’essaiera mĂȘme pas d’analyser le payload de la requĂȘte en JSON.
 
-Et nous analysons directement ce contenu YAML, puis nous utilisons Ă  nouveau le mĂȘme modĂšle Pydantic pour valider le contenu YAML :
+Ensuite, dans notre code, nous analysons directement ce contenu YAML, puis nous utilisons Ă  nouveau le mĂȘme modĂšle Pydantic pour valider le contenu YAML :
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[26:33] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
 
 /// tip | Astuce
 
 Ici, nous rĂ©utilisons le mĂȘme modĂšle Pydantic.
 
-Mais nous aurions pu tout aussi bien pu le valider d'une autre maniĂšre.
+Mais de la mĂȘme maniĂšre, nous aurions pu le valider autrement.
 
 ///
index 4ff883c77070646019ebe7ab8687a3c28c987fbe..f35c39c06fd163ee57c4eb5e42d65e1f5755ce1b 100644 (file)
@@ -1,20 +1,20 @@
-# Renvoyer directement une rĂ©ponse
+# Renvoyer directement une rĂ©ponse { #return-a-response-directly }
 
-Lorsque vous crĂ©ez une *opĂ©ration de chemins* **FastAPI**, vous pouvez normalement retourner n'importe quelle donnĂ©e : un `dict`, une `list`, un modĂšle Pydantic, un modĂšle de base de donnĂ©es, etc.
+Lorsque vous crĂ©ez un *chemin d'accĂšs* **FastAPI**, vous pouvez normalement retourner n'importe quelle donnĂ©e : un `dict`, une `list`, un modĂšle Pydantic, un modĂšle de base de donnĂ©es, etc.
 
-Par dĂ©faut, **FastAPI** convertirait automatiquement cette valeur de retour en JSON en utilisant le `jsonable_encoder` expliquĂ© dans [JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank}.
+Par dĂ©faut, **FastAPI** convertirait automatiquement cette valeur de retour en JSON en utilisant le `jsonable_encoder` expliquĂ© dans [Encodeur compatible JSON](../tutorial/encoder.md){.internal-link target=_blank}.
 
 Ensuite, en arriĂšre-plan, il mettra ces donnĂ©es JSON-compatible (par exemple un `dict`) Ă  l'intĂ©rieur d'un `JSONResponse` qui sera utilisĂ© pour envoyer la rĂ©ponse au client.
 
-Mais vous pouvez retourner une `JSONResponse` directement Ă  partir de vos *opĂ©rations de chemin*.
+Mais vous pouvez retourner une `JSONResponse` directement Ă  partir de vos *chemins d'accĂšs*.
 
 Cela peut ĂȘtre utile, par exemple, pour retourner des en-tĂȘtes personnalisĂ©s ou des cookies.
 
-## Renvoyer une `Response`
+## Renvoyer une `Response` { #return-a-response }
 
 En fait, vous pouvez retourner n'importe quelle `Response` ou n'importe quelle sous-classe de celle-ci.
 
-/// note | Remarque
+/// tip | Astuce
 
 `JSONResponse` est elle-mĂȘme une sous-classe de `Response`.
 
@@ -24,27 +24,27 @@ Et quand vous retournez une `Response`, **FastAPI** la transmet directement.
 
 Elle ne fera aucune conversion de donnĂ©es avec les modĂšles Pydantic, elle ne convertira pas le contenu en un type quelconque.
 
-Cela vous donne beaucoup de flexibilitĂ©. Vous pouvez retourner n'importe quel type de donnĂ©es, surcharger n'importe quelle dĂ©claration ou validation de donnĂ©es.
+Cela vous donne beaucoup de flexibilitĂ©. Vous pouvez retourner n'importe quel type de donnĂ©es, surcharger n'importe quelle dĂ©claration ou validation de donnĂ©es, etc.
 
-## Utiliser le `jsonable_encoder` dans une `Response`
+## Utiliser le `jsonable_encoder` dans une `Response` { #using-the-jsonable-encoder-in-a-response }
 
-Parce que **FastAPI** n'apporte aucune modification Ă  une `Response` que vous retournez, vous devez vous assurer que son contenu est prĂȘt Ă  ĂȘtre utilisĂ© (sĂ©rialisable).
+Parce que **FastAPI** n'apporte aucune modification Ă  une `Response` que vous retournez, vous devez vous assurer que son contenu est prĂȘt pour cela.
 
 Par exemple, vous ne pouvez pas mettre un modĂšle Pydantic dans une `JSONResponse` sans d'abord le convertir en un `dict` avec tous les types de donnĂ©es (comme `datetime`, `UUID`, etc.) convertis en types compatibles avec JSON.
 
-Pour ces cas, vous pouvez spĂ©cifier un appel Ă  `jsonable_encoder` pour convertir vos donnĂ©es avant de les passer Ă  une rĂ©ponse :
+Pour ces cas, vous pouvez utiliser le `jsonable_encoder` pour convertir vos donnĂ©es avant de les passer Ă  une rĂ©ponse :
 
-{* ../../docs_src/response_directly/tutorial001.py hl[6:7,21:22] *}
+{* ../../docs_src/response_directly/tutorial001_py310.py hl[5:6,20:21] *}
 
 /// note | DĂ©tails techniques
 
 Vous pouvez aussi utiliser `from starlette.responses import JSONResponse`.
 
-**FastAPI** fournit le mĂȘme objet `starlette.responses` que `fastapi.responses` juste par commoditĂ© pour le dĂ©veloppeur. Mais la plupart des rĂ©ponses disponibles proviennent directement de Starlette.
+**FastAPI** fournit le mĂȘme `starlette.responses` que `fastapi.responses` juste par commoditĂ© pour vous, le dĂ©veloppeur. Mais la plupart des rĂ©ponses disponibles proviennent directement de Starlette.
 
 ///
 
-## Renvoyer une `Response` personnalisĂ©e
+## Renvoyer une `Response` personnalisĂ©e { #returning-a-custom-response }
 
 L'exemple ci-dessus montre toutes les parties dont vous avez besoin, mais il n'est pas encore trĂšs utile, car vous auriez pu retourner l'`item` directement, et **FastAPI** l'aurait mis dans une `JSONResponse` pour vous, en le convertissant en `dict`, etc. Tout cela par dĂ©faut.
 
@@ -54,9 +54,9 @@ Disons que vous voulez retourner une rĂ©ponse <a href="https://en.wikipedia.org/
 
 Vous pouvez mettre votre contenu XML dans une chaĂźne de caractĂšres, la placer dans une `Response`, et la retourner :
 
-{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
+{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
 
-## Notes
+## Notes { #notes }
 
 Lorsque vous renvoyez une `Response` directement, ses donnĂ©es ne sont pas validĂ©es, converties (sĂ©rialisĂ©es), ni documentĂ©es automatiquement.
 
index d33c263a213d298ebb866e66fd0c07948c7ceca0..4bb35dff7a1b31d490af9a00cf7a42051c69046c 100644 (file)
@@ -1,34 +1,34 @@
-# Test de performance
+# Tests de performance { #benchmarks }
 
-Les tests de performance de TechEmpower montrent que les applications **FastAPI** tournant sous Uvicorn comme <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">Ă©tant l'un des frameworks Python les plus rapides disponibles</a>, seulement infĂ©rieur Ă  Starlette et Uvicorn (tous deux utilisĂ©s au cƓur de FastAPI). (*)
+Les benchmarks indĂ©pendants de TechEmpower montrent que les applications **FastAPI** s’exĂ©cutant avec Uvicorn sont <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">parmi les frameworks Python les plus rapides disponibles</a>, seulement en dessous de Starlette et Uvicorn eux‑mĂȘmes (tous deux utilisĂ©s en interne par FastAPI).
 
-Mais en prĂȘtant attention aux tests de performance et aux comparaisons, il faut tenir compte de ce qu'il suit.
+Mais en prĂȘtant attention aux tests de performance et aux comparaisons, vous devez tenir compte de ce qui suit.
 
-## Tests de performance et rapiditĂ©
+## Tests de performance et rapiditĂ© { #benchmarks-and-speed }
 
 Lorsque vous vĂ©rifiez les tests de performance, il est commun de voir plusieurs outils de diffĂ©rents types comparĂ©s comme Ă©quivalents.
 
 En particulier, on voit Uvicorn, Starlette et FastAPI comparĂ©s (parmi de nombreux autres outils).
 
-Plus le problĂšme rĂ©solu par un outil est simple, mieux seront les performances obtenues. Et la plupart des tests de performance ne prennent pas en compte les fonctionnalitĂ©s additionnelles fournies par les outils.
+Plus le problĂšme rĂ©solu par un outil est simple, meilleures seront les performances obtenues. Et la plupart des tests de performance ne prennent pas en compte les fonctionnalitĂ©s additionnelles fournies par les outils.
 
 La hiĂ©rarchie est la suivante :
 
 * **Uvicorn** : un serveur ASGI
-    * **Starlette** : (utilise Uvicorn) un micro-framework web
-        * **FastAPI**: (utilise Starlette) un micro-framework pour API disposant de fonctionnalitĂ©s additionnelles pour la crĂ©ation d'API, avec la validation des donnĂ©es, etc.
+    * **Starlette** : (utilise Uvicorn) un microframework web
+        * **FastAPI**: (utilise Starlette) un microframework pour API disposant de fonctionnalitĂ©s additionnelles pour la crĂ©ation d'API, avec la validation des donnĂ©es, etc.
 
 * **Uvicorn** :
-    * A les meilleures performances, Ă©tant donnĂ© qu'il n'a pas beaucoup de code mis-Ă -part le serveur en lui-mĂȘme.
-    * On n'Ă©crit pas une application avec uniquement Uvicorn. Cela signifie que le code devrait inclure plus ou moins, au minimum, tout le code offert par Starlette (ou **FastAPI**). Et si on fait cela, l'application finale apportera les mĂȘmes complications que si on avait utilisĂ© un framework et que l'on avait minimisĂ© la quantitĂ© de code et de bugs.
-    * Si on compare Uvicorn, il faut le comparer Ă  d'autre applications de serveurs comme Daphne, Hypercorn, uWSGI, etc.
+    * A les meilleures performances, Ă©tant donnĂ© qu'il n'a pas beaucoup de code mis Ă  part le serveur en lui‑mĂȘme.
+    * On n'Ă©crit pas une application directement avec Uvicorn. Cela signifie que le code devrait inclure, au minimum, plus ou moins tout le code offert par Starlette (ou **FastAPI**). Et si on fait cela, l'application finale aura la mĂȘme surcharge que si on avait utilisĂ© un framework, tout en minimisant la quantitĂ© de code et les bugs.
+    * Si on compare Uvicorn, il faut le comparer Ă  d'autres serveurs d'applications comme Daphne, Hypercorn, uWSGI, etc.
 * **Starlette** :
-    * A les seconde meilleures performances aprĂšs Uvicorn. Starlette utilise en rĂ©alitĂ© Uvicorn. De ce fait, il ne peut qu’ĂȘtre plus "lent" qu'Uvicorn car il requiert l'exĂ©cution de plus de code.
-    * Cependant il nous apporte les outils pour construire une application web simple, avec un routage basĂ© sur des chemins, etc.
-    * Si on compare Starlette, il faut le comparer Ă  d'autres frameworks web (ou micorframework) comme Sanic, Flask, Django, etc.
+    * A les secondes meilleures performances aprĂšs Uvicorn. En rĂ©alitĂ©, Starlette utilise Uvicorn. De ce fait, il ne peut qu’ĂȘtre plus Â« lent Â» qu'Uvicorn car il requiert l'exĂ©cution de plus de code.
+    * Cependant, il apporte les outils pour construire une application web simple, avec un routage basĂ© sur des chemins, etc.
+    * Si on compare Starlette, il faut le comparer Ă  d'autres frameworks web (ou microframeworks) comme Sanic, Flask, Django, etc.
 * **FastAPI** :
-    * Comme Starlette, FastAPI utilise Uvicorn et ne peut donc pas ĂȘtre plus rapide que ce dernier.
-    * FastAPI apporte des fonctionnalitĂ©s supplĂ©mentaires Ă  Starlette. Des fonctionnalitĂ©s qui sont nĂ©cessaires presque systĂ©matiquement lors de la crĂ©ation d'une API, comme la validation des donnĂ©es, la sĂ©rialisation. En utilisant FastAPI, on obtient une documentation automatiquement (qui ne requiert aucune manipulation pour ĂȘtre mise en place).
-    * Si on n'utilisait pas FastAPI mais directement Starlette (ou un outil Ă©quivalent comme Sanic, Flask, Responder, etc) il faudrait implĂ©menter la validation des donnĂ©es et la sĂ©rialisation par nous-mĂȘme. Le rĂ©sultat serait donc le mĂȘme dans les deux cas mais du travail supplĂ©mentaire serait Ă  rĂ©aliser avec Starlette, surtout en considĂ©rant que la validation des donnĂ©es et la sĂ©rialisation reprĂ©sentent la plus grande quantitĂ© de code Ă  Ă©crire dans une application.
-    * De ce fait, en utilisant FastAPI on minimise le temps de dĂ©veloppement, les bugs, le nombre de lignes de code, et on obtient les mĂȘmes performances (si ce n'est de meilleurs performances) que l'on aurait pu avoir sans ce framework (en ayant Ă  implĂ©menter de nombreuses fonctionnalitĂ©s importantes par nous-mĂȘmes).
-    * Si on compare FastAPI, il faut le comparer Ă  d'autres frameworks web (ou ensemble d'outils) qui fournissent la validation des donnĂ©es, la sĂ©rialisation et la documentation, comme Flask-apispec, NestJS, Molten, etc.
+    * Comme Starlette utilise Uvicorn et ne peut donc pas ĂȘtre plus rapide que lui, **FastAPI** utilise Starlette et ne peut donc pas ĂȘtre plus rapide que lui.
+    * FastAPI apporte des fonctionnalitĂ©s supplĂ©mentaires Ă  Starlette. Des fonctionnalitĂ©s dont vous avez presque toujours besoin lors de la crĂ©ation d'une API, comme la validation des donnĂ©es et la sĂ©rialisation. En l'utilisant, vous obtenez une documentation automatique Â« gratuitement Â» (la documentation automatique n'ajoute mĂȘme pas de surcharge Ă  l’exĂ©cution, elle est gĂ©nĂ©rĂ©e au dĂ©marrage).
+    * Si on n'utilisait pas FastAPI mais directement Starlette (ou un autre outil comme Sanic, Flask, Responder, etc.), il faudrait implĂ©menter toute la validation des donnĂ©es et la sĂ©rialisation soi‑mĂȘme. L'application finale aurait donc la mĂȘme surcharge que si elle avait Ă©tĂ© construite avec FastAPI. Et dans de nombreux cas, cette validation des donnĂ©es et cette sĂ©rialisation reprĂ©sentent la plus grande quantitĂ© de code Ă©crite dans les applications.
+    * De ce fait, en utilisant FastAPI on minimise le temps de dĂ©veloppement, les bugs, le nombre de lignes de code, et on obtient probablement les mĂȘmes performances (voire de meilleures performances) que l'on aurait pu avoir sans ce framework (car il aurait fallu tout implĂ©menter dans votre code).
+    * Si on compare FastAPI, il faut le comparer Ă  d'autres frameworks d’application web (ou ensembles d'outils) qui fournissent la validation des donnĂ©es, la sĂ©rialisation et la documentation, comme Flask-apispec, NestJS, Molten, etc. Des frameworks avec validation des donnĂ©es, sĂ©rialisation et documentation automatiques intĂ©grĂ©es.
index 05b597a2df3fa68e9b10a792d7a6d0f29c570a03..ec30f96079c49ccc677b886cd06b848f18257864 100644 (file)
-# DĂ©ployer avec Docker
+# FastAPI dans des conteneurs - Docker { #fastapi-in-containers-docker }
 
-Dans cette section, vous verrez des instructions et des liens vers des guides pour savoir comment :
+Lors du dĂ©ploiement d'applications FastAPI, une approche courante consiste Ă  construire une **image de conteneur Linux**. C'est gĂ©nĂ©ralement fait avec <a href="https://www.docker.com/" class="external-link" target="_blank">**Docker**</a>. Vous pouvez ensuite dĂ©ployer cette image de conteneur de plusieurs façons possibles.
 
-* Faire de votre application **FastAPI** une image/conteneur Docker avec une performance maximale. En environ **5 min**.
-* (Optionnellement) comprendre ce que vous, en tant que dĂ©veloppeur, devez savoir sur HTTPS.
-* Configurer un cluster en mode Docker Swarm avec HTTPS automatique, mĂȘme sur un simple serveur Ă  5 dollars US/mois. En environ **20 min**.
-* GĂ©nĂ©rer et dĂ©ployer une application **FastAPI** complĂšte, en utilisant votre cluster Docker Swarm, avec HTTPS, etc. En environ **10 min**.
+L'utilisation de conteneurs Linux prĂ©sente plusieurs avantages, notamment la **sĂ©curitĂ©**, la **rĂ©plicabilitĂ©**, la **simplicitĂ©**, entre autres.
 
-Vous pouvez utiliser <a href="https://www.docker.com/" class="external-link" target="_blank">**Docker**</a> pour le dĂ©ploiement. Il prĂ©sente plusieurs avantages comme la sĂ©curitĂ©, la rĂ©plicabilitĂ©, la simplicitĂ© de dĂ©veloppement, etc.
-
-Si vous utilisez Docker, vous pouvez utiliser l'image Docker officielle :
+/// tip | Astuce
 
-## <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>
+Vous ĂȘtes pressĂ© et vous connaissez dĂ©jĂ  tout Ă§a ? Allez directement au [`Dockerfile` ci-dessous đŸ‘‡](#build-a-docker-image-for-fastapi).
 
-Cette image est dotĂ©e d'un mĂ©canisme d'"auto-tuning", de sorte qu'il vous suffit d'ajouter votre code pour obtenir automatiquement des performances trĂšs Ă©levĂ©es. Et sans faire de sacrifices.
+///
 
-Mais vous pouvez toujours changer et mettre Ă  jour toutes les configurations avec des variables d'environnement ou des fichiers de configuration.
+<details>
+<summary>Aperçu du Dockerfile đŸ‘€</summary>
 
-/// tip | Astuce
+```Dockerfile
+FROM python:3.9
 
-Pour voir toutes les configurations et options, rendez-vous sur la page de l'image Docker : <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>.
+WORKDIR /code
 
-///
+COPY ./requirements.txt /code/requirements.txt
 
-## CrĂ©er un `Dockerfile`
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
 
-* Allez dans le rĂ©pertoire de votre projet.
-* CrĂ©ez un `Dockerfile` avec :
+COPY ./app /code/app
 
-```Dockerfile
-FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
+CMD ["fastapi", "run", "app/main.py", "--port", "80"]
 
-COPY ./app /app
+# Si vous exĂ©cutez derriĂšre un proxy comme Nginx ou Traefik, ajoutez --proxy-headers
+# CMD ["fastapi", "run", "app/main.py", "--port", "80", "--proxy-headers"]
 ```
 
-### Applications plus larges
+</details>
 
-Si vous avez suivi la section sur la crĂ©ation d' [Applications avec plusieurs fichiers](../tutorial/bigger-applications.md){.internal-link target=_blank}, votre `Dockerfile` pourrait ressembler Ă  ceci :
+## Qu'est-ce qu'un conteneur { #what-is-a-container }
 
-```Dockerfile
-FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
+Les conteneurs (principalement les conteneurs Linux) sont un moyen trĂšs **lĂ©ger** d'empaqueter des applications, y compris toutes leurs dĂ©pendances et les fichiers nĂ©cessaires, tout en les isolant des autres conteneurs (autres applications ou composants) dans le mĂȘme systĂšme.
 
-COPY ./app /app/app
-```
+Les conteneurs Linux s'exĂ©cutent en utilisant le mĂȘme noyau Linux que l'hĂŽte (machine, machine virtuelle, serveur cloud, etc.). Cela signifie simplement qu'ils sont trĂšs lĂ©gers (comparĂ©s Ă  des machines virtuelles complĂštes Ă©mulant un systĂšme d'exploitation entier).
 
-### Raspberry Pi et autres architectures
+Ainsi, les conteneurs consomment **peu de ressources**, une quantitĂ© comparable Ă  l'exĂ©cution directe des processus (alors qu'une machine virtuelle consommerait beaucoup plus).
 
-Si vous utilisez Docker sur un Raspberry Pi (qui a un processeur ARM) ou toute autre architecture, vous pouvez crĂ©er un `Dockerfile` Ă  partir de zĂ©ro, basĂ© sur une image de base Python (qui est multi-architecture) et utiliser Uvicorn seul.
+Les conteneurs ont Ă©galement leurs propres processus d'exĂ©cution **isolĂ©s** (gĂ©nĂ©ralement un seul processus), leur systĂšme de fichiers et leur rĂ©seau, ce qui simplifie le dĂ©ploiement, la sĂ©curitĂ©, le dĂ©veloppement, etc.
 
-Dans ce cas, votre `Dockerfile` pourrait ressembler Ă  ceci :
+## Qu'est-ce qu'une image de conteneur { #what-is-a-container-image }
 
-```Dockerfile
-FROM python:3.7
+Un **conteneur** s'exĂ©cute Ă  partir d'une **image de conteneur**.
+
+Une image de conteneur est une version **statique** de tous les fichiers, des variables d'environnement et de la commande/le programme par dĂ©faut devant ĂȘtre prĂ©sents dans un conteneur. Ici, **statique** signifie que l'**image** du conteneur ne s'exĂ©cute pas, elle n'est pas en cours d'exĂ©cution, ce ne sont que les fichiers et mĂ©tadonnĂ©es empaquetĂ©s.
+
+Par opposition Ă  une Â« **image de conteneur** Â» qui correspond aux contenus statiques stockĂ©s, un Â« **conteneur** Â» fait normalement rĂ©fĂ©rence Ă  l'instance en cours d'exĂ©cution, la chose qui est **exĂ©cutĂ©e**.
+
+Lorsque le **conteneur** est dĂ©marrĂ© et en cours d'exĂ©cution (dĂ©marrĂ© Ă  partir d'une **image de conteneur**), il peut crĂ©er ou modifier des fichiers, des variables d'environnement, etc. Ces changements n'existeront que dans ce conteneur, mais ne persisteront pas dans l'image de conteneur sous-jacente (ils ne seront pas enregistrĂ©s sur le disque).
+
+Une image de conteneur est comparable au **programme** et Ă  ses contenus, par exemple `python` et un fichier `main.py`.
+
+Et le **conteneur** lui-mĂȘme (par opposition Ă  l'**image de conteneur**) est l'instance en cours d'exĂ©cution rĂ©elle de l'image, comparable Ă  un **processus**. En fait, un conteneur ne fonctionne que lorsqu'il a un **processus en cours d'exĂ©cution** (et normalement, il s'agit d'un seul processus). Le conteneur s'arrĂȘte lorsqu'aucun processus n'y est en cours d'exĂ©cution.
+
+## Images de conteneur { #container-images }
+
+Docker a Ă©tĂ© l'un des principaux outils pour crĂ©er et gĂ©rer des **images de conteneur** et des **conteneurs**.
+
+Et il existe un <a href="https://hub.docker.com/" class="external-link" target="_blank">Docker Hub</a> public avec des **images de conteneur officielles** prĂ©-construites pour de nombreux outils, environnements, bases de donnĂ©es et applications.
+
+Par exemple, il existe une <a href="https://hub.docker.com/_/python" class="external-link" target="_blank">image Python officielle</a>.
+
+Et il existe beaucoup d'autres images pour diffĂ©rentes choses comme des bases de donnĂ©es, par exemple :
+
+* <a href="https://hub.docker.com/_/postgres" class="external-link" target="_blank">PostgreSQL</a>
+* <a href="https://hub.docker.com/_/mysql" class="external-link" target="_blank">MySQL</a>
+* <a href="https://hub.docker.com/_/mongo" class="external-link" target="_blank">MongoDB</a>
+* <a href="https://hub.docker.com/_/redis" class="external-link" target="_blank">Redis</a>, etc.
+
+En utilisant une image de conteneur prĂ©-construite, il est trĂšs facile de **combiner** et d'utiliser diffĂ©rents outils. Par exemple, pour essayer une nouvelle base de donnĂ©es. Dans la plupart des cas, vous pouvez utiliser les **images officielles** et simplement les configurer avec des variables d'environnement.
+
+Ainsi, dans de nombreux cas, vous pouvez apprendre les conteneurs et Docker et rĂ©utiliser ces connaissances avec de nombreux outils et composants diffĂ©rents.
+
+Vous exĂ©cuteriez donc **plusieurs conteneurs** avec des Ă©lĂ©ments diffĂ©rents, comme une base de donnĂ©es, une application Python, un serveur web avec une application frontend React, et les connecter entre eux via leur rĂ©seau interne.
+
+Tous les systĂšmes de gestion de conteneurs (comme Docker ou Kubernetes) disposent de ces fonctionnalitĂ©s rĂ©seau intĂ©grĂ©es.
+
+## Conteneurs et processus { #containers-and-processes }
+
+Une **image de conteneur** inclut normalement dans ses mĂ©tadonnĂ©es le programme/la commande par dĂ©faut Ă  exĂ©cuter lorsque le **conteneur** est dĂ©marrĂ© et les paramĂštres Ă  transmettre Ă  ce programme. TrĂšs similaire Ă  ce que vous utiliseriez en ligne de commande.
+
+Lorsqu'un **conteneur** est dĂ©marrĂ©, il exĂ©cutera cette commande/ce programme (bien que vous puissiez la/le remplacer et faire exĂ©cuter une autre commande/un autre programme).
+
+Un conteneur fonctionne tant que le **processus principal** (commande ou programme) est en cours d'exĂ©cution.
+
+Un conteneur a normalement un **seul processus**, mais il est aussi possible de dĂ©marrer des sous-processus Ă  partir du processus principal, et ainsi vous aurez **plusieurs processus** dans le mĂȘme conteneur.
 
-RUN pip install fastapi uvicorn
+Mais il n'est pas possible d'avoir un conteneur en cours d'exĂ©cution sans **au moins un processus en cours**. Si le processus principal s'arrĂȘte, le conteneur s'arrĂȘte.
 
-EXPOSE 80
+## Construire une image Docker pour FastAPI { #build-a-docker-image-for-fastapi }
 
-COPY ./app /app
+TrĂšs bien, construisons quelque chose maintenant ! đŸš€
 
-CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
+Je vais vous montrer comment construire une **image Docker** pour FastAPI **Ă  partir de zĂ©ro**, basĂ©e sur l'image **officielle Python**.
+
+C'est ce que vous voudrez faire dans **la plupart des cas**, par exemple :
+
+* Utiliser **Kubernetes** ou des outils similaires
+* ExĂ©cuter sur un **Raspberry Pi**
+* Utiliser un service cloud qui exĂ©cuterait une image de conteneur pour vous, etc.
+
+### DĂ©pendances des paquets { #package-requirements }
+
+Vous aurez normalement les **dĂ©pendances des paquets** de votre application dans un fichier.
+
+Cela dĂ©pendra principalement de l'outil que vous utilisez pour **installer** ces dĂ©pendances.
+
+La maniĂšre la plus courante consiste Ă  avoir un fichier `requirements.txt` avec les noms des paquets et leurs versions, un par ligne.
+
+Vous utiliserez bien sĂ»r les mĂȘmes idĂ©es que vous avez lues dans [À propos des versions de FastAPI](versions.md){.internal-link target=_blank} pour dĂ©finir les plages de versions.
+
+Par exemple, votre `requirements.txt` pourrait ressembler Ă  :
+
+```
+fastapi[standard]>=0.113.0,<0.114.0
+pydantic>=2.7.0,<3.0.0
 ```
 
-## CrĂ©er le code **FastAPI**.
+Et vous installerez normalement ces dĂ©pendances de paquets avec `pip`, par exemple :
 
-* CrĂ©er un rĂ©pertoire `app` et y entrer.
-* CrĂ©ez un fichier `main.py` avec :
+<div class="termy">
 
-```Python
-from typing import Optional
+```console
+$ pip install -r requirements.txt
+---> 100%
+Successfully installed fastapi pydantic
+```
 
+</div>
+
+/// info
+
+Il existe d'autres formats et outils pour dĂ©finir et installer des dĂ©pendances de paquets.
+
+///
+
+### CrĂ©er le code **FastAPI** { #create-the-fastapi-code }
+
+* CrĂ©ez un rĂ©pertoire `app` et entrez dedans.
+* CrĂ©ez un fichier vide `__init__.py`.
+* CrĂ©ez un fichier `main.py` avec :
+
+```Python
 from fastapi import FastAPI
 
 app = FastAPI()
@@ -81,22 +156,168 @@ def read_root():
 
 
 @app.get("/items/{item_id}")
-def read_item(item_id: int, q: Optional[str] = None):
+def read_item(item_id: int, q: str | None = None):
     return {"item_id": item_id, "q": q}
 ```
 
-* Vous devriez maintenant avoir une structure de rĂ©pertoire telle que :
+### Dockerfile { #dockerfile }
+
+Maintenant, dans le mĂȘme rĂ©pertoire de projet, crĂ©ez un fichier `Dockerfile` avec :
+
+```{ .dockerfile .annotate }
+# (1)!
+FROM python:3.9
+
+# (2)!
+WORKDIR /code
+
+# (3)!
+COPY ./requirements.txt /code/requirements.txt
+
+# (4)!
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+
+# (5)!
+COPY ./app /code/app
+
+# (6)!
+CMD ["fastapi", "run", "app/main.py", "--port", "80"]
+```
+
+1. DĂ©marrer Ă  partir de l'image de base Python officielle.
+
+2. DĂ©finir le rĂ©pertoire de travail courant sur `/code`.
+
+    C'est lĂ  que nous placerons le fichier `requirements.txt` et le rĂ©pertoire `app`.
+
+3. Copier le fichier des dĂ©pendances vers le rĂ©pertoire `/code`.
+
+    Copier **uniquement** le fichier des dĂ©pendances en premier, pas le reste du code.
+
+    Comme ce fichier **ne change pas souvent**, Docker le dĂ©tectera et utilisera le **cache** pour cette Ă©tape, ce qui activera le cache pour l'Ă©tape suivante aussi.
+
+4. Installer les dĂ©pendances listĂ©es dans le fichier des dĂ©pendances.
+
+    L'option `--no-cache-dir` indique Ă  `pip` de ne pas enregistrer localement les paquets tĂ©lĂ©chargĂ©s, car cela ne sert que si `pip` devait ĂȘtre relancĂ© pour installer les mĂȘmes paquets, mais ce n'est pas le cas lorsque l'on travaille avec des conteneurs.
+
+    /// note | Remarque
+
+    Le `--no-cache-dir` concerne uniquement `pip`, cela n'a rien Ă  voir avec Docker ou les conteneurs.
+
+    ///
+
+    L'option `--upgrade` indique Ă  `pip` de mettre Ă  niveau les paquets s'ils sont dĂ©jĂ  installĂ©s.
+
+    Comme l'Ă©tape prĂ©cĂ©dente de copie du fichier peut ĂȘtre dĂ©tectĂ©e par le **cache Docker**, cette Ă©tape **utilisera Ă©galement le cache Docker** lorsqu'il est disponible.
+
+    L'utilisation du cache Ă  cette Ă©tape vous **fera gagner** beaucoup de **temps** lors de la reconstruction de l'image encore et encore pendant le dĂ©veloppement, au lieu de **tĂ©lĂ©charger et installer** toutes les dĂ©pendances **Ă  chaque fois**.
+
+5. Copier le rĂ©pertoire `./app` dans le rĂ©pertoire `/code`.
+
+    Comme cela contient tout le code qui est ce qui **change le plus frĂ©quemment**, le **cache** Docker ne sera pas facilement utilisĂ© pour cette Ă©tape ou pour les **Ă©tapes suivantes**.
+
+    Il est donc important de placer cela **vers la fin** du `Dockerfile`, pour optimiser les temps de construction de l'image de conteneur.
+
+6. DĂ©finir la **commande** pour utiliser `fastapi run`, qui utilise Uvicorn sous le capot.
+
+    `CMD` prend une liste de chaĂźnes, chacune de ces chaĂźnes correspond Ă  ce que vous taperiez en ligne de commande sĂ©parĂ© par des espaces.
+
+    Cette commande sera exĂ©cutĂ©e Ă  partir du **rĂ©pertoire de travail courant**, le mĂȘme rĂ©pertoire `/code` que vous avez dĂ©fini plus haut avec `WORKDIR /code`.
+
+/// tip | Astuce
+
+Passez en revue ce que fait chaque ligne en cliquant sur chaque bulle numĂ©rotĂ©e dans le code. đŸ‘†
+
+///
+
+/// warning | Alertes
+
+Vous devez vous assurer d'utiliser **toujours** la **forme exec** de l'instruction `CMD`, comme expliquĂ© ci-dessous.
+
+///
+
+#### Utiliser `CMD` - Forme Exec { #use-cmd-exec-form }
+
+L'instruction Docker <a href="https://docs.docker.com/reference/dockerfile/#cmd" class="external-link" target="_blank">`CMD`</a> peut ĂȘtre Ă©crite sous deux formes :
+
+✅ Forme **Exec** :
+
+```Dockerfile
+# âœ… Ă€ faire
+CMD ["fastapi", "run", "app/main.py", "--port", "80"]
+```
+
+⛔ Forme **Shell** :
+
+```Dockerfile
+# â›” Ă€ ne pas faire
+CMD fastapi run app/main.py --port 80
+```
+
+Assurez-vous d'utiliser toujours la forme **exec** pour garantir que FastAPI peut s'arrĂȘter proprement et que les [Ă©vĂ©nements de cycle de vie](../advanced/events.md){.internal-link target=_blank} sont dĂ©clenchĂ©s.
+
+Vous pouvez en lire davantage dans la <a href="https://docs.docker.com/reference/dockerfile/#shell-and-exec-form" class="external-link" target="_blank">documentation Docker sur les formes shell et exec</a>.
+
+Cela peut ĂȘtre trĂšs visible lors de l'utilisation de `docker compose`. Voir cette section de la FAQ Docker Compose pour plus de dĂ©tails techniques : <a href="https://docs.docker.com/compose/faq/#why-do-my-services-take-10-seconds-to-recreate-or-stop" class="external-link" target="_blank">Pourquoi mes services mettent-ils 10 secondes Ă  se recrĂ©er ou Ă  s'arrĂȘter ?</a>.
+
+#### Structure du rĂ©pertoire { #directory-structure }
+
+Vous devriez maintenant avoir une structure de rĂ©pertoire comme :
 
 ```
 .
 â”œâ”€â”€ app
+│   â”œâ”€â”€ __init__.py
 â”‚   â””── main.py
-└── Dockerfile
+├── Dockerfile
+└── requirements.txt
+```
+
+#### DerriĂšre un proxy de terminaison TLS { #behind-a-tls-termination-proxy }
+
+Si vous exĂ©cutez votre conteneur derriĂšre un proxy de terminaison TLS (load balancer) comme Nginx ou Traefik, ajoutez l'option `--proxy-headers`, cela indiquera Ă  Uvicorn (via la CLI FastAPI) de faire confiance aux en-tĂȘtes envoyĂ©s par ce proxy lui indiquant que l'application s'exĂ©cute derriĂšre HTTPS, etc.
+
+```Dockerfile
+CMD ["fastapi", "run", "app/main.py", "--proxy-headers", "--port", "80"]
+```
+
+#### Cache Docker { #docker-cache }
+
+Il y a une astuce importante dans ce `Dockerfile`, nous copions d'abord **le fichier des dĂ©pendances seul**, pas le reste du code. Laissez-moi vous expliquer pourquoi.
+
+```Dockerfile
+COPY ./requirements.txt /code/requirements.txt
+```
+
+Docker et d'autres outils **construisent** ces images de conteneur **de maniĂšre incrĂ©mentale**, en ajoutant **une couche au-dessus de l'autre**, en commençant par le haut du `Dockerfile` et en ajoutant tous les fichiers créés par chacune des instructions du `Dockerfile`.
+
+Docker et des outils similaires utilisent Ă©galement un **cache interne** lors de la construction de l'image : si un fichier n'a pas changĂ© depuis la derniĂšre construction de l'image de conteneur, alors il va **rĂ©utiliser la mĂȘme couche** créée la derniĂšre fois, au lieu de recopier le fichier et crĂ©er une nouvelle couche Ă  partir de zĂ©ro.
+
+Éviter simplement la copie des fichiers n'amĂ©liore pas nĂ©cessairement les choses de maniĂšre significative, mais comme il a utilisĂ© le cache pour cette Ă©tape, il peut **utiliser le cache pour l'Ă©tape suivante**. Par exemple, il peut utiliser le cache pour l'instruction qui installe les dĂ©pendances avec :
+
+```Dockerfile
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
 ```
 
-## Construire l'image Docker
+Le fichier des dĂ©pendances **ne changera pas frĂ©quemment**. Ainsi, en copiant uniquement ce fichier, Docker pourra **utiliser le cache** pour cette Ă©tape.
+
+Et ensuite, Docker pourra **utiliser le cache pour l'Ă©tape suivante** qui tĂ©lĂ©charge et installe ces dĂ©pendances. Et c'est lĂ  que nous **gagnons beaucoup de temps**. âœš ... et Ă©vitons l'ennui en attendant. đŸ˜Ș😆
 
-* Allez dans le rĂ©pertoire du projet (dans lequel se trouve votre `Dockerfile`, contenant votre rĂ©pertoire `app`).
+TĂ©lĂ©charger et installer les dĂ©pendances de paquets **peut prendre des minutes**, mais utiliser le **cache** ne **prendra que quelques secondes** au plus.
+
+Et comme vous reconstruirez l'image de conteneur encore et encore pendant le dĂ©veloppement pour vĂ©rifier que vos modifications de code fonctionnent, cela vous fera gagner beaucoup de temps cumulĂ©.
+
+Ensuite, vers la fin du `Dockerfile`, nous copions tout le code. Comme c'est ce qui **change le plus frĂ©quemment**, nous le plaçons vers la fin, car presque toujours, tout ce qui suit cette Ă©tape ne pourra pas utiliser le cache.
+
+```Dockerfile
+COPY ./app /code/app
+```
+
+### Construire l'image Docker { #build-the-docker-image }
+
+Maintenant que tous les fichiers sont en place, construisons l'image de conteneur.
+
+* Allez dans le rĂ©pertoire du projet (lĂ  oĂč se trouve votre `Dockerfile`, contenant votre rĂ©pertoire `app`).
 * Construisez votre image FastAPI :
 
 <div class="termy">
@@ -109,9 +330,17 @@ $ docker build -t myimage .
 
 </div>
 
-## DĂ©marrer le conteneur Docker
+/// tip | Astuce
+
+Remarquez le `.` Ă  la fin, Ă©quivalent Ă  `./`, il indique Ă  Docker le rĂ©pertoire Ă  utiliser pour construire l'image de conteneur.
+
+Dans ce cas, c'est le mĂȘme rĂ©pertoire courant (`.`).
 
-* ExĂ©cutez un conteneur basĂ© sur votre image :
+///
+
+### DĂ©marrer le conteneur Docker { #start-the-docker-container }
+
+* ExĂ©cutez un conteneur basĂ© sur votre image :
 
 <div class="termy">
 
@@ -121,65 +350,269 @@ $ docker run -d --name mycontainer -p 80:80 myimage
 
 </div>
 
-Vous disposez maintenant d'un serveur FastAPI optimisĂ© dans un conteneur Docker. ConfigurĂ© automatiquement pour votre
-serveur actuel (et le nombre de cƓurs du CPU).
-
-## VĂ©rifier
+## VĂ©rifier { #check-it }
 
-Vous devriez pouvoir accĂ©der Ă  votre application via l'URL de votre conteneur Docker, par exemple : <a href="http://192.168.99.100/items/5?q=somequery" class="external-link" target="_blank">http://192.168.99.100/items/5?q=somequery</a> ou <a href="http://127.0.0.1/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1/items/5?q=somequery</a> (ou Ă©quivalent, en utilisant votre hĂŽte Docker).
+Vous devriez pouvoir le vĂ©rifier via l'URL de votre conteneur Docker, par exemple : <a href="http://192.168.99.100/items/5?q=somequery" class="external-link" target="_blank">http://192.168.99.100/items/5?q=somequery</a> ou <a href="http://127.0.0.1/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1/items/5?q=somequery</a> (ou Ă©quivalent, en utilisant votre hĂŽte Docker).
 
-Vous verrez quelque chose comme :
+Vous verrez quelque chose comme :
 
 ```JSON
 {"item_id": 5, "q": "somequery"}
 ```
 
-## Documentation interactive de l'API
+## Documentation interactive de l'API { #interactive-api-docs }
 
-Vous pouvez maintenant visiter <a href="http://192.168.99.100/docs" class="external-link" target="_blank">http://192.168.99.100/docs</a> ou <a href="http://127.0.0.1/docs" class="external-link" target="_blank">http://127.0.0.1/docs</a> (ou Ă©quivalent, en utilisant votre hĂŽte Docker).
+Vous pouvez maintenant aller sur <a href="http://192.168.99.100/docs" class="external-link" target="_blank">http://192.168.99.100/docs</a> ou <a href="http://127.0.0.1/docs" class="external-link" target="_blank">http://127.0.0.1/docs</a> (ou Ă©quivalent, en utilisant votre hĂŽte Docker).
 
-Vous verrez la documentation interactive automatique de l'API (fournie par <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>) :
+Vous verrez la documentation interactive automatique de l'API (fournie par <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>) :
 
 ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
 
-## Documentation de l'API alternative
+## Documentation alternative de l'API { #alternative-api-docs }
 
-Et vous pouvez Ă©galement aller sur <a href="http://192.168.99.100/redoc" class="external-link" target="_blank">http://192.168.99.100/redoc</a> ou <a href="http://127.0.0.1/redoc" class="external-link" target="_blank">http://127.0.0.1/redoc</a> (ou Ă©quivalent, en utilisant votre hĂŽte Docker).
+Et vous pouvez aussi aller sur <a href="http://192.168.99.100/redoc" class="external-link" target="_blank">http://192.168.99.100/redoc</a> ou <a href="http://127.0.0.1/redoc" class="external-link" target="_blank">http://127.0.0.1/redoc</a> (ou Ă©quivalent, en utilisant votre hĂŽte Docker).
 
-Vous verrez la documentation automatique alternative (fournie par <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>) :
+Vous verrez la documentation automatique alternative (fournie par <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>) :
 
 ![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
 
-## Traefik
+## Construire une image Docker avec un FastAPI mono-fichier { #build-a-docker-image-with-a-single-file-fastapi }
+
+Si votre FastAPI est un seul fichier, par exemple `main.py` sans rĂ©pertoire `./app`, votre structure de fichiers pourrait ressembler Ă  ceci :
+
+```
+.
+├── Dockerfile
+├── main.py
+└── requirements.txt
+```
+
+Vous n'auriez alors qu'Ă  changer les chemins correspondants pour copier le fichier dans le `Dockerfile` :
+
+```{ .dockerfile .annotate hl_lines="10  13" }
+FROM python:3.9
+
+WORKDIR /code
+
+COPY ./requirements.txt /code/requirements.txt
+
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+
+# (1)!
+COPY ./main.py /code/
 
-<a href="https://traefik.io/" class="external-link" target="_blank">Traefik</a> est un reverse proxy/load balancer
-haute performance. Il peut faire office de "Proxy de terminaison TLS" (entre autres fonctionnalitĂ©s).
+# (2)!
+CMD ["fastapi", "run", "main.py", "--port", "80"]
+```
+
+1. Copier le fichier `main.py` directement dans le rĂ©pertoire `/code` (sans rĂ©pertoire `./app`).
+
+2. Utiliser `fastapi run` pour servir votre application dans le fichier unique `main.py`.
+
+Lorsque vous passez le fichier Ă  `fastapi run`, il dĂ©tectera automatiquement qu'il s'agit d'un fichier unique et non d'un package et saura comment l'importer et servir votre application FastAPI. đŸ˜Ž
+
+## Concepts de dĂ©ploiement { #deployment-concepts }
+
+Parlons Ă  nouveau de certains des mĂȘmes [Concepts de dĂ©ploiement](concepts.md){.internal-link target=_blank} en termes de conteneurs.
+
+Les conteneurs sont principalement un outil pour simplifier le processus de **construction et de dĂ©ploiement** d'une application, mais ils n'imposent pas une approche particuliĂšre pour gĂ©rer ces **concepts de dĂ©ploiement**, et il existe plusieurs stratĂ©gies possibles.
+
+La **bonne nouvelle**, c'est qu'avec chaque stratĂ©gie diffĂ©rente, il existe un moyen de couvrir tous les concepts de dĂ©ploiement. đŸŽ‰
+
+Passons en revue ces **concepts de dĂ©ploiement** en termes de conteneurs :
+
+* HTTPS
+* ExĂ©cution au dĂ©marrage
+* RedĂ©marrages
+* RĂ©plication (le nombre de processus en cours d'exĂ©cution)
+* MĂ©moire
+* Ă‰tapes prĂ©alables au dĂ©marrage
+
+## HTTPS { #https }
+
+Si l'on se concentre uniquement sur l'**image de conteneur** pour une application FastAPI (et plus tard sur le **conteneur** en cours d'exĂ©cution), HTTPS serait normalement gĂ©rĂ© **Ă  l'extĂ©rieur** par un autre outil.
+
+Cela pourrait ĂȘtre un autre conteneur, par exemple avec <a href="https://traefik.io/" class="external-link" target="_blank">Traefik</a>, gĂ©rant **HTTPS** et l'acquisition **automatique** des **certificats**.
+
+/// tip | Astuce
 
-Il est intĂ©grĂ© Ă  Let's Encrypt. Ainsi, il peut gĂ©rer toutes les parties HTTPS, y compris l'acquisition et le renouvellement des certificats.
+Traefik s'intĂšgre avec Docker, Kubernetes, et d'autres, donc il est trĂšs facile de configurer HTTPS pour vos conteneurs avec lui.
 
-Il est Ă©galement intĂ©grĂ© Ă  Docker. Ainsi, vous pouvez dĂ©clarer vos domaines dans les configurations de chaque application et faire en sorte qu'elles lisent ces configurations, gĂ©nĂšrent les certificats HTTPS et servent via HTTPS Ă  votre application automatiquement, sans nĂ©cessiter aucune modification de leurs configurations.
+///
+
+Alternativement, HTTPS pourrait ĂȘtre gĂ©rĂ© par un fournisseur cloud comme l'un de leurs services (tout en exĂ©cutant l'application dans un conteneur).
+
+## ExĂ©cution au dĂ©marrage et redĂ©marrages { #running-on-startup-and-restarts }
+
+Il y a normalement un autre outil chargĂ© de **dĂ©marrer et exĂ©cuter** votre conteneur.
+
+Cela pourrait ĂȘtre **Docker** directement, **Docker Compose**, **Kubernetes**, un **service cloud**, etc.
+
+Dans la plupart (ou toutes) des situations, il existe une option simple pour activer l'exĂ©cution du conteneur au dĂ©marrage et activer les redĂ©marrages en cas d'Ă©chec. Par exemple, dans Docker, c'est l'option de ligne de commande `--restart`.
+
+Sans utiliser de conteneurs, faire en sorte que les applications s'exĂ©cutent au dĂ©marrage et avec redĂ©marrages peut ĂȘtre fastidieux et difficile. Mais en **travaillant avec des conteneurs**, dans la plupart des cas, cette fonctionnalitĂ© est incluse par dĂ©faut. âœš
+
+## RĂ©plication - Nombre de processus { #replication-number-of-processes }
+
+Si vous avez un <abbr title="Un groupe de machines configurĂ©es pour ĂȘtre connectĂ©es et fonctionner ensemble d'une certaine maniĂšre.">cluster</abbr> de machines avec **Kubernetes**, Docker Swarm Mode, Nomad, ou un autre systĂšme complexe similaire pour gĂ©rer des conteneurs distribuĂ©s sur plusieurs machines, alors vous voudrez probablement **gĂ©rer la rĂ©plication** au **niveau du cluster** plutĂŽt que d'utiliser un **gestionnaire de processus** (comme Uvicorn avec workers) dans chaque conteneur.
+
+L'un de ces systĂšmes de gestion de conteneurs distribuĂ©s comme Kubernetes dispose normalement d'une maniĂšre intĂ©grĂ©e de gĂ©rer la **rĂ©plication des conteneurs** tout en supportant l'**Ă©quilibrage de charge** des requĂȘtes entrantes. Le tout au **niveau du cluster**.
+
+Dans ces cas, vous voudrez probablement construire une **image Docker Ă  partir de zĂ©ro** comme [expliquĂ© ci-dessus](#dockerfile), en installant vos dĂ©pendances et en exĂ©cutant **un seul processus Uvicorn** au lieu d'utiliser plusieurs workers Uvicorn.
+
+### Ă‰quilibreur de charge { #load-balancer }
+
+Lors de l'utilisation de conteneurs, vous aurez normalement un composant **Ă  l'Ă©coute sur le port principal**. Cela pourrait ĂȘtre un autre conteneur qui est Ă©galement un **proxy de terminaison TLS** pour gĂ©rer **HTTPS** ou un outil similaire.
+
+Comme ce composant prend la **charge** des requĂȘtes et la distribue entre les workers de façon (espĂ©rons-le) **Ă©quilibrĂ©e**, on l'appelle Ă©galement communĂ©ment un **Ă©quilibreur de charge**.
+
+/// tip | Astuce
+
+Le mĂȘme composant de **proxy de terminaison TLS** utilisĂ© pour HTTPS sera probablement aussi un **Ă©quilibreur de charge**.
+
+///
+
+Et en travaillant avec des conteneurs, le mĂȘme systĂšme que vous utilisez pour les dĂ©marrer et les gĂ©rer dispose dĂ©jĂ  d'outils internes pour transmettre la **communication rĂ©seau** (par ex. les requĂȘtes HTTP) depuis cet **Ă©quilibreur de charge** (qui peut aussi ĂȘtre un **proxy de terminaison TLS**) vers le ou les conteneurs avec votre application.
+
+### Un Ă©quilibreur de charge - Plusieurs conteneurs worker { #one-load-balancer-multiple-worker-containers }
+
+Lorsque vous travaillez avec **Kubernetes** ou des systĂšmes de gestion de conteneurs distribuĂ©s similaires, l'utilisation de leurs mĂ©canismes rĂ©seau internes permet au **seul Ă©quilibreur de charge** Ă  l'Ă©coute sur le **port** principal de transmettre la communication (les requĂȘtes) vers potentiellement **plusieurs conteneurs** exĂ©cutant votre application.
+
+Chacun de ces conteneurs exĂ©cutant votre application aura normalement **un seul processus** (par ex. un processus Uvicorn exĂ©cutant votre application FastAPI). Ils seront tous des **conteneurs identiques**, exĂ©cutant la mĂȘme chose, mais chacun avec son propre processus, sa mĂ©moire, etc. De cette façon, vous profiterez de la **parallĂ©lisation** sur **diffĂ©rents cƓurs** du CPU, voire sur **diffĂ©rentes machines**.
+
+Et le systĂšme de conteneurs distribuĂ©s avec l'**Ă©quilibreur de charge** **distribuera les requĂȘtes** Ă  chacun des conteneurs exĂ©cutant votre application **Ă  tour de rĂŽle**. Ainsi, chaque requĂȘte pourrait ĂȘtre traitĂ©e par l'un des multiples **conteneurs rĂ©pliquĂ©s** exĂ©cutant votre application.
+
+Et normalement cet **Ă©quilibreur de charge** pourra gĂ©rer des requĂȘtes qui vont vers *d'autres* applications dans votre cluster (par ex. vers un autre domaine, ou sous un autre prĂ©fixe de chemin d'URL), et transmettra cette communication aux bons conteneurs pour *cette autre* application s'exĂ©cutant dans votre cluster.
+
+### Un processus par conteneur { #one-process-per-container }
+
+Dans ce type de scĂ©nario, vous voudrez probablement avoir **un seul processus (Uvicorn) par conteneur**, puisque vous gĂ©rez dĂ©jĂ  la rĂ©plication au niveau du cluster.
+
+Donc, dans ce cas, vous **ne voudrez pas** avoir plusieurs workers dans le conteneur, par exemple avec l'option de ligne de commande `--workers`. Vous voudrez avoir **un seul processus Uvicorn** par conteneur (mais probablement plusieurs conteneurs).
+
+Avoir un autre gestionnaire de processus Ă  l'intĂ©rieur du conteneur (comme ce serait le cas avec plusieurs workers) n'ajouterait que de la **complexitĂ© inutile** que vous gĂ©rez trĂšs probablement dĂ©jĂ  avec votre systĂšme de cluster.
+
+### Conteneurs avec plusieurs processus et cas particuliers { #containers-with-multiple-processes-and-special-cases }
+
+Bien sĂ»r, il existe des **cas particuliers** oĂč vous pourriez vouloir avoir **un conteneur** avec plusieurs **processus worker Uvicorn** Ă  l'intĂ©rieur.
+
+Dans ces cas, vous pouvez utiliser l'option de ligne de commande `--workers` pour dĂ©finir le nombre de workers que vous souhaitez exĂ©cuter :
+
+```{ .dockerfile .annotate }
+FROM python:3.9
+
+WORKDIR /code
+
+COPY ./requirements.txt /code/requirements.txt
+
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+
+COPY ./app /code/app
+
+# (1)!
+CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
+```
+
+1. Ici, nous utilisons l'option de ligne de commande `--workers` pour dĂ©finir le nombre de workers Ă  4.
+
+Voici quelques exemples oĂč cela pourrait avoir du sens :
+
+#### Une application simple { #a-simple-app }
+
+Vous pourriez vouloir un gestionnaire de processus dans le conteneur si votre application est **suffisamment simple** pour s'exĂ©cuter sur un **seul serveur**, pas un cluster.
+
+#### Docker Compose { #docker-compose }
+
+Vous pourriez dĂ©ployer sur un **seul serveur** (pas un cluster) avec **Docker Compose**, donc vous n'auriez pas un moyen simple de gĂ©rer la rĂ©plication des conteneurs (avec Docker Compose) tout en prĂ©servant le rĂ©seau partagĂ© et l'**Ă©quilibrage de charge**.
+
+Vous pourriez alors vouloir avoir **un seul conteneur** avec un **gestionnaire de processus** qui dĂ©marre **plusieurs processus worker** Ă  l'intĂ©rieur.
 
 ---
 
-Avec ces informations et ces outils, passez Ă  la section suivante pour tout combiner.
+L'idĂ©e principale est que **rien** de tout cela ne sont des **rĂšgles gravĂ©es dans la pierre** que vous devez suivre aveuglĂ©ment. Vous pouvez utiliser ces idĂ©es pour **Ă©valuer votre propre cas d'usage** et dĂ©cider de la meilleure approche pour votre systĂšme, en vĂ©rifiant comment gĂ©rer les concepts suivants :
+
+* SĂ©curitĂ© - HTTPS
+* ExĂ©cution au dĂ©marrage
+* RedĂ©marrages
+* RĂ©plication (le nombre de processus en cours d'exĂ©cution)
+* MĂ©moire
+* Ă‰tapes prĂ©alables au dĂ©marrage
+
+## MĂ©moire { #memory }
+
+Si vous exĂ©cutez **un seul processus par conteneur**, vous aurez une quantitĂ© de mĂ©moire consommĂ©e plus ou moins bien dĂ©finie, stable et limitĂ©e par chacun de ces conteneurs (plus d'un s'ils sont rĂ©pliquĂ©s).
+
+Vous pouvez alors dĂ©finir ces mĂȘmes limites et exigences de mĂ©moire dans vos configurations pour votre systĂšme de gestion de conteneurs (par exemple dans **Kubernetes**). De cette façon, il pourra **rĂ©pliquer les conteneurs** sur les **machines disponibles** en tenant compte de la quantitĂ© de mĂ©moire dont ils ont besoin et de la quantitĂ© disponible sur les machines du cluster.
+
+Si votre application est **simple**, cela ne sera probablement **pas un problĂšme**, et vous n'aurez peut-ĂȘtre pas besoin de spĂ©cifier des limites de mĂ©moire strictes. Mais si vous **utilisez beaucoup de mĂ©moire** (par exemple avec des modĂšles de **machine learning**), vous devez vĂ©rifier combien de mĂ©moire vous consommez et ajuster le **nombre de conteneurs** qui s'exĂ©cutent sur **chaque machine** (et peut-ĂȘtre ajouter plus de machines Ă  votre cluster).
+
+Si vous exĂ©cutez **plusieurs processus par conteneur**, vous devez vous assurer que le nombre de processus dĂ©marrĂ©s ne **consomme pas plus de mĂ©moire** que ce qui est disponible.
+
+## Ă‰tapes prĂ©alables au dĂ©marrage et conteneurs { #previous-steps-before-starting-and-containers }
+
+Si vous utilisez des conteneurs (par ex. Docker, Kubernetes), alors il existe deux approches principales que vous pouvez utiliser.
+
+### Plusieurs conteneurs { #multiple-containers }
+
+Si vous avez **plusieurs conteneurs**, probablement chacun exĂ©cutant un **seul processus** (par exemple, dans un cluster **Kubernetes**), alors vous voudrez probablement avoir un **conteneur sĂ©parĂ©** effectuant le travail des **Ă©tapes prĂ©alables** dans un seul conteneur, exĂ©cutant un seul processus, **avant** d'exĂ©cuter les conteneurs worker rĂ©pliquĂ©s.
+
+/// info
+
+Si vous utilisez Kubernetes, ce sera probablement un <a href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/" class="external-link" target="_blank">Init Container</a>.
+
+///
+
+Si, dans votre cas d'usage, il n'y a pas de problĂšme Ă  exĂ©cuter ces Ă©tapes prĂ©alables **plusieurs fois en parallĂšle** (par exemple si vous n'exĂ©cutez pas de migrations de base de donnĂ©es, mais vĂ©rifiez simplement si la base de donnĂ©es est prĂȘte), alors vous pourriez aussi simplement les mettre dans chaque conteneur juste avant de dĂ©marrer le processus principal.
+
+### Un seul conteneur { #single-container }
+
+Si vous avez une configuration simple, avec **un seul conteneur** qui dĂ©marre ensuite plusieurs **processus worker** (ou un seul processus aussi), vous pouvez alors exĂ©cuter ces Ă©tapes prĂ©alables dans le mĂȘme conteneur, juste avant de dĂ©marrer le processus avec l'application.
+
+### Image Docker de base { #base-docker-image }
+
+Il existait une image Docker officielle FastAPI : <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>. Mais elle est dĂ©sormais dĂ©prĂ©ciĂ©e. â›”
+
+Vous ne devriez probablement **pas** utiliser cette image Docker de base (ni aucune autre similaire).
+
+Si vous utilisez **Kubernetes** (ou autres) et que vous dĂ©finissez dĂ©jĂ  la **rĂ©plication** au niveau du cluster, avec plusieurs **conteneurs**. Dans ces cas, il est prĂ©fĂ©rable de **construire une image Ă  partir de zĂ©ro** comme dĂ©crit ci-dessus : [Construire une image Docker pour FastAPI](#build-a-docker-image-for-fastapi).
+
+Et si vous devez avoir plusieurs workers, vous pouvez simplement utiliser l'option de ligne de commande `--workers`.
+
+/// note | DĂ©tails techniques
+
+L'image Docker a Ă©tĂ© créée Ă  une Ă©poque oĂč Uvicorn ne supportait pas la gestion et le redĂ©marrage des workers morts, il fallait donc utiliser Gunicorn avec Uvicorn, ce qui ajoutait pas mal de complexitĂ©, uniquement pour que Gunicorn gĂšre et redĂ©marre les processus worker Uvicorn.
+
+Mais maintenant qu'Uvicorn (et la commande `fastapi`) supporte l'usage de `--workers`, il n'y a plus de raison d'utiliser une image Docker de base au lieu de construire la vĂŽtre (c'est Ă  peu prĂšs la mĂȘme quantitĂ© de code đŸ˜…).
+
+///
+
+## DĂ©ployer l'image de conteneur { #deploy-the-container-image }
 
-## Cluster en mode Docker Swarm avec Traefik et HTTPS
+AprĂšs avoir une image de conteneur (Docker), il existe plusieurs façons de la dĂ©ployer.
 
-Vous pouvez avoir un cluster en mode Docker Swarm configurĂ© en quelques minutes (environ 20 min) avec un processus Traefik principal gĂ©rant HTTPS (y compris l'acquisition et le renouvellement des certificats).
+Par exemple :
 
-En utilisant le mode Docker Swarm, vous pouvez commencer par un "cluster" d'une seule machine (il peut mĂȘme s'agir
-d'un serveur Ă  5 USD/mois) et ensuite vous pouvez vous dĂ©velopper autant que vous le souhaitez en ajoutant d'autres serveurs.
+* Avec **Docker Compose** sur un seul serveur
+* Avec un cluster **Kubernetes**
+* Avec un cluster Docker Swarm Mode
+* Avec un autre outil comme Nomad
+* Avec un service cloud qui prend votre image de conteneur et la dĂ©ploie
 
-Pour configurer un cluster en mode Docker Swarm avec Traefik et la gestion de HTTPS, suivez ce guide :
+## Image Docker avec `uv` { #docker-image-with-uv }
 
-### <a href="https://medium.com/@tiangolo/docker-swarm-mode-and-traefik-for-a-https-cluster-20328dba6232" class="external-link" target="_blank">Docker Swarm Mode et Traefik pour un cluster HTTPS</a>
+Si vous utilisez <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a> pour installer et gĂ©rer votre projet, vous pouvez suivre leur <a href="https://docs.astral.sh/uv/guides/integration/docker/" class="external-link" target="_blank">guide Docker pour uv</a>.
 
-### DĂ©ployer une application FastAPI
+## RĂ©capitulatif { #recap }
 
-La façon la plus simple de tout mettre en place, serait d'utiliser les [**GĂ©nĂ©rateurs de projet FastAPI**](../project-generation.md){.internal-link target=_blank}.
+Avec les systĂšmes de conteneurs (par ex. avec **Docker** et **Kubernetes**), il devient assez simple de gĂ©rer tous les **concepts de dĂ©ploiement** :
 
-Le gĂ©nerateur de projet adĂ©quat est conçu pour ĂȘtre intĂ©grĂ© Ă  ce cluster Docker Swarm avec Traefik et HTTPS dĂ©crit ci-dessus.
+* HTTPS
+* ExĂ©cution au dĂ©marrage
+* RedĂ©marrages
+* RĂ©plication (le nombre de processus en cours d'exĂ©cution)
+* MĂ©moire
+* Ă‰tapes prĂ©alables au dĂ©marrage
 
-Vous pouvez gĂ©nĂ©rer un projet en 2 min environ.
+Dans la plupart des cas, vous ne voudrez probablement pas utiliser d'image de base, et au contraire **construire une image de conteneur Ă  partir de zĂ©ro** basĂ©e sur l'image Docker Python officielle.
 
-Le projet gĂ©nĂ©rĂ© a des instructions pour le dĂ©ployer et le faire prend 2 min de plus.
+En prenant soin de l'**ordre** des instructions dans le `Dockerfile` et du **cache Docker**, vous pouvez **minimiser les temps de construction**, maximiser votre productivitĂ© (et Ă©viter l'ennui). đŸ˜Ž
index 3f7068ff032d2b06859aa35e9ee667d26afe3623..74d38cdb9f0d87ecd99e82ec4e2eab6eb7253fa1 100644 (file)
-# Ă€ propos de HTTPS
+# Ă€ propos de HTTPS { #about-https }
 
-Il est facile de penser que HTTPS peut simplement ĂȘtre "activĂ©" ou non.
+Il est facile de supposer que HTTPS est quelque chose qui est simplement Â« activĂ© Â» ou non.
 
 Mais c'est beaucoup plus complexe que cela.
 
-/// tip
+/// tip | Astuce
 
-Si vous ĂȘtes pressĂ© ou si cela ne vous intĂ©resse pas, passez aux sections suivantes pour obtenir des instructions Ă©tape par Ă©tape afin de tout configurer avec diffĂ©rentes techniques.
+Si vous ĂȘtes pressĂ© ou si cela ne vous intĂ©resse pas, continuez avec les sections suivantes pour obtenir des instructions Ă©tape par Ă©tape afin de tout configurer avec diffĂ©rentes techniques.
 
 ///
 
-Pour apprendre les bases du HTTPS, du point de vue d'un utilisateur, consultez <a href="https://howhttps.works/"
-class="external-link" target="_blank">https://howhttps.works/</a>.
+Pour apprendre les bases du HTTPS, du point de vue d'un utilisateur, consultez <a href="https://howhttps.works/" class="external-link" target="_blank">https://howhttps.works/</a>.
 
 Maintenant, du point de vue d'un dĂ©veloppeur, voici plusieurs choses Ă  avoir en tĂȘte en pensant au HTTPS :
 
-* Pour le HTTPS, le serveur a besoin de "certificats" gĂ©nĂ©rĂ©s par une tierce partie.
-    * Ces certificats sont en fait acquis auprĂšs de la tierce partie, et non "gĂ©nĂ©rĂ©s".
-* Les certificats ont une durĂ©e de vie.
-    * Ils expirent.
-    * Puis ils doivent ĂȘtre renouvelĂ©s et acquis Ă  nouveau auprĂšs de la tierce partie.
-* Le cryptage de la connexion se fait au niveau du protocole TCP.
-    * C'est une couche en dessous de HTTP.
-    * Donc, le certificat et le traitement du cryptage sont faits avant HTTP.
-* TCP ne connaĂźt pas les "domaines", seulement les adresses IP.
-    * L'information sur le domaine spĂ©cifique demandĂ© se trouve dans les donnĂ©es HTTP.
-* Les certificats HTTPS "certifient" un certain domaine, mais le protocole et le cryptage se font au niveau TCP, avant de savoir quel domaine est traitĂ©.
-* Par dĂ©faut, cela signifie que vous ne pouvez avoir qu'un seul certificat HTTPS par adresse IP.
-    * Quelle que soit la taille de votre serveur ou la taille de chacune des applications qu'il contient.
-    * Il existe cependant une solution Ă  ce problĂšme.
-* Il existe une extension du protocole TLS (celui qui gĂšre le cryptage au niveau TCP, avant HTTP) appelĂ©e <a
-  href="https://fr.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr
-  title="Server Name Indication (indication du nom du serveur)">SNI (indication du nom du serveur)</abbr></a>.
-    * Cette extension SNI permet Ă  un seul serveur (avec une seule adresse IP) d'avoir plusieurs certificats HTTPS et de servir plusieurs domaines/applications HTTPS.
-    * Pour que cela fonctionne, un seul composant (programme) fonctionnant sur le serveur, Ă©coutant sur l'adresse IP publique, doit avoir tous les certificats HTTPS du serveur.
-* AprĂšs avoir obtenu une connexion sĂ©curisĂ©e, le protocole de communication est toujours HTTP.
-    * Le contenu est cryptĂ©, mĂȘme s'il est envoyĂ© avec le protocole HTTP.
-
-Il est courant d'avoir un seul programme/serveur HTTP fonctionnant sur le serveur (la machine, l'hĂŽte, etc.) et
-gĂ©rant toutes les parties HTTPS : envoyer les requĂȘtes HTTP dĂ©cryptĂ©es Ă  l'application HTTP rĂ©elle fonctionnant sur
-le mĂȘme serveur (dans ce cas, l'application **FastAPI**), prendre la rĂ©ponse HTTP de l'application, la crypter en utilisant le certificat appropriĂ© et la renvoyer au client en utilisant HTTPS. Ce serveur est souvent appelĂ© un <a href="https://en.wikipedia.org/wiki/TLS_termination_proxy" class="external-link" target="_blank">Proxy de terminaison TLS</a>.
-
-## Let's Encrypt
-
-Avant Let's Encrypt, ces certificats HTTPS Ă©taient vendus par des tiers de confiance.
-
-Le processus d'acquisition d'un de ces certificats Ă©tait auparavant lourd, nĂ©cessitait pas mal de paperasses et les certificats Ă©taient assez chers.
-
-Mais ensuite, <a href="https://letsencrypt.org/" class="external-link" target="_blank">Let's Encrypt</a> a Ă©tĂ© créé.
-
-Il s'agit d'un projet de la Fondation Linux. Il fournit des certificats HTTPS gratuitement. De maniĂšre automatisĂ©e. Ces certificats utilisent toutes les sĂ©curitĂ©s cryptographiques standard et ont une durĂ©e de vie courte (environ 3 mois), de sorte que la sĂ©curitĂ© est en fait meilleure en raison de leur durĂ©e de vie rĂ©duite.
+* Pour le HTTPS, **le serveur** doit **disposer de Â« certificats Â»** gĂ©nĂ©rĂ©s par une **tierce partie**.
+    * Ces certificats sont en rĂ©alitĂ© **acquis** auprĂšs de la tierce partie, et non Â« gĂ©nĂ©rĂ©s Â».
+* Les certificats ont une **durĂ©e de vie**.
+    * Ils **expirent**.
+    * Puis ils doivent ĂȘtre **renouvelĂ©s**, **acquis Ă  nouveau** auprĂšs de la tierce partie.
+* Le cryptage de la connexion se fait au **niveau TCP**.
+    * C'est une couche **en dessous de HTTP**.
+    * Donc, la gestion du **certificat et du cryptage** est effectuĂ©e **avant HTTP**.
+* **TCP ne connaĂźt pas les Â« domaines Â»**. Il ne connaĂźt que les adresses IP.
+    * L'information sur le **domaine spĂ©cifique** demandĂ© se trouve dans les **donnĂ©es HTTP**.
+* Les **certificats HTTPS** Â« certifient Â» un **certain domaine**, mais le protocole et le cryptage se font au niveau TCP, **avant de savoir** quel domaine est traitĂ©.
+* **Par dĂ©faut**, cela signifie que vous ne pouvez avoir qu'**un seul certificat HTTPS par adresse IP**.
+    * Quelle que soit la taille de votre serveur ou la petitesse de chacune des applications qu'il contient.
+    * Il existe cependant une **solution** Ă  ce problĂšme.
+* Il existe une **extension** du protocole **TLS** (celui qui gĂšre le cryptage au niveau TCP, avant HTTP) appelĂ©e **<a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="Server Name Indication - Indication du nom du serveur">SNI</abbr></a>**.
+    * Cette extension SNI permet Ă  un seul serveur (avec une **seule adresse IP**) d'avoir **plusieurs certificats HTTPS** et de servir **plusieurs domaines/applications HTTPS**.
+    * Pour que cela fonctionne, un **seul** composant (programme) fonctionnant sur le serveur, Ă©coutant sur l'**adresse IP publique**, doit avoir **tous les certificats HTTPS** du serveur.
+* **AprĂšs** l'Ă©tablissement d'une connexion sĂ©curisĂ©e, le protocole de communication est **toujours HTTP**.
+    * Le contenu est **cryptĂ©**, mĂȘme s'il est envoyĂ© avec le **protocole HTTP**.
+
+Il est courant d'avoir **un seul programme/serveur HTTP** fonctionnant sur le serveur (la machine, l'hĂŽte, etc.) et **gĂ©rant toutes les parties HTTPS** : recevoir les **requĂȘtes HTTPS chiffrĂ©es**, envoyer les **requĂȘtes HTTP dĂ©chiffrĂ©es** Ă  l'application HTTP rĂ©elle fonctionnant sur le mĂȘme serveur (l'application **FastAPI**, dans ce cas), prendre la **rĂ©ponse HTTP** de l'application, la **chiffrer** en utilisant le **certificat HTTPS** appropriĂ© et la renvoyer au client en utilisant **HTTPS**. Ce serveur est souvent appelĂ© un **<a href="https://en.wikipedia.org/wiki/TLS_termination_proxy" class="external-link" target="_blank">Proxy de terminaison TLS</a>**.
+
+Parmi les options que vous pourriez utiliser comme Proxy de terminaison TLS :
+
+* Traefik (qui peut Ă©galement gĂ©rer les renouvellements de certificats)
+* Caddy (qui peut Ă©galement gĂ©rer les renouvellements de certificats)
+* Nginx
+* HAProxy
+
+## Let's Encrypt { #lets-encrypt }
+
+Avant Let's Encrypt, ces **certificats HTTPS** Ă©taient vendus par des tiers de confiance.
+
+Le processus d'acquisition de l'un de ces certificats Ă©tait auparavant lourd, nĂ©cessitait pas mal de paperasses et les certificats Ă©taient assez chers.
+
+Mais ensuite, **<a href="https://letsencrypt.org/" class="external-link" target="_blank">Let's Encrypt</a>** a Ă©tĂ© créé.
+
+Il s'agit d'un projet de la Fondation Linux. Il fournit **des certificats HTTPS gratuitement**, de maniĂšre automatisĂ©e. Ces certificats utilisent toutes les sĂ©curitĂ©s cryptographiques standard et ont une durĂ©e de vie courte (environ 3 mois), de sorte que la **sĂ©curitĂ© est en fait meilleure** en raison de leur durĂ©e de vie rĂ©duite.
 
 Les domaines sont vĂ©rifiĂ©s de maniĂšre sĂ©curisĂ©e et les certificats sont gĂ©nĂ©rĂ©s automatiquement. Cela permet Ă©galement d'automatiser le renouvellement de ces certificats.
 
-L'idĂ©e est d'automatiser l'acquisition et le renouvellement de ces certificats, afin que vous puissiez disposer d'un HTTPS sĂ©curisĂ©, gratuitement et pour toujours.
+L'idĂ©e est d'automatiser l'acquisition et le renouvellement de ces certificats, afin que vous puissiez disposer d'un **HTTPS sĂ©curisĂ©, gratuitement et pour toujours**.
+
+## HTTPS pour les dĂ©veloppeurs { #https-for-developers }
+
+Voici un exemple de ce Ă  quoi pourrait ressembler une API HTTPS, Ă©tape par Ă©tape, en portant principalement attention aux idĂ©es importantes pour les dĂ©veloppeurs.
+
+### Nom de domaine { #domain-name }
+
+Tout commencerait probablement par le fait que vous **acquĂ©riez** un **nom de domaine**. Ensuite, vous le configureriez dans un serveur DNS (possiblement le mĂȘme que votre fournisseur cloud).
+
+Vous obtiendriez probablement un serveur cloud (une machine virtuelle) ou quelque chose de similaire, et il aurait une adresse IP **publique** <abbr title="Qui ne change pas">fixe</abbr>.
+
+Dans le ou les serveurs DNS, vous configureriez un enregistrement (un Â« `A record` Â») pour faire pointer **votre domaine** vers l'**adresse IP publique de votre serveur**.
+
+Vous feriez probablement cela une seule fois, la premiĂšre fois, lors de la mise en place de l'ensemble.
+
+/// tip | Astuce
+
+Cette partie relative au nom de domaine intervient bien avant HTTPS, mais comme tout dĂ©pend du domaine et de l'adresse IP, il vaut la peine de la mentionner ici.
+
+///
+
+### DNS { #dns }
+
+Concentrons-nous maintenant sur toutes les parties rĂ©ellement liĂ©es Ă  HTTPS.
+
+D'abord, le navigateur vĂ©rifierait auprĂšs des **serveurs DNS** quelle est l'**IP du domaine**, dans ce cas, `someapp.example.com`.
+
+Les serveurs DNS indiqueraient au navigateur d'utiliser une **adresse IP** spĂ©cifique. Ce serait l'adresse IP publique utilisĂ©e par votre serveur, celle que vous avez configurĂ©e dans les serveurs DNS.
+
+<img src="/img/deployment/https/https01.drawio.svg">
+
+### DĂ©but de la nĂ©gociation TLS (Handshake) { #tls-handshake-start }
+
+Le navigateur communiquerait ensuite avec cette adresse IP sur le **port 443** (le port HTTPS).
+
+La premiĂšre partie de la communication consiste simplement Ă  Ă©tablir la connexion entre le client et le serveur et Ă  dĂ©cider des clĂ©s cryptographiques qu'ils utiliseront, etc.
+
+<img src="/img/deployment/https/https02.drawio.svg">
+
+Cette interaction entre le client et le serveur pour Ă©tablir la connexion TLS s'appelle la **nĂ©gociation TLS (TLS handshake)**.
+
+### TLS avec l'extension SNI { #tls-with-sni-extension }
+
+**Un seul processus** sur le serveur peut Ă©couter sur un **port** spĂ©cifique d'une **adresse IP** spĂ©cifique. Il pourrait y avoir d'autres processus Ă©coutant sur d'autres ports de la mĂȘme adresse IP, mais un seul pour chaque combinaison d'adresse IP et de port.
+
+TLS (HTTPS) utilise par dĂ©faut le port spĂ©cifique `443`. C'est donc le port dont nous aurions besoin.
+
+Comme un seul processus peut Ă©couter sur ce port, le processus qui le ferait serait le **Proxy de terminaison TLS**.
+
+Le Proxy de terminaison TLS aurait accĂšs Ă  un ou plusieurs **certificats TLS** (certificats HTTPS).
+
+En utilisant l'**extension SNI** mentionnĂ©e plus haut, le Proxy de terminaison TLS vĂ©rifierait lequel des certificats TLS (HTTPS) disponibles il devrait utiliser pour cette connexion, en choisissant celui qui correspond au domaine attendu par le client.
+
+Dans ce cas, il utiliserait le certificat pour `someapp.example.com`.
+
+<img src="/img/deployment/https/https03.drawio.svg">
+
+Le client **fait dĂ©jĂ  confiance** Ă  l'entitĂ© qui a gĂ©nĂ©rĂ© ce certificat TLS (dans ce cas Let's Encrypt, mais nous y reviendrons plus tard), il peut donc **vĂ©rifier** que le certificat est valide.
+
+Ensuite, en utilisant le certificat, le client et le Proxy de terminaison TLS **dĂ©cident comment chiffrer** le reste de la **communication TCP**. Cela termine la partie **nĂ©gociation TLS**.
+
+AprĂšs cela, le client et le serveur disposent d'une **connexion TCP chiffrĂ©e**, c'est ce que fournit TLS. Ils peuvent alors utiliser cette connexion pour dĂ©marrer la **communication HTTP** proprement dite.
+
+Et c'est ce qu'est **HTTPS** : c'est simplement du **HTTP** Ă  l'intĂ©rieur d'une **connexion TLS sĂ©curisĂ©e** au lieu d'une connexion TCP pure (non chiffrĂ©e).
+
+/// tip | Astuce
+
+Remarquez que le cryptage de la communication se produit au **niveau TCP**, pas au niveau HTTP.
+
+///
+
+### RequĂȘte HTTPS { #https-request }
+
+Maintenant que le client et le serveur (spĂ©cifiquement le navigateur et le Proxy de terminaison TLS) ont une **connexion TCP chiffrĂ©e**, ils peuvent dĂ©marrer la **communication HTTP**.
+
+Ainsi, le client envoie une **requĂȘte HTTPS**. Ce n'est qu'une requĂȘte HTTP Ă  travers une connexion TLS chiffrĂ©e.
+
+<img src="/img/deployment/https/https04.drawio.svg">
+
+### DĂ©chiffrer la requĂȘte { #decrypt-the-request }
+
+Le Proxy de terminaison TLS utiliserait le chiffrement convenu pour **dĂ©chiffrer la requĂȘte**, et transmettrait la **requĂȘte HTTP en clair (dĂ©chiffrĂ©e)** au processus exĂ©cutant l'application (par exemple un processus avec Uvicorn exĂ©cutant l'application FastAPI).
+
+<img src="/img/deployment/https/https05.drawio.svg">
+
+### RĂ©ponse HTTP { #http-response }
+
+L'application traiterait la requĂȘte et enverrait une **rĂ©ponse HTTP en clair (non chiffrĂ©e)** au Proxy de terminaison TLS.
+
+<img src="/img/deployment/https/https06.drawio.svg">
+
+### RĂ©ponse HTTPS { #https-response }
+
+Le Proxy de terminaison TLS **chiffrerait ensuite la rĂ©ponse** en utilisant la cryptographie convenue auparavant (qui a commencĂ© avec le certificat pour `someapp.example.com`), et la renverrait au navigateur.
+
+Ensuite, le navigateur vĂ©rifierait que la rĂ©ponse est valide et chiffrĂ©e avec la bonne clĂ© cryptographique, etc. Il **dĂ©chiffrerait la rĂ©ponse** et la traiterait.
+
+<img src="/img/deployment/https/https07.drawio.svg">
+
+Le client (navigateur) saura que la rĂ©ponse provient du bon serveur parce qu'elle utilise la cryptographie convenue auparavant Ă  l'aide du **certificat HTTPS**.
+
+### Applications multiples { #multiple-applications }
+
+Sur le mĂȘme serveur (ou les mĂȘmes serveurs), il pourrait y avoir **plusieurs applications**, par exemple d'autres programmes d'API ou une base de donnĂ©es.
+
+Un seul processus peut gĂ©rer l'adresse IP et le port spĂ©cifiques (le Proxy de terminaison TLS dans notre exemple), mais les autres applications/processus peuvent Ă©galement s'exĂ©cuter sur le ou les serveurs, tant qu'ils n'essaient pas d'utiliser la mĂȘme **combinaison d'adresse IP publique et de port**.
+
+<img src="/img/deployment/https/https08.drawio.svg">
+
+De cette façon, le Proxy de terminaison TLS pourrait gĂ©rer HTTPS et les certificats pour **plusieurs domaines**, pour plusieurs applications, puis transmettre les requĂȘtes Ă  la bonne application dans chaque cas.
+
+### Renouvellement des certificats { #certificate-renewal }
+
+À un moment donnĂ© dans le futur, chaque certificat **expirerait** (environ 3 mois aprĂšs son acquisition).
+
+Ensuite, il y aurait un autre programme (dans certains cas c'est un autre programme, dans d'autres cas cela pourrait ĂȘtre le mĂȘme Proxy de terminaison TLS) qui communiquerait avec Let's Encrypt et renouvellerait le ou les certificats.
+
+<img src="/img/deployment/https/https.drawio.svg">
+
+Les **certificats TLS** sont **associĂ©s Ă  un nom de domaine**, pas Ă  une adresse IP.
+
+Ainsi, pour renouveler les certificats, le programme de renouvellement doit **prouver** Ă  l'autoritĂ© (Let's Encrypt) qu'il **« possĂšde Â» et contrĂŽle ce domaine**.
+
+Pour ce faire, et pour s'adapter aux diffĂ©rents besoins des applications, il existe plusieurs façons de procĂ©der. Parmi les plus courantes :
+
+* **Modifier certains enregistrements DNS**.
+    * Pour cela, le programme de renouvellement doit prendre en charge les API du fournisseur DNS ; ainsi, selon le fournisseur DNS que vous utilisez, cela peut ĂȘtre ou non une option.
+* **S'exĂ©cuter comme un serveur** (au moins pendant le processus d'acquisition du certificat) sur l'adresse IP publique associĂ©e au domaine.
+    * Comme nous l'avons dit plus haut, un seul processus peut Ă©couter sur une adresse IP et un port spĂ©cifiques.
+    * C'est l'une des raisons pour lesquelles il est trĂšs utile que le mĂȘme Proxy de terminaison TLS prenne Ă©galement en charge le processus de renouvellement des certificats.
+    * Sinon, vous pourriez avoir Ă  arrĂȘter le Proxy de terminaison TLS momentanĂ©ment, dĂ©marrer le programme de renouvellement pour acquĂ©rir les certificats, puis les configurer avec le Proxy de terminaison TLS, et ensuite redĂ©marrer le Proxy de terminaison TLS. Ce n'est pas idĂ©al, car votre/vos application(s) ne seront pas disponibles pendant le temps oĂč le Proxy de terminaison TLS est arrĂȘtĂ©.
+
+Tout ce processus de renouvellement, tout en continuant Ă  servir l'application, est l'une des principales raisons pour lesquelles vous voudriez avoir un **systĂšme sĂ©parĂ© pour gĂ©rer HTTPS** avec un Proxy de terminaison TLS, au lieu d'utiliser directement les certificats TLS avec le serveur d'application (par exemple Uvicorn).
+
+## En-tĂȘtes Proxy Forwarded { #proxy-forwarded-headers }
+
+Lorsque vous utilisez un proxy pour gĂ©rer HTTPS, votre **serveur d'application** (par exemple Uvicorn via FastAPI CLI) ne connaĂźt rien du processus HTTPS, il communique en HTTP en clair avec le **Proxy de terminaison TLS**.
+
+Ce **proxy** dĂ©finirait normalement certains en-tĂȘtes HTTP Ă  la volĂ©e avant de transmettre la requĂȘte au **serveur d'application**, pour informer le serveur d'application que la requĂȘte est **transmise** par le proxy.
+
+/// note | DĂ©tails techniques
+
+Les en-tĂȘtes du proxy sont :
+
+* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For" class="external-link" target="_blank">X-Forwarded-For</a>
+* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto" class="external-link" target="_blank">X-Forwarded-Proto</a>
+* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host" class="external-link" target="_blank">X-Forwarded-Host</a>
+
+///
+
+NĂ©anmoins, comme le **serveur d'application** ne sait pas qu'il se trouve derriĂšre un **proxy** de confiance, par dĂ©faut, il ne ferait pas confiance Ă  ces en-tĂȘtes.
+
+Mais vous pouvez configurer le **serveur d'application** pour qu'il fasse confiance aux en-tĂȘtes transmis (*forwarded*) envoyĂ©s par le **proxy**. Si vous utilisez FastAPI CLI, vous pouvez utiliser l'*option CLI* `--forwarded-allow-ips` pour lui indiquer Ă  partir de quelles IP il doit faire confiance Ă  ces en-tĂȘtes transmis.
+
+Par exemple, si le **serveur d'application** ne reçoit des communications que du **proxy** de confiance, vous pouvez dĂ©finir `--forwarded-allow-ips="*"` pour lui faire faire confiance Ă  toutes les IP entrantes, puisqu'il ne recevra des requĂȘtes que depuis l'IP utilisĂ©e par le **proxy**.
+
+De cette façon, l'application sera en mesure de savoir quelle est sa propre URL publique, si elle utilise HTTPS, le domaine, etc.
+
+Cela serait utile, par exemple, pour gĂ©rer correctement les redirections.
+
+/// tip | Astuce
+
+Vous pouvez en savoir plus dans la documentation [DerriĂšre un proxy - Activer les en-tĂȘtes transmis par le proxy](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers){.internal-link target=_blank}
+
+///
+
+## RĂ©capitulatif { #recap }
+
+Disposer de **HTTPS** est trĂšs important, et assez **critique** dans la plupart des cas. La majeure partie de l'effort que vous, en tant que dĂ©veloppeur, devez fournir autour de HTTPS consiste simplement Ă  **comprendre ces concepts** et leur fonctionnement.
+
+Mais une fois que vous connaissez les informations de base sur **HTTPS pour les dĂ©veloppeurs**, vous pouvez facilement combiner et configurer diffĂ©rents outils pour vous aider Ă  tout gĂ©rer simplement.
+
+Dans certains des prochains chapitres, je vous montrerai plusieurs exemples concrets de configuration de **HTTPS** pour des applications **FastAPI**. đŸ”’
index e2014afe9561cc2f4f3813e61f96e0bf7890393f..3b08e9af76d287672bf0fe5486ca60b6d4832b01 100644 (file)
@@ -1,8 +1,8 @@
-# DĂ©ploiement
+# DĂ©ploiement { #deployment }
 
 Le dĂ©ploiement d'une application **FastAPI** est relativement simple.
 
-## Que signifie le dĂ©ploiement
+## Que signifie le dĂ©ploiement { #what-does-deployment-mean }
 
 **DĂ©ployer** une application signifie effectuer les Ă©tapes nĂ©cessaires pour la rendre **disponible pour les
 utilisateurs**.
@@ -14,7 +14,7 @@ l'application efficacement et sans interruption ni problĂšme.
 Ceci contraste avec les Ă©tapes de **dĂ©veloppement**, oĂč vous ĂȘtes constamment en train de modifier le code, de le casser
 et de le rĂ©parer, d'arrĂȘter et de redĂ©marrer le serveur de dĂ©veloppement, _etc._
 
-## StratĂ©gies de dĂ©ploiement
+## StratĂ©gies de dĂ©ploiement { #deployment-strategies }
 
 Il existe plusieurs façons de procĂ©der, en fonction de votre cas d'utilisation spĂ©cifique et des outils que vous
 utilisez.
@@ -22,6 +22,8 @@ utilisez.
 Vous pouvez **dĂ©ployer un serveur** vous-mĂȘme en utilisant une combinaison d'outils, vous pouvez utiliser un **service
 cloud** qui fait une partie du travail pour vous, ou encore d'autres options possibles.
 
+Par exemple, nous, l'Ă©quipe derriĂšre FastAPI, avons créé <a href="https://fastapicloud.com" class="external-link" target="_blank">**FastAPI Cloud**</a>, pour rendre le dĂ©ploiement d'applications FastAPI dans le cloud aussi fluide que possible, avec la mĂȘme expĂ©rience dĂ©veloppeur que lorsque vous travaillez avec FastAPI.
+
 Je vais vous montrer certains des principaux concepts que vous devriez probablement avoir Ă  l'esprit lors du dĂ©ploiement
 d'une application **FastAPI** (bien que la plupart de ces concepts s'appliquent Ă  tout autre type d'application web).
 
index 9d84274e27345000e9bf777a69b58bbf05d37d5e..81794428fbac5a72e7c95ba45f378b8ba38244bf 100644 (file)
-# Ă€ propos des versions de FastAPI
+# Ă€ propos des versions de FastAPI { #about-fastapi-versions }
 
-**FastAPI** est dĂ©jĂ  utilisĂ© en production dans de nombreuses applications et systĂšmes. Et la couverture de test est maintenue Ă  100 %. Mais son dĂ©veloppement est toujours aussi rapide.
+**FastAPI** est dĂ©jĂ  utilisĂ© en production dans de nombreuses applications et de nombreux systĂšmes. Et la couverture de tests est maintenue Ă  100 %. Mais son dĂ©veloppement avance toujours rapidement.
 
-De nouvelles fonctionnalitĂ©s sont ajoutĂ©es frĂ©quemment, des bogues sont corrigĂ©s rĂ©guliĂšrement et le code est
-amĂ©liorĂ© continuellement.
+De nouvelles fonctionnalitĂ©s sont ajoutĂ©es frĂ©quemment, des bogues sont corrigĂ©s rĂ©guliĂšrement et le code s'amĂ©liore continuellement.
 
-C'est pourquoi les versions actuelles sont toujours `0.x.x`, cela reflĂšte que chaque version peut potentiellement
-recevoir des changements non rĂ©trocompatibles. Cela suit les conventions de <a href="https://semver.org/" class="external-link"
-target="_blank">versionnage sĂ©mantique</a>.
+C'est pourquoi les versions actuelles sont toujours `0.x.x`, cela reflĂšte que chaque version pourrait potentiellement comporter des changements non rĂ©trocompatibles. Cela suit les conventions de <a href="https://semver.org/" class="external-link" target="_blank">versionnage sĂ©mantique</a>.
 
 Vous pouvez crĂ©er des applications de production avec **FastAPI** dĂšs maintenant (et vous le faites probablement depuis un certain temps), vous devez juste vous assurer que vous utilisez une version qui fonctionne correctement avec le reste de votre code.
 
-## Ă‰pinglez votre version de `fastapi`
+## Ă‰pingler votre version de `fastapi` { #pin-your-fastapi-version }
 
-Tout d'abord il faut "Ă©pingler" la version de **FastAPI** que vous utilisez Ă  la derniĂšre version dont vous savez
-qu'elle fonctionne correctement pour votre application.
+La premiĂšre chose que vous devez faire est Â« Ă©pingler Â» la version de **FastAPI** que vous utilisez Ă  la derniĂšre version spĂ©cifique dont vous savez qu’elle fonctionne correctement pour votre application.
 
-Par exemple, disons que vous utilisez la version `0.45.0` dans votre application.
+Par exemple, disons que vous utilisez la version `0.112.0` dans votre application.
 
-Si vous utilisez un fichier `requirements.txt`, vous pouvez spĂ©cifier la version avec :
+Si vous utilisez un fichier `requirements.txt`, vous pouvez spĂ©cifier la version avec :
 
 ```txt
-fastapi==0.45.0
+fastapi[standard]==0.112.0
 ```
 
-ce qui signifierait que vous utiliseriez exactement la version `0.45.0`.
+ce qui signifierait que vous utiliseriez exactement la version `0.112.0`.
 
-Ou vous pourriez aussi l'Ă©pingler avec :
+Ou vous pourriez aussi l'Ă©pingler avec :
 
 ```txt
-fastapi>=0.45.0,<0.46.0
+fastapi[standard]>=0.112.0,<0.113.0
 ```
 
-cela signifierait que vous utiliseriez les versions `0.45.0` ou supĂ©rieures, mais infĂ©rieures Ă  `0.46.0`, par exemple, une version `0.45.2` serait toujours acceptĂ©e.
+cela signifierait que vous utiliseriez les versions `0.112.0` ou supĂ©rieures, mais infĂ©rieures Ă  `0.113.0`, par exemple, une version `0.112.2` serait toujours acceptĂ©e.
 
-Si vous utilisez un autre outil pour gĂ©rer vos installations, comme Poetry, Pipenv, ou autres, ils ont tous un moyen que vous pouvez utiliser pour dĂ©finir des versions spĂ©cifiques pour vos paquets.
+Si vous utilisez un autre outil pour gĂ©rer vos installations, comme `uv`, Poetry, Pipenv, ou autres, ils ont tous un moyen que vous pouvez utiliser pour dĂ©finir des versions spĂ©cifiques pour vos paquets.
 
-## Versions disponibles
+## Versions disponibles { #available-versions }
 
 Vous pouvez consulter les versions disponibles (par exemple, pour vĂ©rifier quelle est la derniĂšre version en date) dans les [Notes de version](../release-notes.md){.internal-link target=_blank}.
 
-## Ă€ propos des versions
+## Ă€ propos des versions { #about-versions }
 
-Suivant les conventions de versionnage sĂ©mantique, toute version infĂ©rieure Ă  `1.0.0` peut potentiellement ajouter
-des changements non rĂ©trocompatibles.
+Suivant les conventions de versionnage sĂ©mantique, toute version infĂ©rieure Ă  `1.0.0` peut potentiellement ajouter des changements non rĂ©trocompatibles.
 
-FastAPI suit Ă©galement la convention que tout changement de version "PATCH" est pour des corrections de bogues et
-des changements rĂ©trocompatibles.
+FastAPI suit Ă©galement la convention selon laquelle tout changement de version Â« PATCH Â» concerne des corrections de bogues et des changements rĂ©trocompatibles.
 
 /// tip | Astuce
 
-Le "PATCH" est le dernier chiffre, par exemple, dans `0.2.3`, la version PATCH est `3`.
+Le Â« PATCH Â» est le dernier chiffre, par exemple, dans `0.2.3`, la version PATCH est `3`.
 
 ///
 
-Donc, vous devriez ĂȘtre capable d'Ă©pingler une version comme suit :
+Donc, vous devriez ĂȘtre en mesure d'Ă©pingler une version comme suit :
 
 ```txt
 fastapi>=0.45.0,<0.46.0
 ```
 
-Les changements non rĂ©trocompatibles et les nouvelles fonctionnalitĂ©s sont ajoutĂ©s dans les versions "MINOR".
+Les changements non rĂ©trocompatibles et les nouvelles fonctionnalitĂ©s sont ajoutĂ©s dans les versions Â« MINOR Â».
 
 /// tip | Astuce
 
-Le "MINOR" est le numĂ©ro au milieu, par exemple, dans `0.2.3`, la version MINOR est `2`.
+Le Â« MINOR Â» est le numĂ©ro au milieu, par exemple, dans `0.2.3`, la version MINOR est `2`.
 
 ///
 
-## Mise Ă  jour des versions FastAPI
+## Mettre Ă  niveau les versions de FastAPI { #upgrading-the-fastapi-versions }
 
-Vous devriez tester votre application.
+Vous devez ajouter des tests pour votre application.
 
-Avec **FastAPI** c'est trĂšs facile (merci Ă  Starlette), consultez la documentation : [Testing](../tutorial/testing.md){.internal-link target=_blank}
+Avec **FastAPI** c'est trĂšs facile (merci Ă  Starlette), consultez les documents : [Tests](../tutorial/testing.md){.internal-link target=_blank}
 
-AprĂšs avoir effectuĂ© des tests, vous pouvez mettre Ă  jour la version **FastAPI** vers une version plus rĂ©cente, et vous assurer que tout votre code fonctionne correctement en exĂ©cutant vos tests.
+AprĂšs avoir des tests, vous pouvez mettre Ă  niveau la version de **FastAPI** vers une version plus rĂ©cente et vous assurer que tout votre code fonctionne correctement en exĂ©cutant vos tests.
 
-Si tout fonctionne, ou aprĂšs avoir fait les changements nĂ©cessaires, et que tous vos tests passent, vous pouvez
-Ă©pingler votre version de `fastapi` Ă  cette nouvelle version rĂ©cente.
+Si tout fonctionne, ou aprĂšs avoir effectuĂ© les changements nĂ©cessaires, et que tous vos tests passent, vous pouvez alors Ă©pingler votre `fastapi` Ă  cette nouvelle version rĂ©cente.
 
-## Ă€ propos de Starlette
+## Ă€ propos de Starlette { #about-starlette }
 
-Vous ne devriez pas Ă©pingler la version de `starlette`.
+Vous ne devez pas Ă©pingler la version de `starlette`.
 
 DiffĂ©rentes versions de **FastAPI** utiliseront une version spĂ©cifique plus rĂ©cente de Starlette.
 
 Ainsi, vous pouvez simplement laisser **FastAPI** utiliser la bonne version de Starlette.
 
-## Ă€ propos de Pydantic
+## Ă€ propos de Pydantic { #about-pydantic }
 
-Pydantic inclut des tests pour **FastAPI** avec ses propres tests, ainsi les nouvelles versions de Pydantic (au-dessus
-de `1.0.0`) sont toujours compatibles avec **FastAPI**.
+Pydantic inclut les tests pour **FastAPI** avec ses propres tests, ainsi les nouvelles versions de Pydantic (au-dessus de `1.0.0`) sont toujours compatibles avec FastAPI.
 
-Vous pouvez Ă©pingler Pydantic Ă  toute version supĂ©rieure Ă  `1.0.0` qui fonctionne pour vous et infĂ©rieure Ă  `2.0.0`.
+Vous pouvez Ă©pingler Pydantic Ă  toute version supĂ©rieure Ă  `1.0.0` qui fonctionne pour vous.
 
-Par exemple :
+Par exemple :
 
 ```txt
-pydantic>=1.2.0,<2.0.0
+pydantic>=2.7.0,<3.0.0
 ```
index 99ea8dda127a075caa3f5afbe19de04a4415e5ea..2aeaa1c692e44aaac2e7db091db17f4bc3657ea1 100644 (file)
@@ -1,11 +1,11 @@
-# FastAPI
+# FastAPI { #fastapi }
 
 <style>
 .md-content .md-typeset h1 { display: none; }
 </style>
 
 <p align="center">
-  <a href="https://fastapi.tiangolo.com"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
+  <a href="https://fastapi.tiangolo.com/fr"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
 </p>
 <p align="center">
     <em>Framework FastAPI, haute performance, facile Ă  apprendre, rapide Ă  coder, prĂȘt pour la production</em>
@@ -27,7 +27,7 @@
 
 ---
 
-**Documentation** : <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a>
+**Documentation** : <a href="https://fastapi.tiangolo.com/fr" target="_blank">https://fastapi.tiangolo.com/fr</a>
 
 **Code Source** : <a href="https://github.com/fastapi/fastapi" target="_blank">https://github.com/fastapi/fastapi</a>
 
@@ -37,128 +37,130 @@ FastAPI est un framework web moderne et rapide (haute performance) pour la crĂ©a
 
 Les principales fonctionnalitĂ©s sont :
 
-* **RapiditĂ©** : De trĂšs hautes performances, au niveau de **NodeJS** et **Go** (grĂące Ă  Starlette et Pydantic). [L'un des frameworks Python les plus rapides](#performance).
-* **Rapide Ă  coder** : Augmente la vitesse de dĂ©veloppement des fonctionnalitĂ©s d'environ 200 % Ă  300 %. *
-* **Moins de bugs** : RĂ©duit d'environ 40 % les erreurs induites par le dĂ©veloppeur. *
-* **Intuitif** : Excellente compatibilitĂ© avec les IDE. <abbr title="Ă©galement connu sous le nom d'auto-complĂ©tion, autocomplĂ©tion, IntelliSense">ComplĂ©tion</abbr> complĂšte. Moins de temps passĂ© Ă  dĂ©boguer.
-* **Facile** : Conçu pour ĂȘtre facile Ă  utiliser et Ă  apprendre. Moins de temps passĂ© Ă  lire la documentation.
-* **Concis** : Diminue la duplication de code. De nombreuses fonctionnalitĂ©s liĂ©es Ă  la dĂ©claration de chaque paramĂštre. Moins de bugs.
-* **Robuste** : Obtenez un code prĂȘt pour la production. Avec une documentation interactive automatique.
-* **BasĂ© sur des normes** : BasĂ© sur (et entiĂšrement compatible avec) les standards ouverts pour les APIs : <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (prĂ©cĂ©demment connu sous le nom de Swagger) et <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
+* **Rapide** : trĂšs hautes performances, au niveau de **NodeJS** et **Go** (grĂące Ă  Starlette et Pydantic). [L'un des frameworks Python les plus rapides](#performance).
+* **Rapide Ă  coder** : augmente la vitesse de dĂ©veloppement des fonctionnalitĂ©s d'environ 200 % Ă  300 %. *
+* **Moins de bugs** : rĂ©duit d'environ 40 % les erreurs induites par le dĂ©veloppeur. *
+* **Intuitif** : excellente compatibilitĂ© avec les Ă©diteurs. <abbr title="Ă©galement appelĂ© autocomplĂ©tion, IntelliSense">AutocomplĂ©tion</abbr> partout. Moins de temps passĂ© Ă  dĂ©boguer.
+* **Facile** : conçu pour ĂȘtre facile Ă  utiliser et Ă  apprendre. Moins de temps passĂ© Ă  lire les documents.
+* **Concis** : diminue la duplication de code. Plusieurs fonctionnalitĂ©s Ă  partir de chaque dĂ©claration de paramĂštre. Moins de bugs.
+* **Robuste** : obtenez un code prĂȘt pour la production. Avec une documentation interactive automatique.
+* **BasĂ© sur des normes** : basĂ© sur (et entiĂšrement compatible avec) les standards ouverts pour les APIs : <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (prĂ©cĂ©demment connu sous le nom de Swagger) et <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
 
 <small>* estimation basĂ©e sur des tests d'une Ă©quipe de dĂ©veloppement interne, construisant des applications de production.</small>
 
-## Sponsors
+## Sponsors { #sponsors }
 
 <!-- sponsors -->
 
-{% if sponsors %}
+### Sponsor clĂ© de voĂ»te { #keystone-sponsor }
+
+{% for sponsor in sponsors.keystone -%}
+<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
+{% endfor -%}
+
+### Sponsors Or et Argent { #gold-and-silver-sponsors }
+
 {% for sponsor in sponsors.gold -%}
 <a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
 {% endfor -%}
 {%- for sponsor in sponsors.silver -%}
 <a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
 {% endfor %}
-{% endif %}
 
 <!-- /sponsors -->
 
-<a href="https://fastapi.tiangolo.com/fastapi-people/#sponsors" class="external-link" target="_blank">Other sponsors</a>
+<a href="https://fastapi.tiangolo.com/fr/fastapi-people/#sponsors" class="external-link" target="_blank">Autres sponsors</a>
 
-## Opinions
+## Opinions { #opinions }
 
-"_[...] J'utilise beaucoup **FastAPI** ces derniers temps. [...] Je prĂ©vois de l'utiliser dans mon Ă©quipe pour tous les **services de ML chez Microsoft**. Certains d'entre eux seront intĂ©grĂ©s dans le coeur de **Windows** et dans certains produits **Office**._"
+« _[...] J'utilise beaucoup **FastAPI** ces derniers temps. [...] Je prĂ©vois de l'utiliser dans mon Ă©quipe pour tous les **services de ML chez Microsoft**. Certains d'entre eux sont intĂ©grĂ©s au cƓur de **Windows** et Ă  certains produits **Office**._ Â»
 
 <div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
 
 ---
 
-"_Nous avons adoptĂ© la bibliothĂšque **FastAPI** pour crĂ©er un serveur **REST** qui peut ĂȘtre interrogĂ© pour obtenir des **prĂ©dictions**. [pour Ludwig]_"
+« _Nous avons adoptĂ© la bibliothĂšque **FastAPI** pour crĂ©er un serveur **REST** qui peut ĂȘtre interrogĂ© pour obtenir des **prĂ©dictions**. [pour Ludwig]_ Â»
 
-<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin et Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
+<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, et Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
 
 ---
 
-"_**Netflix** a le plaisir d'annoncer la sortie en open-source de notre framework d'orchestration de **gestion de crise** : **Dispatch** ! [construit avec **FastAPI**]_"
+« _**Netflix** est heureux d'annoncer la publication en open source de notre framework d'orchestration de **gestion de crise** : **Dispatch** ! [construit avec **FastAPI**]_ Â»
 
 <div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072" target="_blank"><small>(ref)</small></a></div>
 
 ---
 
-"_Je suis trĂšs enthousiaste Ă  propos de **FastAPI**. C'est un bonheur !_"
+« _Je suis plus qu'enthousiaste Ă  propos de **FastAPI**. C'est tellement fun !_ Â»
 
-<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong>Auteur du podcast <a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a></strong> <a href="https://x.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
+<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong>Animateur du podcast <a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a></strong> <a href="https://x.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
 
 ---
 
-"_HonnĂȘtement, ce que vous avez construit a l'air super solide et Ă©lĂ©gant. A bien des Ă©gards, c'est comme Ă§a que je voulais que **Hug** soit - c'est vraiment inspirant de voir quelqu'un construire Ă§a._"
+« _HonnĂȘtement, ce que vous avez construit a l'air super solide et soignĂ©. Ă€ bien des Ă©gards, c'est ce que je voulais que **Hug** soit â€” c'est vraiment inspirant de voir quelqu'un construire Ă§a._ Â»
 
-<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong> CrĂ©ateur de <a href="https://github.com/hugapi/hug" target="_blank">Hug</a></strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
+<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong>CrĂ©ateur de <a href="https://github.com/hugapi/hug" target="_blank">Hug</a></strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
 
 ---
 
-"_Si vous cherchez Ă  apprendre un **framework moderne** pour crĂ©er des APIs REST, regardez **FastAPI** [...] C'est rapide, facile Ă  utiliser et Ă  apprendre [...]_"
+« _Si vous cherchez Ă  apprendre un **framework moderne** pour crĂ©er des APIs REST, regardez **FastAPI** [...] C'est rapide, facile Ă  utiliser et facile Ă  apprendre [...]_ Â»
 
-"_Nous sommes passĂ©s Ă  **FastAPI** pour nos **APIs** [...] Je pense que vous l'aimerez [...]_"
+« _Nous sommes passĂ©s Ă  **FastAPI** pour nos **APIs** [...] Je pense que vous l'aimerez [...]_ Â»
 
 <div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong>Fondateurs de <a href="https://explosion.ai" target="_blank">Explosion AI</a> - CrĂ©ateurs de <a href="https://spacy.io" target="_blank">spaCy</a></strong> <a href="https://x.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
 
 ---
 
-"_Si quelqu'un cherche Ă  construire une API Python de production, je recommande vivement **FastAPI**. Il est **bien conçu**, **simple Ă  utiliser** et **trĂšs Ă©volutif**. Il est devenu un **composant clĂ©** dans notre stratĂ©gie de dĂ©veloppement API first et il est Ă  l'origine de nombreux automatismes et services tels que notre ingĂ©nieur virtuel TAC._"
+« _Si quelqu'un cherche Ă  construire une API Python de production, je recommande vivement **FastAPI**. Il est **magnifiquement conçu**, **simple Ă  utiliser** et **hautement scalable**. Il est devenu un **composant clĂ©** de notre stratĂ©gie de dĂ©veloppement API-first et alimente de nombreuses automatisations et services tels que notre ingĂ©nieur TAC virtuel._ Â»
 
 <div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/" target="_blank"><small>(ref)</small></a></div>
 
 ---
 
-## **Typer**, le FastAPI des <abbr title="Command Line Interface">CLI</abbr>
+## Mini documentaire FastAPI { #fastapi-mini-documentary }
+
+Un <a href="https://www.youtube.com/watch?v=mpR8ngthqiE" class="external-link" target="_blank">mini documentaire FastAPI</a> est sorti fin 2025, vous pouvez le regarder en ligne :
+
+<a href="https://www.youtube.com/watch?v=mpR8ngthqiE" target="_blank"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
+
+## **Typer**, le FastAPI des CLIs { #typer-the-fastapi-of-clis }
 
 <a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
 
-Si vous souhaitez construire une application <abbr title="Command Line Interface">CLI</abbr> utilisable dans un terminal au lieu d'une API web, regardez <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
+Si vous construisez une application <abbr title="Command Line Interface - Interface en ligne de commande">CLI</abbr> Ă  utiliser dans un terminal au lieu d'une API web, regardez <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
 
-**Typer** est le petit frĂšre de FastAPI. Et il est destinĂ© Ă  ĂȘtre le **FastAPI des <abbr title="Command Line Interface">CLI</abbr>**. âŒšïž đŸš€
+**Typer** est le petit frĂšre de FastAPI. Et il est destinĂ© Ă  ĂȘtre le **FastAPI des CLIs**. âŒšïž đŸš€
 
-## PrĂ©requis
+## PrĂ©requis { #requirements }
 
 FastAPI repose sur les Ă©paules de gĂ©ants :
 
 * <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> pour les parties web.
 * <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> pour les parties donnĂ©es.
 
-## Installation
-
-<div class="termy">
-
-```console
-$ pip install fastapi
+## Installation { #installation }
 
----> 100%
-```
-
-</div>
-
-Vous aurez Ă©galement besoin d'un serveur ASGI pour la production tel que <a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a> ou <a href="https://github.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
+CrĂ©ez et activez un <a href="https://fastapi.tiangolo.com/fr/virtual-environments/" class="external-link" target="_blank">environnement virtuel</a> puis installez FastAPI :
 
 <div class="termy">
 
 ```console
-$ pip install "uvicorn[standard]"
+$ pip install "fastapi[standard]"
 
 ---> 100%
 ```
 
 </div>
 
-## Exemple
+**Remarque** : Vous devez vous assurer de mettre Â« fastapi[standard] Â» entre guillemets pour garantir que cela fonctionne dans tous les terminaux.
 
-### CrĂ©ez
+## Exemple { #example }
 
-* CrĂ©ez un fichier `main.py` avec :
+### CrĂ©er { #create-it }
 
-```Python
-from typing import Union
+CrĂ©ez un fichier `main.py` avec :
 
+```Python
 from fastapi import FastAPI
 
 app = FastAPI()
@@ -170,18 +172,16 @@ def read_root():
 
 
 @app.get("/items/{item_id}")
-def read_item(item_id: int, q: Union[str, None] = None):
+def read_item(item_id: int, q: str | None = None):
     return {"item_id": item_id, "q": q}
 ```
 
 <details markdown="1">
-<summary>Ou utilisez <code>async def</code> ...</summary>
+<summary>Ou utilisez <code>async def</code>...</summary>
 
 Si votre code utilise `async` / `await`, utilisez `async def` :
 
-```Python hl_lines="9  14"
-from typing import Union
-
+```Python hl_lines="7  12"
 from fastapi import FastAPI
 
 app = FastAPI()
@@ -193,28 +193,41 @@ async def read_root():
 
 
 @app.get("/items/{item_id}")
-async def read_item(item_id: int, q: Union[str, None] = None):
+async def read_item(item_id: int, q: str | None = None):
     return {"item_id": item_id, "q": q}
 ```
 
-**Note**
+**Remarque** :
 
-Si vous n'ĂȘtes pas familier avec cette notion, consultez la section _"Vous ĂȘtes pressĂ©s ?"_ Ă  propos de <a href="https://fastapi.tiangolo.com/fr/async/#vous-etes-presses" target="_blank">`async` et `await` dans la documentation</a>.
+Si vous ne savez pas, consultez la section Â« Vous ĂȘtes pressĂ©s ? Â» Ă  propos de <a href="https://fastapi.tiangolo.com/fr/async/#in-a-hurry" target="_blank">`async` et `await` dans la documentation</a>.
 
 </details>
 
-### Lancez
+### Lancer { #run-it }
 
 Lancez le serveur avec :
 
 <div class="termy">
 
 ```console
-$ uvicorn main:app --reload
-
+$ fastapi dev main.py
+
+ â•­â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ FastAPI CLI - Development mode â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â•ź
+ â”‚                                                     â”‚
+ â”‚  Serving at: http://127.0.0.1:8000                  â”‚
+ â”‚                                                     â”‚
+ â”‚  API docs: http://127.0.0.1:8000/docs               â”‚
+ â”‚                                                     â”‚
+ â”‚  Running in development mode, for production use:   â”‚
+ â”‚                                                     â”‚
+ â”‚  fastapi run                                        â”‚
+ â”‚                                                     â”‚
+ â•°â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â•Ż
+
+INFO:     Will watch for changes in these directories: ['/home/user/code/awesomeapp']
 INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
-INFO:     Started reloader process [28720]
-INFO:     Started server process [28722]
+INFO:     Started reloader process [2248755] using WatchFiles
+INFO:     Started server process [2248757]
 INFO:     Waiting for application startup.
 INFO:     Application startup complete.
 ```
@@ -222,34 +235,34 @@ INFO:     Application startup complete.
 </div>
 
 <details markdown="1">
-<summary>À propos de la commande <code>uvicorn main:app --reload</code> ...</summary>
+<summary>À propos de la commande <code>fastapi dev main.py</code>...</summary>
 
-La commande `uvicorn main:app` fait rĂ©fĂ©rence Ă  :
+La commande `fastapi dev` lit votre fichier `main.py`, dĂ©tecte l'application **FastAPI** qu'il contient et lance un serveur avec <a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a>.
 
-* `main` : le fichier `main.py` (le "module" Python).
-* `app` : l'objet créé Ă  l'intĂ©rieur de `main.py` avec la ligne `app = FastAPI()`.
-* `--reload` : fait redĂ©marrer le serveur aprĂšs des changements de code. Ă€ n'utiliser que pour le dĂ©veloppement.
+Par dĂ©faut, `fastapi dev` dĂ©marre avec le rechargement automatique activĂ© pour le dĂ©veloppement local.
+
+Vous pouvez en savoir plus dans la <a href="https://fastapi.tiangolo.com/fr/fastapi-cli/" target="_blank">documentation de la CLI FastAPI</a>.
 
 </details>
 
-### VĂ©rifiez
+### VĂ©rifier { #check-it }
 
 Ouvrez votre navigateur Ă  l'adresse <a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a>.
 
-Vous obtenez alors cette rĂ©ponse <abbr title="JavaScript Object Notation">JSON</abbr> :
+Vous verrez la rĂ©ponse JSON :
 
 ```JSON
 {"item_id": 5, "q": "somequery"}
 ```
 
-Vous venez de crĂ©er une API qui :
+Vous avez dĂ©jĂ  créé une API qui :
 
-* Reçoit les requĂȘtes HTTP pour les _chemins_ `/` et `/items/{item_id}`.
-* Les deux _chemins_ acceptent des <em>opĂ©rations</em> `GET` (Ă©galement connu sous le nom de _mĂ©thodes_ HTTP).
-* Le _chemin_ `/items/{item_id}` a un  _<abbr title="en anglais : path parameter">paramĂštre</abbr>_ `item_id` qui doit ĂȘtre un `int`.
-* Le _chemin_ `/items/{item_id}` a un _<abbr title="en anglais : query param">paramĂštre de requĂȘte</abbr>_ optionnel `q` de type `str`.
+* Reçoit des requĂȘtes HTTP sur les _chemins_ `/` et `/items/{item_id}`.
+* Les deux _chemins_ acceptent des <em>opĂ©rations</em> `GET` (Ă©galement connues sous le nom de _mĂ©thodes_ HTTP).
+* Le _chemin_ `/items/{item_id}` a un _paramĂštre de chemin_ `item_id` qui doit ĂȘtre un `int`.
+* Le _chemin_ `/items/{item_id}` a un _paramĂštre de requĂȘte_ optionnel `q` de type `str`.
 
-### Documentation API interactive
+### Documentation API interactive { #interactive-api-docs }
 
 Maintenant, rendez-vous sur <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
 
@@ -257,23 +270,21 @@ Vous verrez la documentation interactive automatique de l'API (fournie par <a hr
 
 ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
 
-### Documentation API alternative
+### Documentation API alternative { #alternative-api-docs }
 
 Et maintenant, rendez-vous sur <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
 
-Vous verrez la documentation interactive automatique de l'API (fournie par <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>) :
+Vous verrez la documentation alternative automatique (fournie par <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>) :
 
 ![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
 
-## Exemple plus poussĂ©
-
-Maintenant, modifiez le fichier `main.py` pour recevoir <abbr title="en anglais : body">le corps</abbr> d'une requĂȘte `PUT`.
+## Mettre Ă  niveau l'exemple { #example-upgrade }
 
-DĂ©clarez ce corps en utilisant les types Python standards, grĂące Ă  Pydantic.
+Modifiez maintenant le fichier `main.py` pour recevoir un corps depuis une requĂȘte `PUT`.
 
-```Python hl_lines="4  9-12  25-27"
-from typing import Union
+DĂ©clarez le corps en utilisant les types Python standard, grĂące Ă  Pydantic.
 
+```Python hl_lines="2  7-10 23-25"
 from fastapi import FastAPI
 from pydantic import BaseModel
 
@@ -283,7 +294,7 @@ app = FastAPI()
 class Item(BaseModel):
     name: str
     price: float
-    is_offer: Union[bool, None] = None
+    is_offer: bool | None = None
 
 
 @app.get("/")
@@ -292,7 +303,7 @@ def read_root():
 
 
 @app.get("/items/{item_id}")
-def read_item(item_id: int, q: Union[str, None] = None):
+def read_item(item_id: int, q: str | None = None):
     return {"item_id": item_id, "q": q}
 
 
@@ -301,35 +312,35 @@ def update_item(item_id: int, item: Item):
     return {"item_name": item.name, "item_id": item_id}
 ```
 
-Le serveur se recharge normalement automatiquement (car vous avez pensĂ© Ă  `--reload` dans la commande `uvicorn` ci-dessus).
+Le serveur `fastapi dev` devrait se recharger automatiquement.
 
-### Plus loin avec la documentation API interactive
+### Mettre Ă  niveau la documentation API interactive { #interactive-api-docs-upgrade }
 
 Maintenant, rendez-vous sur <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
 
-* La documentation interactive de l'API sera automatiquement mise Ă  jour, y compris le nouveau corps de la requĂȘte :
+* La documentation interactive de l'API sera automatiquement mise Ă  jour, y compris le nouveau corps :
 
 ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)
 
-* Cliquez sur le bouton "Try it out", il vous permet de renseigner les paramĂštres et d'interagir directement avec l'API :
+* Cliquez sur le bouton Â« Try it out Â», il vous permet de renseigner les paramĂštres et d'interagir directement avec l'API :
 
 ![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png)
 
-* Cliquez ensuite sur le bouton "Execute", l'interface utilisateur communiquera avec votre API, enverra les paramĂštres, obtiendra les rĂ©sultats et les affichera Ă  l'Ă©cran :
+* Cliquez ensuite sur le bouton Â« Execute Â», l'interface utilisateur communiquera avec votre API, enverra les paramĂštres, obtiendra les rĂ©sultats et les affichera Ă  l'Ă©cran :
 
 ![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png)
 
-### Plus loin avec la documentation API alternative
+### Mettre Ă  niveau la documentation API alternative { #alternative-api-docs-upgrade }
 
 Et maintenant, rendez-vous sur <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
 
-* La documentation alternative reflétera Ă©galement le nouveau paramĂštre de requĂȘte et le nouveau corps :
+* La documentation alternative reflÚtera Ă©galement le nouveau paramĂštre de requĂȘte et le nouveau corps :
 
 ![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png)
 
-### En rĂ©sumĂ©
+### En rĂ©sumĂ© { #recap }
 
-En rĂ©sumĂ©, vous dĂ©clarez **une fois** les types de paramĂštres, <abbr title="en anglais : body">le corps</abbr>  de la requĂȘte, etc. en tant que paramĂštres de fonction.
+En rĂ©sumĂ©, vous dĂ©clarez **une fois** les types de paramĂštres, le corps, etc. en tant que paramĂštres de fonction.
 
 Vous faites cela avec les types Python standard modernes.
 
@@ -337,7 +348,7 @@ Vous n'avez pas Ă  apprendre une nouvelle syntaxe, les mĂ©thodes ou les classes
 
 Juste du **Python** standard.
 
-Par exemple, pour un `int`:
+Par exemple, pour un `int` :
 
 ```Python
 item_id: int
@@ -351,54 +362,54 @@ item: Item
 
 ... et avec cette dĂ©claration unique, vous obtenez :
 
-* Une assistance dans votre IDE, notamment :
-    * lcomplĂ©tion.
+* Une assistance dans l'Ă©diteur, notamment :
+    * l'autocomplĂ©tion.
     * la vĂ©rification des types.
 * La validation des donnĂ©es :
     * des erreurs automatiques et claires lorsque les donnĂ©es ne sont pas valides.
-    * une validation mĂȘme pour les objets <abbr title="JavaScript Object Notation">JSON</abbr> profondĂ©ment imbriquĂ©s.
-* <abbr title="aussi connu sous le nom de : serialization, parsing, marshalling">Une conversion</abbr> des donnĂ©es d'entrĂ©e : venant du rĂ©seau et allant vers les donnĂ©es et types de Python, permettant de lire :
-    * le <abbr title="JavaScript Object Notation">JSON</abbr>.
-    * <abbr title="en anglais : path parameters">les paramĂštres du chemin</abbr>.
-    * <abbr title="en anglais : query parameters">les paramĂštres de la requĂȘte</abbr>.
-    * les cookies.
-    * <abbr title="en anglais : headers">les en-tĂȘtes</abbr>.
-    * <abbr title="en anglais : forms">les formulaires</abbr>.
-    * <abbr title="en anglais : files">les fichiers</abbr>.
-* <abbr title="aussi connu sous le nom de : serialization, parsing, marshalling">La conversion</abbr> des donnĂ©es de sortie : conversion des donnĂ©es et types Python en donnĂ©es rĂ©seau (au format <abbr title="JavaScript Object Notation">JSON</abbr>), permettant de convertir :
-    * les types Python (`str`, `int`, `float`, `bool`, `list`, etc).
-    * les objets `datetime`.
-    * les objets `UUID`.
-    * les modĂšles de base de donnĂ©es.
-    * ... et beaucoup plus.
-* La documentation API interactive automatique, avec 2 interfaces utilisateur au choix :
+    * une validation mĂȘme pour les objets JSON profondĂ©ment imbriquĂ©s.
+* <abbr title="aussi connu sous le nom de : serialization, parsing, marshalling">Conversion</abbr> des donnĂ©es d'entrĂ©e : venant du rĂ©seau vers les donnĂ©es et types Python. Lecture depuis :
+    * JSON.
+    * ParamĂštres de chemin.
+    * ParamĂštres de requĂȘte.
+    * Cookies.
+    * En-tĂȘtes.
+    * Formulaires.
+    * Fichiers.
+* <abbr title="aussi connu sous le nom de : serialization, parsing, marshalling">Conversion</abbr> des donnĂ©es de sortie : conversion des donnĂ©es et types Python en donnĂ©es rĂ©seau (au format JSON) :
+    * Conversion des types Python (`str`, `int`, `float`, `bool`, `list`, etc).
+    * Objets `datetime`.
+    * Objets `UUID`.
+    * ModĂšles de base de donnĂ©es.
+    * ... et bien plus.
+* Documentation API interactive automatique, avec 2 interfaces utilisateur au choix :
     * Swagger UI.
     * ReDoc.
 
 ---
 
-Pour revenir Ă  l'exemple de code prĂ©cĂ©dent, **FastAPI** permet de :
+Pour revenir Ă  l'exemple de code prĂ©cĂ©dent, **FastAPI** va :
 
-* Valider que `item_id` existe dans le chemin des requĂȘtes `GET` et `PUT`.
+* Valider la prĂ©sence d'un `item_id` dans le chemin pour les requĂȘtes `GET` et `PUT`.
 * Valider que `item_id` est de type `int` pour les requĂȘtes `GET` et `PUT`.
-    * Si ce n'est pas le cas, le client voit une erreur utile et claire.
-* VĂ©rifier qu'il existe un paramĂštre de requĂȘte facultatif nommĂ© `q` (comme dans `http://127.0.0.1:8000/items/foo?q=somequery`) pour les requĂȘtes `GET`.
-    * Puisque le paramĂštre `q` est dĂ©clarĂ© avec `= None`, il est facultatif.
-    * Sans le `None`, il serait nĂ©cessaire (comme l'est <abbr title="en anglais : body">le corps</abbr> de la requĂȘte dans le cas du `PUT`).
-* Pour les requĂȘtes `PUT` vers `/items/{item_id}`, de lire <abbr title="en anglais : body">le corps</abbr>  en <abbr title="JavaScript Object Notation">JSON</abbr> :
-    * VĂ©rifier qu'il a un attribut obligatoire `name` qui devrait ĂȘtre un `str`.
-    * VĂ©rifier qu'il a un attribut obligatoire `prix` qui doit ĂȘtre un `float`.
-    * VĂ©rifier qu'il a un attribut facultatif `is_offer`, qui devrait ĂȘtre un `bool`, s'il est prĂ©sent.
-    * Tout cela fonctionnerait Ă©galement pour les objets <abbr title="JavaScript Object Notation">JSON</abbr> profondĂ©ment imbriquĂ©s.
-* Convertir de et vers <abbr title="JavaScript Object Notation">JSON</abbr> automatiquement.
-* Documenter tout avec OpenAPI, qui peut ĂȘtre utilisĂ© par :
-    * Les systĂšmes de documentation interactifs.
-    * Les systĂšmes de gĂ©nĂ©ration automatique de code client, pour de nombreuses langues.
+    * Si ce n'est pas le cas, le client verra une erreur utile et claire.
+* VĂ©rifier s'il existe un paramĂštre de requĂȘte optionnel nommĂ© `q` (comme dans `http://127.0.0.1:8000/items/foo?q=somequery`) pour les requĂȘtes `GET`.
+    * Comme le paramĂštre `q` est dĂ©clarĂ© avec `= None`, il est optionnel.
+    * Sans le `None`, il serait requis (comme l'est le corps dans le cas de `PUT`).
+* Pour les requĂȘtes `PUT` vers `/items/{item_id}`, lire le corps au format JSON :
+    * VĂ©rifier qu'il a un attribut obligatoire `name` qui doit ĂȘtre un `str`.
+    * VĂ©rifier qu'il a un attribut obligatoire `price` qui doit ĂȘtre un `float`.
+    * VĂ©rifier qu'il a un attribut optionnel `is_offer`, qui doit ĂȘtre un `bool`, s'il est prĂ©sent.
+    * Tout cela fonctionne Ă©galement pour les objets JSON profondĂ©ment imbriquĂ©s.
+* Convertir automatiquement depuis et vers JSON.
+* Tout documenter avec OpenAPI, qui peut ĂȘtre utilisĂ© par :
+    * des systĂšmes de documentation interactive.
+    * des systĂšmes de gĂ©nĂ©ration automatique de clients, pour de nombreux langages.
 * Fournir directement 2 interfaces web de documentation interactive.
 
 ---
 
-Nous n'avons fait qu'effleurer la surface, mais vous avez dĂ©jĂ  une idĂ©e de la façon dont tout cela fonctionne.
+Nous n'avons fait qu'effleurer la surface, mais vous avez dĂ©jĂ  une idĂ©e de la façon dont tout fonctionne.
 
 Essayez de changer la ligne contenant :
 
@@ -412,61 +423,137 @@ Essayez de changer la ligne contenant :
         ... "item_name": item.name ...
 ```
 
-... vers :
+... Ă  :
 
 ```Python
         ... "item_price": item.price ...
 ```
 
-... et voyez comment votre ĂƒÂ©diteur complétera automatiquement les attributs et connaßtra leurs types :
+... et voyez comment votre ĂƒÂ©diteur complÚte automatiquement les attributs et connaßt leurs types :
 
-![compatibilitĂ© IDE](https://fastapi.tiangolo.com/img/vscode-completion.png)
+![compatibilitĂ© Ă©diteur](https://fastapi.tiangolo.com/img/vscode-completion.png)
 
 Pour un exemple plus complet comprenant plus de fonctionnalitĂ©s, voir le <a href="https://fastapi.tiangolo.com/fr/tutorial/">Tutoriel - Guide utilisateur</a>.
 
-**Spoiler alert** : le tutoriel - guide utilisateur inclut :
+**Alerte spoiler** : le tutoriel - guide utilisateur inclut :
 
-* DĂ©claration de **paramĂštres** provenant d'autres endroits diffĂ©rents comme : **<abbr title="en anglais : headers">en-tĂȘtes</abbr>.**, **cookies**, **champs de formulaire** et **fichiers**.
-* L'utilisation de **contraintes de validation** comme `maximum_length` ou `regex`.
-* Un **<abbr title="aussi connu sous le nom de composants, ressources, fournisseurs, services, injectables">systĂšme d'injection de dĂ©pendance </abbr>** trĂšs puissant et facile Ă  utiliser .
-* SĂ©curitĂ© et authentification, y compris la prise en charge de **OAuth2** avec les **<abbr title="en anglais : JWT tokens">jetons <abbr title="JSON Web Tokens">JWT</abbr></abbr>** et l'authentification **HTTP Basic**.
-* Des techniques plus avancĂ©es (mais tout aussi faciles) pour dĂ©clarer les **modĂšles <abbr title="JavaScript Object Notation">JSON</abbr> profondĂ©ment imbriquĂ©s** (grĂące Ă  Pydantic).
-* IntĂ©gration de **GraphQL** avec <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> et d'autres bibliothĂšques.
-* D'obtenir de nombreuses fonctionnalitĂ©s supplĂ©mentaires (grĂące Ă   Starlette) comme :
+* DĂ©claration de **paramĂštres** provenant d'autres emplacements comme : **en-tĂȘtes**, **cookies**, **champs de formulaire** et **fichiers**.
+* Comment dĂ©finir des **contraintes de validation** comme `maximum_length` ou `regex`.
+* Un systĂšme **<abbr title="aussi connu sous le nom de composants, ressources, fournisseurs, services, injectables">d'injection de dĂ©pendances</abbr>** trĂšs puissant et facile Ă  utiliser.
+* SĂ©curitĂ© et authentification, y compris la prise en charge de **OAuth2** avec des **JWT tokens** et l'authentification **HTTP Basic**.
+* Des techniques plus avancĂ©es (mais tout aussi faciles) pour dĂ©clarer des **modĂšles JSON profondĂ©ment imbriquĂ©s** (grĂące Ă  Pydantic).
+* IntĂ©gration **GraphQL** avec <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> et d'autres bibliothĂšques.
+* De nombreuses fonctionnalitĂ©s supplĂ©mentaires (grĂące Ă  Starlette) comme :
     * **WebSockets**
-    * de tester le code trĂšs facilement avec `requests` et `pytest`
-    * **<abbr title="Cross-Origin Resource Sharing">CORS</abbr>**
+    * des tests extrĂȘmement faciles basĂ©s sur HTTPX et `pytest`
+    * **CORS**
     * **Cookie Sessions**
     * ... et plus encore.
 
-## Performance
+### DĂ©ployer votre application (optionnel) { #deploy-your-app-optional }
 
-Les benchmarks TechEmpower indĂ©pendants montrent que les applications **FastAPI** s'exĂ©cutant sous Uvicorn sont <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank"> parmi les frameworks existants en Python les plus rapides </a>, juste derriĂšre Starlette et Uvicorn (utilisĂ©s en interne par FastAPI). (*)
+Vous pouvez, si vous le souhaitez, dĂ©ployer votre application FastAPI sur <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>, allez vous inscrire sur la liste d'attente si ce n'est pas dĂ©jĂ  fait. đŸš€
+
+Si vous avez dĂ©jĂ  un compte **FastAPI Cloud** (nous vous avons invitĂ© depuis la liste d'attente đŸ˜‰), vous pouvez dĂ©ployer votre application avec une seule commande.
+
+Avant de dĂ©ployer, assurez-vous d'ĂȘtre connectĂ© :
+
+<div class="termy">
+
+```console
+$ fastapi login
+
+You are logged in to FastAPI Cloud đŸš€
+```
+
+</div>
+
+Puis dĂ©ployez votre application :
+
+<div class="termy">
+
+```console
+$ fastapi deploy
+
+Deploying to FastAPI Cloud...
+
+✅ Deployment successful!
+
+🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
+```
+
+</div>
+
+C'est tout ! Vous pouvez maintenant accĂ©der Ă  votre application Ă  cette URL. âœš
+
+#### Ă€ propos de FastAPI Cloud { #about-fastapi-cloud }
+
+**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** est construit par le mĂȘme auteur et la mĂȘme Ă©quipe derriĂšre **FastAPI**.
+
+Il simplifie le processus de **construction**, de **dĂ©ploiement** et **d'accĂšs** Ă  une API avec un effort minimal.
+
+Il apporte la mĂȘme **expĂ©rience dĂ©veloppeur** de la crĂ©ation d'applications avec FastAPI au **dĂ©ploiement** dans le cloud. đŸŽ‰
+
+FastAPI Cloud est le principal sponsor et financeur des projets open source *FastAPI and friends*. âœš
+
+#### DĂ©ployer sur d'autres fournisseurs cloud { #deploy-to-other-cloud-providers }
+
+FastAPI est open source et basĂ© sur des standards. Vous pouvez dĂ©ployer des applications FastAPI sur n'importe quel fournisseur cloud de votre choix.
+
+Suivez les guides de votre fournisseur cloud pour y dĂ©ployer des applications FastAPI. đŸ€“
+
+## Performance { #performance }
+
+Les benchmarks TechEmpower indĂ©pendants montrent que les applications **FastAPI** s'exĂ©cutant sous Uvicorn sont <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">parmi les frameworks Python les plus rapides</a>, juste derriĂšre Starlette et Uvicorn eux-mĂȘmes (utilisĂ©s en interne par FastAPI). (*)
 
 Pour en savoir plus, consultez la section <a href="https://fastapi.tiangolo.com/fr/benchmarks/" class="internal-link" target="_blank">Benchmarks</a>.
 
-## DĂ©pendances facultatives
+## DĂ©pendances { #dependencies }
+
+FastAPI dĂ©pend de Pydantic et Starlette.
+
+### DĂ©pendances `standard` { #standard-dependencies }
 
-UtilisĂ©es par Pydantic:
+Lorsque vous installez FastAPI avec `pip install "fastapi[standard]"`, il inclut le groupe `standard` de dĂ©pendances optionnelles :
 
-* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email-validator</code></a> - pour la validation des adresses email.
+UtilisĂ©es par Pydantic :
+
+* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email-validator</code></a> - pour la validation des adresses e-mail.
 
 UtilisĂ©es par Starlette :
 
-* <a href="https://requests.readthedocs.io" target="_blank"><code>requests</code></a> - Obligatoire si vous souhaitez utiliser `TestClient`.
+* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - Obligatoire si vous souhaitez utiliser le `TestClient`.
 * <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Obligatoire si vous souhaitez utiliser la configuration de template par dĂ©faut.
-* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - Obligatoire si vous souhaitez supporter le <abbr title="convertit la chaine de caractĂšre d'une requĂȘte HTTP en donnĂ©e Python">"dĂ©codage"</abbr> de formulaire avec `request.form()`.
-* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Obligatoire pour la prise en charge de `SessionMiddleware`.
-* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Obligatoire pour le support `SchemaGenerator` de Starlette (vous n'en avez probablement pas besoin avec FastAPI).
+* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - Obligatoire si vous souhaitez prendre en charge l’<abbr title="convertir la chaĂźne issue d'une requĂȘte HTTP en donnĂ©es Python">« parsing Â»</abbr> de formulaires avec `request.form()`.
 
-UtilisĂ©es par FastAPI / Starlette :
+UtilisĂ©es par FastAPI :
 
-* <a href="https://www.uvicorn.dev" target="_blank"><code>uvicorn</code></a> - Pour le serveur qui charge et sert votre application.
-* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Obligatoire si vous voulez utiliser `ORJSONResponse`.
-* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Obligatoire si vous souhaitez utiliser `UJSONResponse`.
+* <a href="https://www.uvicorn.dev" target="_blank"><code>uvicorn</code></a> - pour le serveur qui charge et sert votre application. Cela inclut `uvicorn[standard]`, qui comprend certaines dĂ©pendances (par ex. `uvloop`) nĂ©cessaires pour une haute performance.
+* `fastapi-cli[standard]` - pour fournir la commande `fastapi`.
+    * Cela inclut `fastapi-cloud-cli`, qui vous permet de dĂ©ployer votre application FastAPI sur <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>.
+
+### Sans les dĂ©pendances `standard` { #without-standard-dependencies }
+
+Si vous ne souhaitez pas inclure les dĂ©pendances optionnelles `standard`, vous pouvez installer avec `pip install fastapi` au lieu de `pip install "fastapi[standard]"`.
 
-Vous pouvez tout installer avec `pip install fastapi[all]`.
+### Sans `fastapi-cloud-cli` { #without-fastapi-cloud-cli }
+
+Si vous souhaitez installer FastAPI avec les dĂ©pendances standard mais sans `fastapi-cloud-cli`, vous pouvez installer avec `pip install "fastapi[standard-no-fastapi-cloud-cli]"`.
+
+### DĂ©pendances optionnelles supplĂ©mentaires { #additional-optional-dependencies }
+
+Il existe des dĂ©pendances supplĂ©mentaires que vous pourriez vouloir installer.
+
+DĂ©pendances optionnelles supplĂ©mentaires pour Pydantic :
+
+* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> - pour la gestion des paramĂštres.
+* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> - pour des types supplĂ©mentaires Ă  utiliser avec Pydantic.
+
+DĂ©pendances optionnelles supplĂ©mentaires pour FastAPI :
+
+* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Obligatoire si vous souhaitez utiliser `ORJSONResponse`.
+* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Obligatoire si vous souhaitez utiliser `UJSONResponse`.
 
-## Licence
+## Licence { #license }
 
 Ce projet est soumis aux termes de la licence MIT.
index 46fc095dcec3f8cbc11b48e553791cd4d3cc8c29..5526877038853291502eaa4a354f2d739210fe4e 100644 (file)
@@ -1,5 +1,5 @@
-# Apprendre
+# Apprendre { #learn }
 
 Voici les sections introductives et les tutoriels pour apprendre **FastAPI**.
 
-Vous pouvez considĂ©rer ceci comme un **manuel**, un **cours**, la **mĂ©thode officielle** et recommandĂ©e pour apprĂ©hender FastAPI. đŸ˜Ž
+Vous pouvez considĂ©rer ceci comme un **livre**, un **cours**, la **mĂ©thode officielle** et recommandĂ©e pour apprendre FastAPI. đŸ˜Ž
index 4c04dc167d7bbb2b4c0619885dae65bece15f785..f062ffecf5158f71c39e8b356026c5af1eefa984 100644 (file)
@@ -1,84 +1,28 @@
-# GĂ©nĂ©ration de projets - ModĂšle
-
-Vous pouvez utiliser un gĂ©nĂ©rateur de projet pour commencer, qui rĂ©alisera pour vous la mise en place de bases cĂŽtĂ© architecture globale, sĂ©curitĂ©, base de donnĂ©es et premiĂšres routes d'API.
-
-Un gĂ©nĂ©rateur de projet fera toujours une mise en place trĂšs subjective que vous devriez modifier et adapter suivant vos besoins, mais cela reste un bon point de dĂ©part pour vos projets.
-
-## Full Stack FastAPI PostgreSQL
-
-GitHub : <a href="https://github.com/tiangolo/full-stack-fastapi-postgresql" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-fastapi-postgresql</a>
-
-### Full Stack FastAPI PostgreSQL - FonctionnalitĂ©s
-
-* IntĂ©gration **Docker** complĂšte (basĂ©e sur Docker).
-* DĂ©ploiement Docker en mode <a href="https://docs.docker.com/engine/swarm/" class="external-link" target="_blank">Swarm</a>
-* IntĂ©gration **Docker Compose** et optimisation pour dĂ©veloppement local.
-* Serveur web Python **prĂȘt au dĂ©ploiement** utilisant Uvicorn et Gunicorn.
-* Backend Python <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">**FastAPI**</a> :
-    * **Rapide** : TrĂšs hautes performances, comparables Ă  **NodeJS** ou **Go** (grĂące Ă  Starlette et Pydantic).
-    * **Intuitif** : Excellent support des Ă©diteurs. <abbr title="aussi appelĂ©e auto-complĂ©tion, autocomplĂ©tion, IntelliSense...">ComplĂ©tion</abbr> partout. Moins de temps passĂ© Ă  dĂ©boguer.
-    * **Facile** : Fait pour ĂȘtre facile Ă  utiliser et apprendre. Moins de temps passĂ© Ă  lire de la documentation.
-    * **Concis** : Minimise la duplication de code. Plusieurs fonctionnalitĂ©s Ă  chaque dĂ©claration de paramĂštre.
-    * **Robuste** : Obtenez du code prĂȘt pour ĂȘtre utilisĂ© en production. Avec de la documentation automatique interactive.
-    * **BasĂ© sur des normes** : BasĂ© sur (et totalement compatible avec) les normes ouvertes pour les APIs : <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> et <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
-    * <a href="https://fastapi.tiangolo.com/features/" class="external-link" target="_blank">**Et bien d'autres fonctionnalitĂ©s**</a> comme la validation automatique, la sĂ©rialisation, l'authentification avec OAuth2 JWT tokens, etc.
-* Hashage de **mots de passe sĂ©curisĂ©** par dĂ©faut.
-* Authentification par **jetons JWT**.
-* ModĂšles **SQLAlchemy** (indĂ©pendants des extensions Flask, afin qu'ils puissent ĂȘtre utilisĂ©s directement avec des *workers* Celery).
-* ModĂšle de dĂ©marrages basiques pour les utilisateurs (Ă  modifier et supprimer au besoin).
-* Migrations **Alembic**.
-* **CORS** (partage des ressources entre origines multiples, ou *Cross Origin Resource Sharing*).
-* *Worker* **Celery** pouvant importer et utiliser les modĂšles et le code du reste du backend.
-* Tests du backend REST basĂ©s sur **Pytest**, intĂ©grĂ©s dans Docker, pour que vous puissiez tester toutes les interactions de l'API indĂ©pendamment de la base de donnĂ©es. Ă‰tant exĂ©cutĂ©s dans Docker, les tests peuvent utiliser un nouvel entrepĂŽt de donnĂ©es créé de zĂ©ro Ă  chaque fois (vous pouvez donc utiliser ElasticSearch, MongoDB, CouchDB, etc. et juste tester que l'API fonctionne).
-* IntĂ©gration Python facile avec **Jupyter Kernels** pour le dĂ©veloppement Ă  distance ou intra-Docker avec des extensions comme Atom Hydrogen ou Visual Studio Code Jupyter.
-* Frontend **Vue** :
-    * GĂ©nĂ©rĂ© avec Vue CLI.
-    * Gestion de l'**Authentification JWT**.
-    * Page de connexion.
-    * AprĂšs la connexion, page de tableau de bord principal.
-    * Tableau de bord principal avec crĂ©ation et modification d'utilisateurs.
-    * Modification de ses propres caractĂ©ristiques utilisateur.
-    * **Vuex**.
-    * **Vue-router**.
-    * **Vuetify** pour de magnifiques composants *material design*.
-    * **TypeScript**.
-    * Serveur Docker basĂ© sur **Nginx** (configurĂ© pour ĂȘtre facilement manipulĂ© avec Vue-router).
-    * Utilisation de *Docker multi-stage building*, pour ne pas avoir besoin de sauvegarder ou *commit* du code compilĂ©.
-    * Tests frontend exĂ©cutĂ©s Ă  la compilation (pouvant ĂȘtre dĂ©sactivĂ©s).
-    * Fait aussi modulable que possible, pour pouvoir fonctionner comme tel, tout en pouvant ĂȘtre utilisĂ© qu'en partie grĂące Ă  Vue CLI.
-* **PGAdmin** pour les bases de donnĂ©es PostgreSQL, facilement modifiable pour utiliser PHPMYAdmin ou MySQL.
-* **Flower** pour la surveillance de tĂąches Celery.
-* Ă‰quilibrage de charge entre le frontend et le backend avec **Traefik**, afin de pouvoir avoir les deux sur le mĂȘme domaine, sĂ©parĂ©s par chemins, mais servis par diffĂ©rents conteneurs.
-* IntĂ©gration Traefik, comprenant la gĂ©nĂ©ration automatique de certificat **HTTPS** Let's Encrypt.
-* GitLab **CI** (intĂ©gration continue), comprenant des tests pour le frontend et le backend.
-
-## Full Stack FastAPI Couchbase
-
-GitHub : <a href="https://github.com/tiangolo/full-stack-fastapi-couchbase" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-fastapi-couchbase</a>
-
-⚠ **ATTENTION** âš ïž
-
-Si vous dĂ©marrez un nouveau projet de zĂ©ro, allez voir les alternatives au dĂ©but de cette page.
-
-Par exemple, le gĂ©nĂ©rateur de projet <a href="https://github.com/tiangolo/full-stack-fastapi-postgresql" class="external-link" target="_blank">Full Stack FastAPI PostgreSQL</a>  peut ĂȘtre une meilleure alternative, Ă©tant activement maintenu et utilisĂ© et comprenant toutes les nouvelles fonctionnalitĂ©s et amĂ©liorations.
-
-Vous ĂȘtes toujours libre d'utiliser le gĂ©nĂ©rateur basĂ© sur Couchbase si vous le voulez, cela devrait probablement fonctionner correctement, et si vous avez dĂ©jĂ  un projet gĂ©nĂ©rĂ© en utilisant ce dernier, cela devrait fonctionner aussi (et vous l'avez dĂ©jĂ  probablement mis Ă  jour suivant vos besoins).
-
-Vous pouvez en apprendre plus dans la documentation du dĂ©pĂŽt GithHub.
-
-## Full Stack FastAPI MongoDB
-
-...viendra surement plus tard, suivant le temps que j'ai.  đŸ˜… đŸŽ‰
-
-## ModĂšles d'apprentissage automatique avec spaCy et FastAPI
-
-GitHub : <a href="https://github.com/microsoft/cookiecutter-spacy-fastapi" class="external-link" target="_blank">https://github.com/microsoft/cookiecutter-spacy-fastapi</a>
-
-## ModĂšles d'apprentissage automatique avec spaCy et FastAPI - FonctionnalitĂ©s
-
-* IntĂ©gration d'un modĂšle NER **spaCy**.
-* Formatage de requĂȘte pour **Azure Cognitive Search**.
-* Serveur Python web **prĂȘt Ă  utiliser en production** utilisant Uvicorn et Gunicorn.
-* DĂ©ploiement CI/CD Kubernetes pour **Azure DevOps** (AKS).
-* **Multilangues**. Choisissez facilement l'une des langues intĂ©grĂ©es Ă  spaCy durant la mise en place du projet.
-* **Facilement gĂ©nĂ©ralisable** Ă  d'autres bibliothĂšques similaires (Pytorch, Tensorflow), et non juste spaCy.
+# ModĂšle Full Stack FastAPI { #full-stack-fastapi-template }
+
+Les modĂšles, bien qu'ils soient gĂ©nĂ©ralement livrĂ©s avec une configuration spĂ©cifique, sont conçus pour ĂȘtre flexibles et personnalisables. Cela vous permet de les modifier et de les adapter aux exigences de votre projet, ce qui en fait un excellent point de dĂ©part. đŸ
+
+Vous pouvez utiliser ce modĂšle pour dĂ©marrer, car il inclut une grande partie de la configuration initiale, la sĂ©curitĂ©, la base de donnĂ©es et quelques endpoints d'API dĂ©jĂ  prĂȘts pour vous.
+
+DĂ©pĂŽt GitHub : <a href="https://github.com/tiangolo/full-stack-fastapi-template" class="external-link" target="_blank">ModĂšle Full Stack FastAPI</a>
+
+## ModĂšle Full Stack FastAPI - Pile technologique et fonctionnalitĂ©s { #full-stack-fastapi-template-technology-stack-and-features }
+
+- âšĄ [**FastAPI**](https://fastapi.tiangolo.com/fr) pour l'API backend Python.
+  - đŸ§° [SQLModel](https://sqlmodel.tiangolo.com) pour les interactions avec la base de donnĂ©es SQL en Python (ORM).
+  - đŸ” [Pydantic](https://docs.pydantic.dev), utilisĂ© par FastAPI, pour la validation des donnĂ©es et la gestion des paramĂštres.
+  - đŸ’Ÿ [PostgreSQL](https://www.postgresql.org) comme base de donnĂ©es SQL.
+- đŸš€ [React](https://react.dev) pour le frontend.
+  - đŸ’ƒ Utilisation de TypeScript, des hooks, de Vite et d'autres Ă©lĂ©ments d'un stack frontend moderne.
+  - đŸŽš [Tailwind CSS](https://tailwindcss.com) et [shadcn/ui](https://ui.shadcn.com) pour les composants frontend.
+  - đŸ€– Un client frontend gĂ©nĂ©rĂ© automatiquement.
+  - đŸ§Ș [Playwright](https://playwright.dev) pour les tests de bout en bout.
+  - đŸŠ‡ Prise en charge du mode sombre.
+- đŸ‹ [Docker Compose](https://www.docker.com) pour le dĂ©veloppement et la production.
+- đŸ”’ Hachage sĂ©curisĂ© des mots de passe par dĂ©faut.
+- đŸ”‘ Authentification JWT (JSON Web Token).
+- đŸ“« RĂ©cupĂ©ration de mot de passe par e-mail.
+- âœ… Tests avec [Pytest](https://pytest.org).
+- đŸ“ž [Traefik](https://traefik.io) comme proxy inverse / rĂ©partiteur de charge.
+- đŸšą Instructions de dĂ©ploiement avec Docker Compose, y compris la configuration d'un proxy Traefik frontal pour gĂ©rer les certificats HTTPS automatiques.
+- đŸ­ CI (intĂ©gration continue) et CD (dĂ©ploiement continu) basĂ©s sur GitHub Actions.
index 99ca9082772111e60c78ba940059dc5d74d3e30d..f393b0f5c1663a4dea7ee1847843a913f969acf7 100644 (file)
@@ -1,70 +1,68 @@
-# Introduction aux Types Python
+# Introduction aux types Python { #python-types-intro }
 
-Python supporte des annotations de type (ou *type hints*) optionnelles.
+Python prend en charge des Â« type hints Â» (aussi appelĂ©es Â« annotations de type Â») facultatives.
 
-Ces annotations de type constituent une syntaxe spĂ©ciale qui permet de dĂ©clarer le <abbr title="par exemple : str, int, float, bool">type</abbr> d'une variable.
+Ces Â« type hints Â» ou annotations sont une syntaxe spĂ©ciale qui permet de dĂ©clarer le <abbr title="par exemple : str, int, float, bool">type</abbr> d'une variable.
 
-En dĂ©clarant les types de vos variables, cela permet aux diffĂ©rents outils comme les Ă©diteurs de texte d'offrir un meilleur support.
+En dĂ©clarant les types de vos variables, les Ă©diteurs et outils peuvent vous offrir un meilleur support.
 
-Ce chapitre n'est qu'un **tutoriel rapide / rappel** sur les annotations de type Python.
-Seulement le minimum nĂ©cessaire pour les utiliser avec **FastAPI** sera couvert... ce qui est en rĂ©alitĂ© trĂšs peu.
+Ceci est un **tutoriel rapide / rappel** Ă  propos des annotations de type Python. Il couvre uniquement le minimum nĂ©cessaire pour les utiliser avec **FastAPI** ... ce qui est en rĂ©alitĂ© trĂšs peu.
 
-**FastAPI** est totalement basĂ© sur ces annotations de type, qui lui donnent de nombreux avantages.
+**FastAPI** est totalement basĂ© sur ces annotations de type, elles lui donnent de nombreux avantages et bĂ©nĂ©fices.
 
-Mais mĂȘme si vous n'utilisez pas ou n'utiliserez jamais **FastAPI**, vous pourriez bĂ©nĂ©ficier d'apprendre quelques choses sur ces derniĂšres.
+Mais mĂȘme si vous n'utilisez jamais **FastAPI**, vous auriez intĂ©rĂȘt Ă  en apprendre un peu Ă  leur sujet.
 
-/// note
+/// note | Remarque
 
-Si vous ĂȘtes un expert Python, et que vous savez dĂ©jĂ  **tout** sur les annotations de type, passez au chapitre suivant.
+Si vous ĂȘtes un expert Python, et que vous savez dĂ©jĂ  tout sur les annotations de type, passez au chapitre suivant.
 
 ///
 
-## Motivations
+## Motivation { #motivation }
 
-Prenons un exemple simple :
+Commençons par un exemple simple :
 
-{*../../docs_src/python_types/tutorial001.py*}
+{* ../../docs_src/python_types/tutorial001_py39.py *}
 
-ExĂ©cuter ce programe affiche :
+ExĂ©cuter ce programme affiche :
 
 ```
 John Doe
 ```
 
-La fonction :
+La fonction fait ce qui suit :
 
 * Prend un `first_name` et un `last_name`.
-* Convertit la premiĂšre lettre de chaque paramĂštre en majuscules grĂące Ă  `title()`.
-* ConcatĂšne les rĂ©sultats avec un espace entre les deux.
+* Convertit la premiĂšre lettre de chacun en majuscule avec `title()`.
+* <abbr title="Les met ensemble, en un seul. Avec le contenu de l'un aprĂšs l'autre.">ConcatĂšne</abbr> ces deux valeurs avec un espace au milieu.
 
-{*../../docs_src/python_types/tutorial001.py hl[2] *}
+{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
 
-### Limitations
+### Modifier le code { #edit-it }
 
 C'est un programme trĂšs simple.
 
 Mais maintenant imaginez que vous l'Ă©criviez de zĂ©ro.
 
-À un certain point vous auriez commencĂ© la dĂ©finition de la fonction, vous aviez les paramĂštres prĂȘts.
+À un certain moment, vous auriez commencĂ© la dĂ©finition de la fonction, vous aviez les paramĂštres prĂȘts ...
 
-Mais vous aviez besoin de "cette mĂ©thode qui convertit la premiĂšre lettre en majuscule".
+Mais ensuite vous devez appeler Â« cette mĂ©thode qui convertit la premiĂšre lettre en majuscule Â».
 
-Était-ce `upper` ? `uppercase` ? `first_uppercase` ? `capitalize` ?
+Était-ce `upper` ? Ă‰tait-ce `uppercase` ? `first_uppercase` ? `capitalize` ?
 
-Vous essayez donc d'utiliser le vieil ami du programmeur, l'auto-complĂ©tion de l'Ă©diteur.
+Vous essayez alors avec l'ami de toujours des programmeurs, l'autocomplĂ©tion de l'Ă©diteur.
 
-Vous Ă©crivez le premier paramĂštre, `first_name`, puis un point (`.`) et appuyez sur `Ctrl+Espace` pour dĂ©clencher l'auto-complĂ©tion.
+Vous tapez le premier paramĂštre de la fonction, `first_name`, puis un point (`.`) et appuyez sur `Ctrl+Espace` pour dĂ©clencher l'autocomplĂ©tion.
 
-Mais malheureusement, rien d'utile n'en rĂ©sulte :
+Mais, malheureusement, vous n'obtenez rien d'utile :
 
 <img src="/img/python-types/image01.png">
 
-### Ajouter des types
+### Ajouter des types { #add-types }
 
 Modifions une seule ligne de la version prĂ©cĂ©dente.
 
-Nous allons changer seulement cet extrait, les paramĂštres de la fonction, de :
-
+Nous allons changer exactement ce fragment, les paramĂštres de la fonction, de :
 
 ```Python
     first_name, last_name
@@ -78,222 +76,389 @@ Nous allons changer seulement cet extrait, les paramĂštres de la fonction, de :
 
 C'est tout.
 
-Ce sont des annotations de types :
+Ce sont les Â« annotations de type Â» :
 
-{*../../docs_src/python_types/tutorial002.py hl[1] *}
+{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *}
 
-À ne pas confondre avec la dĂ©claration de valeurs par dĂ©faut comme ici :
+Ce n'est pas la mĂȘme chose que de dĂ©clarer des valeurs par dĂ©faut, ce qui serait :
 
 ```Python
     first_name="john", last_name="doe"
 ```
 
-C'est une chose diffĂ©rente.
+C'est diffĂ©rent.
 
-On utilise un deux-points (`:`), et pas un Ă©gal (`=`).
+Nous utilisons des deux-points (`:`), pas des signes Ă©gal (`=`).
 
-Et ajouter des annotations de types ne crĂ©e normalement pas de diffĂ©rence avec le comportement qui aurait eu lieu si elles n'Ă©taient pas lĂ .
+Et ajouter des annotations de type ne change normalement pas ce qui se passe par rapport Ă  ce qui se passerait sans elles.
 
-Maintenant, imaginez que vous ĂȘtes en train de crĂ©er cette fonction, mais avec des annotations de type cette fois.
+Mais maintenant, imaginez que vous ĂȘtes Ă  nouveau en train de crĂ©er cette fonction, mais avec des annotations de type.
 
-Au mĂȘme moment que durant l'exemple prĂ©cĂ©dent, vous essayez de dĂ©clencher l'auto-complĂ©tion et vous voyez :
+Au mĂȘme moment, vous essayez de dĂ©clencher l'autocomplĂ©tion avec `Ctrl+Espace` et vous voyez :
 
 <img src="/img/python-types/image02.png">
 
-Vous pouvez donc dĂ©rouler les options jusqu'Ă  trouver la mĂ©thode Ă  laquelle vous pensiez.
+Avec cela, vous pouvez faire dĂ©filer en voyant les options, jusqu'Ă  trouver celle qui Â« vous dit quelque chose Â» :
 
 <img src="/img/python-types/image03.png">
 
-## Plus de motivations
+## Plus de motivation { #more-motivation }
 
-Cette fonction possĂšde dĂ©jĂ  des annotations de type :
+Regardez cette fonction, elle a dĂ©jĂ  des annotations de type :
 
-{*../../docs_src/python_types/tutorial003.py hl[1] *}
+{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *}
 
-Comme l'Ă©diteur connaĂźt le type des variables, vous n'avez pas seulement l'auto-complĂ©tion, mais aussi de la dĂ©tection d'erreurs :
+Comme l'Ă©diteur connaĂźt les types des variables, vous n'obtenez pas seulement l'autocomplĂ©tion, vous obtenez aussi des vĂ©rifications d'erreurs :
 
 <img src="/img/python-types/image04.png">
 
-Maintenant que vous avez connaissance du problĂšme, convertissez `age` en <abbr title="string">chaĂźne de caractĂšres</abbr> grĂące Ă  `str(age)` :
+Vous savez maintenant qu'il faut corriger, convertir `age` en chaĂźne avec `str(age)` :
 
-{*../../docs_src/python_types/tutorial004.py hl[2] *}
+{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
 
-## DĂ©clarer des types
+## DĂ©clarer des types { #declaring-types }
 
-Vous venez de voir lĂ  oĂč les types sont gĂ©nĂ©ralement dĂ©clarĂ©s : dans les paramĂštres de fonctions.
+Vous venez de voir l'endroit principal pour dĂ©clarer des annotations de type : dans les paramĂštres des fonctions.
 
-C'est aussi ici que vous les utiliseriez avec **FastAPI**.
+C'est aussi l'endroit principal oĂč vous les utiliserez avec **FastAPI**.
 
-### Types simples
+### Types simples { #simple-types }
 
-Vous pouvez dĂ©clarer tous les types  de Python, pas seulement `str`.
+Vous pouvez dĂ©clarer tous les types standards de Python, pas seulement `str`.
 
-Comme par exemple :
+Vous pouvez utiliser, par exemple :
 
 * `int`
 * `float`
 * `bool`
 * `bytes`
 
-{*../../docs_src/python_types/tutorial005.py hl[1] *}
+{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
 
-### Types gĂ©nĂ©riques avec des paramĂštres de types
+### Types gĂ©nĂ©riques avec paramĂštres de type { #generic-types-with-type-parameters }
 
-Il existe certaines structures de donnĂ©es qui contiennent d'autres valeurs, comme `dict`, `list`, `set` et `tuple`. Et les valeurs internes peuvent elles aussi avoir leurs propres types.
+Il existe certaines structures de donnĂ©es qui peuvent contenir d'autres valeurs, comme `dict`, `list`, `set` et `tuple`. Et les valeurs internes peuvent aussi avoir leur propre type.
 
-Pour dĂ©clarer ces types et les types internes, on utilise le module standard de Python `typing`.
+Ces types qui ont des types internes sont appelĂ©s types Â« gĂ©nĂ©riques Â». Et il est possible de les dĂ©clarer, mĂȘme avec leurs types internes.
 
-Il existe spĂ©cialement pour supporter ces annotations de types.
+Pour dĂ©clarer ces types et les types internes, vous pouvez utiliser le module standard Python `typing`. Il existe spĂ©cifiquement pour prendre en charge ces annotations de type.
 
-#### `List`
+#### Versions plus rĂ©centes de Python { #newer-versions-of-python }
 
-Par exemple, dĂ©finissons une variable comme `list` de `str`.
+La syntaxe utilisant `typing` est compatible avec toutes les versions, de Python 3.6 aux plus rĂ©centes, y compris Python 3.9, Python 3.10, etc.
 
-Importez `List` (avec un `L` majuscule) depuis `typing`.
+Au fur et Ă  mesure que Python Ă©volue, les versions plus rĂ©centes apportent un meilleur support pour ces annotations de type et dans de nombreux cas vous n'aurez mĂȘme pas besoin d'importer et d'utiliser le module `typing` pour les dĂ©clarer.
 
-{*../../docs_src/python_types/tutorial006.py hl[1] *}
+Si vous pouvez choisir une version plus rĂ©cente de Python pour votre projet, vous pourrez profiter de cette simplicitĂ© supplĂ©mentaire.
 
-DĂ©clarez la variable, en utilisant la syntaxe des deux-points (`:`).
+Dans toute la documentation, il y a des exemples compatibles avec chaque version de Python (lorsqu'il y a une diffĂ©rence).
 
-Et comme type, mettez `List`.
+Par exemple Â« Python 3.6+ Â» signifie que c'est compatible avec Python 3.6 ou supĂ©rieur (y compris 3.7, 3.8, 3.9, 3.10, etc.). Et Â« Python 3.9+ Â» signifie que c'est compatible avec Python 3.9 ou supĂ©rieur (y compris 3.10, etc).
 
-Les listes Ă©tant un type contenant des types internes, mettez ces derniers entre crochets (`[`, `]`) :
+Si vous pouvez utiliser les derniĂšres versions de Python, utilisez les exemples pour la derniĂšre version, ils auront la meilleure et la plus simple syntaxe, par exemple, Â« Python 3.10+ Â».
 
-{*../../docs_src/python_types/tutorial006.py hl[4] *}
+#### Liste { #list }
 
-/// tip | Astuce
+Par exemple, dĂ©finissons une variable comme une `list` de `str`.
+
+DĂ©clarez la variable, en utilisant la mĂȘme syntaxe avec deux-points (`:`).
+
+Comme type, mettez `list`.
+
+Comme la liste est un type qui contient des types internes, mettez-les entre crochets :
+
+{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *}
 
-Ces types internes entre crochets sont appelĂ©s des "paramĂštres de type".
+/// info
+
+Ces types internes entre crochets sont appelĂ©s Â« paramĂštres de type Â».
 
-Ici, `str` est un paramĂštre de type passĂ© Ă  `List`.
+Dans ce cas, `str` est le paramĂštre de type passĂ© Ă  `list`.
 
 ///
 
-Ce qui signifie : "la variable `items` est une `list`, et chacun de ses Ă©lĂ©ments a pour type `str`.
+Cela signifie : Â« la variable `items` est une `list`, et chacun des Ă©lĂ©ments de cette liste est un `str` Â».
 
-En faisant cela, votre Ă©diteur pourra vous aider, mĂȘme pendant que vous traitez des Ă©lĂ©ments de la liste.
+En faisant cela, votre Ă©diteur peut vous fournir de l'aide mĂȘme pendant le traitement des Ă©lĂ©ments de la liste :
 
 <img src="/img/python-types/image05.png">
 
 Sans types, c'est presque impossible Ă  rĂ©aliser.
 
-Vous remarquerez que la variable `item` n'est qu'un des Ă©lĂ©ments de la list `items`.
+Remarquez que la variable `item` est l'un des Ă©lĂ©ments de la liste `items`.
 
-Et pourtant, l'Ă©diteur sait qu'elle est de type `str` et pourra donc vous aider Ă  l'utiliser.
+Et pourtant, l'Ă©diteur sait que c'est un `str` et fournit le support appropriĂ©.
 
-#### `Tuple` et `Set`
+#### Tuple et Set { #tuple-and-set }
 
-C'est le mĂȘme fonctionnement pour dĂ©clarer un `tuple` ou un `set` :
+Vous feriez la mĂȘme chose pour dĂ©clarer des `tuple` et des `set` :
 
-{*../../docs_src/python_types/tutorial007.py hl[1,4] *}
+{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
 
-Dans cet exemple :
+Cela signifie :
 
-* La variable `items_t` est un `tuple` avec 3 Ă©lĂ©ments, un `int`, un deuxiĂšme `int`, et un `str`.
+* La variable `items_t` est un `tuple` avec 3 Ă©lĂ©ments, un `int`, un autre `int`, et un `str`.
 * La variable `items_s` est un `set`, et chacun de ses Ă©lĂ©ments est de type `bytes`.
 
-#### `Dict`
+#### Dict { #dict }
+
+Pour dĂ©finir un `dict`, vous passez 2 paramĂštres de type, sĂ©parĂ©s par des virgules.
+
+Le premier paramĂštre de type est pour les clĂ©s du `dict`.
+
+Le second paramĂštre de type est pour les valeurs du `dict` :
+
+{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *}
+
+Cela signifie :
+
+* La variable `prices` est un `dict` :
+    * Les clĂ©s de ce `dict` sont de type `str` (disons, le nom de chaque article).
+    * Les valeurs de ce `dict` sont de type `float` (disons, le prix de chaque article).
+
+#### Union { #union }
+
+Vous pouvez dĂ©clarer qu'une variable peut ĂȘtre de plusieurs types, par exemple, un `int` ou un `str`.
+
+Dans Python 3.6 et supĂ©rieur (y compris Python 3.10), vous pouvez utiliser le type `Union` de `typing` et mettre entre crochets les types possibles Ă  accepter.
+
+Dans Python 3.10, il existe aussi une nouvelle syntaxe oĂč vous pouvez mettre les types possibles sĂ©parĂ©s par une <abbr title='aussi appelĂ© Â« opĂ©rateur OU bit Ă  bit Â», mais ce sens n’est pas pertinent ici'>barre verticale (`|`)</abbr>.
+
+//// tab | Python 3.10+
+
+```Python hl_lines="1"
+{!> ../../docs_src/python_types/tutorial008b_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="1  4"
+{!> ../../docs_src/python_types/tutorial008b_py39.py!}
+```
+
+////
+
+Dans les deux cas, cela signifie que `item` peut ĂȘtre un `int` ou un `str`.
+
+#### Possiblement `None` { #possibly-none }
+
+Vous pouvez dĂ©clarer qu'une valeur peut avoir un type, comme `str`, mais qu'elle peut aussi ĂȘtre `None`.
+
+Dans Python 3.6 et supĂ©rieur (y compris Python 3.10), vous pouvez le dĂ©clarer en important et en utilisant `Optional` depuis le module `typing`.
+
+```Python hl_lines="1  4"
+{!../../docs_src/python_types/tutorial009_py39.py!}
+```
+
+Utiliser `Optional[str]` au lieu de simplement `str` permettra Ă  l'Ă©diteur de vous aider Ă  dĂ©tecter des erreurs oĂč vous supposeriez qu'une valeur est toujours un `str`, alors qu'elle pourrait en fait aussi ĂȘtre `None`.
+
+`Optional[Something]` est en rĂ©alitĂ© un raccourci pour `Union[Something, None]`, ils sont Ă©quivalents.
+
+Cela signifie aussi que dans Python 3.10, vous pouvez utiliser `Something | None` :
+
+//// tab | Python 3.10+
+
+```Python hl_lines="1"
+{!> ../../docs_src/python_types/tutorial009_py310.py!}
+```
+
+////
+
+//// tab | Python 3.9+
+
+```Python hl_lines="1  4"
+{!> ../../docs_src/python_types/tutorial009_py39.py!}
+```
+
+////
+
+//// tab | Python 3.9+ alternative
+
+```Python hl_lines="1  4"
+{!> ../../docs_src/python_types/tutorial009b_py39.py!}
+```
+
+////
+
+#### Utiliser `Union` ou `Optional` { #using-union-or-optional }
+
+Si vous utilisez une version de Python infĂ©rieure Ă  3.10, voici un conseil de mon point de vue trĂšs **subjectif** :
+
+* đŸšš Ă‰vitez d'utiliser `Optional[SomeType]`
+* Ă€ la place âœš **utilisez `Union[SomeType, None]`** âœš.
+
+Les deux sont Ă©quivalents et sous le capot ce sont les mĂȘmes, mais je recommanderais `Union` plutĂŽt que `Optional` parce que le mot Â« facultatif Â» semble impliquer que la valeur est optionnelle, alors que cela signifie en fait Â« elle peut ĂȘtre `None` Â», mĂȘme si elle n'est pas facultative et est toujours requise.
+
+Je pense que `Union[SomeType, None]` est plus explicite sur ce que cela signifie.
 
-Pour dĂ©finir un `dict`, il faut lui passer 2 paramĂštres, sĂ©parĂ©s par une virgule (`,`).
+Il ne s'agit que des mots et des noms. Mais ces mots peuvent influencer la maniĂšre dont vous et vos coĂ©quipiers pensez au code.
 
-Le premier paramĂštre de type est pour les clĂ©s et le second pour les valeurs du dictionnaire (`dict`).
+Par exemple, prenons cette fonction :
 
-{*../../docs_src/python_types/tutorial008.py hl[1,4] *}
+{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *}
 
-Dans cet exemple :
+Le paramĂštre `name` est dĂ©fini comme `Optional[str]`, mais il n'est pas facultatif, vous ne pouvez pas appeler la fonction sans le paramĂštre :
 
-* La variable `prices` est de type `dict` :
-    * Les clĂ©s de ce dictionnaire sont de type `str`.
-    * Les valeurs de ce dictionnaire sont de type `float`.
+```Python
+say_hi()  # Oh non, cela lĂšve une erreur ! đŸ˜±
+```
+
+Le paramĂštre `name` est toujours requis (pas Â« optionnel Â») parce qu'il n'a pas de valeur par dĂ©faut. NĂ©anmoins, `name` accepte `None` comme valeur :
+
+```Python
+say_hi(name=None)  # Cela fonctionne, None est valide đŸŽ‰
+```
 
-#### `Optional`
+La bonne nouvelle est que, dĂšs que vous ĂȘtes sur Python 3.10, vous n'avez plus Ă  vous en soucier, car vous pourrez simplement utiliser `|` pour dĂ©finir des unions de types :
 
-Vous pouvez aussi utiliser `Optional` pour dĂ©clarer qu'une variable a un type, comme `str` mais qu'il est "optionnel" signifiant qu'il pourrait aussi ĂȘtre `None`.
+{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *}
 
-{*../../docs_src/python_types/tutorial009.py hl[1,4] *}
+Et alors vous n'aurez plus Ă  vous soucier de noms comme `Optional` et `Union`. đŸ˜Ž
 
-Utiliser `Optional[str]` plutĂŽt que `str` permettra Ă  l'Ă©diteur de vous aider Ă  dĂ©tecter les erreurs oĂč vous supposeriez qu'une valeur est toujours de type `str`, alors qu'elle pourrait aussi ĂȘtre `None`.
+#### Types gĂ©nĂ©riques { #generic-types }
 
-#### Types gĂ©nĂ©riques
+Ces types qui prennent des paramĂštres de type entre crochets sont appelĂ©s des **types gĂ©nĂ©riques** ou **Generics**, par exemple :
 
-Les types qui peuvent contenir des paramĂštres de types entre crochets, comme :
+//// tab | Python 3.10+
 
-* `List`
-* `Tuple`
-* `Set`
-* `Dict`
+Vous pouvez utiliser les mĂȘmes types intĂ©grĂ©s comme gĂ©nĂ©riques (avec des crochets et des types Ă  l'intĂ©rieur) :
+
+* `list`
+* `tuple`
+* `set`
+* `dict`
+
+Et, comme avec les versions prĂ©cĂ©dentes de Python, depuis le module `typing` :
+
+* `Union`
 * `Optional`
-* ...et d'autres.
+* ... et d'autres.
 
-sont appelĂ©s des **types gĂ©nĂ©riques** ou **Generics**.
+Dans Python 3.10, comme alternative Ă  l'utilisation des gĂ©nĂ©riques `Union` et `Optional`, vous pouvez utiliser la <abbr title='aussi appelĂ© Â« opĂ©rateur OU bit Ă  bit Â», mais ce sens n’est pas pertinent ici'>barre verticale (`|`)</abbr> pour dĂ©clarer des unions de types, c'est bien mieux et plus simple.
 
-### Classes en tant que types
+////
 
-Vous pouvez aussi dĂ©clarer une classe comme type d'une variable.
+//// tab | Python 3.9+
+
+Vous pouvez utiliser les mĂȘmes types intĂ©grĂ©s comme gĂ©nĂ©riques (avec des crochets et des types Ă  l'intĂ©rieur) :
+
+* `list`
+* `tuple`
+* `set`
+* `dict`
+
+Et des gĂ©nĂ©riques depuis le module `typing` :
+
+* `Union`
+* `Optional`
+* ... et d'autres.
+
+////
+
+### Classes en tant que types { #classes-as-types }
 
-Disons que vous avez une classe `Person`, avec une variable `name` :
+Vous pouvez aussi dĂ©clarer une classe comme type d'une variable.
 
-{*../../docs_src/python_types/tutorial010.py hl[1:3] *}
+Disons que vous avez une classe `Person`, avec un nom :
 
+{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
 
 Vous pouvez ensuite dĂ©clarer une variable de type `Person` :
 
-{*../../docs_src/python_types/tutorial010.py hl[6] *}
+{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
 
-Et vous aurez accĂšs, encore une fois, au support complet offert par l'Ă©diteur :
+Et lĂ  encore, vous obtenez tout le support de l'Ă©diteur :
 
 <img src="/img/python-types/image06.png">
 
-## Les modĂšles Pydantic
+Remarquez que cela signifie Â« `one_person` est une instance de la classe `Person` Â».
+
+Cela ne signifie pas Â« `one_person` est la classe appelĂ©e `Person` Â».
+
+## ModĂšles Pydantic { #pydantic-models }
 
 <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> est une bibliothĂšque Python pour effectuer de la validation de donnĂ©es.
 
-Vous dĂ©clarez la forme de la donnĂ©e avec des classes et des attributs.
+Vous dĂ©clarez la Â« forme Â» de la donnĂ©e sous forme de classes avec des attributs.
 
-Chaque attribut possĂšde un type.
+Et chaque attribut a un type.
 
-Puis vous crĂ©ez une instance de cette classe avec certaines valeurs et **Pydantic** validera les valeurs, les convertira dans le type adĂ©quat (si c'est nĂ©cessaire et possible) et vous donnera un objet avec toute la donnĂ©e.
+Ensuite, vous crĂ©ez une instance de cette classe avec certaines valeurs et elle validera les valeurs, les convertira dans le type appropriĂ© (le cas Ă©chĂ©ant) et vous donnera un objet avec toutes les donnĂ©es.
 
-Ainsi, votre Ă©diteur vous offrira un support adaptĂ© pour l'objet rĂ©sultant.
+Et vous obtenez tout le support de l'Ă©diteur avec cet objet rĂ©sultant.
 
-Extrait de la documentation officielle de **Pydantic** :
+Un exemple tirĂ© de la documentation officielle de Pydantic :
 
-{*../../docs_src/python_types/tutorial011.py*}
+{* ../../docs_src/python_types/tutorial011_py310.py *}
 
 /// info
 
-Pour en savoir plus Ă  propos de <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic, allez jeter un coup d'oeil Ă  sa documentation</a>.
+Pour en savoir plus Ă  propos de <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic, consultez sa documentation</a>.
+
+///
+
+**FastAPI** est entiĂšrement basĂ© sur Pydantic.
+
+Vous verrez beaucoup plus de tout cela en pratique dans le [Tutoriel - Guide utilisateur](tutorial/index.md){.internal-link target=_blank}.
+
+/// tip | Astuce
+
+Pydantic a un comportement spĂ©cial lorsque vous utilisez `Optional` ou `Union[Something, None]` sans valeur par dĂ©faut, vous pouvez en lire davantage dans la documentation de Pydantic Ă  propos des <a href="https://docs.pydantic.dev/2.3/usage/models/#required-fields" class="external-link" target="_blank">champs Optionals requis</a>.
 
 ///
 
-**FastAPI** est basĂ© entiĂšrement sur **Pydantic**.
+## Annotations de type avec mĂ©tadonnĂ©es { #type-hints-with-metadata-annotations }
+
+Python dispose Ă©galement d'une fonctionnalitĂ© qui permet de mettre des **<abbr title="DonnĂ©es sur les donnĂ©es, dans ce cas, des informations sur le type, p. ex. une description.">mĂ©tadonnĂ©es</abbr> supplĂ©mentaires** dans ces annotations de type en utilisant `Annotated`.
+
+Depuis Python 3.9, `Annotated` fait partie de la bibliothĂšque standard, vous pouvez donc l'importer depuis `typing`.
 
-Vous verrez bien plus d'exemples de son utilisation dans [Tutoriel - Guide utilisateur](tutorial/index.md){.internal-link target=_blank}.
+{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *}
+
+Python lui-mĂȘme ne fait rien avec ce `Annotated`. Et pour les Ă©diteurs et autres outils, le type est toujours `str`.
+
+Mais vous pouvez utiliser cet espace dans `Annotated` pour fournir Ă  **FastAPI** des mĂ©tadonnĂ©es supplĂ©mentaires sur la façon dont vous voulez que votre application se comporte.
+
+L'important Ă  retenir est que le premier paramĂštre de type que vous passez Ă  `Annotated` est le type rĂ©el. Le reste n'est que des mĂ©tadonnĂ©es pour d'autres outils.
+
+Pour l'instant, vous avez juste besoin de savoir que `Annotated` existe, et que c'est du Python standard. đŸ˜Ž
+
+Plus tard, vous verrez Ă  quel point cela peut ĂȘtre puissant.
+
+/// tip | Astuce
+
+Le fait que ce soit du Python standard signifie que vous bĂ©nĂ©ficierez toujours de la meilleure expĂ©rience dĂ©veloppeur possible dans votre Ă©diteur, avec les outils que vous utilisez pour analyser et refactoriser votre code, etc. âœš
+
+Et aussi que votre code sera trĂšs compatible avec de nombreux autres outils et bibliothĂšques Python. đŸš€
+
+///
 
-## Les annotations de type dans **FastAPI**
+## Annotations de type dans **FastAPI** { #type-hints-in-fastapi }
 
-**FastAPI** utilise ces annotations pour faire diffĂ©rentes choses.
+**FastAPI** tire parti de ces annotations de type pour faire plusieurs choses.
 
-Avec **FastAPI**, vous dĂ©clarez des paramĂštres grĂące aux annotations de types et vous obtenez :
+Avec **FastAPI**, vous dĂ©clarez des paramĂštres avec des annotations de type et vous obtenez :
 
-* **du support de l'Ă©diteur**
-* **de la vĂ©rification de types**
+* **Du support de l'Ă©diteur**.
+* **Des vĂ©rifications de types**.
 
-...et **FastAPI** utilise ces mĂȘmes dĂ©clarations pour :
+... et **FastAPI** utilise les mĂȘmes dĂ©clarations pour :
 
-* **DĂ©finir les prĂ©requis** : depuis les paramĂštres de chemins des requĂȘtes, les entĂȘtes, les corps, les dĂ©pendances, etc.
-* **Convertir des donnĂ©es** : depuis la requĂȘte vers les types requis.
-* **Valider des donnĂ©es** : venant de chaque requĂȘte :
-    * GĂ©nĂ©rant automatiquement des **erreurs** renvoyĂ©es au client quand la donnĂ©e est invalide.
+* **DĂ©finir des prĂ©requis** : Ă  partir des paramĂštres de chemin de la requĂȘte, des paramĂštres de requĂȘte, des en-tĂȘtes, des corps, des dĂ©pendances, etc.
+* **Convertir des donnĂ©es** : de la requĂȘte vers le type requis.
+* **Valider des donnĂ©es** : provenant de chaque requĂȘte :
+    * En gĂ©nĂ©rant des **erreurs automatiques** renvoyĂ©es au client lorsque la donnĂ©e est invalide.
 * **Documenter** l'API avec OpenAPI :
-    * ce qui ensuite utilisĂ© par les interfaces utilisateur automatiques de documentation interactive.
+    * ce qui est ensuite utilisĂ© par les interfaces utilisateur de documentation interactive automatiques.
 
-Tout cela peut paraĂźtre bien abstrait, mais ne vous inquiĂ©tez pas, vous verrez tout Ă§a en pratique dans [Tutoriel - Guide utilisateur](tutorial/index.md){.internal-link target=_blank}.
+Tout cela peut sembler abstrait. Ne vous inquiĂ©tez pas. Vous verrez tout cela en action dans le [Tutoriel - Guide utilisateur](tutorial/index.md){.internal-link target=_blank}.
 
-Ce qu'il faut retenir c'est qu'en utilisant les types standard de Python, Ă  un seul endroit (plutĂŽt que d'ajouter plus de classes, de dĂ©corateurs, etc.), **FastAPI** fera une grande partie du travail pour vous.
+L'important est qu'en utilisant les types standards de Python, en un seul endroit (au lieu d'ajouter plus de classes, de dĂ©corateurs, etc.), **FastAPI** fera une grande partie du travail pour vous.
 
 /// info
 
-Si vous avez dĂ©jĂ  lu le tutoriel et ĂȘtes revenus ici pour voir plus sur les types, une bonne ressource est la <a href="https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html" class="external-link" target="_blank">"cheat sheet" de `mypy`</a>.
+Si vous avez dĂ©jĂ  parcouru tout le tutoriel et ĂȘtes revenu pour en voir plus sur les types, une bonne ressource est <a href="https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html" class="external-link" target="_blank">l'« aide-mĂ©moire Â» de `mypy`</a>.
 
 ///
index 6efd16e07d4aec8e9d471fc334ef9dcc7f827e75..ed7494669f3581494d294abb106a2d6cc398e93b 100644 (file)
@@ -1,4 +1,4 @@
-# TĂąches d'arriĂšre-plan
+# TĂąches d'arriĂšre-plan { #background-tasks }
 
 Vous pouvez dĂ©finir des tĂąches d'arriĂšre-plan qui seront exĂ©cutĂ©es aprĂšs avoir retournĂ© une rĂ©ponse.
 
@@ -7,20 +7,19 @@ Ceci est utile pour les opĂ©rations qui doivent avoir lieu aprĂšs une requĂȘte,
 Cela comprend, par exemple :
 
 * Les notifications par email envoyĂ©es aprĂšs l'exĂ©cution d'une action :
-    * Ă‰tant donnĂ© que se connecter Ă  un serveur et envoyer un email a tendance Ă  ĂȘtre Â«lent» (plusieurs secondes), vous pouvez retourner la rĂ©ponse directement et envoyer la notification en arriĂšre-plan.
+    * Ă‰tant donnĂ© que se connecter Ă  un serveur et envoyer un email a tendance Ă  ĂȘtre Â« lent Â» (plusieurs secondes), vous pouvez retourner la rĂ©ponse directement et envoyer la notification en arriĂšre-plan.
 * Traiter des donnĂ©es :
-    * Par exemple, si vous recevez un fichier qui doit passer par un traitement lent, vous pouvez retourner une rĂ©ponse Â«Accepted» (HTTP 202) puis faire le traitement en arriĂšre-plan.
+    * Par exemple, si vous recevez un fichier qui doit passer par un traitement lent, vous pouvez retourner une rĂ©ponse Â« Accepted Â» (HTTP 202) puis faire le traitement en arriĂšre-plan.
 
+## Utiliser `BackgroundTasks` { #using-backgroundtasks }
 
-## Utiliser `BackgroundTasks`
+Pour commencer, importez `BackgroundTasks` et dĂ©finissez un paramĂštre dans votre *fonction de chemin d'accĂšs* avec `BackgroundTasks` comme type dĂ©clarĂ©.
 
-Pour commencer, importez `BackgroundTasks` et dĂ©finissez un paramĂštre dans votre *fonction de chemin* avec `BackgroundTasks` comme type dĂ©clarĂ©.
-
-{* ../../docs_src/background_tasks/tutorial001.py hl[1,13] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *}
 
 **FastAPI** crĂ©era l'objet de type `BackgroundTasks` pour vous et le passera comme paramĂštre.
 
-## CrĂ©er une fonction de tĂąche
+## CrĂ©er une fonction de tĂąche { #create-a-task-function }
 
 Une fonction Ă  exĂ©cuter comme tĂąche d'arriĂšre-plan est juste une fonction standard qui peut recevoir des paramĂštres.
 
@@ -30,14 +29,13 @@ Dans cet exemple, la fonction de tĂąche Ă©crira dans un fichier (afin de simuler
 
 L'opĂ©ration d'Ă©criture n'utilisant ni `async` ni `await`, on dĂ©finit la fonction avec un `def` normal.
 
-{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *}
-
-## Ajouter une tĂąche d'arriĂšre-plan
+{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *}
 
-Dans votre *fonction de chemin*, passez votre fonction de tĂąche Ă  l'objet de type `BackgroundTasks` (`background_tasks` ici) grĂące Ă  la mĂ©thode `.add_task()` :
+## Ajouter une tĂąche d'arriĂšre-plan { #add-the-background-task }
 
+Dans votre *fonction de chemin d'accĂšs*, passez votre fonction de tĂąche Ă  l'objet de type `BackgroundTasks` (`background_tasks` ici) grĂące Ă  la mĂ©thode `.add_task()` :
 
-{* ../../docs_src/background_tasks/tutorial001.py hl[14] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *}
 
 `.add_task()` reçoit comme arguments :
 
@@ -45,40 +43,40 @@ Dans votre *fonction de chemin*, passez votre fonction de tĂąche Ă  l'objet de t
 * Les arguments positionnels Ă  passer Ă  la fonction de tĂąche dans l'ordre (`email`).
 * Les arguments nommĂ©s Ă  passer Ă  la fonction de tĂąche (`message="some notification"`).
 
-## Injection de dĂ©pendances
+## Injection de dĂ©pendances { #dependency-injection }
 
-Utiliser `BackgroundTasks` fonctionne aussi avec le systĂšme d'injection de dĂ©pendances. Vous pouvez dĂ©clarer un paramĂštre de type `BackgroundTasks` Ă  diffĂ©rents niveaux : dans une *fonction de chemin*, dans une dĂ©pendance, dans une sous-dĂ©pendance...
+Utiliser `BackgroundTasks` fonctionne aussi avec le systĂšme d'injection de dĂ©pendances. Vous pouvez dĂ©clarer un paramĂštre de type `BackgroundTasks` Ă  diffĂ©rents niveaux : dans une *fonction de chemin d'accĂšs*, dans une dĂ©pendance (dependable), dans une sous-dĂ©pendance, etc.
 
-**FastAPI** sait quoi faire dans chaque cas et comment rĂ©utiliser le mĂȘme objet, afin que tous les paramĂštres de type `BackgroundTasks` soient fusionnĂ©s et que les tĂąches soient exĂ©cutĂ©es en arriĂšre-plan :
+**FastAPI** sait quoi faire dans chaque cas et comment rĂ©utiliser le mĂȘme objet, afin que toutes les tĂąches d'arriĂšre-plan soient fusionnĂ©es et que les tĂąches soient ensuite exĂ©cutĂ©es en arriĂšre-plan :
 
-{* ../../docs_src/background_tasks/tutorial002.py hl[13,15,22,25] *}
+{* ../../docs_src/background_tasks/tutorial002_an_py310.py hl[13,15,22,25] *}
 
 Dans cet exemple, les messages seront Ă©crits dans le fichier `log.txt` aprĂšs que la rĂ©ponse soit envoyĂ©e.
 
-S'il y avait une `query` (paramĂštre nommĂ© `q`) dans la requĂȘte, alors elle sera Ă©crite dans `log.txt` via une tĂąche d'arriĂšre-plan.
+S'il y avait un paramĂštre de requĂȘte dans la requĂȘte, alors il sera Ă©crit dans le journal via une tĂąche d'arriĂšre-plan.
 
-Et ensuite une autre tĂąche d'arriĂšre-plan (gĂ©nĂ©rĂ©e dans les paramĂštres de la *la fonction de chemin*) Ă©crira un message dans `log.txt` comprenant le paramĂštre de chemin `email`.
+Et ensuite une autre tĂąche d'arriĂšre-plan (gĂ©nĂ©rĂ©e dans la *fonction de chemin d'accĂšs*) Ă©crira un message comprenant le paramĂštre de chemin `email`.
 
-## DĂ©tails techniques
+## DĂ©tails techniques { #technical-details }
 
 La classe `BackgroundTasks` provient directement de <a href="https://www.starlette.dev/background/" class="external-link" target="_blank">`starlette.background`</a>.
 
 Elle est importĂ©e/incluse directement dans **FastAPI** pour que vous puissiez l'importer depuis `fastapi` et Ă©viter d'importer accidentellement `BackgroundTask` (sans `s` Ă  la fin) depuis `starlette.background`.
 
-En utilisant seulement `BackgroundTasks` (et non `BackgroundTask`), il est possible de l'utiliser en tant que paramĂštre de *fonction de chemin* et de laisser **FastAPI** gĂ©rer le reste pour vous, comme en utilisant l'objet `Request` directement.
+En utilisant seulement `BackgroundTasks` (et non `BackgroundTask`), il est possible de l'utiliser en tant que paramĂštre de *fonction de chemin d'accĂšs* et de laisser **FastAPI** gĂ©rer le reste pour vous, comme en utilisant l'objet `Request` directement.
 
 Il est tout de mĂȘme possible d'utiliser `BackgroundTask` seul dans **FastAPI**, mais dans ce cas il faut crĂ©er l'objet dans le code et renvoyer une `Response` Starlette l'incluant.
 
-Plus de dĂ©tails sont disponibles dans <a href="https://www.starlette.dev/background/" class="external-link" target="_blank">la documentation officielle de Starlette sur les tĂąches d'arriĂšre-plan</a> (via leurs classes `BackgroundTasks`et `BackgroundTask`).
+Plus de dĂ©tails sont disponibles dans <a href="https://www.starlette.dev/background/" class="external-link" target="_blank">la documentation officielle de Starlette sur les tĂąches d'arriĂšre-plan</a>.
 
-## Avertissement
+## Avertissement { #caveat }
 
 Si vous avez besoin de rĂ©aliser des traitements lourds en tĂąche d'arriĂšre-plan et que vous n'avez pas besoin que ces traitements aient lieu dans le mĂȘme process (par exemple, pas besoin de partager la mĂ©moire, les variables, etc.), il peut s'avĂ©rer profitable d'utiliser des outils plus importants tels que <a href="https://docs.celeryq.dev" class="external-link" target="_blank">Celery</a>.
 
-Ces outils nĂ©cessitent gĂ©nĂ©ralement des configurations plus complexes ainsi qu'un gestionnaire de queue de message, comme RabbitMQ ou Redis, mais ils permettent d'exĂ©cuter des tĂąches d'arriĂšre-plan dans diffĂ©rents process, et potentiellement, sur plusieurs serveurs.
+Ces outils nĂ©cessitent gĂ©nĂ©ralement des configurations plus complexes ainsi qu'un gestionnaire de queue de message, comme RabbitMQ ou Redis, mais ils permettent d'exĂ©cuter des tĂąches d'arriĂšre-plan dans diffĂ©rents process, et surtout, sur plusieurs serveurs.
 
 Mais si vous avez besoin d'accĂ©der aux variables et objets de la mĂȘme application **FastAPI**, ou si vous avez besoin d'effectuer de petites tĂąches d'arriĂšre-plan (comme envoyer des notifications par email), vous pouvez simplement vous contenter d'utiliser `BackgroundTasks`.
 
-## RĂ©sumĂ©
+## RĂ©sumĂ© { #recap }
 
-Importez et utilisez `BackgroundTasks` grĂące aux paramĂštres de *fonction de chemin* et les dĂ©pendances pour ajouter des tĂąches d'arriĂšre-plan.
+Importez et utilisez `BackgroundTasks` grĂące aux paramĂštres de *fonction de chemin d'accĂšs* et les dĂ©pendances pour ajouter des tĂąches d'arriĂšre-plan.
index 0541acc74e37f1febef79b0c477e0992365eeea7..9aed24e98932722c7273fb1cea15ba4548885955 100644 (file)
@@ -1,24 +1,24 @@
-# Body - ParamĂštres multiples
+# Body - ParamĂštres multiples { #body-multiple-parameters }
 
-Maintenant que nous avons vu comment manipuler `Path` et `Query`, voyons comment faire pour le corps d'une requĂȘte, communĂ©ment dĂ©signĂ© par le terme anglais "body".
+Maintenant que nous avons vu comment utiliser `Path` et `Query`, voyons des usages plus avancĂ©s des dĂ©clarations de paramĂštres du corps de la requĂȘte.
 
-## MĂ©langer les paramĂštres `Path`, `Query` et body
+## MĂ©langer les paramĂštres `Path`, `Query` et body { #mix-path-query-and-body-parameters }
 
-Tout d'abord, sachez que vous pouvez mĂ©langer les dĂ©clarations des paramĂštres `Path`, `Query` et body, **FastAPI** saura quoi faire.
+Tout d'abord, sachez que vous pouvez mĂ©langer librement les dĂ©clarations des paramĂštres `Path`, `Query` et du body, **FastAPI** saura quoi faire.
 
-Vous pouvez Ă©galement dĂ©clarer des paramĂštres body comme Ă©tant optionnels, en leur assignant une valeur par dĂ©faut Ă  `None` :
+Et vous pouvez Ă©galement dĂ©clarer des paramĂštres du body comme Ă©tant optionnels, en leur assignant une valeur par dĂ©faut Ă  `None` :
 
 {* ../../docs_src/body_multiple_params/tutorial001_an_py310.py hl[18:20] *}
 
-/// note
+/// note | Remarque
 
-Notez que, dans ce cas, le paramĂštre `item` provenant du `Body` est optionnel (sa valeur par dĂ©faut est `None`).
+Notez que, dans ce cas, l'Ă©lĂ©ment `item` rĂ©cupĂ©rĂ© depuis le body est optionnel. Comme sa valeur par dĂ©faut est `None`.
 
 ///
 
-## ParamĂštres multiples du body
+## ParamĂštres multiples du body { #multiple-body-parameters }
 
-Dans l'exemple prĂ©cĂ©dent, les opĂ©rations de routage attendaient un body JSON avec les attributs d'un `Item`, par exemple :
+Dans l'exemple prĂ©cĂ©dent, les chemins d'accĂšs attendraient un body JSON avec les attributs d'un `Item`, par exemple :
 
 ```JSON
 {
@@ -29,13 +29,13 @@ Dans l'exemple prĂ©cĂ©dent, les opĂ©rations de routage attendaient un body JSON
 }
 ```
 
-Mais vous pouvez Ă©galement dĂ©clarer plusieurs paramĂštres provenant de body, par exemple `item` et `user` simultanĂ©ment :
+Mais vous pouvez Ă©galement dĂ©clarer plusieurs paramĂštres provenant du body, par exemple `item` et `user` :
 
 {* ../../docs_src/body_multiple_params/tutorial002_py310.py hl[20] *}
 
-Dans ce cas, **FastAPI** dĂ©tectera qu'il y a plus d'un paramĂštre dans le body (chacun correspondant Ă  un modĂšle Pydantic).
+Dans ce cas, **FastAPI** dĂ©tectera qu'il y a plus d'un paramĂštre du body dans la fonction (il y a deux paramĂštres qui sont des modĂšles Pydantic).
 
-Il utilisera alors les noms des paramĂštres comme clĂ©s, et s'attendra Ă  recevoir quelque chose de semblable Ă  :
+Il utilisera alors les noms des paramĂštres comme clĂ©s (noms de champs) dans le body, et s'attendra Ă  recevoir un body semblable Ă  :
 
 ```JSON
 {
@@ -52,25 +52,25 @@ Il utilisera alors les noms des paramĂštres comme clĂ©s, et s'attendra Ă  recevo
 }
 ```
 
-/// note
+/// note | Remarque
 
-"Notez que, bien que nous ayons dĂ©clarĂ© le paramĂštre `item` de la mĂȘme maniĂšre que prĂ©cĂ©demment, il est maintenant associĂ© Ă  la clĂ© `item` dans le corps de la requĂȘte."`.
+Notez que, bien que `item` ait Ă©tĂ© dĂ©clarĂ© de la mĂȘme maniĂšre qu'auparavant, il est dĂ©sormais attendu Ă  l'intĂ©rieur du body sous la clĂ© `item`.
 
 ///
 
-**FastAPI** effectue la conversion de la requĂȘte de façon transparente, de sorte que les objets `item` et `user` se trouvent correctement dĂ©finis.
+**FastAPI** effectuera la conversion automatique depuis la requĂȘte, de sorte que le paramĂštre `item` reçoive son contenu spĂ©cifique, et de mĂȘme pour `user`.
 
-Il effectue Ă©galement la validation des donnĂ©es (mĂȘme imbriquĂ©es les unes dans les autres), et permet de les documenter correctement (schĂ©ma OpenAPI et documentation auto-gĂ©nĂ©rĂ©e).
+Il effectuera la validation des donnĂ©es composĂ©es, et les documentera ainsi pour le schĂ©ma OpenAPI et la documentation automatique.
 
-## Valeurs scalaires dans le body
+## Valeurs singuliĂšres dans le body { #singular-values-in-body }
 
-De la mĂȘme façon qu'il existe `Query` et `Path` pour dĂ©finir des donnĂ©es supplĂ©mentaires pour les paramĂštres query et path, **FastAPI** fournit un Ă©quivalent `Body`.
+De la mĂȘme façon qu'il existe `Query` et `Path` pour dĂ©finir des donnĂ©es supplĂ©mentaires pour les paramĂštres de requĂȘte et de chemin, **FastAPI** fournit un Ă©quivalent `Body`.
 
-Par exemple, en Ă©tendant le modĂšle prĂ©cĂ©dent, vous pouvez vouloir ajouter un paramĂštre `importance` dans le mĂȘme body, en plus des paramĂštres `item` et `user`.
+Par exemple, en Ă©tendant le modĂšle prĂ©cĂ©dent, vous pourriez dĂ©cider d'avoir une autre clĂ© `importance` dans le mĂȘme body, en plus de `item` et `user`.
 
-Si vous le dĂ©clarez tel quel, comme c'est une valeur [scalaire](https://docs.github.com/fr/graphql/reference/scalars), **FastAPI** supposera qu'il s'agit d'un paramĂštre de requĂȘte (`Query`).
+Si vous le dĂ©clarez tel quel, comme c'est une valeur singuliĂšre, **FastAPI** supposera qu'il s'agit d'un paramĂštre de requĂȘte.
 
-Mais vous pouvez indiquer Ă  **FastAPI** de la traiter comme une variable de body en utilisant `Body` :
+Mais vous pouvez indiquer Ă  **FastAPI** de la traiter comme une autre clĂ© du body en utilisant `Body` :
 
 {* ../../docs_src/body_multiple_params/tutorial003_an_py310.py hl[23] *}
 
@@ -92,51 +92,51 @@ Dans ce cas, **FastAPI** s'attendra Ă  un body semblable Ă  :
 }
 ```
 
-Encore une fois, cela convertira les types de donnĂ©es, les validera, permettra de gĂ©nĂ©rer la documentation, etc...
+Encore une fois, il convertira les types de donnĂ©es, validera, documentera, etc.
 
-## ParamĂštres multiples body et query
+## ParamĂštres multiples du body et paramĂštres de requĂȘte { #multiple-body-params-and-query }
 
-Bien entendu, vous pouvez dĂ©clarer autant de paramĂštres que vous le souhaitez, en plus des paramĂštres body dĂ©jĂ  dĂ©clarĂ©s.
+Bien entendu, vous pouvez Ă©galement dĂ©clarer des paramĂštres de requĂȘte supplĂ©mentaires quand vous en avez besoin, en plus de tout paramĂštre du body.
 
-Par dĂ©faut, les valeurs [scalaires](https://docs.github.com/fr/graphql/reference/scalars) sont interprĂ©tĂ©es comme des paramĂštres query, donc inutile d'ajouter explicitement `Query`. Vous pouvez juste Ă©crire :
+Comme, par dĂ©faut, les valeurs singuliĂšres sont interprĂ©tĂ©es comme des paramĂštres de requĂȘte, vous n'avez pas besoin d'ajouter explicitement `Query`, vous pouvez simplement Ă©crire :
 
 ```Python
-q: Union[str, None] = None
+q: str | None = None
 ```
 
-Ou bien, en Python 3.10 et supĂ©rieur :
+Ou en Python 3.9 :
 
 ```Python
-q: str | None = None
+q: Union[str, None] = None
 ```
 
 Par exemple :
 
-{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[27] *}
+{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *}
 
 /// info
 
-`Body` possĂšde les mĂȘmes paramĂštres de validation additionnels et de gestion des mĂ©tadonnĂ©es que `Query` et `Path`, ainsi que d'autres que nous verrons plus tard.
+`Body` possĂšde Ă©galement les mĂȘmes paramĂštres supplĂ©mentaires de validation et de mĂ©tadonnĂ©es que `Query`, `Path` et d'autres que vous verrez plus tard.
 
 ///
 
-## Inclure un paramĂštre imbriquĂ© dans le body
+## IntĂ©grer un seul paramĂštre du body { #embed-a-single-body-parameter }
 
-Disons que vous avez seulement un paramĂštre `item` dans le body, correspondant Ă  un modĂšle Pydantic `Item`.
+Supposons que vous n'ayez qu'un seul paramĂštre `item` dans le body, provenant d'un modĂšle Pydantic `Item`.
 
-Par dĂ©faut, **FastAPI** attendra sa dĂ©claration directement dans le body.
+Par dĂ©faut, **FastAPI** attendra alors son contenu directement.
 
-Cependant, si vous souhaitez qu'il interprĂȘte correctement un JSON avec une clĂ© `item` associĂ©e au contenu du modĂšle, comme cela serait le cas si vous dĂ©clariez des paramĂštres body additionnels, vous pouvez utiliser le paramĂštre spĂ©cial `embed` de `Body` :
+Mais si vous voulez qu'il attende un JSON avec une clĂ© `item` contenant le contenu du modĂšle, comme lorsqu'on dĂ©clare des paramĂštres supplĂ©mentaires du body, vous pouvez utiliser le paramĂštre spĂ©cial `embed` de `Body` :
 
 ```Python
 item: Item = Body(embed=True)
 ```
 
-Voici un exemple complet :
+comme dans :
 
 {* ../../docs_src/body_multiple_params/tutorial005_an_py310.py hl[17] *}
 
-Dans ce cas **FastAPI** attendra un body semblable Ă  :
+Dans ce cas **FastAPI** s'attendra Ă  un body semblable Ă  :
 
 ```JSON hl_lines="2"
 {
@@ -160,12 +160,12 @@ au lieu de :
 }
 ```
 
-## Pour rĂ©sumer
+## RĂ©capitulatif { #recap }
 
-Vous pouvez ajouter plusieurs paramĂštres body dans votre fonction de routage, mĂȘme si une requĂȘte ne peut avoir qu'un seul body.
+Vous pouvez ajouter plusieurs paramĂštres du body Ă  votre fonction de chemin d'accĂšs, mĂȘme si une requĂȘte ne peut avoir qu'un seul body.
 
-Cependant, **FastAPI** se chargera de faire opĂ©rer sa magie, afin de toujours fournir Ă  votre fonction des donnĂ©es correctes, les validera et documentera le schĂ©ma associĂ©.
+Mais **FastAPI** s'en chargera, vous fournira les bonnes donnĂ©es dans votre fonction, et validera et documentera le schĂ©ma correct dans le chemin d'accĂšs.
 
-Vous pouvez Ă©galement dĂ©clarer des valeurs [scalaires](https://docs.github.com/fr/graphql/reference/scalars) Ă  recevoir dans le body.
+Vous pouvez Ă©galement dĂ©clarer des valeurs singuliĂšres Ă  recevoir dans le body.
 
-Et vous pouvez indiquer Ă  **FastAPI** d'inclure le body dans une autre variable, mĂȘme lorsqu'un seul paramĂštre est dĂ©clarĂ©.
+Et vous pouvez indiquer Ă  **FastAPI** d'intĂ©grer le body sous une clĂ© mĂȘme lorsqu'un seul paramĂštre est dĂ©clarĂ©.
index 760b6d80ae3d9e6e29d089b21e07a62bc19db5d0..ca115fabc76ad82f737fcb3245d382f4b8750855 100644 (file)
@@ -1,10 +1,10 @@
-# Corps de la requĂȘte
+# Corps de la requĂȘte { #request-body }
 
 Quand vous avez besoin d'envoyer de la donnĂ©e depuis un client (comme un navigateur) vers votre API, vous l'envoyez en tant que **corps de requĂȘte**.
 
 Le corps d'une **requĂȘte** est de la donnĂ©e envoyĂ©e par le client Ă  votre API. Le corps d'une **rĂ©ponse** est la donnĂ©e envoyĂ©e par votre API au client.
 
-Votre API aura presque toujours Ă  envoyer un corps de **rĂ©ponse**. Mais un client n'a pas toujours Ă  envoyer un corps de **requĂȘte**.
+Votre API aura presque toujours Ă  envoyer un corps de **rĂ©ponse**. Mais un client n'a pas toujours Ă  envoyer un **corps de requĂȘte** : parfois il demande seulement un chemin, peut-ĂȘtre avec quelques paramĂštres de requĂȘte, mais n'envoie pas de corps.
 
 Pour dĂ©clarer un corps de **requĂȘte**, on utilise les modĂšles de <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> en profitant de tous leurs avantages et fonctionnalitĂ©s.
 
@@ -18,23 +18,23 @@ Ceci Ă©tant dĂ©couragĂ©, la documentation interactive gĂ©nĂ©rĂ©e par Swagger UI
 
 ///
 
-## Importez le `BaseModel` de Pydantic
+## Importer le `BaseModel` de Pydantic { #import-pydantics-basemodel }
 
 Commencez par importer la classe `BaseModel` du module `pydantic` :
 
-{* ../../docs_src/body/tutorial001.py hl[4] *}
+{* ../../docs_src/body/tutorial001_py310.py hl[2] *}
 
-## CrĂ©ez votre modĂšle de donnĂ©es
+## CrĂ©er votre modĂšle de donnĂ©es { #create-your-data-model }
 
 DĂ©clarez ensuite votre modĂšle de donnĂ©es en tant que classe qui hĂ©rite de `BaseModel`.
 
 Utilisez les types Python standard pour tous les attributs :
 
-{* ../../docs_src/body/tutorial001.py hl[7:11] *}
+{* ../../docs_src/body/tutorial001_py310.py hl[5:9] *}
 
-Tout comme pour la dĂ©claration de paramĂštres de requĂȘte, quand un attribut de modĂšle a une valeur par dĂ©faut, il n'est pas nĂ©cessaire. Sinon, cet attribut doit ĂȘtre renseignĂ© dans le corps de la requĂȘte. Pour rendre ce champ optionnel simplement, utilisez `None` comme valeur par dĂ©faut.
+Tout comme pour la dĂ©claration de paramĂštres de requĂȘte, quand un attribut de modĂšle a une valeur par dĂ©faut, il n'est pas nĂ©cessaire. Sinon, cet attribut doit ĂȘtre renseignĂ© dans le corps de la requĂȘte. Utilisez `None` pour le rendre simplement optionnel.
 
-Par exemple, le modĂšle ci-dessus dĂ©clare un "objet" JSON (ou `dict` Python) tel que :
+Par exemple, le modĂšle ci-dessus dĂ©clare un JSON Â«Â `object` » (ou `dict` Python) tel que :
 
 ```JSON
 {
@@ -45,7 +45,7 @@ Par exemple, le modĂšle ci-dessus dĂ©clare un "objet" JSON (ou `dict` Python) te
 }
 ```
 
-...`description` et `tax` Ă©tant des attributs optionnels (avec `None` comme valeur par dĂ©faut), cet "objet" JSON serait aussi valide :
+... `description` et `tax` Ă©tant des attributs optionnels (avec `None` comme valeur par dĂ©faut), ce JSON Â«Â `object` » serait aussi valide :
 
 ```JSON
 {
@@ -54,28 +54,28 @@ Par exemple, le modĂšle ci-dessus dĂ©clare un "objet" JSON (ou `dict` Python) te
 }
 ```
 
-## DĂ©clarez-le comme paramĂštre
+## Le dĂ©clarer comme paramĂštre { #declare-it-as-a-parameter }
 
 Pour l'ajouter Ă  votre *opĂ©ration de chemin*, dĂ©clarez-le comme vous dĂ©clareriez des paramĂštres de chemin ou de requĂȘte :
 
-{* ../../docs_src/body/tutorial001.py hl[18] *}
+{* ../../docs_src/body/tutorial001_py310.py hl[16] *}
 
-...et dĂ©clarez que son type est le modĂšle que vous avez créé : `Item`.
+... et dĂ©clarez que son type est le modĂšle que vous avez créé : `Item`.
 
-## RĂ©sultats
+## RĂ©sultats { #results }
 
 En utilisant uniquement les dĂ©clarations de type Python, **FastAPI** rĂ©ussit Ă  :
 
 * Lire le contenu de la requĂȘte en tant que JSON.
 * Convertir les types correspondants (si nĂ©cessaire).
 * Valider la donnĂ©e.
-    * Si la donnĂ©e est invalide, une erreur propre et claire sera renvoyĂ©e, indiquant exactement oĂč Ă©tait la donnĂ©e incorrecte.
+    * Si la donnĂ©e est invalide, une erreur propre et claire sera renvoyĂ©e, indiquant exactement oĂč et quelle Ă©tait la donnĂ©e incorrecte.
 * Passer la donnĂ©e reçue dans le paramĂštre `item`.
-    * Ce paramĂštre ayant Ă©tĂ© dĂ©clarĂ© dans la fonction comme Ă©tant de type `Item`, vous aurez aussi tout le support offert par l'Ă©diteur (auto-complĂ©tion, etc.) pour tous les attributs de ce paramĂštre et les types de ces attributs.
-* GĂ©nĂ©rer des dĂ©finitions <a href="https://json-schema.org" class="external-link" target="_blank">JSON Schema</a> pour votre modĂšle, qui peuvent ĂȘtre utilisĂ©es oĂč vous en avez besoin dans votre projet ensuite.
-* Ces schĂ©mas participeront Ă  la constitution du schĂ©ma gĂ©nĂ©rĂ© OpenAPI, et seront donc utilisĂ©s par les documentations automatiquement gĂ©nĂ©rĂ©es.
+    * Ce paramĂštre ayant Ă©tĂ© dĂ©clarĂ© dans la fonction comme Ă©tant de type `Item`, vous aurez aussi tout le support offert par l'Ă©diteur (autocomplĂ©tion, etc.) pour tous les attributs de ce paramĂštre et les types de ces attributs.
+* GĂ©nĂ©rer des dĂ©finitions <a href="https://json-schema.org" class="external-link" target="_blank">JSON Schema</a> pour votre modĂšle ; vous pouvez Ă©galement les utiliser partout ailleurs si cela a du sens pour votre projet.
+* Ces schĂ©mas participeront Ă  la constitution du schĂ©ma gĂ©nĂ©rĂ© OpenAPI, et seront utilisĂ©s par les documentations automatiques <abbr title="User Interfaces - Interfaces utilisateur">UIs</abbr>.
 
-## Documentation automatique
+## Documentation automatique { #automatic-docs }
 
 Les schĂ©mas JSON de vos modĂšles seront intĂ©grĂ©s au schĂ©ma OpenAPI global de votre application, et seront donc affichĂ©s dans la documentation interactive de l'API :
 
@@ -85,63 +85,63 @@ Et seront aussi utilisĂ©s dans chaque *opĂ©ration de chemin* de la documentation
 
 <img src="/img/tutorial/body/image02.png">
 
-## Support de l'Ă©diteur
+## Support de l'Ă©diteur { #editor-support }
 
-Dans votre Ă©diteur, vous aurez des annotations de types et de l'auto-complĂ©tion partout dans votre fonction (ce qui n'aurait pas Ă©tĂ© le cas si vous aviez utilisĂ© un classique `dict` plutĂŽt qu'un modĂšle Pydantic) :
+Dans votre Ă©diteur, vous aurez des annotations de type et de l'autocomplĂ©tion partout dans votre fonction (ce qui n'aurait pas Ă©tĂ© le cas si vous aviez reçu un `dict` plutĂŽt qu'un modĂšle Pydantic) :
 
 <img src="/img/tutorial/body/image03.png">
 
-Et vous obtenez aussi de la vĂ©rification d'erreur pour les opĂ©rations incorrectes de types :
+Et vous obtenez aussi des vĂ©rifications d'erreurs pour les opĂ©rations de types incorrectes :
 
 <img src="/img/tutorial/body/image04.png">
 
 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.
+Et cela a Ă©tĂ© rigoureusement testĂ© durant la phase de design, avant toute implĂ©mentation, pour vous assurer que cela fonctionnerait avec tous les Ă©diteurs.
 
 Des changements sur Pydantic ont mĂȘme Ă©tĂ© faits pour supporter cela.
 
-Les captures d'Ă©crans prĂ©cĂ©dentes ont Ă©tĂ© prises sur <a href="https://code.visualstudio.com" class="external-link" target="_blank">Visual Studio Code</a>.
+Les captures d'Ă©cran prĂ©cĂ©dentes ont Ă©tĂ© prises sur <a href="https://code.visualstudio.com" class="external-link" target="_blank">Visual Studio Code</a>.
 
-Mais vous auriez le mĂȘme support de l'Ă©diteur avec <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> et la majoritĂ© des autres Ă©diteurs de code Python.
+Mais vous auriez le mĂȘme support de l'Ă©diteur avec <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> et la majoritĂ© des autres Ă©diteurs de code Python :
 
 <img src="/img/tutorial/body/image05.png">
 
 /// tip | Astuce
 
-Si vous utilisez <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> comme Ă©diteur, vous pouvez utiliser le Plugin <a href="https://github.com/koxudaxi/pydantic-pycharm-plugin/" class="external-link" target="_blank">Pydantic PyCharm Plugin</a>.
+Si vous utilisez <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> comme Ă©diteur, vous pouvez utiliser le plug-in <a href="https://github.com/koxudaxi/pydantic-pycharm-plugin/" class="external-link" target="_blank">Pydantic PyCharm Plugin</a>.
 
 Ce qui amĂ©liore le support pour les modĂšles Pydantic avec :
 
-* de l'auto-complĂ©tion
+* de l'autocomplĂ©tion
 * des vĂ©rifications de type
-* du "refactoring" (ou remaniement de code)
+* du Â«Â refactoring » (ou remaniement de code)
 * de la recherche
-* de l'inspection
+* des inspections
 
 ///
 
-## Utilisez le modĂšle
+## Utiliser le modĂšle { #use-the-model }
 
 Dans la fonction, vous pouvez accĂ©der Ă  tous les attributs de l'objet du modĂšle directement :
 
-{* ../../docs_src/body/tutorial002.py hl[21] *}
+{* ../../docs_src/body/tutorial002_py310.py *}
 
-## Corps de la requĂȘte + paramĂštres de chemin
+## Corps de la requĂȘte + paramĂštres de chemin { #request-body-path-parameters }
 
 Vous pouvez dĂ©clarer des paramĂštres de chemin et un corps de requĂȘte pour la mĂȘme *opĂ©ration de chemin*.
 
 **FastAPI** est capable de reconnaĂźtre que les paramĂštres de la fonction qui correspondent aux paramĂštres de chemin doivent ĂȘtre **rĂ©cupĂ©rĂ©s depuis le chemin**, et que les paramĂštres de fonctions dĂ©clarĂ©s comme modĂšles Pydantic devraient ĂȘtre **rĂ©cupĂ©rĂ©s depuis le corps de la requĂȘte**.
 
-{* ../../docs_src/body/tutorial003.py hl[17:18] *}
+{* ../../docs_src/body/tutorial003_py310.py hl[15:16] *}
 
-## Corps de la requĂȘte + paramĂštres de chemin et de requĂȘte
+## Corps de la requĂȘte + paramĂštres de chemin et de requĂȘte { #request-body-path-query-parameters }
 
 Vous pouvez aussi dĂ©clarer un **corps**, et des paramĂštres de **chemin** et de **requĂȘte** dans la mĂȘme *opĂ©ration de chemin*.
 
 **FastAPI** saura reconnaĂźtre chacun d'entre eux et rĂ©cupĂ©rer la bonne donnĂ©e au bon endroit.
 
-{* ../../docs_src/body/tutorial004.py hl[18] *}
+{* ../../docs_src/body/tutorial004_py310.py hl[16] *}
 
 Les paramĂštres de la fonction seront reconnus comme tel :
 
@@ -149,14 +149,16 @@ Les paramĂštres de la fonction seront reconnus comme tel :
 * Si le paramĂštre est d'un **type singulier** (comme `int`, `float`, `str`, `bool`, etc.), il sera interprĂ©tĂ© comme un paramĂštre de **requĂȘte**.
 * Si le paramĂštre est dĂ©clarĂ© comme ayant pour type un **modĂšle Pydantic**, il sera interprĂ©tĂ© comme faisant partie du **corps** de la requĂȘte.
 
-/// note
+/// note | Remarque
 
-**FastAPI** saura que la valeur de `q` n'est pas requise grĂące Ă  la valeur par dĂ©faut `=None`.
+**FastAPI** saura que la valeur de `q` n'est pas requise grĂące Ă  la valeur par dĂ©faut `= None`.
 
-Le type `Optional` dans `Optional[str]` n'est pas utilisĂ© par **FastAPI**, mais sera utile Ă  votre Ă©diteur pour amĂ©liorer le support offert par ce dernier et dĂ©tecter plus facilement des erreurs de type.
+L'annotation de type `str | None` (Python 3.10+) ou `Union` dans `Union[str, None]` (Python 3.9+) n'est pas utilisĂ©e par **FastAPI** pour dĂ©terminer que la valeur n'est pas requise, il le saura parce qu'elle a une valeur par dĂ©faut `= None`.
+
+Mais ajouter ces annotations de type permettra Ă  votre Ă©diteur de vous offrir un meilleur support et de dĂ©tecter des erreurs.
 
 ///
 
-## Sans Pydantic
+## Sans Pydantic { #without-pydantic }
 
-Si vous ne voulez pas utiliser des modĂšles Pydantic, vous pouvez aussi utiliser des paramĂštres de **Corps**. Pour cela, allez voir la partie de la documentation sur  [Corps de la requĂȘte - ParamĂštres multiples](body-multiple-params.md){.internal-link target=_blank}.
+Si vous ne voulez pas utiliser des modĂšles Pydantic, vous pouvez aussi utiliser des paramĂštres de **Body**. Pour cela, allez voir la documentation sur [Corps de la requĂȘte - ParamĂštres multiples : Valeurs singuliĂšres dans le corps](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}.
index ab00fbdeb268c52d954d814e7172d582d9e2edfb..a88fa2b23fb98d6be3fe121f5a9252d2de4a5b2f 100644 (file)
@@ -1,14 +1,14 @@
-# <abbr title="En anglais: Debugging">DĂ©bogage</abbr>
+# <abbr title="En anglais: Debugging">DĂ©bogage</abbr> { #debugging }
 
 Vous pouvez connecter le <abbr title="En anglais: debugger">dĂ©bogueur</abbr> dans votre Ă©diteur, par exemple avec Visual Studio Code ou PyCharm.
 
-## Faites appel Ă  `uvicorn`
+## Appeler `uvicorn` { #call-uvicorn }
 
 Dans votre application FastAPI, importez et exĂ©cutez directement `uvicorn` :
 
-{* ../../docs_src/debugging/tutorial001.py hl[1,15] *}
+{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *}
 
-### Ă€ propos de `__name__ == "__main__"`
+### Ă€ propos de `__name__ == "__main__"` { #about-name-main }
 
 Le but principal de `__name__ == "__main__"` est d'avoir du code qui est exĂ©cutĂ© lorsque votre fichier est appelĂ© avec :
 
@@ -26,7 +26,7 @@ mais qui n'est pas appelĂ© lorsqu'un autre fichier l'importe, comme dans :
 from myapp import app
 ```
 
-#### Pour davantage de dĂ©tails
+#### Pour davantage de dĂ©tails { #more-details }
 
 Imaginons que votre fichier s'appelle `myapp.py`.
 
@@ -78,7 +78,7 @@ Pour plus d'informations, consultez <a href="https://docs.python.org/3/library/_
 
 ///
 
-## ExĂ©cutez votre code avec votre <abbr title="En anglais: debugger">dĂ©bogueur</abbr>
+## ExĂ©cuter votre code avec votre <abbr title="En anglais: debugger">dĂ©bogueur</abbr> { #run-your-code-with-your-debugger }
 
 Parce que vous exĂ©cutez le serveur Uvicorn directement depuis votre code, vous pouvez appeler votre programme Python (votre application FastAPI) directement depuis le <abbr title="En anglais: debugger">dĂ©bogueur</abbr>.
 
@@ -86,10 +86,10 @@ Parce que vous exĂ©cutez le serveur Uvicorn directement depuis votre code, vous
 
 Par exemple, dans Visual Studio Code, vous pouvez :
 
-- Cliquer sur l'onglet "Debug" de la barre d'activitĂ©s de Visual Studio Code.
-- "Add configuration...".
-- SĂ©lectionnez "Python".
-- Lancez le <abbr title="En anglais: debugger">dĂ©bogueur</abbr> avec l'option "`Python: Current File (Integrated Terminal)`".
+- Allez dans le panneau Â« Debug Â».
+- Â« Add configuration... Â».
+- SĂ©lectionnez Â« Python Â».
+- Lancez le <abbr title="En anglais: debugger">dĂ©bogueur</abbr> avec l'option Â« Python: Current File (Integrated Terminal) Â».
 
 Il dĂ©marrera alors le serveur avec votre code **FastAPI**, s'arrĂȘtera Ă  vos points d'arrĂȘt, etc.
 
@@ -101,8 +101,8 @@ Voici Ă  quoi cela pourrait ressembler :
 
 Si vous utilisez Pycharm, vous pouvez :
 
-- Ouvrir le menu "Run".
-- SĂ©lectionnez l'option "Debug...".
+- Ouvrez le menu Â« Run Â».
+- SĂ©lectionnez l'option Â« Debug... Â».
 - Un menu contextuel s'affiche alors.
 - SĂ©lectionnez le fichier Ă  dĂ©boguer (dans ce cas, `main.py`).
 
index 96ea56e6229c4024744f0fb297c8f8b27e294355..b2693b3e5a7632699df33f846c66f5150826a464 100644 (file)
-# DĂ©marrage
+# DĂ©marrage { #first-steps }
 
-Le fichier **FastAPI** le plus simple possible pourrait ressembler Ă  cela  :
+Le fichier **FastAPI** le plus simple possible pourrait ressembler Ă  ceci :
 
-{* ../../docs_src/first_steps/tutorial001.py *}
+{* ../../docs_src/first_steps/tutorial001_py39.py *}
 
-Copiez ce code dans un fichier nommĂ© `main.py`.
+Copiez cela dans un fichier `main.py`.
 
-DĂ©marrez le serveur :
+DĂ©marrez le serveur en direct :
 
 <div class="termy">
 
 ```console
-$ uvicorn main:app --reload
+$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u>
 
-<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
-<span style="color: green;">INFO</span>:     Started reloader process [28720]
-<span style="color: green;">INFO</span>:     Started server process [28722]
-<span style="color: green;">INFO</span>:     Waiting for application startup.
-<span style="color: green;">INFO</span>:     Application startup complete.
-```
+  <span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span>  Starting development server đŸš€
 
-</div>
+             Searching for package file structure from directories
+             with <font color="#3465A4">__init__.py</font> files
+             Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
 
-/// note
+   <span style="background-color:#007166"><font color="#D3D7CF"> module </font></span>  đŸ main.py
 
-La commande `uvicorn main:app` fait rĂ©fĂ©rence Ă  :
+     <span style="background-color:#007166"><font color="#D3D7CF"> code </font></span>  Importing the FastAPI app object from the module with
+             the following code:
 
-* `main` : le fichier `main.py` (le module Python).
-* `app` : l'objet créé dans `main.py` via la ligne `app = FastAPI()`.
-* `--reload` : l'option disant Ă  uvicorn de redĂ©marrer le serveur Ă  chaque changement du code. Ă€ ne pas utiliser en production !
+             <u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
 
-///
+      <span style="background-color:#007166"><font color="#D3D7CF"> app </font></span>  Using import string: <font color="#3465A4">main:app</font>
+
+   <span style="background-color:#007166"><font color="#D3D7CF"> server </font></span>  Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font>
+   <span style="background-color:#007166"><font color="#D3D7CF"> server </font></span>  Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000/docs</u></font>
+
+      <span style="background-color:#007166"><font color="#D3D7CF"> tip </font></span>  Running in development mode, for production use:
+             <b>fastapi run</b>
 
-Vous devriez voir dans la console, une ligne semblable Ă  la suivante :
+             Logs:
+
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Will watch for changes in these directories:
+             <b>[</b><font color="#4E9A06">&apos;/home/user/code/awesomeapp&apos;</font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font> <b>(</b>Press CTRL+C
+             to quit<b>)</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started reloader process <b>[</b><font color="#34E2E2"><b>383138</b></font><b>]</b> using WatchFiles
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started server process <b>[</b><font color="#34E2E2"><b>383153</b></font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Waiting for application startup.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Application startup complete.
+```
+
+</div>
+
+Dans la sortie, il y a une ligne semblable Ă  :
 
 ```hl_lines="4"
 INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
 
-Cette ligne montre l'URL par laquelle l'app est actuellement accessible, sur votre machine locale.
+Cette ligne montre l’URL oĂč votre application est servie, sur votre machine locale.
 
-### Allez voir le rĂ©sultat
+### VĂ©rifiez { #check-it }
 
-Ouvrez votre navigateur Ă  l'adresse <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>.
+Ouvrez votre navigateur Ă  l’adresse <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>.
 
-Vous obtiendrez cette rĂ©ponse JSON :
+Vous verrez la rĂ©ponse JSON suivante :
 
 ```JSON
 {"message": "Hello World"}
 ```
 
-### Documentation interactive de l'API
+### Documentation interactive de l’API { #interactive-api-docs }
 
-Rendez-vous sur <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Allez maintenant sur <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
 
-Vous verrez la documentation interactive de l'API gĂ©nĂ©rĂ©e automatiquement (via <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>) :
+Vous verrez la documentation interactive de l’API gĂ©nĂ©rĂ©e automatiquement (fournie par <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>) :
 
 ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
 
-### Documentation alternative
+### Documentation alternative de l’API { #alternative-api-docs }
 
-Ensuite, rendez-vous sur <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
+Et maintenant, allez sur <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
 
-Vous y verrez la documentation alternative (via <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>) :
+Vous verrez la documentation automatique alternative (fournie par <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>) :
 
 ![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
 
-### OpenAPI
+### OpenAPI { #openapi }
 
-**FastAPI** gĂ©nĂšre un "schĂ©ma" contenant toute votre API dans le standard de dĂ©finition d'API **OpenAPI**.
+**FastAPI** gĂ©nĂšre un Â« schĂ©ma Â» contenant toute votre API en utilisant le standard **OpenAPI** pour dĂ©finir des API.
 
-#### "SchĂ©ma"
+#### Â« SchĂ©ma Â» { #schema }
 
-Un "schĂ©ma" est une dĂ©finition ou une description de quelque chose. Pas le code qui l'implĂ©mente, uniquement une description abstraite.
+Un Â« schĂ©ma Â» est une dĂ©finition ou une description de quelque chose. Pas le code qui l’implĂ©mente, mais uniquement une description abstraite.
 
-#### "SchĂ©ma" d'API
+#### Â« SchĂ©ma Â» d’API { #api-schema }
 
 Ici, <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> est une spĂ©cification qui dicte comment dĂ©finir le schĂ©ma de votre API.
 
-Le schĂ©ma inclut les chemins de votre API, les paramĂštres potentiels de chaque chemin, etc.
-
-#### "SchĂ©ma" de donnĂ©es
+Cette dĂ©finition de schĂ©ma inclut les chemins de votre API, les paramĂštres possibles qu’ils prennent, etc.
 
-Le terme "schĂ©ma" peut aussi faire rĂ©fĂ©rence Ă  la forme de la donnĂ©e, comme un contenu JSON.
+#### Â« SchĂ©ma Â» de donnĂ©es { #data-schema }
 
-Dans ce cas, cela signifierait les attributs JSON, ainsi que les types de ces attributs, etc.
+Le terme Â« schĂ©ma Â» peut Ă©galement faire rĂ©fĂ©rence Ă  la forme d’une donnĂ©e, comme un contenu JSON.
 
-#### OpenAPI et JSON Schema
+Dans ce cas, cela dĂ©signerait les attributs JSON, ainsi que leurs types, etc.
 
-**OpenAPI** dĂ©finit un schĂ©ma d'API pour votre API. Il inclut des dĂ©finitions (ou "schĂ©mas") de la donnĂ©e envoyĂ©e et reçue par votre API en utilisant **JSON Schema**, le standard des schĂ©mas de donnĂ©es JSON.
+#### OpenAPI et JSON Schema { #openapi-and-json-schema }
 
-#### Allez voir `openapi.json`
+OpenAPI dĂ©finit un schĂ©ma d’API pour votre API. Et ce schĂ©ma inclut des dĂ©finitions (ou Â« schĂ©mas Â») des donnĂ©es envoyĂ©es et reçues par votre API en utilisant **JSON Schema**, le standard pour les schĂ©mas de donnĂ©es JSON.
 
-Si vous ĂȘtes curieux d'Ă  quoi ressemble le schĂ©ma brut **OpenAPI**, **FastAPI** gĂ©nĂšre automatiquement un (schĂ©ma) JSON avec les descriptions de toute votre API.
+#### Voir le `openapi.json` { #check-the-openapi-json }
 
-Vous pouvez le voir directement Ă  cette adresse : <a href="http://127.0.0.1:8000/openapi.json" class="external-link" target="_blank">http://127.0.0.1:8000/openapi.json</a>.
+Si vous ĂȘtes curieux de voir Ă  quoi ressemble le schĂ©ma OpenAPI brut, FastAPI gĂ©nĂšre automatiquement un JSON (schĂ©ma) avec les descriptions de toute votre API.
 
-Le schĂ©ma devrait ressembler Ă  ceci :
+Vous pouvez le voir directement Ă  l’adresse : <a href="http://127.0.0.1:8000/openapi.json" class="external-link" target="_blank">http://127.0.0.1:8000/openapi.json</a>.
 
+Il affichera un JSON commençant par quelque chose comme :
 
 ```JSON
 {
-    "openapi": "3.0.2",
+    "openapi": "3.1.0",
     "info": {
         "title": "FastAPI",
         "version": "0.1.0"
@@ -120,79 +135,87 @@ Le schĂ©ma devrait ressembler Ă  ceci :
 ...
 ```
 
-#### Ă€ quoi sert OpenAPI
+#### Ă€ quoi sert OpenAPI { #what-is-openapi-for }
 
-Le schĂ©ma **OpenAPI** est ce qui alimente les deux systĂšmes de documentation interactive.
+Le schĂ©ma OpenAPI est ce qui alimente les deux systĂšmes de documentation interactive inclus.
 
-Et il existe des dizaines d'alternatives, toutes basĂ©es sur **OpenAPI**. Vous pourriez facilement ajouter n'importe laquelle de ces alternatives Ă  votre application **FastAPI**.
+Et il existe des dizaines d’alternatives, toutes basĂ©es sur OpenAPI. Vous pourriez facilement ajouter n’importe laquelle de ces alternatives Ă  votre application construite avec **FastAPI**.
 
-Vous pourriez aussi l'utiliser pour gĂ©nĂ©rer du code automatiquement, pour les clients qui communiquent avec votre API. Comme par exemple, des applications frontend, mobiles ou IOT.
+Vous pourriez Ă©galement l’utiliser pour gĂ©nĂ©rer du code automatiquement, pour les clients qui communiquent avec votre API. Par exemple, des applications frontend, mobiles ou IoT.
 
-## RĂ©capitulatif, Ă©tape par Ă©tape
+### DĂ©ployer votre application (optionnel) { #deploy-your-app-optional }
 
-### Ă‰tape 1 : import `FastAPI`
+Vous pouvez, si vous le souhaitez, dĂ©ployer votre application FastAPI sur <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>, allez rejoindre la liste d’attente si ce n’est pas dĂ©jĂ  fait. đŸš€
 
-{* ../../docs_src/first_steps/tutorial001.py hl[1] *}
+Si vous avez dĂ©jĂ  un compte **FastAPI Cloud** (nous vous avons invitĂ© depuis la liste d’attente đŸ˜‰), vous pouvez dĂ©ployer votre application avec une seule commande.
 
-`FastAPI` est une classe Python qui fournit toutes les fonctionnalitĂ©s nĂ©cessaires au lancement de votre API.
+Avant de dĂ©ployer, vous devez vous assurer que vous ĂȘtes connectĂ© :
 
-/// note | DĂ©tails techniques
-
-`FastAPI` est une classe hĂ©ritant directement de `Starlette`.
-
-Vous pouvez donc aussi utiliser toutes les fonctionnalitĂ©s de <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> depuis `FastAPI`.
-
-///
-
-### Ă‰tape 2 : crĂ©er une "instance" `FastAPI`
+<div class="termy">
 
-{* ../../docs_src/first_steps/tutorial001.py hl[3] *}
+```console
+$ fastapi login
 
-Ici la variable `app` sera une "instance" de la classe `FastAPI`.
+You are logged in to FastAPI Cloud đŸš€
+```
 
-Ce sera le point principal d'interaction pour crĂ©er toute votre API.
+</div>
 
-Cette `app` est la mĂȘme que celle Ă  laquelle fait rĂ©fĂ©rence `uvicorn` dans la commande :
+Puis dĂ©ployez votre application :
 
 <div class="termy">
 
 ```console
-$ uvicorn main:app --reload
+$ fastapi deploy
+
+Deploying to FastAPI Cloud...
+
+✅ Deployment successful!
 
-<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
 ```
 
 </div>
 
-Si vous crĂ©ez votre app avec :
+C’est tout ! Vous pouvez maintenant accĂ©der Ă  votre application Ă  cette URL. âœš
 
-{* ../../docs_src/first_steps/tutorial002.py hl[3] *}
+## RĂ©capitulatif, Ă©tape par Ă©tape { #recap-step-by-step }
 
-Et la mettez dans un fichier `main.py`, alors vous appelleriez `uvicorn` avec :
+### Ă‰tape 1 : importer `FastAPI` { #step-1-import-fastapi }
 
-<div class="termy">
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *}
 
-```console
-$ uvicorn main:my_awesome_api --reload
+`FastAPI` est une classe Python qui fournit toutes les fonctionnalitĂ©s nĂ©cessaires Ă  votre API.
 
-<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
-```
+/// note | DĂ©tails techniques
 
-</div>
+`FastAPI` est une classe qui hĂ©rite directement de `Starlette`.
+
+Vous pouvez donc aussi utiliser toutes les fonctionnalitĂ©s de <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> avec `FastAPI`.
+
+///
+
+### Ă‰tape 2 : crĂ©er une Â« instance Â» `FastAPI` { #step-2-create-a-fastapi-instance }
+
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[3] *}
+
+Ici, la variable `app` sera une Â« instance Â» de la classe `FastAPI`.
+
+Ce sera le point principal d’interaction pour crĂ©er toute votre API.
 
-### Ă‰tape 3: crĂ©er une *opĂ©ration de chemin*
+### Ă‰tape 3 : crĂ©er un Â« chemin d’accĂšs Â» { #step-3-create-a-path-operation }
 
-#### Chemin
+#### Chemin { #path }
 
-Chemin, ou "path" fait rĂ©fĂ©rence ici Ă  la derniĂšre partie de l'URL dĂ©marrant au premier `/`.
+« Chemin Â» fait ici rĂ©fĂ©rence Ă  la derniĂšre partie de l’URL Ă  partir du premier `/`.
 
-Donc, dans un URL tel que :
+Donc, dans une URL telle que :
 
 ```
 https://example.com/items/foo
 ```
 
-...le "path" serait :
+... le chemin serait :
 
 ```
 /items/foo
@@ -200,66 +223,67 @@ https://example.com/items/foo
 
 /// info
 
-Un chemin, ou "path" est aussi souvent appelĂ© route ou "endpoint".
+Un Â« chemin Â» est aussi couramment appelĂ© Â« endpoint Â» ou Â« route Â».
 
 ///
 
-#### OpĂ©ration
+Lors de la crĂ©ation d’une API, le Â« chemin Â» est la maniĂšre principale de sĂ©parer les Â« prĂ©occupations Â» et les Â« ressources Â».
 
-"OpĂ©ration" fait rĂ©fĂ©rence Ă  une des "mĂ©thodes" HTTP.
+#### OpĂ©ration { #operation }
 
-Une de :
+« OpĂ©ration Â» fait ici rĂ©fĂ©rence Ă  l’une des Â« mĂ©thodes Â» HTTP.
+
+L’une de :
 
 * `POST`
 * `GET`
 * `PUT`
 * `DELETE`
 
-...ou une des plus exotiques :
+... et les plus exotiques :
 
 * `OPTIONS`
 * `HEAD`
 * `PATCH`
 * `TRACE`
 
-Dans le protocol HTTP, vous pouvez communiquer avec chaque chemin en utilisant une (ou plus) de ces "mĂ©thodes".
+Dans le protocole HTTP, vous pouvez communiquer avec chaque chemin en utilisant une (ou plusieurs) de ces Â« mĂ©thodes Â».
 
 ---
 
-En construisant des APIs, vous utilisez gĂ©nĂ©ralement ces mĂ©thodes HTTP spĂ©cifiques pour effectuer une action prĂ©cise.
-
-GĂ©nĂ©ralement vous utilisez :
+En construisant des APIs, vous utilisez normalement ces mĂ©thodes HTTP spĂ©cifiques pour effectuer une action prĂ©cise.
 
-* `POST` : pour crĂ©er de la donnĂ©e.
-* `GET` : pour lire de la donnĂ©e.
-* `PUT` : pour mettre Ă  jour de la donnĂ©e.
-* `DELETE` : pour supprimer de la donnĂ©e.
+En gĂ©nĂ©ral, vous utilisez :
 
-Donc, dans **OpenAPI**, chaque mĂ©thode HTTP est appelĂ©e une "opĂ©ration".
+* `POST` : pour crĂ©er des donnĂ©es.
+* `GET` : pour lire des donnĂ©es.
+* `PUT` : pour mettre Ă  jour des donnĂ©es.
+* `DELETE` : pour supprimer des donnĂ©es.
 
-Nous allons donc aussi appeler ces derniĂšres des "**opĂ©rations**".
+Donc, dans OpenAPI, chacune des mĂ©thodes HTTP est appelĂ©e une Â« opĂ©ration Â».
 
+Nous allons donc aussi les appeler Â« opĂ©rations Â».
 
-#### DĂ©finir un *dĂ©corateur d'opĂ©ration de chemin*
+#### DĂ©finir un Â« dĂ©corateur de chemin d’accĂšs Â» { #define-a-path-operation-decorator }
 
-{* ../../docs_src/first_steps/tutorial001.py hl[6] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[6] *}
 
-Le `@app.get("/")` dit Ă  **FastAPI** que la fonction en dessous est chargĂ©e de gĂ©rer les requĂȘtes qui vont sur :
+Le `@app.get("/")` indique Ă  **FastAPI** que la fonction juste en dessous est chargĂ©e de gĂ©rer les requĂȘtes qui vont vers :
 
 * le chemin `/`
-* en utilisant une <abbr title="une mĂ©thode GET HTTP">opĂ©ration <code>get</code></abbr>
+* en utilisant une <abbr title="une mĂ©thode HTTP GET"><code>get</code> opĂ©ration</abbr>
 
 /// info | `@dĂ©corateur` Info
 
-Cette syntaxe `@something` en Python est appelĂ©e un "dĂ©corateur".
+Cette syntaxe `@something` en Python est appelĂ©e un Â« dĂ©corateur Â».
 
-Vous la mettez au dessus d'une fonction. Comme un joli chapeau dĂ©coratif (j'imagine que ce terme vient de lĂ  đŸ€·đŸ»â€â™‚).
+Vous la mettez au-dessus d’une fonction. Comme un joli chapeau dĂ©coratif (j’imagine que c’est de lĂ  que vient le terme đŸ€·đŸ»â€â™‚).
 
-Un "dĂ©corateur" prend la fonction en dessous et en fait quelque chose.
+Un Â« dĂ©corateur Â» prend la fonction en dessous et fait quelque chose avec.
 
-Dans notre cas, ce dĂ©corateur dit Ă  **FastAPI** que la fonction en dessous correspond au **chemin** `/` avec l'**opĂ©ration** `get`.
+Dans notre cas, ce dĂ©corateur indique Ă  **FastAPI** que la fonction en dessous correspond au **chemin** `/` avec une **opĂ©ration** `get`.
 
-C'est le "**dĂ©corateur d'opĂ©ration de chemin**".
+C’est le Â« dĂ©corateur de chemin d’accĂšs Â».
 
 ///
 
@@ -269,7 +293,7 @@ Vous pouvez aussi utiliser les autres opĂ©rations :
 * `@app.put()`
 * `@app.delete()`
 
-Tout comme celles les plus exotiques :
+Ainsi que les plus exotiques :
 
 * `@app.options()`
 * `@app.head()`
@@ -278,58 +302,79 @@ Tout comme celles les plus exotiques :
 
 /// tip | Astuce
 
-Vous ĂȘtes libres d'utiliser chaque opĂ©ration (mĂ©thode HTTP) comme vous le dĂ©sirez.
+Vous ĂȘtes libre d’utiliser chaque opĂ©ration (mĂ©thode HTTP) comme vous le souhaitez.
 
-**FastAPI** n'impose pas de sens spĂ©cifique Ă  chacune d'elle.
+**FastAPI** n’impose aucune signification spĂ©cifique.
 
-Les informations qui sont prĂ©sentĂ©es ici forment une directive gĂ©nĂ©rale, pas des obligations.
+Les informations ici sont prĂ©sentĂ©es comme des lignes directrices, pas comme une obligation.
 
-Par exemple, quand l'on utilise **GraphQL**, toutes les actions sont effectuĂ©es en utilisant uniquement des opĂ©rations `POST`.
+Par exemple, lorsque vous utilisez GraphQL, vous effectuez normalement toutes les actions en utilisant uniquement des opĂ©rations `POST`.
 
 ///
 
-### Ă‰tape 4 : dĂ©finir la **fonction de chemin**.
+### Ă‰tape 4 : dĂ©finir la **fonction de chemin d’accĂšs** { #step-4-define-the-path-operation-function }
 
-Voici notre "**fonction de chemin**" (ou fonction d'opĂ©ration de chemin) :
+Voici notre Â« fonction de chemin d’accĂšs Â» :
 
 * **chemin** : `/`.
 * **opĂ©ration** : `get`.
-* **fonction** : la fonction sous le "dĂ©corateur" (sous `@app.get("/")`).
+* **fonction** : la fonction sous le Â« dĂ©corateur Â» (sous `@app.get("/")`).
 
-{* ../../docs_src/first_steps/tutorial001.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *}
 
-C'est une fonction Python.
+C’est une fonction Python.
 
-Elle sera appelĂ©e par **FastAPI** quand une requĂȘte sur l'URL `/` sera reçue via une opĂ©ration `GET`.
+Elle sera appelĂ©e par **FastAPI** chaque fois qu’il recevra une requĂȘte vers l’URL Â« / Â» en utilisant une opĂ©ration `GET`.
 
-Ici, c'est une fonction asynchrone (dĂ©finie avec `async def`).
+Dans ce cas, c’est une fonction `async`.
 
 ---
 
-Vous pourriez aussi la dĂ©finir comme une fonction classique plutĂŽt qu'avec `async def` :
+Vous pouvez aussi la dĂ©finir comme une fonction normale au lieu de `async def` :
 
-{* ../../docs_src/first_steps/tutorial003.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *}
 
 /// note
 
-Si vous ne connaissez pas la diffĂ©rence, allez voir la section [Concurrence : *"Vous ĂȘtes pressĂ©s ?"*](../async.md#vous-etes-presses){.internal-link target=_blank}.
+Si vous ne connaissez pas la diffĂ©rence, consultez [Asynchrone : Â« PressĂ© ? Â»](../async.md#in-a-hurry){.internal-link target=_blank}.
 
 ///
 
-### Ă‰tape 5 : retourner le contenu
+### Ă‰tape 5 : retourner le contenu { #step-5-return-the-content }
+
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
+
+Vous pouvez retourner un `dict`, une `list`, des valeurs uniques comme `str`, `int`, etc.
+
+Vous pouvez Ă©galement retourner des modĂšles Pydantic (vous en verrez plus Ă  ce sujet plus tard).
+
+Il existe de nombreux autres objets et modĂšles qui seront automatiquement convertis en JSON (y compris des ORM, etc.). Essayez d’utiliser vos favoris, il est fort probable qu’ils soient dĂ©jĂ  pris en charge.
+
+### Ă‰tape 6 : le dĂ©ployer { #step-6-deploy-it }
+
+DĂ©ployez votre application sur **<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** avec une seule commande : `fastapi deploy`. đŸŽ‰
+
+#### Ă€ propos de FastAPI Cloud { #about-fastapi-cloud }
+
+**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** est construit par le mĂȘme auteur et l’équipe derriĂšre **FastAPI**.
+
+Il simplifie le processus de **construction**, de **dĂ©ploiement** et d’**accĂšs** Ă  une API avec un minimum d’effort.
+
+Il apporte la mĂȘme **expĂ©rience dĂ©veloppeur** de crĂ©ation d’applications avec FastAPI au **dĂ©ploiement** dans le cloud. đŸŽ‰
 
-{* ../../docs_src/first_steps/tutorial001.py hl[8] *}
+FastAPI Cloud est le sponsor principal et le financeur des projets open source *FastAPI and friends*. âœš
 
-Vous pouvez retourner un dictionnaire (`dict`), une liste (`list`), des valeurs seules comme des chaines de caractĂšres (`str`) et des entiers (`int`), etc.
+#### DĂ©ployer sur d’autres fournisseurs cloud { #deploy-to-other-cloud-providers }
 
-Vous pouvez aussi retourner des models **Pydantic** (qui seront dĂ©taillĂ©s plus tard).
+FastAPI est open source et basĂ© sur des standards. Vous pouvez dĂ©ployer des applications FastAPI chez n’importe quel fournisseur cloud de votre choix.
 
-Il y a de nombreux autres objets et modĂšles qui seront automatiquement convertis en JSON. Essayez d'utiliser vos favoris, il est fort probable qu'ils soient dĂ©jĂ  supportĂ©s.
+Suivez les guides de votre fournisseur cloud pour y dĂ©ployer des applications FastAPI. đŸ€“
 
-## RĂ©capitulatif
+## RĂ©capitulatif { #recap }
 
 * Importez `FastAPI`.
-* CrĂ©ez une instance d'`app`.
-* Ajoutez une **dĂ©corateur d'opĂ©ration de chemin** (tel que `@app.get("/")`).
-* Ajoutez une **fonction de chemin** (telle que `def root(): ...` comme ci-dessus).
-* Lancez le serveur de dĂ©veloppement (avec `uvicorn main:app --reload`).
+* CrĂ©ez une instance `app`.
+* Ă‰crivez un **dĂ©corateur de chemin d’accĂšs** avec des dĂ©corateurs comme `@app.get("/")`.
+* DĂ©finissez une **fonction de chemin d’accĂšs** ; par exemple, `def root(): ...`.
+* ExĂ©cutez le serveur de dĂ©veloppement avec la commande `fastapi dev`.
+* DĂ©ployez Ă©ventuellement votre application avec `fastapi deploy`.
index 83cc5f9e881b95009342270b7f0c58a6491d961f..0251b9b4b267f9caf608e12da2f569dc6c205aa1 100644 (file)
@@ -1,29 +1,53 @@
-# Tutoriel - Guide utilisateur - Introduction
+# Tutoriel - Guide utilisateur { #tutorial-user-guide }
 
 Ce tutoriel vous montre comment utiliser **FastAPI** avec la plupart de ses fonctionnalitĂ©s, Ă©tape par Ă©tape.
 
-Chaque section s'appuie progressivement sur les prĂ©cĂ©dentes, mais elle est structurĂ©e de maniĂšre Ă  sĂ©parer les sujets, afin que vous puissiez aller directement Ă  l'un d'entre eux pour rĂ©soudre vos besoins spĂ©cifiques en matiĂšre d'API.
+Chaque section s'appuie progressivement sur les prĂ©cĂ©dentes, mais elle est structurĂ©e de maniĂšre Ă  sĂ©parer les sujets, afin que vous puissiez aller directement Ă  l'un d'entre eux pour rĂ©pondre Ă  vos besoins spĂ©cifiques d'API.
 
-Il est Ă©galement conçu pour fonctionner comme une rĂ©fĂ©rence future.
+Il est Ă©galement conçu pour servir de rĂ©fĂ©rence ultĂ©rieure, afin que vous puissiez revenir voir exactement ce dont vous avez besoin.
 
-Vous pouvez donc revenir et voir exactement ce dont vous avez besoin.
-
-## ExĂ©cuter le code
+## ExĂ©cuter le code { #run-the-code }
 
 Tous les blocs de code peuvent ĂȘtre copiĂ©s et utilisĂ©s directement (il s'agit en fait de fichiers Python testĂ©s).
 
-Pour exĂ©cuter l'un de ces exemples, copiez le code dans un fichier `main.py`, et commencez `uvicorn` avec :
+Pour exĂ©cuter l'un de ces exemples, copiez le code dans un fichier `main.py`, et dĂ©marrez `fastapi dev` avec :
 
 <div class="termy">
 
 ```console
-$ uvicorn main:app --reload
+$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u>
+
+  <span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span>  Starting development server đŸš€
+
+             Searching for package file structure from directories
+             with <font color="#3465A4">__init__.py</font> files
+             Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
+
+   <span style="background-color:#007166"><font color="#D3D7CF"> module </font></span>  đŸ main.py
+
+     <span style="background-color:#007166"><font color="#D3D7CF"> code </font></span>  Importing the FastAPI app object from the module with
+             the following code:
+
+             <u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
+
+      <span style="background-color:#007166"><font color="#D3D7CF"> app </font></span>  Using import string: <font color="#3465A4">main:app</font>
+
+   <span style="background-color:#007166"><font color="#D3D7CF"> server </font></span>  Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font>
+   <span style="background-color:#007166"><font color="#D3D7CF"> server </font></span>  Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000/docs</u></font>
+
+      <span style="background-color:#007166"><font color="#D3D7CF"> tip </font></span>  Running in development mode, for production use:
+             <b>fastapi run</b>
 
-<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
-<span style="color: green;">INFO</span>:     Started reloader process [28720]
-<span style="color: green;">INFO</span>:     Started server process [28722]
-<span style="color: green;">INFO</span>:     Waiting for application startup.
-<span style="color: green;">INFO</span>:     Application startup complete.
+             Logs:
+
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Will watch for changes in these directories:
+             <b>[</b><font color="#4E9A06">&apos;/home/user/code/awesomeapp&apos;</font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font> <b>(</b>Press CTRL+C
+             to quit<b>)</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started reloader process <b>[</b><font color="#34E2E2"><b>383138</b></font><b>]</b> using WatchFiles
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started server process <b>[</b><font color="#34E2E2"><b>383153</b></font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Waiting for application startup.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Application startup complete.
 ```
 
 </div>
@@ -34,45 +58,33 @@ L'utiliser dans votre Ă©diteur est ce qui vous montre vraiment les avantages de
 
 ---
 
-## Installer FastAPI
+## Installer FastAPI { #install-fastapi }
 
 La premiĂšre Ă©tape consiste Ă  installer FastAPI.
 
-Pour le tutoriel, vous voudrez peut-ĂȘtre l'installer avec toutes les dĂ©pendances et fonctionnalitĂ©s optionnelles :
+Assurez-vous de crĂ©er un [environnement virtuel](../virtual-environments.md){.internal-link target=_blank}, de l'activer, puis **d'installer FastAPI** :
 
 <div class="termy">
 
 ```console
-$ pip install fastapi[all]
+$ pip install "fastapi[standard]"
 
 ---> 100%
 ```
 
 </div>
 
-... qui comprend Ă©galement `uvicorn`, que vous pouvez utiliser comme serveur pour exĂ©cuter votre code.
-
-/// note
-
-Vous pouvez Ă©galement l'installer piĂšce par piĂšce.
+/// note | Remarque
 
-C'est ce que vous feriez probablement une fois que vous voudrez dĂ©ployer votre application en production :
+Lorsque vous installez avec `pip install "fastapi[standard]"` cela inclut des dĂ©pendances standard optionnelles par dĂ©faut, y compris `fastapi-cloud-cli`, qui vous permet de dĂ©ployer sur <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>.
 
-```
-pip install fastapi
-```
-
-Installez Ă©galement `uvicorn` pour qu'il fonctionne comme serveur :
-
-```
-pip install uvicorn
-```
+Si vous ne souhaitez pas avoir ces dĂ©pendances optionnelles, vous pouvez Ă  la place installer `pip install fastapi`.
 
-Et la mĂȘme chose pour chacune des dĂ©pendances facultatives que vous voulez utiliser.
+Si vous souhaitez installer les dĂ©pendances standard mais sans `fastapi-cloud-cli`, vous pouvez installer avec `pip install "fastapi[standard-no-fastapi-cloud-cli]"`.
 
 ///
 
-## Guide utilisateur avancĂ©
+## Guide d'utilisation avancĂ© { #advanced-user-guide }
 
 Il existe Ă©galement un **Guide d'utilisation avancĂ©** que vous pouvez lire plus tard aprĂšs ce **Tutoriel - Guide d'utilisation**.
 
index 3f3280e640c3f94016b8188351ebf67c899e11c1..c80710777f2df5c4b1f3315cecc46350d29beaf7 100644 (file)
@@ -1,8 +1,8 @@
-# ParamĂštres de chemin et validations numĂ©riques
+# ParamĂštres de chemin et validations numĂ©riques { #path-parameters-and-numeric-validations }
 
 De la mĂȘme façon que vous pouvez dĂ©clarer plus de validations et de mĂ©tadonnĂ©es pour les paramĂštres de requĂȘte avec `Query`, vous pouvez dĂ©clarer le mĂȘme type de validations et de mĂ©tadonnĂ©es pour les paramĂštres de chemin avec `Path`.
 
-## Importer Path
+## Importer `Path` { #import-path }
 
 Tout d'abord, importez `Path` de `fastapi`, et importez `Annotated` :
 
@@ -14,11 +14,11 @@ FastAPI a ajoutĂ© le support pour `Annotated` (et a commencĂ© Ă  le recommander)
 
 Si vous avez une version plus ancienne, vous obtiendrez des erreurs en essayant d'utiliser `Annotated`.
 
-Assurez-vous de [Mettre Ă  jour la version de FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} Ă  la version 0.95.1 Ă  minima avant d'utiliser `Annotated`.
+Assurez-vous de [Mettre Ă  niveau la version de FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} Ă  la version 0.95.1 Ă  minima avant d'utiliser `Annotated`.
 
 ///
 
-## DĂ©clarer des mĂ©tadonnĂ©es
+## DĂ©clarer des mĂ©tadonnĂ©es { #declare-metadata }
 
 Vous pouvez dĂ©clarer les mĂȘmes paramĂštres que pour `Query`.
 
@@ -26,15 +26,15 @@ Par exemple, pour dĂ©clarer une valeur de mĂ©tadonnĂ©e `title` pour le paramĂštr
 
 {* ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py hl[10] *}
 
-/// note
+/// note | Remarque
 
 Un paramĂštre de chemin est toujours requis car il doit faire partie du chemin. MĂȘme si vous l'avez dĂ©clarĂ© avec `None` ou dĂ©fini une valeur par dĂ©faut, cela ne changerait rien, il serait toujours requis.
 
 ///
 
-## Ordonnez les paramĂštres comme vous le souhaitez
+## Ordonner les paramĂštres comme vous le souhaitez { #order-the-parameters-as-you-need }
 
-/// tip
+/// tip | Astuce
 
 Ce n'est probablement pas aussi important ou nĂ©cessaire si vous utilisez `Annotated`.
 
@@ -46,7 +46,7 @@ Et vous n'avez pas besoin de dĂ©clarer autre chose pour ce paramĂštre, donc vous
 
 Mais vous avez toujours besoin d'utiliser `Path` pour le paramĂštre de chemin `item_id`. Et vous ne voulez pas utiliser `Annotated` pour une raison quelconque.
 
-Python se plaindra si vous mettez une valeur avec une "dĂ©faut" avant une valeur qui n'a pas de "dĂ©faut".
+Python se plaindra si vous mettez une valeur avec une Â« valeur par dĂ©faut Â» avant une valeur qui n'a pas de Â« valeur par dĂ©faut Â».
 
 Mais vous pouvez les rĂ©organiser, et avoir la valeur sans dĂ©faut (le paramĂštre de requĂȘte `q`) en premier.
 
@@ -54,15 +54,15 @@ Cela n'a pas d'importance pour **FastAPI**. Il dĂ©tectera les paramĂštres par le
 
 Ainsi, vous pouvez dĂ©clarer votre fonction comme suit :
 
-{* ../../docs_src/path_params_numeric_validations/tutorial002.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *}
 
 Mais gardez Ă  l'esprit que si vous utilisez `Annotated`, vous n'aurez pas ce problĂšme, cela n'aura pas d'importance car vous n'utilisez pas les valeurs par dĂ©faut des paramĂštres de fonction pour `Query()` ou `Path()`.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py hl[10] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py *}
 
-## Ordonnez les paramĂštres comme vous le souhaitez (astuces)
+## Ordonner les paramĂštres comme vous le souhaitez, astuces { #order-the-parameters-as-you-need-tricks }
 
-/// tip
+/// tip | Astuce
 
 Ce n'est probablement pas aussi important ou nĂ©cessaire si vous utilisez `Annotated`.
 
@@ -77,38 +77,29 @@ Si vous voulez :
 * les avoir dans un ordre diffĂ©rent
 * ne pas utiliser `Annotated`
 
-...Python a une petite syntaxe spĂ©ciale pour cela.
+... Python a une petite syntaxe spĂ©ciale pour cela.
 
 Passez `*`, comme premier paramĂštre de la fonction.
 
 Python ne fera rien avec ce `*`, mais il saura que tous les paramĂštres suivants doivent ĂȘtre appelĂ©s comme arguments "mots-clĂ©s" (paires clĂ©-valeur), Ă©galement connus sous le nom de <abbr title="De : K-ey W-ord Arg-uments"><code>kwargs</code></abbr>. MĂȘme s'ils n'ont pas de valeur par dĂ©faut.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *}
 
-# Avec `Annotated`
+### Mieux avec `Annotated` { #better-with-annotated }
 
 Gardez Ă  l'esprit que si vous utilisez `Annotated`, comme vous n'utilisez pas les valeurs par dĂ©faut des paramĂštres de fonction, vous n'aurez pas ce problĂšme, et vous n'aurez probablement pas besoin d'utiliser `*`.
 
 {* ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py hl[10] *}
 
-## Validations numĂ©riques : supĂ©rieur ou Ă©gal
+## Validations numĂ©riques : supĂ©rieur ou Ă©gal { #number-validations-greater-than-or-equal }
 
 Avec `Query` et `Path` (et d'autres que vous verrez plus tard) vous pouvez dĂ©clarer des contraintes numĂ©riques.
 
-Ici, avec `ge=1`, `item_id` devra ĂȘtre un nombre entier "`g`reater than or `e`qual" Ă  `1`.
+Ici, avec `ge=1`, `item_id` devra ĂȘtre un nombre entier Â« `g`reater than or `e`qual Â» Ă  `1`.
 
 {* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *}
 
-## Validations numĂ©riques : supĂ©rieur ou Ă©gal et infĂ©rieur ou Ă©gal
-
-La mĂȘme chose s'applique pour :
-
-* `gt` : `g`reater `t`han
-* `le` : `l`ess than or `e`qual
-
-{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *}
-
-## Validations numĂ©riques : supĂ©rieur et infĂ©rieur ou Ă©gal
+## Validations numĂ©riques : supĂ©rieur et infĂ©rieur ou Ă©gal { #number-validations-greater-than-and-less-than-or-equal }
 
 La mĂȘme chose s'applique pour :
 
@@ -117,7 +108,7 @@ La mĂȘme chose s'applique pour :
 
 {* ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py hl[10] *}
 
-## Validations numĂ©riques : flottants, supĂ©rieur et infĂ©rieur
+## Validations numĂ©riques : flottants, supĂ©rieur et infĂ©rieur { #number-validations-floats-greater-than-and-less-than }
 
 Les validations numĂ©riques fonctionnent Ă©galement pour les valeurs `float`.
 
@@ -129,7 +120,7 @@ Et la mĂȘme chose pour <abbr title="less than"><code>lt</code></abbr>.
 
 {* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *}
 
-## Pour rĂ©sumer
+## Pour rĂ©sumer { #recap }
 
 Avec `Query`, `Path` (et d'autres que vous verrez plus tard) vous pouvez dĂ©clarer des mĂ©tadonnĂ©es et des validations de chaĂźnes de la mĂȘme maniĂšre qu'avec les [ParamĂštres de requĂȘte et validations de chaĂźnes](query-params-str-validations.md){.internal-link target=_blank}.
 
index 71c96b18eefdd957a94330ff24ff26853dd02656..3b2955a95d17530211a73b23a3b5482a9f204c8c 100644 (file)
-# ParamĂštres de chemin
+# ParamĂštres de chemin { #path-parameters }
 
-Vous pouvez dĂ©clarer des "paramĂštres" ou "variables" de chemin avec la mĂȘme syntaxe que celle utilisĂ©e par le
-<a href="https://docs.python.org/fr/3/library/string.html#format-string-syntax" class="external-link" target="_blank">formatage de chaĂźne Python</a> :
+Vous pouvez dĂ©clarer des Â« paramĂštres Â» ou Â« variables Â» de chemin avec la mĂȘme syntaxe utilisĂ©e par les chaĂźnes de format Python :
 
+{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *}
 
-{* ../../docs_src/path_params/tutorial001.py hl[6:7] *}
+La valeur du paramĂštre de chemin `item_id` sera transmise Ă  votre fonction dans l'argument `item_id`.
 
-La valeur du paramĂštre `item_id` sera transmise Ă  la fonction dans l'argument `item_id`.
-
-Donc, si vous exĂ©cutez cet exemple et allez sur <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>,
-vous verrez comme rĂ©ponse :
+Donc, si vous exĂ©cutez cet exemple et allez sur <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>, vous verrez comme rĂ©ponse :
 
 ```JSON
 {"item_id":"foo"}
 ```
 
-## ParamĂštres de chemin typĂ©s
-
-Vous pouvez dĂ©clarer le type d'un paramĂštre de chemin dans la fonction, en utilisant les annotations de type Python :
+## ParamĂštres de chemin typĂ©s { #path-parameters-with-types }
 
+Vous pouvez dĂ©clarer le type d'un paramĂštre de chemin dans la fonction, en utilisant les annotations de type Python standard :
 
-{* ../../docs_src/path_params/tutorial002.py hl[7] *}
+{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *}
 
 Ici, `item_id` est dĂ©clarĂ© comme `int`.
 
-/// check | vĂ©rifier
+/// check | VĂ©rifications
 
-Ceci vous permettra d'obtenir des fonctionnalitĂ©s de l'Ă©diteur dans votre fonction, telles
-que des vĂ©rifications d'erreur, de l'auto-complĂ©tion, etc.
+Cela vous apporte la prise en charge par l'Ă©diteur dans votre fonction, avec vĂ©rifications d'erreurs, autocomplĂ©tion, etc.
 
 ///
 
-## <abbr title="aussi appelĂ© sĂ©rialisation, ou parfois parsing ou marshalling en anglais">Conversion</abbr> de donnĂ©es
+## <abbr title="Ă©galement appelĂ© : sĂ©rialisation, parsing, marshalling">Conversion</abbr> de donnĂ©es { #data-conversion }
 
-Si vous exĂ©cutez cet exemple et allez sur <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a>, vous aurez comme rĂ©ponse :
+Si vous exĂ©cutez cet exemple et ouvrez votre navigateur sur <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a>, vous verrez comme rĂ©ponse :
 
 ```JSON
 {"item_id":3}
 ```
 
-/// check | vĂ©rifier
+/// check | VĂ©rifications
 
-Comme vous l'avez remarquĂ©, la valeur reçue par la fonction (et renvoyĂ©e ensuite) est `3`,
-en tant qu'entier (`int`) Python, pas la chaĂźne de caractĂšres (`string`) `"3"`.
+Remarquez que la valeur reçue par votre fonction (et renvoyĂ©e) est `3`, en tant qu'entier (`int`) Python, pas la chaĂźne de caractĂšres Â« 3 Â».
 
-GrĂące aux dĂ©clarations de types, **FastAPI** fournit du
-<abbr title="conversion de la chaĂźne de caractĂšres venant de la requĂȘte HTTP en donnĂ©es Python">"parsing"</abbr> automatique.
+Ainsi, avec cette dĂ©claration de type, **FastAPI** vous fournit automatiquement le <abbr title="conversion de la chaĂźne de caractĂšres provenant d'une requĂȘte HTTP en donnĂ©es Python">« parsing Â»</abbr> de la requĂȘte.
 
 ///
 
-## Validation de donnĂ©es
+## Validation de donnĂ©es { #data-validation }
 
-Si vous allez sur <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>, vous aurez une belle erreur HTTP :
+Mais si vous allez dans le navigateur sur <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>, vous verrez une belle erreur HTTP :
 
 ```JSON
 {
-    "detail": [
-        {
-            "loc": [
-                "path",
-                "item_id"
-            ],
-            "msg": "value is not a valid integer",
-            "type": "type_error.integer"
-        }
-    ]
+  "detail": [
+    {
+      "type": "int_parsing",
+      "loc": [
+        "path",
+        "item_id"
+      ],
+      "msg": "Input should be a valid integer, unable to parse string as an integer",
+      "input": "foo"
+    }
+  ]
 }
 ```
 
-car le paramĂštre de chemin `item_id` possĂšde comme valeur `"foo"`, qui ne peut pas ĂȘtre convertie en entier (`int`).
-
-La mĂȘme erreur se produira si vous passez un nombre flottant (`float`) et non un entier, comme ici
-<a href="http://127.0.0.1:8000/items/4.2" class="external-link" target="_blank">http://127.0.0.1:8000/items/4.2</a>.
+car le paramĂštre de chemin `item_id` a pour valeur Â« foo Â», qui n'est pas un `int`.
 
+La mĂȘme erreur apparaĂźtrait si vous fournissiez un `float` au lieu d'un `int`, comme ici : <a href="http://127.0.0.1:8000/items/4.2" class="external-link" target="_blank">http://127.0.0.1:8000/items/4.2</a>
 
-/// check | vĂ©rifier
+/// check | VĂ©rifications
 
-Donc, avec ces mĂȘmes dĂ©clarations de type Python, **FastAPI** vous fournit de la validation de donnĂ©es.
+Ainsi, avec la mĂȘme dĂ©claration de type Python, **FastAPI** vous fournit la validation de donnĂ©es.
 
-Notez que l'erreur mentionne le point exact oĂč la validation n'a pas rĂ©ussi.
+Remarquez que l'erreur indique clairement l'endroit exact oĂč la validation n'a pas rĂ©ussi.
 
-Ce qui est incroyablement utile au moment de dĂ©velopper et dĂ©bugger du code qui interagit avec votre API.
+C'est incroyablement utile lors du dĂ©veloppement et du dĂ©bogage du code qui interagit avec votre API.
 
 ///
 
-## Documentation
+## Documentation { #documentation }
 
-Et quand vous vous rendez sur <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, vous verrez la
-documentation gĂ©nĂ©rĂ©e automatiquement et interactive :
+Et lorsque vous ouvrez votre navigateur sur <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, vous verrez une documentation d'API automatique et interactive comme :
 
 <img src="/img/tutorial/path-params/image01.png">
 
-/// info
+/// check | VĂ©rifications
 
-À nouveau, en utilisant uniquement les dĂ©clarations de type Python, **FastAPI** vous fournit automatiquement une documentation interactive (via Swagger UI).
+À nouveau, simplement avec cette mĂȘme dĂ©claration de type Python, **FastAPI** vous fournit une documentation interactive automatique (intĂ©grant Swagger UI).
 
-On voit bien dans la documentation que `item_id` est dĂ©clarĂ© comme entier.
+Remarquez que le paramĂštre de chemin est dĂ©clarĂ© comme entier.
 
 ///
 
-## Les avantages d'avoir une documentation basĂ©e sur une norme, et la documentation alternative.
+## Les avantages d'une norme, documentation alternative { #standards-based-benefits-alternative-documentation }
 
-Le schĂ©ma gĂ©nĂ©rĂ© suivant la norme <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md" class="external-link" target="_blank">OpenAPI</a>,
-il existe de nombreux outils compatibles.
+Et comme le schĂ©ma gĂ©nĂ©rĂ© suit la norme <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md" class="external-link" target="_blank">OpenAPI</a>, il existe de nombreux outils compatibles.
 
-GrĂące Ă  cela, **FastAPI** lui-mĂȘme fournit une documentation alternative (utilisant ReDoc), qui peut ĂȘtre lue
-sur <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> :
+GrĂące Ă  cela, **FastAPI** fournit lui-mĂȘme une documentation d'API alternative (utilisant ReDoc), accessible sur <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> :
 
 <img src="/img/tutorial/path-params/image02.png">
 
-De la mĂȘme façon, il existe bien d'autres outils compatibles, y compris des outils de gĂ©nĂ©ration de code
-pour de nombreux langages.
+De la mĂȘme façon, il existe de nombreux outils compatibles, y compris des outils de gĂ©nĂ©ration de code pour de nombreux langages.
 
-## Pydantic
+## Pydantic { #pydantic }
 
-Toute la validation de donnĂ©es est effectuĂ© en arriĂšre-plan avec <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>,
-dont vous bĂ©nĂ©ficierez de tous les avantages. Vous savez donc que vous ĂȘtes entre de bonnes mains.
+Toute la validation de donnĂ©es est effectuĂ©e sous le capot par <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>, vous en bĂ©nĂ©ficiez donc pleinement. Vous savez ainsi que vous ĂȘtes entre de bonnes mains.
 
-## L'ordre importe
+Vous pouvez utiliser les mĂȘmes dĂ©clarations de type avec `str`, `float`, `bool` et de nombreux autres types de donnĂ©es complexes.
 
-Quand vous crĂ©ez des *fonctions de chemins*, vous pouvez vous retrouver dans une situation oĂč vous avez un chemin fixe.
+Plusieurs d'entre eux sont explorĂ©s dans les prochains chapitres du tutoriel.
 
-Tel que `/users/me`, disons pour rĂ©cupĂ©rer les donnĂ©es sur l'utilisateur actuel.
+## L'ordre importe { #order-matters }
 
-Et vous avez un second chemin : `/users/{user_id}` pour rĂ©cupĂ©rer de la donnĂ©e sur un utilisateur spĂ©cifique grĂące Ă  son identifiant d'utilisateur
+Quand vous crĂ©ez des *chemins d'accĂšs*, vous pouvez vous retrouver dans une situation avec un chemin fixe.
 
-Les *fonctions de chemin* Ă©tant Ă©valuĂ©es dans l'ordre, il faut s'assurer que la fonction correspondant Ă  `/users/me` est dĂ©clarĂ©e avant celle de `/users/{user_id}` :
+Par exemple `/users/me`, disons pour rĂ©cupĂ©rer les donnĂ©es de l'utilisateur actuel.
 
-{* ../../docs_src/path_params/tutorial003.py hl[6,11] *}
+Et vous pouvez aussi avoir un chemin `/users/{user_id}` pour rĂ©cupĂ©rer des donnĂ©es sur un utilisateur spĂ©cifique grĂące Ă  un identifiant d'utilisateur.
 
-Sinon, le chemin `/users/{user_id}` correspondrait aussi Ă  `/users/me`, la fonction "croyant" qu'elle a reçu un paramĂštre `user_id` avec pour valeur `"me"`.
+Comme les *chemins d'accĂšs* sont Ă©valuĂ©s dans l'ordre, vous devez vous assurer que le chemin `/users/me` est dĂ©clarĂ© avant celui de `/users/{user_id}` :
 
-## Valeurs prĂ©dĂ©finies
+{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *}
 
-Si vous avez une *fonction de chemin* qui reçoit un *paramĂštre de chemin*, mais que vous voulez que les valeurs possibles des paramĂštres soient prĂ©dĂ©finies, vous pouvez utiliser les <abbr title="Enumeration">`Enum`</abbr> de Python.
+Sinon, le chemin `/users/{user_id}` correspondrait aussi Ă  `/users/me`, Â« pensant Â» qu'il reçoit un paramĂštre `user_id` avec la valeur Â« me Â».
 
-### CrĂ©ation d'un `Enum`
+De mĂȘme, vous ne pouvez pas redĂ©finir un chemin d'accĂšs :
 
-Importez `Enum` et crĂ©ez une sous-classe qui hĂ©rite de `str` et `Enum`.
+{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
 
-En hĂ©ritant de `str` la documentation sera capable de savoir que les valeurs doivent ĂȘtre de type `string` et pourra donc afficher cette `Enum` correctement.
+Le premier sera toujours utilisĂ© puisque le chemin correspond en premier.
 
-CrĂ©ez ensuite des attributs de classe avec des valeurs fixes, qui seront les valeurs autorisĂ©es pour cette Ă©numĂ©ration.
+## Valeurs prĂ©dĂ©finies { #predefined-values }
 
-{* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *}
+Si vous avez un *chemin d'accĂšs* qui reçoit un *paramĂštre de chemin*, mais que vous voulez que les valeurs possibles de ce *paramĂštre de chemin* soient prĂ©dĂ©finies, vous pouvez utiliser une <abbr title="Enumeration">`Enum`</abbr> Python standard.
 
-/// info
+### CrĂ©er une classe `Enum` { #create-an-enum-class }
 
-<a href="https://docs.python.org/3/library/enum.html" class="external-link" target="_blank">Les Ă©numĂ©rations (ou enums) sont disponibles en Python</a> depuis la version 3.4.
+Importez `Enum` et crĂ©ez une sous-classe qui hĂ©rite de `str` et de `Enum`.
 
-///
+En hĂ©ritant de `str`, la documentation de l'API saura que les valeurs doivent ĂȘtre de type `string` et pourra donc s'afficher correctement.
+
+CrĂ©ez ensuite des attributs de classe avec des valeurs fixes, qui seront les valeurs valides disponibles :
+
+{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *}
 
 /// tip | Astuce
 
-Pour ceux qui se demandent, "AlexNet", "ResNet", et "LeNet" sont juste des noms de <abbr title="Techniquement, des architectures de modĂšles">modĂšles</abbr> de Machine Learning.
+Si vous vous demandez, Â« AlexNet Â», Â« ResNet Â» et Â« LeNet Â» sont juste des noms de <abbr title="Techniquement, architectures de modĂšles de Deep Learning">modĂšles</abbr> de Machine Learning.
 
 ///
 
-### DĂ©clarer un paramĂštre de chemin
+### DĂ©clarer un paramĂštre de chemin { #declare-a-path-parameter }
 
-CrĂ©ez ensuite un *paramĂštre de chemin* avec une annotation de type dĂ©signant l'Ă©numĂ©ration créée prĂ©cĂ©demment (`ModelName`) :
+CrĂ©ez ensuite un *paramĂštre de chemin* avec une annotation de type utilisant la classe d'Ă©numĂ©ration que vous avez créée (`ModelName`) :
 
-{* ../../docs_src/path_params/tutorial005.py hl[16] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}
 
-### Documentation
+### Consulter la documentation { #check-the-docs }
 
-Les valeurs disponibles pour le *paramĂštre de chemin* sont bien prĂ©dĂ©finies, la documentation les affiche correctement :
+Comme les valeurs disponibles pour le *paramĂštre de chemin* sont prĂ©dĂ©finies, la documentation interactive peut les afficher clairement :
 
 <img src="/img/tutorial/path-params/image03.png">
 
-### Manipuler les *Ă©numĂ©rations* Python
+### Travailler avec les *Ă©numĂ©rations* Python { #working-with-python-enumerations }
 
-La valeur du *paramĂštre de chemin* sera un des "membres" de l'Ă©numĂ©ration.
+La valeur du *paramĂštre de chemin* sera un *membre d'Ă©numĂ©ration*.
 
-#### Comparer les *membres d'Ă©numĂ©ration*
+#### Comparer des *membres d'Ă©numĂ©ration* { #compare-enumeration-members }
 
-Vous pouvez comparer ce paramĂštre avec les membres de votre Ă©numĂ©ration `ModelName` :
+Vous pouvez le comparer avec le *membre d'Ă©numĂ©ration* dans votre enum `ModelName` :
 
-{* ../../docs_src/path_params/tutorial005.py hl[17] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *}
 
-#### RĂ©cupĂ©rer la *valeur de l'Ă©numĂ©ration*
+#### Obtenir la *valeur de l'Ă©numĂ©ration* { #get-the-enumeration-value }
 
-Vous pouvez obtenir la valeur rĂ©el d'un membre (une chaĂźne de caractĂšres ici), avec `model_name.value`, ou en gĂ©nĂ©ral, `votre_membre_d'enum.value` :
+Vous pouvez obtenir la valeur rĂ©elle (une `str` dans ce cas) avec `model_name.value`, ou en gĂ©nĂ©ral, `votre_membre_d_enum.value` :
 
-{* ../../docs_src/path_params/tutorial005.py hl[20] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}
 
 /// tip | Astuce
 
-Vous pouvez aussi accĂ©der la valeur `"lenet"` avec `ModelName.lenet.value`.
+Vous pouvez aussi accĂ©der Ă  la valeur Â« lenet Â» avec `ModelName.lenet.value`.
 
 ///
 
-#### Retourner des *membres d'Ă©numĂ©ration*
+#### Retourner des *membres d'Ă©numĂ©ration* { #return-enumeration-members }
 
-Vous pouvez retourner des *membres d'Ă©numĂ©ration* dans vos *fonctions de chemin*, mĂȘme imbriquĂ©e dans un JSON (e.g. un `dict`).
+Vous pouvez retourner des *membres d'Ă©numĂ©ration* depuis votre *chemin d'accĂšs*, mĂȘme imbriquĂ©s dans un corps JSON (par ex. un `dict`).
 
-Ils seront convertis vers leurs valeurs correspondantes (chaĂźnes de caractĂšres ici) avant d'ĂȘtre transmis au client :
+Ils seront convertis vers leurs valeurs correspondantes (des chaĂźnes de caractĂšres ici) avant d'ĂȘtre renvoyĂ©s au client :
 
-{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}
 
-Le client recevra une rĂ©ponse JSON comme celle-ci :
+Dans votre client, vous recevrez une rĂ©ponse JSON comme :
 
 ```JSON
 {
@@ -208,53 +199,53 @@ Le client recevra une rĂ©ponse JSON comme celle-ci :
 }
 ```
 
-## ParamĂštres de chemin contenant des chemins
+## ParamĂštres de chemin contenant des chemins { #path-parameters-containing-paths }
 
-Disons que vous avez une *fonction de chemin* liĂ©e au chemin `/files/{file_path}`.
+Disons que vous avez un *chemin d'accĂšs* avec un chemin `/files/{file_path}`.
 
-Mais que `file_path` lui-mĂȘme doit contenir un *chemin*, comme `home/johndoe/myfile.txt` par exemple.
+Mais vous avez besoin que `file_path` lui-mĂȘme contienne un *chemin*, comme `home/johndoe/myfile.txt`.
 
-Donc, l'URL pour ce fichier pourrait ĂȘtre : `/files/home/johndoe/myfile.txt`.
+Ainsi, l'URL pour ce fichier serait : `/files/home/johndoe/myfile.txt`.
 
-### Support d'OpenAPI
+### Support d'OpenAPI { #openapi-support }
 
-OpenAPI ne supporte pas de maniĂšre de dĂ©clarer un paramĂštre de chemin contenant un *chemin*, cela pouvant causer des scĂ©narios difficiles Ă  tester et dĂ©finir.
+OpenAPI ne prend pas en charge une maniĂšre de dĂ©clarer un *paramĂštre de chemin* contenant un *chemin* Ă  l'intĂ©rieur, car cela peut conduire Ă  des scĂ©narios difficiles Ă  tester et Ă  dĂ©finir.
 
-NĂ©anmoins, cela reste faisable dans **FastAPI**, via les outils internes de Starlette.
+NĂ©anmoins, vous pouvez toujours le faire dans **FastAPI**, en utilisant l'un des outils internes de Starlette.
 
-Et la documentation fonctionne quand mĂȘme, bien qu'aucune section ne soit ajoutĂ©e pour dire que la paramĂštre devrait contenir un *chemin*.
+Et la documentation fonctionnera quand mĂȘme, mĂȘme si aucune indication supplĂ©mentaire ne sera ajoutĂ©e pour dire que le paramĂštre doit contenir un chemin.
 
-### Convertisseur de *chemin*
+### Convertisseur de chemin { #path-convertor }
 
-En utilisant une option de Starlette directement, vous pouvez dĂ©clarer un *paramĂštre de chemin* contenant un *chemin* avec une URL comme :
+En utilisant une option directement depuis Starlette, vous pouvez dĂ©clarer un *paramĂštre de chemin* contenant un *chemin* avec une URL comme :
 
 ```
 /files/{file_path:path}
 ```
 
-Dans ce cas, le nom du paramĂštre est `file_path`, et la derniĂšre partie, `:path`, indique Ă  Starlette que le paramĂštre devrait correspondre Ă  un *chemin*.
+Dans ce cas, le nom du paramĂštre est `file_path`, et la derniĂšre partie, `:path`, indique que le paramĂštre doit correspondre Ă  n'importe quel *chemin*.
 
-Vous pouvez donc l'utilisez comme tel :
+Vous pouvez donc l'utiliser ainsi :
 
-{* ../../docs_src/path_params/tutorial004.py hl[6] *}
+{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
 
 /// tip | Astuce
 
-Vous pourriez avoir besoin que le paramĂštre contienne `/home/johndoe/myfile.txt`, avec un slash au dĂ©but (`/`).
+Vous pourriez avoir besoin que le paramĂštre contienne `/home/johndoe/myfile.txt`, avec un slash initial (`/`).
 
 Dans ce cas, l'URL serait : `/files//home/johndoe/myfile.txt`, avec un double slash (`//`) entre `files` et `home`.
 
 ///
 
-## RĂ©capitulatif
+## RĂ©capitulatif { #recap }
 
-Avec **FastAPI**, en utilisant les dĂ©clarations de type rapides, intuitives et standards de Python, vous bĂ©nĂ©ficiez de :
+Avec **FastAPI**, en utilisant des dĂ©clarations de type Python courtes, intuitives et standard, vous obtenez :
 
-* Support de l'Ă©diteur : vĂ©rification d'erreurs, auto-complĂ©tion, etc.
-* <abbr title="conversion de la chaĂźne de caractĂšres venant de la requĂȘte HTTP en donnĂ©es Python">"Parsing"</abbr> de donnĂ©es.
-* Validation de donnĂ©es.
-* Annotations d'API et documentation automatique.
+* Support de l'Ă©diteur : vĂ©rifications d'erreurs, autocomplĂ©tion, etc.
+* DonnĂ©es Â« <abbr title="conversion de la chaĂźne de caractĂšres provenant d'une requĂȘte HTTP en donnĂ©es Python">parsing</abbr> Â»
+* Validation de donnĂ©es
+* Annotations d'API et documentation automatique
 
-Et vous n'avez besoin de le dĂ©clarer qu'une fois.
+Et vous n'avez besoin de les dĂ©clarer qu'une seule fois.
 
-C'est probablement l'avantage visible principal de **FastAPI** comparĂ© aux autres *frameworks* (outre les performances pures).
+C'est probablement l'avantage visible principal de **FastAPI** comparĂ© aux autres frameworks (outre les performances pures).
index c54c0c717165d195f68651538f9ccf13f16ecae1..544d10328e78d20eb412185290aebf31de10c3ee 100644 (file)
-# ParamĂštres de requĂȘte et validations de chaĂźnes de caractĂšres
+# ParamĂštres de requĂȘte et validations de chaĂźnes de caractĂšres { #query-parameters-and-string-validations }
 
-**FastAPI** vous permet de dĂ©clarer des informations et des validateurs additionnels pour vos paramĂštres de requĂȘtes.
+**FastAPI** vous permet de dĂ©clarer des informations et des validations supplĂ©mentaires pour vos paramĂštres.
 
-Commençons avec cette application pour exemple :
+Prenons cette application comme exemple :
 
-{* ../../docs_src/query_params_str_validations/tutorial001.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial001_py310.py hl[7] *}
 
-Le paramĂštre de requĂȘte `q` a pour type `Union[str, None]` (ou `str | None` en Python 3.10), signifiant qu'il est de type `str` mais pourrait aussi ĂȘtre Ă©gal Ă  `None`, et bien sĂ»r, la valeur par dĂ©faut est `None`, donc **FastAPI** saura qu'il n'est pas requis.
+Le paramĂštre de requĂȘte `q` est de type `str | None`, cela signifie qu’il est de type `str` mais peut aussi ĂȘtre `None`, et en effet, la valeur par dĂ©faut est `None`, donc FastAPI saura qu’il n’est pas requis.
 
-/// note
+/// note | Remarque
 
-**FastAPI** saura que la valeur de `q` n'est pas requise grĂące Ă  la valeur par dĂ©faut `= None`.
+FastAPI saura que la valeur de `q` n’est pas requise grĂące Ă  la valeur par dĂ©faut `= None`.
 
-Le `Union` dans `Union[str, None]` permettra Ă  votre Ă©diteur de vous offrir un meilleur support et de dĂ©tecter les erreurs.
+Avoir `str | None` permettra Ă  votre Ă©diteur de vous offrir un meilleur support et de dĂ©tecter les erreurs.
 
 ///
 
-## Validation additionnelle
+## Validation additionnelle { #additional-validation }
 
-Nous allons imposer que bien que `q` soit un paramĂštre optionnel, dĂšs qu'il est fourni, **sa longueur n'excĂšde pas 50 caractĂšres**.
+Nous allons imposer que, mĂȘme si `q` est optionnel, dĂšs qu’il est fourni, **sa longueur n’excĂšde pas 50 caractĂšres**.
 
-## Importer `Query`
+### Importer `Query` et `Annotated` { #import-query-and-annotated }
 
-Pour cela, importez d'abord `Query` depuis `fastapi` :
+Pour ce faire, importez d’abord :
 
-{* ../../docs_src/query_params_str_validations/tutorial002.py hl[3] *}
+- `Query` depuis `fastapi`
+- `Annotated` depuis `typing`
 
-## Utiliser `Query` comme valeur par dĂ©faut
+{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[1,3] *}
 
-Construisez ensuite la valeur par dĂ©faut de votre paramĂštre avec `Query`, en choisissant 50 comme `max_length` :
+/// info
 
-{* ../../docs_src/query_params_str_validations/tutorial002.py hl[9] *}
+FastAPI a ajoutĂ© la prise en charge de `Annotated` (et a commencĂ© Ă  le recommander) dans la version 0.95.0.
 
-Comme nous devons remplacer la valeur par dĂ©faut `None` dans la fonction par `Query()`, nous pouvons maintenant dĂ©finir la valeur par dĂ©faut avec le paramĂštre `Query(default=None)`, il sert le mĂȘme objectif qui est de dĂ©finir cette valeur par dĂ©faut.
+Si vous avez une version plus ancienne, vous obtiendrez des erreurs en essayant d’utiliser `Annotated`.
 
-Donc :
+Assurez-vous de [mettre Ă  niveau la version de FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} vers au moins 0.95.1 avant d’utiliser `Annotated`.
+
+///
+
+## Utiliser `Annotated` dans le type pour le paramĂštre `q` { #use-annotated-in-the-type-for-the-q-parameter }
+
+Vous vous souvenez que je vous ai dit plus tĂŽt que `Annotated` peut ĂȘtre utilisĂ© pour ajouter des mĂ©tadonnĂ©es Ă  vos paramĂštres dans l’[Introduction aux types Python](../python-types.md#type-hints-with-metadata-annotations){.internal-link target=_blank} ?
+
+C’est le moment de l’utiliser avec FastAPI. đŸš€
+
+Nous avions cette annotation de type :
+
+//// tab | Python 3.10+
 
 ```Python
-q: Union[str, None] = Query(default=None)
+q: str | None = None
 ```
 
-... rend le paramĂštre optionnel, et est donc Ă©quivalent Ă  :
+////
+
+//// tab | Python 3.9+
 
 ```Python
 q: Union[str, None] = None
 ```
 
-Mais dĂ©clare explicitement `q` comme Ă©tant un paramĂštre de requĂȘte.
+////
 
-/// info
+Ce que nous allons faire, c’est l’englober avec `Annotated`, de sorte que cela devienne :
 
-Gardez Ă  l'esprit que la partie la plus importante pour rendre un paramĂštre optionnel est :
+//// tab | Python 3.10+
 
 ```Python
-= None
+q: Annotated[str | None] = None
 ```
 
-ou :
+////
+
+//// tab | Python 3.9+
 
 ```Python
-= Query(None)
+q: Annotated[Union[str, None]] = None
 ```
 
-et utilisera ce `None` pour dĂ©tecter que ce paramĂštre de requĂȘte **n'est pas requis**.
+////
+
+Les deux versions signifient la mĂȘme chose, `q` est un paramĂštre qui peut ĂȘtre une `str` ou `None`, et par dĂ©faut, c’est `None`.
+
+Passons maintenant aux choses amusantes. đŸŽ‰
 
-Le `Union[str, None]` est uniquement lĂ  pour permettre Ă  votre Ă©diteur un meilleur support.
+## Ajouter `Query` Ă  `Annotated` dans le paramĂštre `q` { #add-query-to-annotated-in-the-q-parameter }
+
+Maintenant que nous avons cet `Annotated` dans lequel nous pouvons mettre plus d’informations (dans ce cas une validation supplĂ©mentaire), ajoutez `Query` Ă  l’intĂ©rieur de `Annotated`, et dĂ©finissez le paramĂštre `max_length` Ă  `50` :
+
+{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[9] *}
+
+Remarquez que la valeur par dĂ©faut est toujours `None`, donc le paramĂštre est toujours optionnel.
+
+Mais maintenant, avec `Query(max_length=50)` Ă  l’intĂ©rieur de `Annotated`, nous indiquons Ă  FastAPI que nous voulons **une validation supplĂ©mentaire** pour cette valeur, nous voulons qu’elle ait au maximum 50 caractĂšres. đŸ˜Ž
+
+/// tip | Astuce
+
+Ici nous utilisons `Query()` parce qu’il s’agit d’un **paramĂštre de requĂȘte**. Plus tard nous verrons d’autres comme `Path()`, `Body()`, `Header()` et `Cookie()`, qui acceptent Ă©galement les mĂȘmes arguments que `Query()`.
 
 ///
 
-Ensuite, nous pouvons passer d'autres paramĂštres Ă  `Query`. Dans cet exemple, le paramĂštre `max_length` qui s'applique aux chaĂźnes de caractĂšres :
+FastAPI va maintenant :
+
+- **Valider** les donnĂ©es en s’assurant que la longueur maximale est de 50 caractĂšres
+- Afficher une **erreur claire** au client quand les donnĂ©es ne sont pas valides
+- **Documenter** le paramĂštre dans la *chemin d'accĂšs* du schĂ©ma OpenAPI (il apparaĂźtra donc dans l’**interface de documentation automatique**)
+
+## Alternative (ancienne) : `Query` comme valeur par dĂ©faut { #alternative-old-query-as-the-default-value }
+
+Les versions prĂ©cĂ©dentes de FastAPI (avant <abbr title="avant 2023-03">0.95.0</abbr>) exigeaient d’utiliser `Query` comme valeur par dĂ©faut de votre paramĂštre, au lieu de le mettre dans `Annotated`. Il y a de fortes chances que vous voyiez du code qui l’utilise encore, je vais donc vous l’expliquer.
+
+/// tip | Astuce
+
+Pour du nouveau code et dĂšs que possible, utilisez `Annotated` comme expliquĂ© ci-dessus. Il y a de multiples avantages (expliquĂ©s ci-dessous) et aucun inconvĂ©nient. đŸ°
+
+///
+
+Voici comment vous utiliseriez `Query()` comme valeur par dĂ©faut du paramĂštre de votre fonction, en dĂ©finissant le paramĂštre `max_length` Ă  50 :
+
+{* ../../docs_src/query_params_str_validations/tutorial002_py310.py hl[7] *}
+
+Comme, dans ce cas (sans utiliser `Annotated`), nous devons remplacer la valeur par dĂ©faut `None` dans la fonction par `Query()`, nous devons maintenant dĂ©finir la valeur par dĂ©faut avec le paramĂštre `Query(default=None)`, cela sert le mĂȘme objectif de dĂ©finir cette valeur par dĂ©faut (au moins pour FastAPI).
+
+Donc :
+
+```Python
+q: str | None = Query(default=None)
+```
+
+... rend le paramĂštre optionnel, avec une valeur par dĂ©faut de `None`, comme :
+
+```Python
+q: str | None = None
+```
+
+Mais la version avec `Query` le dĂ©clare explicitement comme Ă©tant un paramĂštre de requĂȘte.
+
+Ensuite, nous pouvons passer plus de paramĂštres Ă  `Query`. Dans ce cas, le paramĂštre `max_length` qui s’applique aux chaĂźnes de caractĂšres :
+
+```Python
+q: str | None = Query(default=None, max_length=50)
+```
+
+Cela validera les donnĂ©es, affichera une erreur claire lorsque les donnĂ©es ne sont pas valides et documentera le paramĂštre dans la *chemin d'accĂšs* du schĂ©ma OpenAPI.
+
+### `Query` comme valeur par dĂ©faut ou dans `Annotated` { #query-as-the-default-value-or-in-annotated }
+
+Gardez Ă  l’esprit qu’en utilisant `Query` Ă  l’intĂ©rieur de `Annotated`, vous ne pouvez pas utiliser le paramĂštre `default` de `Query`.
+
+Utilisez Ă  la place la valeur par dĂ©faut rĂ©elle du paramĂštre de fonction. Sinon, ce serait incohĂ©rent.
+
+Par exemple, ceci n’est pas autorisĂ© :
+
+```Python
+q: Annotated[str, Query(default="rick")] = "morty"
+```
+
+... parce qu’il n’est pas clair si la valeur par dĂ©faut doit ĂȘtre Â« rick Â» ou Â« morty Â».
+
+Donc, vous utiliseriez (de prĂ©fĂ©rence) :
 
 ```Python
-q: Union[str, None] = Query(default=None, max_length=50)
+q: Annotated[str, Query()] = "rick"
 ```
 
-Cela va valider les donnĂ©es, montrer une erreur claire si ces derniĂšres ne sont pas valides, et documenter le paramĂštre dans le schĂ©ma `OpenAPI` de cette *path operation*.
+... ou dans des bases de code plus anciennes, vous trouverez :
+
+```Python
+q: str = Query(default="rick")
+```
+
+### Avantages de `Annotated` { #advantages-of-annotated }
+
+**L’utilisation de `Annotated` est recommandĂ©e** plutĂŽt que la valeur par dĂ©faut dans les paramĂštres de fonction, c’est **mieux** pour plusieurs raisons. đŸ€“
+
+La valeur **par dĂ©faut** du **paramĂštre de fonction** est la **vraie valeur par dĂ©faut**, c’est plus intuitif en Python en gĂ©nĂ©ral. đŸ˜Œ
 
-## Rajouter plus de validation
+Vous pouvez **appeler** cette mĂȘme fonction dans **d’autres endroits** sans FastAPI, et elle **fonctionnera comme prĂ©vu**. S’il y a un paramĂštre **requis** (sans valeur par dĂ©faut), votre **Ă©diteur** vous le signalera avec une erreur, **Python** se plaindra aussi si vous l’exĂ©cutez sans passer le paramĂštre requis.
 
-Vous pouvez aussi rajouter un second paramĂštre `min_length` :
+Quand vous n’utilisez pas `Annotated` et utilisez Ă  la place l’**ancienne** mĂ©thode avec la **valeur par dĂ©faut**, si vous appelez cette fonction sans FastAPI dans **d’autres endroits**, vous devez **penser** Ă  passer les arguments Ă  la fonction pour qu’elle fonctionne correctement, sinon les valeurs seront diffĂ©rentes de ce que vous attendez (par ex. `QueryInfo` ou quelque chose de similaire au lieu d’une `str`). Et votre Ă©diteur ne se plaindra pas, et Python ne se plaindra pas en exĂ©cutant cette fonction, seulement quand les opĂ©rations internes Ă©choueront.
 
-{* ../../docs_src/query_params_str_validations/tutorial003.py hl[9] *}
+Comme `Annotated` peut avoir plus d’une annotation de mĂ©tadonnĂ©es, vous pouvez maintenant mĂȘme utiliser la mĂȘme fonction avec d’autres outils, comme <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">Typer</a>. đŸš€
 
-## Ajouter des validations par expressions rĂ©guliĂšres
+## Ajouter plus de validations { #add-more-validations }
 
-On peut dĂ©finir une <abbr title="Une expression rĂ©guliĂšre, regex ou regexp est une suite de caractĂšres qui dĂ©finit un pattern de correspondance pour les chaĂźnes de caractĂšres.">expression rĂ©guliĂšre</abbr> Ă  laquelle le paramĂštre doit correspondre :
+Vous pouvez Ă©galement ajouter un paramĂštre `min_length` :
 
-{* ../../docs_src/query_params_str_validations/tutorial004.py hl[10] *}
+{* ../../docs_src/query_params_str_validations/tutorial003_an_py310.py hl[10] *}
 
-Cette expression rĂ©guliĂšre vĂ©rifie que la valeur passĂ©e comme paramĂštre :
+## Ajouter des expressions rĂ©guliĂšres { #add-regular-expressions }
 
-* `^` : commence avec les caractĂšres qui suivent, avec aucun caractĂšre avant ceux-lĂ .
-* `fixedquery` : a pour valeur exacte `fixedquery`.
-* `$` : se termine directement ensuite, n'a pas d'autres caractĂšres aprĂšs `fixedquery`.
+Vous pouvez dĂ©finir un `pattern` d’<abbr title="Une expression rĂ©guliĂšre, regex ou regexp, est une suite de caractĂšres qui dĂ©finit un motif de recherche pour les chaĂźnes de caractĂšres.">expression rĂ©guliĂšre</abbr> auquel le paramĂštre doit correspondre :
 
-Si vous vous sentez perdu avec le concept d'**expression rĂ©guliĂšre**, pas d'inquiĂ©tudes. Il s'agit d'une notion difficile pour beaucoup, et l'on peut dĂ©jĂ  rĂ©ussir Ă  faire beaucoup sans jamais avoir Ă  les manipuler.
+{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
 
-Mais si vous dĂ©cidez d'apprendre Ă  les utiliser, sachez qu'ensuite vous pouvez les utiliser directement dans **FastAPI**.
+Ce pattern d’expression rĂ©guliĂšre spĂ©cifique vĂ©rifie que la valeur reçue pour le paramĂštre :
 
-## Valeurs par dĂ©faut
+- `^` : commence avec les caractĂšres qui suivent, n’a pas de caractĂšres avant.
+- `fixedquery` : a exactement la valeur `fixedquery`.
+- `$` : se termine lĂ , n’a pas d’autres caractĂšres aprĂšs `fixedquery`.
 
-De la mĂȘme façon que vous pouvez passer `None` comme premier argument pour l'utiliser comme valeur par dĂ©faut, vous pouvez passer d'autres valeurs.
+Si vous vous sentez perdu avec toutes ces idĂ©es d’**« expression rĂ©guliĂšre Â»**, pas d’inquiĂ©tude. C’est un sujet difficile pour beaucoup. Vous pouvez dĂ©jĂ  faire beaucoup de choses sans avoir besoin d’expressions rĂ©guliĂšres.
 
-Disons que vous dĂ©clarez le paramĂštre `q` comme ayant une longueur minimale de `3`, et une valeur par dĂ©faut Ă©tant `"fixedquery"` :
+DĂ©sormais, vous savez que, lorsque vous en aurez besoin, vous pourrez les utiliser dans **FastAPI**.
 
-{* ../../docs_src/query_params_str_validations/tutorial005.py hl[7] *}
+## Valeurs par dĂ©faut { #default-values }
 
-/// note | Rappel
+Vous pouvez, bien sĂ»r, utiliser des valeurs par dĂ©faut autres que `None`.
 
-Avoir une valeur par dĂ©faut rend le paramĂštre optionnel.
+Disons que vous voulez dĂ©clarer le paramĂštre de requĂȘte `q` avec un `min_length` de `3`, et avec une valeur par dĂ©faut de Â« fixedquery Â» :
+
+{* ../../docs_src/query_params_str_validations/tutorial005_an_py39.py hl[9] *}
+
+/// note | Remarque
+
+Avoir une valeur par dĂ©faut de n’importe quel type, y compris `None`, rend le paramĂštre optionnel (non requis).
 
 ///
 
-## Rendre ce paramĂštre requis
+## ParamĂštres requis { #required-parameters }
 
-Quand on ne dĂ©clare ni validation, ni mĂ©tadonnĂ©e, on peut rendre le paramĂštre `q` requis en ne lui dĂ©clarant juste aucune valeur par dĂ©faut :
+Quand nous n’avons pas besoin de dĂ©clarer plus de validations ou de mĂ©tadonnĂ©es, nous pouvons rendre le paramĂštre de requĂȘte `q` requis en n’indiquant simplement pas de valeur par dĂ©faut, comme :
 
 ```Python
 q: str
 ```
 
-Ă  la place de :
+au lieu de :
 
 ```Python
-q: Union[str, None] = None
+q: str | None = None
 ```
 
-Mais maintenant, on dĂ©clare `q` avec `Query`, comme ceci :
+Mais maintenant nous le dĂ©clarons avec `Query`, par exemple ainsi :
 
 ```Python
-q: Union[str, None] = Query(default=None, min_length=3)
+q: Annotated[str | None, Query(min_length=3)] = None
 ```
 
-Donc pour dĂ©clarer une valeur comme requise tout en utilisant `Query`, il faut utiliser `...` comme premier argument :
+Donc, lorsque vous avez besoin de dĂ©clarer une valeur comme requise tout en utilisant `Query`, vous pouvez simplement ne pas dĂ©clarer de valeur par dĂ©faut :
 
-{* ../../docs_src/query_params_str_validations/tutorial006.py hl[7] *}
+{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
 
-/// info
+### Requis, peut valoir `None` { #required-can-be-none }
 
-Si vous n'avez jamais vu ce `...` auparavant : c'est une des constantes natives de Python <a href="https://docs.python.org/fr/3/library/constants.html#Ellipsis" class="external-link" target="_blank">appelĂ©e "Ellipsis"</a>.
+Vous pouvez dĂ©clarer qu’un paramĂštre accepte `None`, mais qu’il est tout de mĂȘme requis. Cela obligerait les clients Ă  envoyer une valeur, mĂȘme si la valeur est `None`.
 
-///
+Pour ce faire, vous pouvez dĂ©clarer que `None` est un type valide tout en ne dĂ©clarant pas de valeur par dĂ©faut :
 
-Cela indiquera Ă  **FastAPI** que la prĂ©sence de ce paramĂštre est obligatoire.
+{* ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py hl[9] *}
 
-## Liste de paramĂštres / valeurs multiples via Query
+## Liste de paramĂštres de requĂȘte / valeurs multiples { #query-parameter-list-multiple-values }
 
-Quand on dĂ©finit un paramĂštre de requĂȘte explicitement avec `Query` on peut aussi dĂ©clarer qu'il reçoit une liste de valeur, ou des "valeurs multiples".
+Quand vous dĂ©finissez un paramĂštre de requĂȘte explicitement avec `Query`, vous pouvez aussi dĂ©clarer qu’il reçoit une liste de valeurs, autrement dit, qu’il reçoit des valeurs multiples.
 
-Par exemple, pour dĂ©clarer un paramĂštre de requĂȘte `q` qui peut apparaĂźtre plusieurs fois dans une URL, on Ă©crit :
+Par exemple, pour dĂ©clarer un paramĂštre de requĂȘte `q` qui peut apparaĂźtre plusieurs fois dans l’URL, vous pouvez Ă©crire :
 
-{* ../../docs_src/query_params_str_validations/tutorial011.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial011_an_py310.py hl[9] *}
 
-Ce qui fait qu'avec une URL comme :
+Ensuite, avec une URL comme :
 
 ```
 http://localhost:8000/items/?q=foo&q=bar
 ```
 
-vous recevriez les valeurs des multiples paramĂštres de requĂȘte `q` (`foo` et `bar`) dans une `list` Python au sein de votre fonction de **path operation**, dans le paramĂštre de fonction `q`.
+vous recevriez les valeurs des multiples paramĂštres de requĂȘte `q` (`foo` et `bar`) dans une `list` Python Ă  l’intĂ©rieur de votre fonction de *chemin d'accĂšs*, dans le *paramĂštre de fonction* `q`.
 
-Donc la rĂ©ponse de cette URL serait :
+Donc, la rĂ©ponse pour cette URL serait :
 
 ```JSON
 {
@@ -173,19 +280,19 @@ Donc la rĂ©ponse de cette URL serait :
 
 /// tip | Astuce
 
-Pour dĂ©clarer un paramĂštre de requĂȘte de type `list`, comme dans l'exemple ci-dessus, il faut explicitement utiliser `Query`, sinon cela sera interprĂ©tĂ© comme faisant partie du corps de la requĂȘte.
+Pour dĂ©clarer un paramĂštre de requĂȘte avec un type `list`, comme dans l’exemple ci-dessus, vous devez explicitement utiliser `Query`, sinon il serait interprĂ©tĂ© comme faisant partie du corps de la requĂȘte.
 
 ///
 
-La documentation sera donc mise Ă  jour automatiquement pour autoriser plusieurs valeurs :
+L’interface de documentation interactive de l’API sera mise Ă  jour en consĂ©quence, pour autoriser plusieurs valeurs :
 
 <img src="/img/tutorial/query-params-str-validations/image02.png">
 
-### Combiner liste de paramĂštres et valeurs par dĂ©faut
+### Liste de paramĂštres de requĂȘte / valeurs multiples avec valeurs par dĂ©faut { #query-parameter-list-multiple-values-with-defaults }
 
-Et l'on peut aussi dĂ©finir une liste de valeurs par dĂ©faut si aucune n'est fournie :
+Vous pouvez Ă©galement dĂ©finir une `list` de valeurs par dĂ©faut si aucune n’est fournie :
 
-{* ../../docs_src/query_params_str_validations/tutorial012.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *}
 
 Si vous allez Ă  :
 
@@ -193,9 +300,7 @@ Si vous allez Ă  :
 http://localhost:8000/items/
 ```
 
-la valeur par dĂ©faut de `q` sera : `["foo", "bar"]`
-
-et la rĂ©ponse sera :
+la valeur par dĂ©faut de `q` sera : `["foo", "bar"]` et votre rĂ©ponse sera :
 
 ```JSON
 {
@@ -206,93 +311,163 @@ et la rĂ©ponse sera :
 }
 ```
 
-#### Utiliser `list`
+#### Utiliser simplement `list` { #using-just-list }
 
-Il est aussi possible d'utiliser directement `list` plutĂŽt que `List[str]` :
+Vous pouvez aussi utiliser `list` directement au lieu de `list[str]` :
 
-{* ../../docs_src/query_params_str_validations/tutorial013.py hl[7] *}
+{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
 
-/// note
+/// note | Remarque
 
-Dans ce cas-lĂ , **FastAPI** ne vĂ©rifiera pas le contenu de la liste.
+Gardez Ă  l’esprit que dans ce cas, 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.
+Par exemple, `list[int]` vĂ©rifierait (et documenterait) que le contenu de la liste est composĂ© d’entiers. Mais un simple `list` ne le ferait pas.
 
 ///
 
-## DĂ©clarer des mĂ©tadonnĂ©es supplĂ©mentaires
+## DĂ©clarer plus de mĂ©tadonnĂ©es { #declare-more-metadata }
 
-On peut aussi ajouter plus d'informations sur le paramĂštre.
+Vous pouvez ajouter plus d’informations Ă  propos du 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.
+Ces informations seront incluses dans l’OpenAPI gĂ©nĂ©rĂ© et utilisĂ©es par les interfaces de documentation et les outils externes.
 
-/// note
+/// note | Remarque
 
-Gardez en tĂȘte que les outils externes utilisĂ©s ne supportent pas forcĂ©ment tous parfaitement OpenAPI.
+Gardez Ă  l’esprit que diffĂ©rents outils peuvent avoir des niveaux de prise en charge d’OpenAPI diffĂ©rents.
 
-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.
+Certains d’entre eux pourraient ne pas encore afficher toutes les informations supplĂ©mentaires dĂ©clarĂ©es, bien que, dans la plupart des cas, la fonctionnalitĂ© manquante soit dĂ©jĂ  prĂ©vue au dĂ©veloppement.
 
 ///
 
 Vous pouvez ajouter un `title` :
 
-{* ../../docs_src/query_params_str_validations/tutorial007.py hl[10] *}
+{* ../../docs_src/query_params_str_validations/tutorial007_an_py310.py hl[10] *}
 
 Et une `description` :
 
-{* ../../docs_src/query_params_str_validations/tutorial008.py hl[13] *}
+{* ../../docs_src/query_params_str_validations/tutorial008_an_py310.py hl[14] *}
 
-## Alias de paramĂštres
+## ParamĂštres avec alias { #alias-parameters }
 
-Imaginez que vous vouliez que votre paramĂštre se nomme `item-query`.
+Imaginez que vous vouliez que le paramĂštre soit `item-query`.
 
-Comme dans la requĂȘte :
+Comme dans :
 
 ```
 http://127.0.0.1:8000/items/?item-query=foobaritems
 ```
 
-Mais `item-query` n'est pas un nom de variable valide en Python.
+Mais `item-query` n’est pas un nom de variable Python valide.
 
-Le nom le plus proche serait `item_query`.
+Le plus proche serait `item_query`.
 
-Mais vous avez vraiment envie que ce soit exactement `item-query`...
+Mais vous avez quand mĂȘme besoin 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 :
+Vous pouvez alors dĂ©clarer un `alias`, et cet alias sera utilisĂ© pour trouver la valeur du paramĂštre :
 
-{* ../../docs_src/query_params_str_validations/tutorial009.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial009_an_py310.py hl[9] *}
 
-## DĂ©prĂ©cier des paramĂštres
+## DĂ©prĂ©cier des paramĂštres { #deprecating-parameters }
 
-Disons que vous ne vouliez plus utiliser ce paramĂštre dĂ©sormais.
+Disons que vous n’aimez plus ce paramĂštre.
 
-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 <abbr title="obsolĂšte, recommandĂ© de ne pas l'utiliser">dĂ©prĂ©ciĂ©</abbr>.
+Vous devez le laisser lĂ  quelque temps car des clients l’utilisent, mais vous voulez que les documents l’affichent clairement comme <abbr title="obsolĂšte, recommandĂ© de ne pas l’utiliser">dĂ©prĂ©ciĂ©</abbr>.
 
-On utilise alors l'argument `deprecated=True` de `Query` :
+Passez alors le paramĂštre `deprecated=True` Ă  `Query` :
 
-{* ../../docs_src/query_params_str_validations/tutorial010.py hl[18] *}
+{* ../../docs_src/query_params_str_validations/tutorial010_an_py310.py hl[19] *}
 
-La documentation le prĂ©sentera comme il suit :
+Les documents l’afficheront ainsi :
 
 <img src="/img/tutorial/query-params-str-validations/image01.png">
 
-## Pour rĂ©sumer
+## Exclure des paramĂštres d’OpenAPI { #exclude-parameters-from-openapi }
+
+Pour exclure un paramĂštre de requĂȘte du schĂ©ma OpenAPI gĂ©nĂ©rĂ© (et donc, des systĂšmes de documentation automatiques), dĂ©finissez le paramĂštre `include_in_schema` de `Query` Ă  `False` :
+
+{* ../../docs_src/query_params_str_validations/tutorial014_an_py310.py hl[10] *}
+
+## Validation personnalisĂ©e { #custom-validation }
+
+Il peut y avoir des cas oĂč vous devez faire une **validation personnalisĂ©e** qui ne peut pas ĂȘtre rĂ©alisĂ©e avec les paramĂštres montrĂ©s ci-dessus.
+
+Dans ces cas, vous pouvez utiliser une **fonction de validation personnalisĂ©e** qui est appliquĂ©e aprĂšs la validation normale (par ex. aprĂšs avoir validĂ© que la valeur est une `str`).
+
+Vous pouvez y parvenir en utilisant <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator" class="external-link" target="_blank">`AfterValidator` de Pydantic</a> Ă  l’intĂ©rieur de `Annotated`.
+
+/// tip | Astuce
+
+Pydantic a aussi <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-before-validator" class="external-link" target="_blank">`BeforeValidator`</a> et d’autres. đŸ€“
+
+///
+
+Par exemple, ce validateur personnalisĂ© vĂ©rifie que l’ID d’item commence par `isbn-` pour un numĂ©ro de livre <abbr title="International Standard Book Number - NumĂ©ro international normalisĂ© du livre">ISBN</abbr> ou par `imdb-` pour un ID d’URL de film <abbr title="IMDB (Internet Movie Database) est un site web contenant des informations sur les films">IMDB</abbr> :
+
+{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
+
+/// info
+
+C’est disponible avec Pydantic version 2 ou supĂ©rieure. đŸ˜Ž
+
+///
+
+/// tip | Astuce
+
+Si vous devez faire un type de validation qui nĂ©cessite de communiquer avec un **composant externe**, comme une base de donnĂ©es ou une autre API, vous devez plutĂŽt utiliser les **DĂ©pendances de FastAPI**, vous en apprendrez davantage plus tard.
+
+Ces validateurs personnalisĂ©s sont destinĂ©s aux Ă©lĂ©ments qui peuvent ĂȘtre vĂ©rifiĂ©s **uniquement** avec les **mĂȘmes donnĂ©es** fournies dans la requĂȘte.
+
+///
+
+### Comprendre ce code { #understand-that-code }
+
+Le point important est simplement d’utiliser **`AfterValidator` avec une fonction Ă  l’intĂ©rieur de `Annotated`**. N’hĂ©sitez pas Ă  passer cette partie. đŸ€ž
+
+---
+
+Mais si vous ĂȘtes curieux de cet exemple de code spĂ©cifique et que vous ĂȘtes toujours partant, voici quelques dĂ©tails supplĂ©mentaires.
+
+#### ChaĂźne avec `value.startswith()` { #string-with-value-startswith }
+
+Avez-vous remarquĂ© ? Une chaĂźne utilisant `value.startswith()` peut prendre un tuple, et elle vĂ©rifiera chaque valeur du tuple :
+
+{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[16:19] hl[17] *}
+
+#### Un Ă©lĂ©ment alĂ©atoire { #a-random-item }
+
+Avec `data.items()` nous obtenons un <abbr title="Quelque chose que l’on peut itĂ©rer avec une boucle for, comme une liste, un set, etc.">objet itĂ©rable</abbr> avec des tuples contenant la clĂ© et la valeur pour chaque Ă©lĂ©ment du dictionnaire.
+
+Nous convertissons cet objet itĂ©rable en une `list` propre avec `list(data.items())`.
+
+Ensuite, avec `random.choice()` nous pouvons obtenir une **valeur alĂ©atoire** depuis la liste, nous obtenons donc un tuple `(id, name)`. Ce sera quelque chose comme `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")`.
+
+Puis nous **affectons ces deux valeurs** du tuple aux variables `id` et `name`.
+
+Ainsi, si l’utilisateur n’a pas fourni d’ID d’item, il recevra quand mĂȘme une suggestion alĂ©atoire.
+
+... nous faisons tout cela en **une seule ligne simple**. đŸ€Ż Vous n’adorez pas Python ? đŸ
+
+{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[22:30] hl[29] *}
+
+## RĂ©capitulatif { #recap }
+
+Vous pouvez dĂ©clarer des validations et des mĂ©tadonnĂ©es supplĂ©mentaires pour vos paramĂštres.
 
-Il est possible d'ajouter des validateurs et mĂ©tadonnĂ©es pour vos paramĂštres.
+Validations et mĂ©tadonnĂ©es gĂ©nĂ©riques :
 
-Validateurs et mĂ©tadonnĂ©es gĂ©nĂ©riques:
+- `alias`
+- `title`
+- `description`
+- `deprecated`
 
-* `alias`
-* `title`
-* `description`
-* `deprecated`
+Validations spĂ©cifiques aux chaĂźnes :
 
-Validateurs spĂ©cifiques aux chaĂźnes de caractĂšres :
+- `min_length`
+- `max_length`
+- `pattern`
 
-* `min_length`
-* `max_length`
-* `regex`
+Validations personnalisĂ©es avec `AfterValidator`.
 
-Parmi ces exemples, vous avez pu voir comment dĂ©clarer des validateurs pour les chaĂźnes de caractĂšres.
+Dans ces exemples, vous avez vu comment dĂ©clarer des validations pour des valeurs `str`.
 
-Dans les prochains chapitres, vous verrez comment dĂ©clarer des validateurs pour d'autres types, comme les nombres.
+Voyez les prochains chapitres pour apprendre Ă  dĂ©clarer des validations pour d’autres types, comme les nombres.
index b87c26c782c3eab64769ab66b18234988f599abb..1a4880ced399e6f4d6281bc339248dfee1c72b00 100644 (file)
@@ -1,10 +1,10 @@
-# ParamĂštres de requĂȘte
+# ParamĂštres de requĂȘte { #query-parameters }
 
-Quand vous dĂ©clarez des paramĂštres dans votre fonction de chemin qui ne font pas partie des paramĂštres indiquĂ©s dans le chemin associĂ©, ces paramĂštres sont automatiquement considĂ©rĂ©s comme des paramĂštres de "requĂȘte".
+Quand vous dĂ©clarez d'autres paramĂštres de fonction qui ne font pas partie des paramĂštres de chemin, ils sont automatiquement interprĂ©tĂ©s comme des paramĂštres de Â« query Â».
 
-{* ../../docs_src/query_params/tutorial001.py hl[9] *}
+{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *}
 
-La partie appelĂ©e requĂȘte (ou **query**) dans une URL est l'ensemble des paires clĂ©s-valeurs placĂ©es aprĂšs le `?` , sĂ©parĂ©es par des `&`.
+La query est l'ensemble des paires clĂ©-valeur placĂ©es aprĂšs le `?` dans une URL, sĂ©parĂ©es par des caractĂšres `&`.
 
 Par exemple, dans l'URL :
 
@@ -12,27 +12,27 @@ Par exemple, dans l'URL :
 http://127.0.0.1:8000/items/?skip=0&limit=10
 ```
 
-...les paramĂštres de requĂȘte sont :
+... les paramĂštres de requĂȘte sont :
 
-* `skip` : avec une valeur de`0`
+* `skip` : avec une valeur de `0`
 * `limit` : avec une valeur de `10`
 
-Faisant partie de l'URL, ces valeurs sont des chaĂźnes de caractĂšres (`str`).
+Comme ils font partie de l'URL, ce sont Â« naturellement Â» des chaĂźnes de caractĂšres.
 
-Mais quand on les dĂ©clare avec des types Python (dans l'exemple prĂ©cĂ©dent, en tant qu'`int`), elles sont converties dans les types renseignĂ©s.
+Mais lorsque vous les dĂ©clarez avec des types Python (dans l'exemple ci-dessus, en tant que `int`), ils sont convertis vers ce type et validĂ©s par rapport Ă  celui-ci.
 
-Toutes les fonctionnalitĂ©s qui s'appliquent aux paramĂštres de chemin s'appliquent aussi aux paramĂštres de requĂȘte :
+Tous les mĂȘmes processus qui s'appliquaient aux paramĂštres de chemin s'appliquent aussi aux paramĂštres de requĂȘte :
 
-* Support de l'Ă©diteur : vĂ©rification d'erreurs, auto-complĂ©tion, etc.
-* <abbr title="conversion de la chaĂźne de caractĂšres venant de la requĂȘte HTTP en donnĂ©es Python">"Parsing"</abbr> de donnĂ©es.
-* Validation de donnĂ©es.
-* Annotations d'API et documentation automatique.
+* Prise en charge de l'Ă©diteur (Ă©videmment)
+* <abbr title="conversion de la chaĂźne provenant d'une requĂȘte HTTP en donnĂ©es Python">« parsing Â»</abbr> des donnĂ©es
+* Validation des donnĂ©es
+* Documentation automatique
 
-## Valeurs par dĂ©faut
+## Valeurs par dĂ©faut { #defaults }
 
-Les paramĂštres de requĂȘte ne sont pas une partie fixe d'un chemin, ils peuvent ĂȘtre optionnels et avoir des valeurs par dĂ©faut.
+Comme les paramĂštres de requĂȘte ne sont pas une partie fixe d'un chemin, ils peuvent ĂȘtre optionnels et avoir des valeurs par dĂ©faut.
 
-Dans l'exemple ci-dessus, ils ont des valeurs par dĂ©faut qui sont `skip=0` et `limit=10`.
+Dans l'exemple ci-dessus, ils ont des valeurs par dĂ©faut `skip=0` et `limit=10`.
 
 Donc, accĂ©der Ă  l'URL :
 
@@ -40,52 +40,44 @@ Donc, accĂ©der Ă  l'URL :
 http://127.0.0.1:8000/items/
 ```
 
-serait Ă©quivalent Ă  accĂ©der Ă  l'URL :
+serait Ă©quivalent Ă  accĂ©der Ă  :
 
 ```
 http://127.0.0.1:8000/items/?skip=0&limit=10
 ```
 
-Mais si vous accĂ©dez Ă , par exemple :
+Mais si vous accĂ©dez, par exemple, Ă  :
 
 ```
 http://127.0.0.1:8000/items/?skip=20
 ```
 
-Les valeurs des paramĂštres de votre fonction seront :
+Les valeurs des paramĂštres dans votre fonction seront :
 
-* `skip=20` : car c'est la valeur dĂ©clarĂ©e dans l'URL.
-* `limit=10` : car `limit` n'a pas Ă©tĂ© dĂ©clarĂ© dans l'URL, et que la valeur par dĂ©faut Ă©tait `10`.
+* `skip=20` : car vous l'avez dĂ©fini dans l'URL
+* `limit=10` : car c'Ă©tait la valeur par dĂ©faut
 
-## ParamĂštres optionnels
+## ParamĂštres optionnels { #optional-parameters }
 
-De la mĂȘme façon, vous pouvez dĂ©finir des paramĂštres de requĂȘte comme optionnels, en leur donnant comme valeur par dĂ©faut `None` :
+De la mĂȘme façon, vous pouvez dĂ©clarer des paramĂštres de requĂȘte optionnels, en dĂ©finissant leur valeur par dĂ©faut Ă  `None` :
 
-{* ../../docs_src/query_params/tutorial002.py hl[9] *}
+{* ../../docs_src/query_params/tutorial002_py310.py hl[7] *}
 
-Ici, le paramĂštre `q` sera optionnel, et aura `None` comme valeur par dĂ©faut.
+Dans ce cas, le paramĂštre de fonction `q` sera optionnel et vaudra `None` par dĂ©faut.
 
-/// check | Remarque
+/// check | VĂ©rifications
 
-On peut voir que **FastAPI** est capable de dĂ©tecter que le paramĂštre de chemin `item_id` est un paramĂštre de chemin et que `q` n'en est pas un, c'est donc un paramĂštre de requĂȘte.
+Notez Ă©galement que FastAPI est suffisamment intelligent pour remarquer que le paramĂštre de chemin `item_id` est un paramĂštre de chemin et que `q` ne l'est pas, c'est donc un paramĂštre de requĂȘte.
 
 ///
 
-/// note
+## Conversion des types des paramĂštres de requĂȘte { #query-parameter-type-conversion }
 
-**FastAPI** saura que `q` est optionnel grĂące au `=None`.
+Vous pouvez aussi dĂ©clarer des types `bool`, ils seront convertis :
 
-Le `Optional` dans `Optional[str]` n'est pas utilisĂ© par **FastAPI** (**FastAPI** n'en utilisera que la partie `str`), mais il servira tout de mĂȘme Ă  votre Ă©diteur de texte pour dĂ©tecter des erreurs dans votre code.
+{* ../../docs_src/query_params/tutorial003_py310.py hl[7] *}
 
-///
-
-## Conversion des types des paramĂštres de requĂȘte
-
-Vous pouvez aussi dĂ©clarer des paramĂštres de requĂȘte comme boolĂ©ens (`bool`), **FastAPI** les convertira :
-
-{* ../../docs_src/query_params/tutorial003.py hl[9] *}
-
-Avec ce code, en allant sur :
+Dans ce cas, si vous allez sur :
 
 ```
 http://127.0.0.1:8000/items/foo?short=1
@@ -115,60 +107,61 @@ ou
 http://127.0.0.1:8000/items/foo?short=yes
 ```
 
-ou n'importe quelle autre variation de casse (tout en majuscules, uniquement la premiĂšre lettre en majuscule, etc.), votre fonction considĂ©rera le paramĂštre `short` comme ayant une valeur boolĂ©enne Ă  `True`. Sinon la valeur sera Ă  `False`.
+ou n'importe quelle autre variation de casse (tout en majuscules, uniquement la premiĂšre lettre en majuscule, etc.), votre fonction verra le paramĂštre `short` avec une valeur `bool` Ă  `True`. Sinon la valeur sera Ă  `False`.
 
-## Multiples paramĂštres de chemin et de requĂȘte
+## Multiples paramĂštres de chemin et de requĂȘte { #multiple-path-and-query-parameters }
 
-Vous pouvez dĂ©clarer plusieurs paramĂštres de chemin et paramĂštres de requĂȘte dans la mĂȘme fonction, **FastAPI** saura comment les gĂ©rer.
+Vous pouvez dĂ©clarer plusieurs paramĂštres de chemin et paramĂštres de requĂȘte en mĂȘme temps, FastAPI sait lequel est lequel.
 
 Et vous n'avez pas besoin de les dĂ©clarer dans un ordre spĂ©cifique.
 
-Ils seront dĂ©tectĂ©s par leurs noms :
+Ils seront dĂ©tectĂ©s par leur nom :
 
-{* ../../docs_src/query_params/tutorial004.py hl[8,10] *}
+{* ../../docs_src/query_params/tutorial004_py310.py hl[6,8] *}
 
-## ParamĂštres de requĂȘte requis
+## ParamĂštres de requĂȘte requis { #required-query-parameters }
 
-Quand vous dĂ©clarez une valeur par dĂ©faut pour un paramĂštre qui n'est pas un paramĂštre de chemin (actuellement, nous n'avons vu que les paramĂštres de requĂȘte), alors ce paramĂštre n'est pas requis.
+Quand vous dĂ©clarez une valeur par dĂ©faut pour des paramĂštres qui ne sont pas des paramĂštres de chemin (pour l'instant, nous n'avons vu que les paramĂštres de requĂȘte), alors ils ne sont pas requis.
 
-Si vous ne voulez pas leur donner de valeur par dĂ©faut mais juste les rendre optionnels, utilisez `None` comme valeur par dĂ©faut.
+Si vous ne voulez pas leur donner de valeur spĂ©cifique mais simplement les rendre optionnels, dĂ©finissez la valeur par dĂ©faut Ă  `None`.
 
-Mais si vous voulez rendre un paramĂštre de requĂȘte obligatoire, vous pouvez juste ne pas y affecter de valeur par dĂ©faut :
+Mais si vous voulez rendre un paramĂštre de requĂȘte obligatoire, vous pouvez simplement ne dĂ©clarer aucune valeur par dĂ©faut :
 
-{* ../../docs_src/query_params/tutorial005.py hl[6:7] *}
+{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *}
 
-Ici le paramĂštre `needy` est un paramĂštre requis (ou obligatoire) de type `str`.
+Ici, le paramĂštre de requĂȘte `needy` est un paramĂštre de requĂȘte requis de type `str`.
 
-Si vous ouvrez une URL comme :
+Si vous ouvrez dans votre navigateur une URL comme :
 
 ```
 http://127.0.0.1:8000/items/foo-item
 ```
 
-...sans ajouter le paramĂštre requis `needy`, vous aurez une erreur :
+... sans ajouter le paramĂštre requis `needy`, vous verrez une erreur comme :
 
 ```JSON
 {
-    "detail": [
-        {
-            "loc": [
-                "query",
-                "needy"
-            ],
-            "msg": "field required",
-            "type": "value_error.missing"
-        }
-    ]
+  "detail": [
+    {
+      "type": "missing",
+      "loc": [
+        "query",
+        "needy"
+      ],
+      "msg": "Field required",
+      "input": null
+    }
+  ]
 }
 ```
 
-La prĂ©sence de `needy` Ă©tant nĂ©cessaire, vous auriez besoin de l'insĂ©rer dans l'URL :
+Comme `needy` est un paramĂštre requis, vous devez le dĂ©finir dans l'URL :
 
 ```
 http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
 ```
 
-...ce qui fonctionnerait :
+... cela fonctionnerait :
 
 ```JSON
 {
@@ -177,18 +170,18 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
 }
 ```
 
-Et bien sur, vous pouvez dĂ©finir certains paramĂštres comme requis, certains avec des valeurs par dĂ©faut et certains entiĂšrement optionnels :
+Et bien sĂ»r, vous pouvez dĂ©finir certains paramĂštres comme requis, certains avec une valeur par dĂ©faut et certains entiĂšrement optionnels :
 
-{* ../../docs_src/query_params/tutorial006.py hl[10] *}
+{* ../../docs_src/query_params/tutorial006_py310.py hl[8] *}
 
-Ici, on a donc 3 paramĂštres de requĂȘte :
+Dans ce cas, il y a 3 paramĂštres de requĂȘte :
 
-* `needy`, requis et de type `str`.
-* `skip`, un `int` avec comme valeur par dĂ©faut `0`.
+* `needy`, un `str` requis.
+* `skip`, un `int` avec une valeur par dĂ©faut de `0`.
 * `limit`, un `int` optionnel.
 
 /// tip | Astuce
 
-Vous pouvez utiliser les `Enum`s de la mĂȘme façon qu'avec les [ParamĂštres de chemin](path-params.md#valeurs-predefinies){.internal-link target=_blank}.
+Vous pourriez aussi utiliser des `Enum`s de la mĂȘme façon qu'avec les [ParamĂštres de chemin](path-params.md#predefined-values){.internal-link target=_blank}.
 
 ///