diff --git a/docs/fr/docs/_llm-test.md b/docs/fr/docs/_llm-test.md
new file mode 100644
index 000000000..4fdc67738
--- /dev/null
+++ b/docs/fr/docs/_llm-test.md
@@ -0,0 +1,503 @@
+# Fichier de test LLM { #llm-test-file }
+
+Ce document teste si le LLM, qui traduit la documentation, comprend le `general_prompt` dans `scripts/translate.py` et l’invite spécifique à la langue dans `docs/{language code}/llm-prompt.md`. L’invite spécifique à la langue est ajoutée à la fin de `general_prompt`.
+
+Les tests ajoutés ici seront visibles par tous les concepteurs d’invites spécifiques à chaque langue.
+
+Utiliser comme suit :
+
+* Avoir une invite spécifique à la langue - `docs/{language code}/llm-prompt.md`.
+* Effectuer une nouvelle traduction de ce document dans votre langue cible souhaitée (voir par exemple la commande `translate-page` de `translate.py`). Cela créera la traduction sous `docs/{language code}/docs/_llm-test.md`.
+* Vérifier si tout est correct dans la traduction.
+* Si nécessaire, améliorer votre invite spécifique à la langue, l’invite générale, ou le document anglais.
+* Corriger ensuite manuellement les problèmes restants dans la traduction, afin que ce soit une bonne traduction.
+* Retraduire, en ayant la bonne traduction en place. Le résultat idéal serait que le LLM ne fasse plus aucun changement à la traduction. Cela signifie que l’invite générale et votre invite spécifique à la langue sont aussi bonnes que possible (il fera parfois quelques changements apparemment aléatoires, la raison étant que les LLM ne sont pas des algorithmes déterministes).
+
+Les tests :
+
+## Extraits de code { #code-snippets }
+
+//// tab | Test
+
+Ceci est un extrait de code : `foo`. Et ceci est un autre extrait de code : `bar`. Et encore un autre : `baz quux`.
+
+////
+
+//// tab | Info
+
+Le contenu des extraits de code doit être laissé tel quel.
+
+Voir la section `### Content of code snippets` dans l’invite générale dans `scripts/translate.py`.
+
+////
+
+## Guillemets { #quotes }
+
+//// tab | Test
+
+Hier, mon ami a écrit : « Si vous écrivez « incorrectly » correctement, vous l’avez écrit de façon incorrecte ». À quoi j’ai répondu : « Correct, mais ‘incorrectly’ est incorrectement non pas ‘« incorrectly »’ ».
+
+/// note | Remarque
+
+Le LLM traduira probablement ceci de manière erronée. Il est seulement intéressant de voir s’il conserve la traduction corrigée lors d’une retraduction.
+
+///
+
+////
+
+//// tab | Info
+
+Le concepteur de l’invite peut choisir s’il souhaite convertir les guillemets neutres en guillemets typographiques. Il est acceptable de les laisser tels quels.
+
+Voir par exemple la section `### Quotes` dans `docs/de/llm-prompt.md`.
+
+////
+
+## Guillemets dans les extraits de code { #quotes-in-code-snippets }
+
+//// tab | Test
+
+`pip install "foo[bar]"`
+
+Exemples de littéraux de chaîne dans des extraits de code : `"this"`, `'that'`.
+
+Un exemple difficile de littéraux de chaîne dans des extraits de code : `f"I like {'oranges' if orange else "apples"}"`
+
+Hardcore: `Yesterday, my friend wrote: "If you spell incorrectly correctly, you have spelled it incorrectly". To which I answered: "Correct, but 'incorrectly' is incorrectly not '"incorrectly"'"`
+
+////
+
+//// tab | Info
+
+... Cependant, les guillemets à l’intérieur des extraits de code doivent rester tels quels.
+
+////
+
+## Blocs de code { #code-blocks }
+
+//// tab | Test
+
+Un exemple de code Bash ...
+
+```bash
+# Afficher un message de bienvenue à l'univers
+echo "Hello universe"
+```
+
+... et un exemple de code console ...
+
+```console
+$ fastapi run main.py
+ FastAPI Starting server
+ Searching for package file structure
+```
+
+... et un autre exemple de code console ...
+
+```console
+// Créer un répertoire "Code"
+$ mkdir code
+// Aller dans ce répertoire
+$ cd code
+```
+
+... et un exemple de code Python ...
+
+```Python
+wont_work() # Cela ne fonctionnera pas 😱
+works(foo="bar") # Cela fonctionne 🎉
+```
+
+... et c’est tout.
+
+////
+
+//// tab | Info
+
+Le code dans les blocs de code ne doit pas être modifié, à l’exception des commentaires.
+
+Voir la section `### Content of code blocks` dans l’invite générale dans `scripts/translate.py`.
+
+////
+
+## Onglets et encadrés colorés { #tabs-and-colored-boxes }
+
+//// tab | Test
+
+/// info | Info
+Du texte
+///
+
+/// note | Remarque
+Du texte
+///
+
+/// note | Détails techniques
+Du texte
+///
+
+/// check | Vérifications
+Du texte
+///
+
+/// tip | Astuce
+Du texte
+///
+
+/// warning | Alertes
+Du texte
+///
+
+/// danger | Danger
+Du texte
+///
+
+////
+
+//// tab | Info
+
+Les onglets et les blocs « Info »/« Note »/« Warning »/etc. doivent avoir la traduction de leur titre ajoutée après une barre verticale (« | »).
+
+Voir les sections `### Special blocks` et `### Tab blocks` dans l’invite générale dans `scripts/translate.py`.
+
+////
+
+## Liens Web et internes { #web-and-internal-links }
+
+//// tab | Test
+
+Le texte du lien doit être traduit, l’adresse du lien doit rester inchangée :
+
+* [Lien vers le titre ci-dessus](#code-snippets)
+* [Lien interne](index.md#installation){.internal-link target=_blank}
+* Lien externe
+* Lien vers une feuille de style
+* Lien vers un script
+* Lien vers une image
+
+Le texte du lien doit être traduit, l’adresse du lien doit pointer vers la traduction :
+
+* Lien FastAPI
+
+////
+
+//// tab | Info
+
+Les liens doivent être traduits, mais leur adresse doit rester inchangée. Exception faite des liens absolus vers des pages de la documentation FastAPI. Dans ce cas, il faut pointer vers la traduction.
+
+Voir la section `### Links` dans l’invite générale dans `scripts/translate.py`.
+
+////
+
+## Éléments HTML « abbr » { #html-abbr-elements }
+
+//// tab | Test
+
+Voici quelques éléments entourés d’un élément HTML « abbr » (certains sont inventés) :
+
+### L’abbr fournit une expression complète { #the-abbr-gives-a-full-phrase }
+
+* GTD
+* lt
+* XWT
+* PSGI
+
+### L’abbr donne une expression complète et une explication { #the-abbr-gives-a-full-phrase-and-an-explanation }
+
+* MDN
+* I/O.
+
+////
+
+//// tab | Info
+
+Les attributs « title » des éléments « abbr » sont traduits en suivant des consignes spécifiques.
+
+Les traductions peuvent ajouter leurs propres éléments « abbr » que le LLM ne doit pas supprimer. Par exemple pour expliquer des mots anglais.
+
+Voir la section `### HTML abbr elements` dans l’invite générale dans `scripts/translate.py`.
+
+////
+
+## Éléments HTML « dfn » { #html-dfn-elements }
+
+* grappe
+* Apprentissage profond
+
+## Titres { #headings }
+
+//// tab | Test
+
+### Créer une application Web - un tutoriel { #develop-a-webapp-a-tutorial }
+
+Bonjour.
+
+### Annotations de type et indications de type { #type-hints-and-annotations }
+
+Rebonjour.
+
+### Superclasses et sous-classes { #super-and-subclasses }
+
+Rebonjour.
+
+////
+
+//// tab | Info
+
+La seule règle stricte pour les titres est que le LLM laisse la partie hachage entre accolades inchangée, ce qui garantit que les liens ne se rompent pas.
+
+Voir la section `### Headings` dans l’invite générale dans `scripts/translate.py`.
+
+Pour certaines consignes spécifiques à la langue, voir par exemple la section `### Headings` dans `docs/de/llm-prompt.md`.
+
+////
+
+## Termes utilisés dans les documents { #terms-used-in-the-docs }
+
+//// tab | Test
+
+* vous
+* votre
+
+* p. ex.
+* etc.
+
+* `foo` en tant que `int`
+* `bar` en tant que `str`
+* `baz` en tant que `list`
+
+* le Tutoriel - Guide utilisateur
+* le Guide utilisateur avancé
+* la documentation SQLModel
+* la documentation de l’API
+* la documentation automatique
+
+* Data Science
+* Apprentissage profond
+* Apprentissage automatique
+* Injection de dépendances
+* authentification HTTP Basic
+* HTTP Digest
+* format ISO
+* la norme JSON Schema
+* le schéma JSON
+* la définition de schéma
+* Flux Password
+* Mobile
+
+* déprécié
+* conçu
+* invalide
+* à la volée
+* standard
+* par défaut
+* sensible à la casse
+* insensible à la casse
+
+* servir l’application
+* servir la page
+
+* l’app
+* l’application
+
+* la requête
+* la réponse
+* la réponse d’erreur
+
+* le chemin d’accès
+* le décorateur de chemin d’accès
+* la fonction de chemin d’accès
+
+* le corps
+* le corps de la requête
+* le corps de la réponse
+* le corps JSON
+* le corps de formulaire
+* le corps de fichier
+* le corps de la fonction
+
+* le paramètre
+* le paramètre de corps
+* le paramètre de chemin
+* le paramètre de requête
+* le paramètre de cookie
+* le paramètre d’en-tête
+* le paramètre de formulaire
+* le paramètre de fonction
+
+* l’événement
+* l’événement de démarrage
+* le démarrage du serveur
+* l’événement d’arrêt
+* l’événement de cycle de vie
+
+* le gestionnaire
+* le gestionnaire d’événements
+* le gestionnaire d’exceptions
+* gérer
+
+* le modèle
+* le modèle Pydantic
+* le modèle de données
+* le modèle de base de données
+* le modèle de formulaire
+* l’objet modèle
+
+* la classe
+* la classe de base
+* la classe parente
+* la sous-classe
+* la classe enfant
+* la classe sœur
+* la méthode de classe
+
+* l’en-tête
+* les en-têtes
+* l’en-tête d’autorisation
+* l’en-tête `Authorization`
+* l’en-tête transféré
+
+* le système d’injection de dépendances
+* la dépendance
+* l’élément dépendable
+* le dépendant
+
+* lié aux E/S
+* lié au processeur
+* concurrence
+* parallélisme
+* multi-traitement
+
+* la variable d’env
+* la variable d’environnement
+* le `PATH`
+* la variable `PATH`
+
+* l’authentification
+* le fournisseur d’authentification
+* l’autorisation
+* le formulaire d’autorisation
+* le fournisseur d’autorisation
+* l’utilisateur s’authentifie
+* le système authentifie l’utilisateur
+
+* la CLI
+* l’interface en ligne de commande
+
+* le serveur
+* le client
+
+* le fournisseur cloud
+* le service cloud
+
+* le développement
+* les étapes de développement
+
+* le dict
+* le dictionnaire
+* l’énumération
+* l’enum
+* le membre d’enum
+
+* l’encodeur
+* le décodeur
+* encoder
+* décoder
+
+* l’exception
+* lever
+
+* l’expression
+* l’instruction
+
+* le frontend
+* le backend
+
+* la discussion GitHub
+* le ticket GitHub
+
+* la performance
+* l’optimisation des performances
+
+* le type de retour
+* la valeur de retour
+
+* la sécurité
+* le schéma de sécurité
+
+* la tâche
+* la tâche d’arrière-plan
+* la fonction de tâche
+
+* le template
+* le moteur de templates
+
+* l’annotation de type
+* l’annotation de type
+
+* le worker du serveur
+* le worker Uvicorn
+* le Worker Gunicorn
+* le processus worker
+* la classe de worker
+* la charge de travail
+
+* le déploiement
+* déployer
+
+* le SDK
+* le kit de développement logiciel
+
+* le `APIRouter`
+* le `requirements.txt`
+* le jeton Bearer
+* le changement majeur incompatible
+* le bogue
+* le bouton
+* l’appelable
+* le code
+* le commit
+* le gestionnaire de contexte
+* la coroutine
+* la session de base de données
+* le disque
+* le domaine
+* le moteur
+* le faux X
+* la méthode HTTP GET
+* l’élément
+* la bibliothèque
+* le cycle de vie
+* le verrou
+* le middleware
+* l’application mobile
+* le module
+* le montage
+* le réseau
+* l’origine
+* la surcharge
+* le payload
+* le processeur
+* la propriété
+* le proxy
+* la pull request
+* la requête
+* la RAM
+* la machine distante
+* le code d’état
+* la chaîne
+* l’étiquette
+* le framework Web
+* le joker
+* retourner
+* valider
+
+////
+
+//// tab | Info
+
+Il s’agit d’une liste non exhaustive et non normative de termes (principalement) techniques présents dans les documents. Elle peut aider le concepteur de l’invite à déterminer pour quels termes le LLM a besoin d’un coup de main. Par exemple, lorsqu’il continue de remplacer une bonne traduction par une traduction sous-optimale. Ou lorsqu’il a des difficultés à conjuguer/décliner un terme dans votre langue.
+
+Voir par exemple la section `### List of English terms and their preferred German translations` dans `docs/de/llm-prompt.md`.
+
+////
diff --git a/docs/fr/docs/about/index.md b/docs/fr/docs/about/index.md
new file mode 100644
index 000000000..f6ec12a4f
--- /dev/null
+++ b/docs/fr/docs/about/index.md
@@ -0,0 +1,3 @@
+# À propos { #about }
+
+À propos de FastAPI, de sa conception, de ses sources d'inspiration et plus encore. 🤓
diff --git a/docs/fr/docs/advanced/additional-responses.md b/docs/fr/docs/advanced/additional-responses.md
index dabcded52..a073dec69 100644
--- a/docs/fr/docs/advanced/additional-responses.md
+++ b/docs/fr/docs/advanced/additional-responses.md
@@ -8,7 +8,7 @@ Si vous débutez avec **FastAPI**, vous n'en aurez peut-être pas besoin.
///
-Vous pouvez déclarer des réponses supplémentaires, avec des codes HTTP, des types de médias, des descriptions, etc.
+Vous pouvez déclarer des réponses supplémentaires, avec des codes d'état supplémentaires, des types de médias, des descriptions, etc.
Ces réponses supplémentaires seront incluses dans le schéma OpenAPI, elles apparaîtront donc également dans la documentation de l'API.
@@ -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_py39.py hl[18,22] *}
+{* ../../docs_src/additional_responses/tutorial001_py310.py hl[18,22] *}
/// note | Remarque
@@ -203,7 +203,7 @@ 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_py39.py hl[20:31] *}
+{* ../../docs_src/additional_responses/tutorial003_py310.py hl[20:31] *}
Tout sera combiné et inclus dans votre OpenAPI, et affiché dans la documentation de l'API :
diff --git a/docs/fr/docs/advanced/additional-status-codes.md b/docs/fr/docs/advanced/additional-status-codes.md
index b2befffa8..b9c8ab113 100644
--- a/docs/fr/docs/advanced/additional-status-codes.md
+++ b/docs/fr/docs/advanced/additional-status-codes.md
@@ -36,6 +36,6 @@ Pour plus de commodités, **FastAPI** fournit les objets `starlette.responses` s
## 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.
+Si vous renvoyez directement des codes HTTP et des réponses supplémentaires, ils ne seront pas inclus dans le schéma OpenAPI (les documents 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](additional-responses.md){.internal-link target=_blank}.
diff --git a/docs/fr/docs/advanced/advanced-dependencies.md b/docs/fr/docs/advanced/advanced-dependencies.md
new file mode 100644
index 000000000..8afd58b48
--- /dev/null
+++ b/docs/fr/docs/advanced/advanced-dependencies.md
@@ -0,0 +1,163 @@
+# Dépendances avancées { #advanced-dependencies }
+
+## Dépendances paramétrées { #parameterized-dependencies }
+
+Toutes les dépendances que nous avons vues étaient des fonctions ou des classes fixes.
+
+Mais il peut y avoir des cas où vous souhaitez pouvoir définir des paramètres sur la dépendance, sans devoir déclarer de nombreuses fonctions ou classes différentes.
+
+Imaginons que nous voulions avoir une dépendance qui vérifie si le paramètre de requête `q` contient un contenu fixe.
+
+Mais nous voulons pouvoir paramétrer ce contenu fixe.
+
+## Une instance « callable » { #a-callable-instance }
+
+En Python, il existe un moyen de rendre une instance de classe « callable ».
+
+Pas la classe elle‑même (qui est déjà un callable), mais une instance de cette classe.
+
+Pour cela, nous déclarons une méthode `__call__` :
+
+{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[12] *}
+
+Dans ce cas, ce `__call__` est ce que **FastAPI** utilisera pour détecter des paramètres supplémentaires et des sous‑dépendances, et c’est ce qui sera appelé pour transmettre ensuite une valeur au paramètre dans votre *fonction de chemin d'accès*.
+
+## Paramétrer l'instance { #parameterize-the-instance }
+
+Et maintenant, nous pouvons utiliser `__init__` pour déclarer les paramètres de l’instance, que nous utiliserons pour « paramétrer » la dépendance :
+
+{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[9] *}
+
+Dans ce cas, **FastAPI** n’accèdera pas à `__init__` et ne s’en souciera pas ; nous l’utiliserons directement dans notre code.
+
+## Créer une instance { #create-an-instance }
+
+Nous pouvons créer une instance de cette classe avec :
+
+{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[18] *}
+
+Et de cette façon, nous pouvons « paramétrer » notre dépendance, qui contient maintenant « bar », en tant qu’attribut `checker.fixed_content`.
+
+## Utiliser l'instance comme dépendance { #use-the-instance-as-a-dependency }
+
+Ensuite, nous pourrions utiliser ce `checker` dans un `Depends(checker)`, au lieu de `Depends(FixedContentQueryChecker)`, car la dépendance est l’instance, `checker`, et non la classe elle‑même.
+
+Et lors de la résolution de la dépendance, **FastAPI** appellera ce `checker` comme ceci :
+
+```Python
+checker(q="somequery")
+```
+
+... et passera ce que cela renvoie comme valeur de la dépendance à notre *fonction de chemin d'accès*, en tant que paramètre `fixed_content_included` :
+
+{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[22] *}
+
+/// tip | Astuce
+
+Tout cela peut sembler artificiel. Et il n’est peut‑être pas encore très clair en quoi c’est utile.
+
+Ces exemples sont volontairement simples, mais ils montrent comment tout cela fonctionne.
+
+Dans les chapitres sur la sécurité, il existe des fonctions utilitaires implémentées de la même manière.
+
+Si vous avez compris tout cela, vous savez déjà comment ces outils utilitaires pour la sécurité fonctionnent en interne.
+
+///
+
+## Dépendances avec `yield`, `HTTPException`, `except` et tâches d'arrière‑plan { #dependencies-with-yield-httpexception-except-and-background-tasks }
+
+/// warning | Alertes
+
+Vous n’avez très probablement pas besoin de ces détails techniques.
+
+Ces détails sont utiles principalement si vous aviez une application FastAPI antérieure à la version 0.121.0 et que vous rencontrez des problèmes avec des dépendances utilisant `yield`.
+
+///
+
+Les dépendances avec `yield` ont évolué au fil du temps pour couvrir différents cas d’utilisation et corriger certains problèmes ; voici un résumé de ce qui a changé.
+
+### Dépendances avec `yield` et `scope` { #dependencies-with-yield-and-scope }
+
+Dans la version 0.121.0, **FastAPI** a ajouté la prise en charge de `Depends(scope="function")` pour les dépendances avec `yield`.
+
+Avec `Depends(scope="function")`, le code d’arrêt après `yield` s’exécute immédiatement après la fin de la *fonction de chemin d'accès*, avant que la réponse ne soit renvoyée au client.
+
+Et lorsque vous utilisez `Depends(scope="request")` (valeur par défaut), le code d’arrêt après `yield` s’exécute après l’envoi de la réponse.
+
+Vous pouvez en lire davantage dans les documents pour [Dépendances avec `yield` - Sortie anticipée et `scope`](../tutorial/dependencies/dependencies-with-yield.md#early-exit-and-scope).
+
+### Dépendances avec `yield` et `StreamingResponse`, Détails techniques { #dependencies-with-yield-and-streamingresponse-technical-details }
+
+Avant FastAPI 0.118.0, si vous utilisiez une dépendance avec `yield`, elle exécutait le code d’arrêt après que la *fonction de chemin d'accès* a retourné, mais juste avant d’envoyer la réponse.
+
+L’objectif était d’éviter de conserver des ressources plus longtemps que nécessaire pendant que la réponse transitait sur le réseau.
+
+Ce changement impliquait aussi que si vous retourniez une `StreamingResponse`, le code d’arrêt de la dépendance avec `yield` aurait déjà été exécuté.
+
+Par exemple, si vous aviez une session de base de données dans une dépendance avec `yield`, la `StreamingResponse` ne pourrait pas utiliser cette session pendant le streaming des données, car la session aurait déjà été fermée dans le code d’arrêt après `yield`.
+
+Ce comportement a été annulé en 0.118.0, afin que le code d’arrêt après `yield` s’exécute après l’envoi de la réponse.
+
+/// info
+
+Comme vous le verrez ci‑dessous, c’est très similaire au comportement avant la version 0.106.0, mais avec plusieurs améliorations et corrections de bogues pour des cas limites.
+
+///
+
+#### Cas d’utilisation avec sortie anticipée du code { #use-cases-with-early-exit-code }
+
+Il existe certains cas d’utilisation avec des conditions spécifiques qui pourraient bénéficier de l’ancien comportement, où le code d’arrêt des dépendances avec `yield` s’exécute avant l’envoi de la réponse.
+
+Par exemple, imaginez que vous ayez du code qui utilise une session de base de données dans une dépendance avec `yield` uniquement pour vérifier un utilisateur, mais que la session de base de données ne soit plus jamais utilisée dans la *fonction de chemin d'accès*, seulement dans la dépendance, et que la réponse mette longtemps à être envoyée, comme une `StreamingResponse` qui envoie les données lentement mais qui, pour une raison quelconque, n’utilise pas la base de données.
+
+Dans ce cas, la session de base de données serait conservée jusqu’à la fin de l’envoi de la réponse, mais si vous ne l’utilisez pas, il ne serait pas nécessaire de la conserver.
+
+Voici à quoi cela pourrait ressembler :
+
+{* ../../docs_src/dependencies/tutorial013_an_py310.py *}
+
+Le code d’arrêt, la fermeture automatique de la `Session` dans :
+
+{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[19:21] *}
+
+... serait exécuté après que la réponse a fini d’envoyer les données lentes :
+
+{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[30:38] hl[31:33] *}
+
+Mais comme `generate_stream()` n’utilise pas la session de base de données, il n’est pas vraiment nécessaire de garder la session ouverte pendant l’envoi de la réponse.
+
+Si vous avez ce cas d’utilisation spécifique avec SQLModel (ou SQLAlchemy), vous pouvez fermer explicitement la session dès que vous n’en avez plus besoin :
+
+{* ../../docs_src/dependencies/tutorial014_an_py310.py ln[24:28] hl[28] *}
+
+De cette manière, la session libérera la connexion à la base de données, afin que d’autres requêtes puissent l’utiliser.
+
+Si vous avez un autre cas d’utilisation qui nécessite une sortie anticipée depuis une dépendance avec `yield`, veuillez créer une Question de discussion GitHub avec votre cas spécifique et pourquoi vous bénéficieriez d’une fermeture anticipée pour les dépendances avec `yield`.
+
+S’il existe des cas d’utilisation convaincants pour une fermeture anticipée dans les dépendances avec `yield`, j’envisagerai d’ajouter une nouvelle façon d’y opter.
+
+### Dépendances avec `yield` et `except`, Détails techniques { #dependencies-with-yield-and-except-technical-details }
+
+Avant FastAPI 0.110.0, si vous utilisiez une dépendance avec `yield`, puis capturiez une exception avec `except` dans cette dépendance, et que vous ne relanciez pas l’exception, l’exception était automatiquement levée/transmise à tout gestionnaire d’exceptions ou au gestionnaire d’erreur interne du serveur.
+
+Cela a été modifié dans la version 0.110.0 pour corriger une consommation de mémoire non gérée due aux exceptions transmises sans gestionnaire (erreurs internes du serveur), et pour rendre le comportement cohérent avec celui du code Python classique.
+
+### Tâches d'arrière‑plan et dépendances avec `yield`, Détails techniques { #background-tasks-and-dependencies-with-yield-technical-details }
+
+Avant FastAPI 0.106.0, lever des exceptions après `yield` n’était pas possible, le code d’arrêt dans les dépendances avec `yield` s’exécutait après l’envoi de la réponse, donc les [Gestionnaires d'exceptions](../tutorial/handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} avaient déjà été exécutés.
+
+Cela avait été conçu ainsi principalement pour permettre d’utiliser les mêmes objets « générés par yield » par les dépendances à l’intérieur de tâches d’arrière‑plan, car le code d’arrêt s’exécutait après la fin des tâches d’arrière‑plan.
+
+Cela a été modifié dans FastAPI 0.106.0 afin de ne pas conserver des ressources pendant l’attente de la transmission de la réponse sur le réseau.
+
+/// tip | Astuce
+
+De plus, une tâche d’arrière‑plan est normalement un ensemble de logique indépendant qui devrait être géré séparément, avec ses propres ressources (par ex. sa propre connexion à la base de données).
+
+Ainsi, vous aurez probablement un code plus propre.
+
+///
+
+Si vous comptiez sur ce comportement, vous devez désormais créer les ressources pour les tâches d’arrière‑plan à l’intérieur de la tâche elle‑même, et n’utiliser en interne que des données qui ne dépendent pas des ressources des dépendances avec `yield`.
+
+Par exemple, au lieu d’utiliser la même session de base de données, vous créeriez une nouvelle session de base de données à l’intérieur de la tâche d’arrière‑plan, et vous obtiendriez les objets depuis la base de données en utilisant cette nouvelle session. Puis, au lieu de passer l’objet obtenu depuis la base de données en paramètre à la fonction de tâche d’arrière‑plan, vous passeriez l’identifiant (ID) de cet objet et vous obtiendriez à nouveau l’objet à l’intérieur de la fonction de la tâche d’arrière‑plan.
diff --git a/docs/fr/docs/advanced/advanced-python-types.md b/docs/fr/docs/advanced/advanced-python-types.md
new file mode 100644
index 000000000..3e2d9453b
--- /dev/null
+++ b/docs/fr/docs/advanced/advanced-python-types.md
@@ -0,0 +1,61 @@
+# Types Python avancés { #advanced-python-types }
+
+Voici quelques idées supplémentaires qui peuvent être utiles lorsque vous travaillez avec les types Python.
+
+## Utiliser `Union` ou `Optional` { #using-union-or-optional }
+
+Si votre code ne peut pas utiliser `|` pour une raison quelconque, par exemple si ce n'est pas dans une annotation de type mais dans quelque chose comme `response_model=`, au lieu d'utiliser la barre verticale (`|`) vous pouvez utiliser `Union` de `typing`.
+
+Par exemple, vous pourriez déclarer que quelque chose peut être un `str` ou `None` :
+
+```python
+from typing import Union
+
+
+def say_hi(name: Union[str, None]):
+ print(f"Hi {name}!")
+```
+
+`typing` propose également un raccourci pour déclarer que quelque chose peut être `None`, avec `Optional`.
+
+Voici un conseil issu de mon point de vue très subjectif :
+
+- 🚨 Évitez d'utiliser `Optional[SomeType]`
+- À la place ✨ **utilisez `Union[SomeType, None]`** ✨.
+
+Les deux sont équivalents et, en interne, identiques, mais je recommande `Union` plutôt que `Optional` parce que le mot « optional » semble impliquer que la valeur est facultative, alors qu'il signifie en réalité « elle peut être `None` », même si elle n'est pas facultative et reste requise.
+
+Je pense que `Union[SomeType, None]` est plus explicite quant à sa signification.
+
+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.
+
+À titre d'exemple, prenons cette fonction :
+
+```python
+from typing import Optional
+
+
+def say_hi(name: Optional[str]):
+ print(f"Hey {name}!")
+```
+
+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 :
+
+```Python
+say_hi() # Oh non, cela lève une erreur ! 😱
+```
+
+Le paramètre `name` est toujours requis (pas facultatif) car il n'a pas de valeur par défaut. En revanche, `name` accepte `None` comme valeur :
+
+```Python
+say_hi(name=None) # Ceci fonctionne, None est valide 🎉
+```
+
+La bonne nouvelle, c'est que, dans la plupart des cas, vous pourrez simplement utiliser `|` pour définir des unions de types :
+
+```python
+def say_hi(name: str | None):
+ print(f"Hey {name}!")
+```
+
+Ainsi, normalement, vous n'avez pas à vous préoccuper de noms comme `Optional` et `Union`. 😎
diff --git a/docs/fr/docs/advanced/async-tests.md b/docs/fr/docs/advanced/async-tests.md
new file mode 100644
index 000000000..f9cea0ad1
--- /dev/null
+++ b/docs/fr/docs/advanced/async-tests.md
@@ -0,0 +1,99 @@
+# Tests asynchrones { #async-tests }
+
+Vous avez déjà vu comment tester vos applications **FastAPI** en utilisant le `TestClient` fourni. Jusqu'à présent, vous n'avez vu que comment écrire des tests synchrones, sans utiliser de fonctions `async`.
+
+Pouvoir utiliser des fonctions asynchrones dans vos tests peut être utile, par exemple lorsque vous interrogez votre base de données de manière asynchrone. Imaginez que vous vouliez tester l'envoi de requêtes à votre application FastAPI puis vérifier que votre backend a bien écrit les bonnes données dans la base, tout en utilisant une bibliothèque de base de données asynchrone.
+
+Voyons comment procéder.
+
+## pytest.mark.anyio { #pytest-mark-anyio }
+
+Si nous voulons appeler des fonctions asynchrones dans nos tests, nos fonctions de test doivent être asynchrones. AnyIO fournit un plug-in pratique qui nous permet d'indiquer que certaines fonctions de test doivent être appelées de manière asynchrone.
+
+## HTTPX { #httpx }
+
+Même si votre application **FastAPI** utilise des fonctions `def` normales au lieu de `async def`, c'est toujours une application `async` en interne.
+
+Le `TestClient` fait un peu de magie pour appeler l'application FastAPI asynchrone depuis vos fonctions de test `def` normales, en utilisant pytest standard. Mais cette magie ne fonctionne plus lorsque nous l'utilisons dans des fonctions asynchrones. En exécutant nos tests de manière asynchrone, nous ne pouvons plus utiliser le `TestClient` dans nos fonctions de test.
+
+Le `TestClient` est basé sur HTTPX et, heureusement, nous pouvons l'utiliser directement pour tester l'API.
+
+## Exemple { #example }
+
+Pour un exemple simple, considérons une structure de fichiers similaire à celle décrite dans [Applications plus grandes](../tutorial/bigger-applications.md){.internal-link target=_blank} et [Tests](../tutorial/testing.md){.internal-link target=_blank} :
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+│ └── test_main.py
+```
+
+Le fichier `main.py` contiendrait :
+
+{* ../../docs_src/async_tests/app_a_py310/main.py *}
+
+Le fichier `test_main.py` contiendrait les tests pour `main.py`, il pourrait maintenant ressembler à ceci :
+
+{* ../../docs_src/async_tests/app_a_py310/test_main.py *}
+
+## Exécuter { #run-it }
+
+Vous pouvez lancer vos tests comme d'habitude via :
+
+
+
+```console
+$ pytest
+
+---> 100%
+```
+
+
+
+## En détail { #in-detail }
+
+Le marqueur `@pytest.mark.anyio` indique à pytest que cette fonction de test doit être appelée de manière asynchrone :
+
+{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[7] *}
+
+/// tip | Astuce
+
+Notez que la fonction de test est maintenant `async def` au lieu de simplement `def` comme auparavant avec le `TestClient`.
+
+///
+
+Nous pouvons ensuite créer un `AsyncClient` avec l'application et lui envoyer des requêtes asynchrones en utilisant `await`.
+
+{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[9:12] *}
+
+C'est l'équivalent de :
+
+```Python
+response = client.get('/')
+```
+
+... que nous utilisions pour faire nos requêtes avec le `TestClient`.
+
+/// tip | Astuce
+
+Notez que nous utilisons async/await avec le nouveau `AsyncClient` — la requête est asynchrone.
+
+///
+
+/// warning | Alertes
+
+Si votre application s'appuie sur des événements de cycle de vie (lifespan), le `AsyncClient` ne déclenchera pas ces événements. Pour vous assurer qu'ils sont déclenchés, utilisez `LifespanManager` depuis florimondmanca/asgi-lifespan.
+
+///
+
+## Autres appels de fonctions asynchrones { #other-asynchronous-function-calls }
+
+Comme la fonction de test est désormais asynchrone, vous pouvez également appeler (et `await`) d'autres fonctions `async` en plus d'envoyer des requêtes à votre application FastAPI dans vos tests, exactement comme vous le feriez ailleurs dans votre code.
+
+/// tip | Astuce
+
+Si vous rencontrez une erreur `RuntimeError: Task attached to a different loop` lors de l'intégration d'appels de fonctions asynchrones dans vos tests (par exemple en utilisant MotorClient de MongoDB), n'oubliez pas d'instancier les objets qui ont besoin d'une boucle d'événements uniquement dans des fonctions async, par exemple dans un callback `@app.on_event("startup")`.
+
+///
diff --git a/docs/fr/docs/advanced/behind-a-proxy.md b/docs/fr/docs/advanced/behind-a-proxy.md
new file mode 100644
index 000000000..4b540e1a1
--- /dev/null
+++ b/docs/fr/docs/advanced/behind-a-proxy.md
@@ -0,0 +1,466 @@
+# Être derrière un proxy { #behind-a-proxy }
+
+Dans de nombreuses situations, vous utiliserez un **proxy** comme Traefik ou Nginx devant votre application FastAPI.
+
+Ces proxies peuvent gérer les certificats HTTPS et d'autres aspects.
+
+## En-têtes transférés par le proxy { #proxy-forwarded-headers }
+
+Un **proxy** placé devant votre application définit normalement certains en-têtes à la volée avant d'envoyer les requêtes à votre **serveur**, afin d'indiquer au serveur que la requête a été **transférée** par le proxy, en lui donnant l'URL d'origine (publique), y compris le domaine, le fait qu'elle utilise HTTPS, etc.
+
+Le programme **serveur** (par exemple **Uvicorn** via **FastAPI CLI**) est capable d'interpréter ces en‑têtes, puis de transmettre ces informations à votre application.
+
+Mais, par sécurité, comme le serveur ne sait pas qu'il se trouve derrière un proxy de confiance, il n'interprétera pas ces en‑têtes.
+
+/// note | Détails techniques
+
+Les en-têtes du proxy sont :
+
+* X-Forwarded-For
+* X-Forwarded-Proto
+* X-Forwarded-Host
+
+///
+
+### Activer les en-têtes transférés par le proxy { #enable-proxy-forwarded-headers }
+
+Vous pouvez démarrer FastAPI CLI avec l'option de CLI `--forwarded-allow-ips` et fournir les adresses IP à considérer comme fiables pour lire ces en‑têtes transférés.
+
+Si vous la définissez à `--forwarded-allow-ips="*"`, elle fera confiance à toutes les IP entrantes.
+
+Si votre **serveur** est derrière un **proxy** de confiance et que seul le proxy lui parle, cela fera accepter l'IP de ce **proxy**, quelle qu'elle soit.
+
+
+
+```console
+$ fastapi run --forwarded-allow-ips="*"
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+### Redirections avec HTTPS { #redirects-with-https }
+
+Par exemple, disons que vous définissez un *chemin d'accès* `/items/` :
+
+{* ../../docs_src/behind_a_proxy/tutorial001_01_py310.py hl[6] *}
+
+Si le client essaie d'aller à `/items`, par défaut, il sera redirigé vers `/items/`.
+
+Mais avant de définir l'option de CLI `--forwarded-allow-ips`, il pourrait rediriger vers `http://localhost:8000/items/`.
+
+Mais peut‑être que votre application est hébergée à `https://mysuperapp.com`, et la redirection devrait être vers `https://mysuperapp.com/items/`.
+
+En définissant `--proxy-headers`, FastAPI pourra désormais rediriger vers l'emplacement correct. 😎
+
+```
+https://mysuperapp.com/items/
+```
+
+/// tip | Astuce
+
+Si vous voulez en savoir plus sur HTTPS, consultez le guide [À propos de HTTPS](../deployment/https.md){.internal-link target=_blank}.
+
+///
+
+### Comment fonctionnent les en‑têtes transférés par le proxy { #how-proxy-forwarded-headers-work }
+
+Voici une représentation visuelle de la façon dont le **proxy** ajoute des en‑têtes transférés entre le client et le **serveur d'application** :
+
+```mermaid
+sequenceDiagram
+ participant Client
+ participant Proxy as Proxy/Load Balancer
+ participant Server as FastAPI Server
+
+ Client->>Proxy: HTTPS Request
Host: mysuperapp.com
Path: /items
+
+ Note over Proxy: Proxy adds forwarded headers
+
+ Proxy->>Server: HTTP Request
X-Forwarded-For: [client IP]
X-Forwarded-Proto: https
X-Forwarded-Host: mysuperapp.com
Path: /items
+
+ Note over Server: Server interprets headers
(if --forwarded-allow-ips is set)
+
+ Server->>Proxy: HTTP Response
with correct HTTPS URLs
+
+ Proxy->>Client: HTTPS Response
+```
+
+Le **proxy** intercepte la requête client d'origine et ajoute les en-têtes spéciaux *forwarded* (`X-Forwarded-*`) avant de transmettre la requête au **serveur d'application**.
+
+Ces en‑têtes conservent des informations sur la requête d'origine qui seraient autrement perdues :
+
+* **X-Forwarded-For** : l'adresse IP du client d'origine
+* **X-Forwarded-Proto** : le protocole d'origine (`https`)
+* **X-Forwarded-Host** : l'hôte d'origine (`mysuperapp.com`)
+
+Lorsque **FastAPI CLI** est configurée avec `--forwarded-allow-ips`, elle fait confiance à ces en‑têtes et les utilise, par exemple pour générer les bonnes URL dans les redirections.
+
+## Proxy avec un préfixe de chemin supprimé { #proxy-with-a-stripped-path-prefix }
+
+Vous pouvez avoir un proxy qui ajoute un préfixe de chemin à votre application.
+
+Dans ces cas, vous pouvez utiliser `root_path` pour configurer votre application.
+
+Le `root_path` est un mécanisme fourni par la spécification ASGI (sur laquelle FastAPI est construit, via Starlette).
+
+Le `root_path` est utilisé pour gérer ces cas spécifiques.
+
+Et il est également utilisé en interne lors du montage de sous‑applications.
+
+Avoir un proxy avec un préfixe de chemin supprimé, dans ce cas, signifie que vous pourriez déclarer un chemin à `/app` dans votre code, mais ensuite, vous ajoutez une couche au‑dessus (le proxy) qui place votre application **FastAPI** sous un chemin comme `/api/v1`.
+
+Dans ce cas, le chemin original `/app` serait en réalité servi à `/api/v1/app`.
+
+Même si tout votre code est écrit en supposant qu'il n'y a que `/app`.
+
+{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[6] *}
+
+Et le proxy **« stripping »** le **préfixe de chemin** à la volée avant de transmettre la requête au serveur de l'application (probablement Uvicorn via FastAPI CLI), en gardant votre application convaincue qu'elle est servie à `/app`, afin que vous n'ayez pas à mettre à jour tout votre code pour inclure le préfixe `/api/v1`.
+
+Jusqu'ici, tout fonctionnerait normalement.
+
+Mais ensuite, lorsque vous ouvrez l'interface de documentation intégrée (le frontend), elle s'attendra à obtenir le schéma OpenAPI à `/openapi.json`, au lieu de `/api/v1/openapi.json`.
+
+Ainsi, le frontend (qui s'exécute dans le navigateur) essaiera d'atteindre `/openapi.json` et ne pourra pas obtenir le schéma OpenAPI.
+
+Parce que nous avons un proxy avec un préfixe de chemin `/api/v1` pour notre application, le frontend doit récupérer le schéma OpenAPI à `/api/v1/openapi.json`.
+
+```mermaid
+graph LR
+
+browser("Browser")
+proxy["Proxy on http://0.0.0.0:9999/api/v1/app"]
+server["Server on http://127.0.0.1:8000/app"]
+
+browser --> proxy
+proxy --> server
+```
+
+/// tip | Astuce
+
+L'IP `0.0.0.0` est couramment utilisée pour signifier que le programme écoute sur toutes les IP disponibles de cette machine/serveur.
+
+///
+
+L'interface de documents doit également indiquer dans le schéma OpenAPI que ce `server` d'API se trouve à `/api/v1` (derrière le proxy). Par exemple :
+
+```JSON hl_lines="4-8"
+{
+ "openapi": "3.1.0",
+ // Plus d'éléments ici
+ "servers": [
+ {
+ "url": "/api/v1"
+ }
+ ],
+ "paths": {
+ // Plus d'éléments ici
+ }
+}
+```
+
+Dans cet exemple, le « Proxy » pourrait être quelque chose comme **Traefik**. Et le serveur serait quelque chose comme FastAPI CLI avec **Uvicorn**, exécutant votre application FastAPI.
+
+### Fournir le `root_path` { #providing-the-root-path }
+
+Pour y parvenir, vous pouvez utiliser l'option de ligne de commande `--root-path` comme suit :
+
+
+
+```console
+$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+Si vous utilisez Hypercorn, il dispose également de l'option `--root-path`.
+
+/// note | Détails techniques
+
+La spécification ASGI définit un `root_path` pour ce cas d'usage.
+
+Et l'option de ligne de commande `--root-path` fournit ce `root_path`.
+
+///
+
+### Vérifier le `root_path` actuel { #checking-the-current-root-path }
+
+Vous pouvez obtenir le `root_path` actuel utilisé par votre application pour chaque requête, il fait partie du dictionnaire `scope` (qui fait partie de la spécification ASGI).
+
+Ici, nous l'incluons dans le message uniquement à des fins de démonstration.
+
+{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[8] *}
+
+Ensuite, si vous démarrez Uvicorn avec :
+
+
+
+```console
+$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+La réponse sera semblable à :
+
+```JSON
+{
+ "message": "Hello World",
+ "root_path": "/api/v1"
+}
+```
+
+### Définir le `root_path` dans l'application FastAPI { #setting-the-root-path-in-the-fastapi-app }
+
+Autrement, si vous n'avez pas la possibilité de fournir une option de ligne de commande comme `--root-path` ou équivalent, vous pouvez définir le paramètre `root_path` lors de la création de votre application FastAPI :
+
+{* ../../docs_src/behind_a_proxy/tutorial002_py310.py hl[3] *}
+
+Passer le `root_path` à `FastAPI` équivaut à passer l'option de ligne de commande `--root-path` à Uvicorn ou Hypercorn.
+
+### À propos de `root_path` { #about-root-path }
+
+Gardez à l'esprit que le serveur (Uvicorn) n'utilisera ce `root_path` que pour le transmettre à l'application.
+
+Mais si vous allez avec votre navigateur sur http://127.0.0.1:8000/app, vous verrez la réponse normale :
+
+```JSON
+{
+ "message": "Hello World",
+ "root_path": "/api/v1"
+}
+```
+
+Donc, il ne s'attendra pas à être accessible à `http://127.0.0.1:8000/api/v1/app`.
+
+Uvicorn s'attendra à ce que le proxy accède à Uvicorn sur `http://127.0.0.1:8000/app`, et ce sera ensuite la responsabilité du proxy d'ajouter le préfixe supplémentaire `/api/v1` au‑dessus.
+
+## À propos des proxies avec un préfixe de chemin supprimé { #about-proxies-with-a-stripped-path-prefix }
+
+Gardez à l'esprit qu'un proxy avec préfixe de chemin supprimé n'est qu'une des façons de le configurer.
+
+Dans de nombreux cas, la valeur par défaut sera probablement que le proxy n'a pas de préfixe de chemin supprimé.
+
+Dans un cas comme celui‑ci (sans préfixe de chemin supprimé), le proxy écoutera sur quelque chose comme `https://myawesomeapp.com`, puis si le navigateur va sur `https://myawesomeapp.com/api/v1/app` et que votre serveur (par ex. Uvicorn) écoute sur `http://127.0.0.1:8000`, le proxy (sans préfixe de chemin supprimé) accédera à Uvicorn au même chemin : `http://127.0.0.1:8000/api/v1/app`.
+
+## Tester localement avec Traefik { #testing-locally-with-traefik }
+
+Vous pouvez facilement faire l'expérience en local avec un préfixe de chemin supprimé en utilisant Traefik.
+
+Téléchargez Traefik ; c'est un binaire unique, vous pouvez extraire le fichier compressé et l'exécuter directement depuis le terminal.
+
+Créez ensuite un fichier `traefik.toml` avec :
+
+```TOML hl_lines="3"
+[entryPoints]
+ [entryPoints.http]
+ address = ":9999"
+
+[providers]
+ [providers.file]
+ filename = "routes.toml"
+```
+
+Cela indique à Traefik d'écouter sur le port 9999 et d'utiliser un autre fichier `routes.toml`.
+
+/// tip | Astuce
+
+Nous utilisons le port 9999 au lieu du port HTTP standard 80 afin que vous n'ayez pas à l'exécuter avec des privilèges administrateur (`sudo`).
+
+///
+
+Créez maintenant cet autre fichier `routes.toml` :
+
+```TOML hl_lines="5 12 20"
+[http]
+ [http.middlewares]
+
+ [http.middlewares.api-stripprefix.stripPrefix]
+ prefixes = ["/api/v1"]
+
+ [http.routers]
+
+ [http.routers.app-http]
+ entryPoints = ["http"]
+ service = "app"
+ rule = "PathPrefix(`/api/v1`)"
+ middlewares = ["api-stripprefix"]
+
+ [http.services]
+
+ [http.services.app]
+ [http.services.app.loadBalancer]
+ [[http.services.app.loadBalancer.servers]]
+ url = "http://127.0.0.1:8000"
+```
+
+Ce fichier configure Traefik pour utiliser le préfixe de chemin `/api/v1`.
+
+Puis Traefik redirigera ses requêtes vers votre Uvicorn tournant sur `http://127.0.0.1:8000`.
+
+Démarrez maintenant Traefik :
+
+
+
+```console
+$ ./traefik --configFile=traefik.toml
+
+INFO[0000] Configuration loaded from file: /home/user/awesomeapi/traefik.toml
+```
+
+
+
+Et démarrez maintenant votre application, en utilisant l'option `--root-path` :
+
+
+
+```console
+$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+### Vérifier les réponses { #check-the-responses }
+
+Maintenant, si vous allez à l'URL avec le port pour Uvicorn : http://127.0.0.1:8000/app, vous verrez la réponse normale :
+
+```JSON
+{
+ "message": "Hello World",
+ "root_path": "/api/v1"
+}
+```
+
+/// tip | Astuce
+
+Remarquez que même si vous y accédez via `http://127.0.0.1:8000/app`, il affiche le `root_path` de `/api/v1`, repris depuis l'option `--root-path`.
+
+///
+
+Et maintenant ouvrez l'URL avec le port pour Traefik, en incluant le préfixe de chemin : http://127.0.0.1:9999/api/v1/app.
+
+Nous obtenons la même réponse :
+
+```JSON
+{
+ "message": "Hello World",
+ "root_path": "/api/v1"
+}
+```
+
+mais cette fois à l'URL avec le préfixe fourni par le proxy : `/api/v1`.
+
+Bien sûr, l'idée ici est que tout le monde accède à l'application via le proxy ; la version avec le préfixe de chemin `/api/v1` est donc la « correcte ».
+
+Et la version sans préfixe de chemin (`http://127.0.0.1:8000/app`), fournie directement par Uvicorn, serait exclusivement destinée au _proxy_ (Traefik) pour y accéder.
+
+Cela montre comment le Proxy (Traefik) utilise le préfixe de chemin et comment le serveur (Uvicorn) utilise le `root_path` fourni par l'option `--root-path`.
+
+### Vérifier l'interface de documentation { #check-the-docs-ui }
+
+Mais voici la partie intéressante. ✨
+
+La manière « officielle » d'accéder à l'application serait via le proxy avec le préfixe de chemin que nous avons défini. Donc, comme on s'y attend, si vous essayez l'interface de documentation servie directement par Uvicorn, sans le préfixe de chemin dans l'URL, cela ne fonctionne pas, car elle s'attend à être accédée via le proxy.
+
+Vous pouvez le vérifier sur http://127.0.0.1:8000/docs :
+
+
+
+Mais si nous accédons à l'interface de documents à l'URL « officielle » en utilisant le proxy avec le port `9999`, à `/api/v1/docs`, cela fonctionne correctement ! 🎉
+
+Vous pouvez le vérifier sur http://127.0.0.1:9999/api/v1/docs :
+
+
+
+Exactement comme nous le voulions. ✔️
+
+C'est parce que FastAPI utilise ce `root_path` pour créer le `server` par défaut dans OpenAPI avec l'URL fournie par `root_path`.
+
+## Serveurs supplémentaires { #additional-servers }
+
+/// warning | Alertes
+
+Ceci est un cas d'utilisation plus avancé. N'hésitez pas à l'ignorer.
+
+///
+
+Par défaut, **FastAPI** créera un `server` dans le schéma OpenAPI avec l'URL correspondant au `root_path`.
+
+Mais vous pouvez aussi fournir d'autres `servers` alternatifs, par exemple si vous voulez que la même interface de documents interagisse avec un environnement de staging et un environnement de production.
+
+Si vous passez une liste personnalisée de `servers` et qu'il y a un `root_path` (parce que votre API vit derrière un proxy), **FastAPI** insérera un « server » avec ce `root_path` au début de la liste.
+
+Par exemple :
+
+{* ../../docs_src/behind_a_proxy/tutorial003_py310.py hl[4:7] *}
+
+Générera un schéma OpenAPI comme :
+
+```JSON hl_lines="5-7"
+{
+ "openapi": "3.1.0",
+ // Plus d'éléments ici
+ "servers": [
+ {
+ "url": "/api/v1"
+ },
+ {
+ "url": "https://stag.example.com",
+ "description": "Staging environment"
+ },
+ {
+ "url": "https://prod.example.com",
+ "description": "Production environment"
+ }
+ ],
+ "paths": {
+ // Plus d'éléments ici
+ }
+}
+```
+
+/// tip | Astuce
+
+Remarquez le serveur généré automatiquement avec une valeur `url` de `/api/v1`, reprise depuis le `root_path`.
+
+///
+
+Dans l'interface de documents sur http://127.0.0.1:9999/api/v1/docs, cela ressemblera à ceci :
+
+
+
+/// tip | Astuce
+
+L'interface de documents interagit avec le serveur que vous sélectionnez.
+
+///
+
+/// note | Détails techniques
+
+La propriété `servers` dans la spécification OpenAPI est facultative.
+
+Si vous ne spécifiez pas le paramètre `servers` et que `root_path` est égal à `/`, la propriété `servers` dans le schéma OpenAPI généré sera entièrement omise par défaut, ce qui équivaut à un seul serveur avec une valeur `url` de `/`.
+
+///
+
+### Désactiver le serveur automatique issu de `root_path` { #disable-automatic-server-from-root-path }
+
+Si vous ne voulez pas que **FastAPI** inclue un serveur automatique utilisant le `root_path`, vous pouvez utiliser le paramètre `root_path_in_servers=False` :
+
+{* ../../docs_src/behind_a_proxy/tutorial004_py310.py hl[9] *}
+
+et il ne l'inclura alors pas dans le schéma OpenAPI.
+
+## Monter une sous-application { #mounting-a-sub-application }
+
+Si vous avez besoin de monter une sous‑application (comme décrit dans [Sous‑applications - montages](sub-applications.md){.internal-link target=_blank}) tout en utilisant un proxy avec `root_path`, vous pouvez le faire normalement, comme vous vous y attendez.
+
+FastAPI utilisera intelligemment le `root_path` en interne, donc cela fonctionnera simplement. ✨
diff --git a/docs/fr/docs/advanced/custom-response.md b/docs/fr/docs/advanced/custom-response.md
new file mode 100644
index 000000000..7eab5b53f
--- /dev/null
+++ b/docs/fr/docs/advanced/custom-response.md
@@ -0,0 +1,312 @@
+# Réponse personnalisée - HTML, flux, fichier, autres { #custom-response-html-stream-file-others }
+
+Par défaut, **FastAPI** renverra les réponses en utilisant `JSONResponse`.
+
+Vous pouvez le remplacer en renvoyant directement une `Response` comme expliqué dans [Renvoyer directement une Response](response-directly.md){.internal-link target=_blank}.
+
+Mais si vous renvoyez directement une `Response` (ou n'importe quelle sous-classe, comme `JSONResponse`), les données ne seront pas automatiquement converties (même si vous déclarez un `response_model`), et la documentation ne sera pas générée automatiquement (par exemple, l'inclusion du « media type » dans l'en-tête HTTP `Content-Type` comme partie de l'OpenAPI généré).
+
+Vous pouvez aussi déclarer la `Response` que vous voulez utiliser (par ex. toute sous-classe de `Response`), dans le décorateur de chemin d'accès en utilisant le paramètre `response_class`.
+
+Le contenu que vous renvoyez depuis votre fonction de chemin d'accès sera placé à l'intérieur de cette `Response`.
+
+Et si cette `Response` a un « media type » JSON (`application/json`), comme c'est le cas avec `JSONResponse` et `UJSONResponse`, les données que vous renvoyez seront automatiquement converties (et filtrées) avec tout `response_model` Pydantic que vous avez déclaré dans le décorateur de chemin d'accès.
+
+/// note | Remarque
+
+Si vous utilisez une classe de réponse sans « media type », FastAPI s'attendra à ce que votre réponse n'ait pas de contenu ; il ne documentera donc pas le format de la réponse dans les documents OpenAPI générés.
+
+///
+
+## Utiliser `ORJSONResponse` { #use-orjsonresponse }
+
+Par exemple, si vous cherchez à maximiser la performance, vous pouvez installer et utiliser `orjson` et définir la réponse sur `ORJSONResponse`.
+
+Importez la classe (sous-classe) `Response` que vous voulez utiliser et déclarez-la dans le décorateur de chemin d'accès.
+
+Pour de grandes réponses, renvoyer directement une `Response` est bien plus rapide que de renvoyer un dictionnaire.
+
+Cela vient du fait que, par défaut, FastAPI inspectera chaque élément et s'assurera qu'il est sérialisable en JSON, en utilisant le même [Encodeur compatible JSON](../tutorial/encoder.md){.internal-link target=_blank} expliqué dans le didacticiel. C'est ce qui vous permet de renvoyer des objets arbitraires, par exemple des modèles de base de données.
+
+Mais si vous êtes certain que le contenu que vous renvoyez est sérialisable en JSON, vous pouvez le passer directement à la classe de réponse et éviter le surcoût supplémentaire qu'aurait FastAPI en faisant passer votre contenu de retour par le `jsonable_encoder` avant de le transmettre à la classe de réponse.
+
+{* ../../docs_src/custom_response/tutorial001b_py310.py hl[2,7] *}
+
+/// info
+
+Le paramètre `response_class` sera aussi utilisé pour définir le « media type » de la réponse.
+
+Dans ce cas, l'en-tête HTTP `Content-Type` sera défini à `application/json`.
+
+Et il sera documenté comme tel dans OpenAPI.
+
+///
+
+/// tip | Astuce
+
+`ORJSONResponse` est disponible uniquement dans FastAPI, pas dans Starlette.
+
+///
+
+## Réponse HTML { #html-response }
+
+Pour renvoyer une réponse avec du HTML directement depuis **FastAPI**, utilisez `HTMLResponse`.
+
+- Importez `HTMLResponse`.
+- Passez `HTMLResponse` comme paramètre `response_class` de votre décorateur de chemin d'accès.
+
+{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
+
+/// info
+
+Le paramètre `response_class` sera aussi utilisé pour définir le « media type » de la réponse.
+
+Dans ce cas, l'en-tête HTTP `Content-Type` sera défini à `text/html`.
+
+Et il sera documenté comme tel dans OpenAPI.
+
+///
+
+### Renvoyer une `Response` { #return-a-response }
+
+Comme vu dans [Renvoyer directement une Response](response-directly.md){.internal-link target=_blank}, vous pouvez aussi remplacer la réponse directement dans votre chemin d'accès, en la renvoyant.
+
+Le même exemple ci-dessus, renvoyant une `HTMLResponse`, pourrait ressembler à :
+
+{* ../../docs_src/custom_response/tutorial003_py310.py hl[2,7,19] *}
+
+/// warning | Alertes
+
+Une `Response` renvoyée directement par votre fonction de chemin d'accès ne sera pas documentée dans OpenAPI (par exemple, le `Content-Type` ne sera pas documenté) et ne sera pas visible dans les documents interactifs automatiques.
+
+///
+
+/// info
+
+Bien sûr, l'en-tête `Content-Type` réel, le code d'état, etc., proviendront de l'objet `Response` que vous avez renvoyé.
+
+///
+
+### Documenter dans OpenAPI et remplacer `Response` { #document-in-openapi-and-override-response }
+
+Si vous voulez remplacer la réponse depuis l'intérieur de la fonction mais en même temps documenter le « media type » dans OpenAPI, vous pouvez utiliser le paramètre `response_class` ET renvoyer un objet `Response`.
+
+`response_class` sera alors utilisé uniquement pour documenter l'opération de chemin d'accès OpenAPI, mais votre `Response` sera utilisée telle quelle.
+
+#### Renvoyer directement une `HTMLResponse` { #return-an-htmlresponse-directly }
+
+Par exemple, cela pourrait être quelque chose comme :
+
+{* ../../docs_src/custom_response/tutorial004_py310.py hl[7,21,23] *}
+
+Dans cet exemple, la fonction `generate_html_response()` génère déjà et renvoie une `Response` au lieu de renvoyer le HTML dans une `str`.
+
+En renvoyant le résultat de l'appel à `generate_html_response()`, vous renvoyez déjà une `Response` qui remplacera le comportement par défaut de **FastAPI**.
+
+Mais comme vous avez aussi passé `HTMLResponse` dans `response_class`, **FastAPI** saura comment la documenter dans OpenAPI et les documents interactifs comme HTML avec `text/html` :
+
+
+
+## Réponses disponibles { #available-responses }
+
+Voici certaines des réponses disponibles.
+
+Gardez à l'esprit que vous pouvez utiliser `Response` pour renvoyer autre chose, ou même créer une sous-classe personnalisée.
+
+/// note | Détails techniques
+
+Vous pourriez aussi utiliser `from starlette.responses import HTMLResponse`.
+
+**FastAPI** fournit les mêmes `starlette.responses` sous `fastapi.responses` simplement pour votre confort de développement. Mais la plupart des réponses disponibles viennent directement de Starlette.
+
+///
+
+### `Response` { #response }
+
+La classe principale `Response`, toutes les autres réponses en héritent.
+
+Vous pouvez la renvoyer directement.
+
+Elle accepte les paramètres suivants :
+
+- `content` - Une `str` ou des `bytes`.
+- `status_code` - Un code d'état HTTP de type `int`.
+- `headers` - Un `dict` de chaînes.
+- `media_type` - Une `str` donnant le media type. Par exemple « text/html ».
+
+FastAPI (en fait Starlette) inclura automatiquement un en-tête Content-Length. Il inclura aussi un en-tête Content-Type, basé sur `media_type` et en ajoutant un charset pour les types textuels.
+
+{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
+
+### `HTMLResponse` { #htmlresponse }
+
+Prend du texte ou des octets et renvoie une réponse HTML, comme vous l'avez lu ci-dessus.
+
+### `PlainTextResponse` { #plaintextresponse }
+
+Prend du texte ou des octets et renvoie une réponse en texte brut.
+
+{* ../../docs_src/custom_response/tutorial005_py310.py hl[2,7,9] *}
+
+### `JSONResponse` { #jsonresponse }
+
+Prend des données et renvoie une réponse encodée en `application/json`.
+
+C'est la réponse par défaut utilisée dans **FastAPI**, comme vous l'avez lu ci-dessus.
+
+### `ORJSONResponse` { #orjsonresponse }
+
+Une réponse JSON alternative rapide utilisant `orjson`, comme vous l'avez lu ci-dessus.
+
+/// info
+
+Cela nécessite l'installation de `orjson`, par exemple avec `pip install orjson`.
+
+///
+
+### `UJSONResponse` { #ujsonresponse }
+
+Une réponse JSON alternative utilisant `ujson`.
+
+/// info
+
+Cela nécessite l'installation de `ujson`, par exemple avec `pip install ujson`.
+
+///
+
+/// warning | Alertes
+
+`ujson` est moins rigoureux que l'implémentation intégrée de Python dans sa gestion de certains cas limites.
+
+///
+
+{* ../../docs_src/custom_response/tutorial001_py310.py hl[2,7] *}
+
+/// tip | Astuce
+
+Il est possible que `ORJSONResponse` soit une alternative plus rapide.
+
+///
+
+### `RedirectResponse` { #redirectresponse }
+
+Renvoie une redirection HTTP. Utilise par défaut un code d'état 307 (Temporary Redirect).
+
+Vous pouvez renvoyer directement une `RedirectResponse` :
+
+{* ../../docs_src/custom_response/tutorial006_py310.py hl[2,9] *}
+
+---
+
+Ou vous pouvez l'utiliser dans le paramètre `response_class` :
+
+{* ../../docs_src/custom_response/tutorial006b_py310.py hl[2,7,9] *}
+
+Si vous faites cela, vous pouvez alors renvoyer directement l'URL depuis votre fonction de chemin d'accès.
+
+Dans ce cas, le `status_code` utilisé sera celui par défaut pour `RedirectResponse`, c'est-à-dire `307`.
+
+---
+
+Vous pouvez aussi utiliser le paramètre `status_code` combiné avec le paramètre `response_class` :
+
+{* ../../docs_src/custom_response/tutorial006c_py310.py hl[2,7,9] *}
+
+### `StreamingResponse` { #streamingresponse }
+
+Prend un générateur async ou un générateur/itérateur normal et diffuse le corps de la réponse.
+
+{* ../../docs_src/custom_response/tutorial007_py310.py hl[2,14] *}
+
+#### Utiliser `StreamingResponse` avec des objets de type fichier { #using-streamingresponse-with-file-like-objects }
+
+Si vous avez un objet de type fichier (par ex. l'objet renvoyé par `open()`), vous pouvez créer une fonction génératrice pour itérer sur cet objet de type fichier.
+
+De cette façon, vous n'avez pas à tout lire en mémoire au préalable, et vous pouvez passer cette fonction génératrice à `StreamingResponse`, puis la renvoyer.
+
+Cela inclut de nombreuses bibliothèques pour interagir avec du stockage cloud, du traitement vidéo, et autres.
+
+{* ../../docs_src/custom_response/tutorial008_py310.py hl[2,10:12,14] *}
+
+1. C'est la fonction génératrice. C'est une « fonction génératrice » parce qu'elle contient des instructions `yield` à l'intérieur.
+2. En utilisant un bloc `with`, nous nous assurons que l'objet de type fichier est fermé après l'exécution de la fonction génératrice. Donc, après qu'elle a fini d'envoyer la réponse.
+3. Ce `yield from` indique à la fonction d'itérer sur l'objet nommé `file_like`. Puis, pour chaque partie itérée, de produire cette partie comme provenant de cette fonction génératrice (`iterfile`).
+
+ Ainsi, c'est une fonction génératrice qui transfère le travail de « génération » à autre chose en interne.
+
+ En procédant ainsi, nous pouvons la placer dans un bloc `with` et, de cette façon, garantir que l'objet de type fichier est fermé après la fin.
+
+/// tip | Astuce
+
+Remarquez qu'ici, comme nous utilisons le `open()` standard qui ne prend pas en charge `async` et `await`, nous déclarons le chemin d'accès avec un `def` normal.
+
+///
+
+### `FileResponse` { #fileresponse }
+
+Diffuse de façon asynchrone un fichier comme réponse.
+
+Prend un ensemble de paramètres différent à l'instanciation par rapport aux autres types de réponse :
+
+- `path` - Le chemin du fichier à diffuser.
+- `headers` - D'éventuels en-têtes personnalisés à inclure, sous forme de dictionnaire.
+- `media_type` - Une chaîne donnant le media type. Si non défini, le nom du fichier ou le chemin sera utilisé pour en déduire un media type.
+- `filename` - Si défini, sera inclus dans l'en-tête `Content-Disposition` de la réponse.
+
+Les réponses de type fichier incluront les en-têtes appropriés `Content-Length`, `Last-Modified` et `ETag`.
+
+{* ../../docs_src/custom_response/tutorial009_py310.py hl[2,10] *}
+
+Vous pouvez aussi utiliser le paramètre `response_class` :
+
+{* ../../docs_src/custom_response/tutorial009b_py310.py hl[2,8,10] *}
+
+Dans ce cas, vous pouvez renvoyer directement le chemin du fichier depuis votre fonction de chemin d'accès.
+
+## Classe de réponse personnalisée { #custom-response-class }
+
+Vous pouvez créer votre propre classe de réponse personnalisée, héritant de `Response`, et l'utiliser.
+
+Par exemple, disons que vous voulez utiliser `orjson`, mais avec certains réglages personnalisés non utilisés dans la classe `ORJSONResponse` incluse.
+
+Disons que vous voulez renvoyer du JSON indenté et formaté, donc vous voulez utiliser l'option orjson `orjson.OPT_INDENT_2`.
+
+Vous pourriez créer une `CustomORJSONResponse`. L'essentiel est de créer une méthode `Response.render(content)` qui renvoie le contenu en `bytes` :
+
+{* ../../docs_src/custom_response/tutorial009c_py310.py hl[9:14,17] *}
+
+Maintenant, au lieu de renvoyer :
+
+```json
+{"message": "Hello World"}
+```
+
+... cette réponse renverra :
+
+```json
+{
+ "message": "Hello World"
+}
+```
+
+Bien sûr, vous trouverez probablement des moyens bien meilleurs de tirer parti de cela que de formater du JSON. 😉
+
+## Classe de réponse par défaut { #default-response-class }
+
+Lors de la création d'une instance de classe **FastAPI** ou d'un `APIRouter`, vous pouvez spécifier quelle classe de réponse utiliser par défaut.
+
+Le paramètre qui le définit est `default_response_class`.
+
+Dans l'exemple ci-dessous, **FastAPI** utilisera `ORJSONResponse` par défaut, dans tous les chemins d'accès, au lieu de `JSONResponse`.
+
+{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}
+
+/// tip | Astuce
+
+Vous pouvez toujours remplacer `response_class` dans les chemins d'accès comme auparavant.
+
+///
+
+## Documentation supplémentaire { #additional-documentation }
+
+Vous pouvez aussi déclarer le media type et de nombreux autres détails dans OpenAPI en utilisant `responses` : [Réponses supplémentaires dans OpenAPI](additional-responses.md){.internal-link target=_blank}.
diff --git a/docs/fr/docs/advanced/dataclasses.md b/docs/fr/docs/advanced/dataclasses.md
new file mode 100644
index 000000000..2bd77157e
--- /dev/null
+++ b/docs/fr/docs/advanced/dataclasses.md
@@ -0,0 +1,95 @@
+# Utiliser des dataclasses { #using-dataclasses }
+
+FastAPI est construit au‑dessus de **Pydantic**, et je vous ai montré comment utiliser des modèles Pydantic pour déclarer les requêtes et les réponses.
+
+Mais FastAPI prend aussi en charge l'utilisation de `dataclasses` de la même manière :
+
+{* ../../docs_src/dataclasses_/tutorial001_py310.py hl[1,6:11,18:19] *}
+
+Cela fonctionne grâce à **Pydantic**, qui offre une prise en charge interne des `dataclasses`.
+
+Ainsi, même avec le code ci‑dessus qui n'emploie pas explicitement Pydantic, FastAPI utilise Pydantic pour convertir ces dataclasses standard en la variante de dataclasses de Pydantic.
+
+Et bien sûr, cela prend en charge la même chose :
+
+* validation des données
+* sérialisation des données
+* documentation des données, etc.
+
+Cela fonctionne de la même manière qu'avec les modèles Pydantic. Et, en réalité, c'est mis en œuvre de la même façon en interne, en utilisant Pydantic.
+
+/// info | Info
+
+Gardez à l'esprit que les dataclasses ne peuvent pas tout ce que peuvent faire les modèles Pydantic.
+
+Vous pourriez donc avoir encore besoin d'utiliser des modèles Pydantic.
+
+Mais si vous avez déjà un ensemble de dataclasses sous la main, c'est une astuce pratique pour les utiliser afin d'alimenter une API Web avec FastAPI. 🤓
+
+///
+
+## Utiliser des dataclasses dans `response_model` { #dataclasses-in-response-model }
+
+Vous pouvez aussi utiliser `dataclasses` dans le paramètre `response_model` :
+
+{* ../../docs_src/dataclasses_/tutorial002_py310.py hl[1,6:12,18] *}
+
+La dataclass sera automatiquement convertie en dataclass Pydantic.
+
+Ainsi, son schéma apparaîtra dans l'interface utilisateur de la documentation de l'API :
+
+
+
+## Utiliser des dataclasses dans des structures de données imbriquées { #dataclasses-in-nested-data-structures }
+
+Vous pouvez aussi combiner `dataclasses` avec d'autres annotations de type pour créer des structures de données imbriquées.
+
+Dans certains cas, vous devrez peut‑être encore utiliser la version `dataclasses` de Pydantic. Par exemple, si vous rencontrez des erreurs avec la documentation d'API générée automatiquement.
+
+Dans ce cas, vous pouvez simplement remplacer les `dataclasses` standard par `pydantic.dataclasses`, qui est un remplacement drop‑in :
+
+{* ../../docs_src/dataclasses_/tutorial003_py310.py hl[1,4,7:10,13:16,22:24,27] *}
+
+1. Nous continuons à importer `field` depuis les `dataclasses` standard.
+
+2. `pydantic.dataclasses` est un remplacement drop‑in pour `dataclasses`.
+
+3. La dataclass `Author` inclut une liste de dataclasses `Item`.
+
+4. La dataclass `Author` est utilisée comme paramètre `response_model`.
+
+5. Vous pouvez utiliser d'autres annotations de type standard avec des dataclasses comme corps de la requête.
+
+ Dans ce cas, il s'agit d'une liste de dataclasses `Item`.
+
+6. Ici, nous renvoyons un dictionnaire qui contient `items`, qui est une liste de dataclasses.
+
+ FastAPI est toujours capable de sérialiser les données en JSON.
+
+7. Ici, `response_model` utilise une annotation de type correspondant à une liste de dataclasses `Author`.
+
+ Là encore, vous pouvez combiner `dataclasses` avec des annotations de type standard.
+
+8. Notez que cette *fonction de chemin d'accès* utilise un `def` classique au lieu de `async def`.
+
+ Comme toujours, avec FastAPI vous pouvez combiner `def` et `async def` selon vos besoins.
+
+ Si vous avez besoin d'un rappel sur quand utiliser l'un ou l'autre, consultez la section _« In a hurry? »_ dans la documentation à propos de [`async` et `await`](../async.md#in-a-hurry){.internal-link target=_blank}.
+
+9. Cette *fonction de chemin d'accès* ne renvoie pas des dataclasses (même si elle le pourrait), mais une liste de dictionnaires contenant des données internes.
+
+ FastAPI utilisera le paramètre `response_model` (qui inclut des dataclasses) pour convertir la réponse.
+
+Vous pouvez combiner `dataclasses` avec d'autres annotations de type, selon de nombreuses combinaisons, pour former des structures de données complexes.
+
+Reportez‑vous aux annotations dans le code ci‑dessus pour voir plus de détails spécifiques.
+
+## En savoir plus { #learn-more }
+
+Vous pouvez aussi combiner `dataclasses` avec d'autres modèles Pydantic, en hériter, les inclure dans vos propres modèles, etc.
+
+Pour en savoir plus, consultez la documentation Pydantic sur les dataclasses.
+
+## Version { #version }
+
+C'est disponible depuis FastAPI version `0.67.0`. 🔖
diff --git a/docs/fr/docs/advanced/events.md b/docs/fr/docs/advanced/events.md
new file mode 100644
index 000000000..6d0907a8b
--- /dev/null
+++ b/docs/fr/docs/advanced/events.md
@@ -0,0 +1,165 @@
+# Événements de cycle de vie { #lifespan-events }
+
+Vous pouvez définir une logique (du code) qui doit être exécutée avant que l'application ne **démarre**. Cela signifie que ce code sera exécuté **une seule fois**, **avant** que l'application ne **commence à recevoir des requêtes**.
+
+De la même manière, vous pouvez définir une logique (du code) qui doit être exécutée lorsque l'application **s'arrête**. Dans ce cas, ce code sera exécuté **une seule fois**, **après** avoir traité potentiellement **de nombreuses requêtes**.
+
+Comme ce code est exécuté avant que l'application ne **commence** à recevoir des requêtes, et juste après qu'elle **termine** de les traiter, il couvre tout le **cycle de vie** de l'application (le mot « lifespan » va être important dans un instant 😉).
+
+Cela peut être très utile pour configurer des **ressources** dont vous avez besoin pour l'ensemble de l'application, qui sont **partagées** entre les requêtes, et/ou que vous devez **nettoyer** ensuite. Par exemple, un pool de connexions à une base de données, ou le chargement d'un modèle d'apprentissage automatique partagé.
+
+## Cas d'utilisation { #use-case }
+
+Commençons par un exemple de **cas d'utilisation**, puis voyons comment le résoudre avec ceci.
+
+Imaginons que vous ayez des **modèles d'apprentissage automatique** que vous souhaitez utiliser pour traiter des requêtes. 🤖
+
+Les mêmes modèles sont partagés entre les requêtes, ce n'est donc pas un modèle par requête, ni un par utilisateur, ou quelque chose de similaire.
+
+Imaginons que le chargement du modèle puisse **prendre pas mal de temps**, car il doit lire beaucoup de **données depuis le disque**. Vous ne voulez donc pas le faire pour chaque requête.
+
+Vous pourriez le charger au niveau supérieur du module/fichier, mais cela signifierait aussi qu'il **chargerait le modèle** même si vous exécutez simplement un test automatisé simple ; ce test serait alors **lent** car il devrait attendre le chargement du modèle avant de pouvoir exécuter une partie indépendante du code.
+
+C'est ce que nous allons résoudre : chargeons le modèle avant que les requêtes ne soient traitées, mais seulement juste avant que l'application ne commence à recevoir des requêtes, pas pendant le chargement du code.
+
+## Cycle de vie { #lifespan }
+
+Vous pouvez définir cette logique de *démarrage* et d'*arrêt* en utilisant le paramètre `lifespan` de l'application `FastAPI`, et un « gestionnaire de contexte » (je vais vous montrer ce que c'est dans un instant).
+
+Commençons par un exemple, puis voyons-le en détail.
+
+Nous créons une fonction async `lifespan()` avec `yield` comme ceci :
+
+{* ../../docs_src/events/tutorial003_py310.py hl[16,19] *}
+
+Ici, nous simulons l'opération de *démarrage* coûteuse de chargement du modèle en plaçant la fonction (factice) du modèle dans le dictionnaire avec les modèles d'apprentissage automatique avant le `yield`. Ce code sera exécuté **avant** que l'application ne **commence à recevoir des requêtes**, pendant le *démarrage*.
+
+Puis, juste après le `yield`, nous déchargeons le modèle. Ce code sera exécuté **après** que l'application **a fini de traiter les requêtes**, juste avant l'*arrêt*. Cela pourrait, par exemple, libérer des ressources comme la mémoire ou un GPU.
+
+/// tip | Astuce
+
+L’« arrêt » se produit lorsque vous **arrêtez** l'application.
+
+Peut-être devez-vous démarrer une nouvelle version, ou vous en avez simplement assez de l'exécuter. 🤷
+
+///
+
+### Fonction de cycle de vie { #lifespan-function }
+
+La première chose à remarquer est que nous définissons une fonction async avec `yield`. C'est très similaire aux Dépendances avec `yield`.
+
+{* ../../docs_src/events/tutorial003_py310.py hl[14:19] *}
+
+La première partie de la fonction, avant le `yield`, sera exécutée **avant** le démarrage de l'application.
+
+Et la partie après le `yield` sera exécutée **après** que l'application a terminé.
+
+### Gestionnaire de contexte asynchrone { #async-context-manager }
+
+Si vous regardez, la fonction est décorée avec `@asynccontextmanager`.
+
+Cela convertit la fonction en quelque chose appelé un « **gestionnaire de contexte asynchrone** ».
+
+{* ../../docs_src/events/tutorial003_py310.py hl[1,13] *}
+
+Un **gestionnaire de contexte** en Python est quelque chose que vous pouvez utiliser dans une instruction `with`. Par exemple, `open()` peut être utilisé comme gestionnaire de contexte :
+
+```Python
+with open("file.txt") as file:
+ file.read()
+```
+
+Dans les versions récentes de Python, il existe aussi un **gestionnaire de contexte asynchrone**. Vous l'utiliseriez avec `async with` :
+
+```Python
+async with lifespan(app):
+ await do_stuff()
+```
+
+Quand vous créez un gestionnaire de contexte ou un gestionnaire de contexte asynchrone comme ci-dessus, ce qu'il fait, c'est qu'avant d'entrer dans le bloc `with`, il exécute le code avant le `yield`, et après être sorti du bloc `with`, il exécute le code après le `yield`.
+
+Dans notre exemple de code ci-dessus, nous ne l'utilisons pas directement, mais nous le transmettons à FastAPI pour qu'il l'utilise.
+
+Le paramètre `lifespan` de l'application `FastAPI` accepte un **gestionnaire de contexte asynchrone**, nous pouvons donc lui passer notre nouveau gestionnaire de contexte asynchrone `lifespan`.
+
+{* ../../docs_src/events/tutorial003_py310.py hl[22] *}
+
+## Événements alternatifs (déprécié) { #alternative-events-deprecated }
+
+/// warning | Alertes
+
+La méthode recommandée pour gérer le *démarrage* et l'*arrêt* est d'utiliser le paramètre `lifespan` de l'application `FastAPI` comme décrit ci-dessus. Si vous fournissez un paramètre `lifespan`, les gestionnaires d'événements `startup` et `shutdown` ne seront plus appelés. C'est soit tout en `lifespan`, soit tout en événements, pas les deux.
+
+Vous pouvez probablement passer cette partie.
+
+///
+
+Il existe une autre manière de définir cette logique à exécuter au *démarrage* et à l'*arrêt*.
+
+Vous pouvez définir des gestionnaires d'événements (fonctions) qui doivent être exécutés avant le démarrage de l'application, ou lorsque l'application s'arrête.
+
+Ces fonctions peuvent être déclarées avec `async def` ou un `def` normal.
+
+### Événement `startup` { #startup-event }
+
+Pour ajouter une fonction qui doit être exécutée avant le démarrage de l'application, déclarez-la avec l'événement « startup » :
+
+{* ../../docs_src/events/tutorial001_py310.py hl[8] *}
+
+Dans ce cas, la fonction gestionnaire de l'événement `startup` initialisera la « base de données » des items (juste un `dict`) avec quelques valeurs.
+
+Vous pouvez ajouter plusieurs fonctions de gestion d'événements.
+
+Et votre application ne commencera pas à recevoir des requêtes avant que tous les gestionnaires de l'événement `startup` aient terminé.
+
+### Événement `shutdown` { #shutdown-event }
+
+Pour ajouter une fonction qui doit être exécutée lorsque l'application s'arrête, déclarez-la avec l'événement « shutdown » :
+
+{* ../../docs_src/events/tutorial002_py310.py hl[6] *}
+
+Ici, la fonction gestionnaire de l'événement `shutdown` écrira une ligne de texte « Application shutdown » dans un fichier `log.txt`.
+
+/// info
+
+Dans la fonction `open()`, le `mode="a"` signifie « append » (ajouter) ; la ligne sera donc ajoutée après ce qui se trouve déjà dans ce fichier, sans écraser le contenu précédent.
+
+///
+
+/// tip | Astuce
+
+Notez que dans ce cas, nous utilisons une fonction Python standard `open()` qui interagit avec un fichier.
+
+Cela implique des E/S (input/output), qui nécessitent « d'attendre » que des choses soient écrites sur le disque.
+
+Mais `open()` n'utilise pas `async` et `await`.
+
+Nous déclarons donc la fonction gestionnaire d'événement avec un `def` standard plutôt qu'avec `async def`.
+
+///
+
+### `startup` et `shutdown` ensemble { #startup-and-shutdown-together }
+
+Il y a de fortes chances que la logique de votre *démarrage* et de votre *arrêt* soit liée : vous pourriez vouloir démarrer quelque chose puis le terminer, acquérir une ressource puis la libérer, etc.
+
+Faire cela dans des fonctions séparées qui ne partagent pas de logique ni de variables est plus difficile, car vous devriez stocker des valeurs dans des variables globales ou recourir à des astuces similaires.
+
+Pour cette raison, il est désormais recommandé d'utiliser plutôt le `lifespan` comme expliqué ci-dessus.
+
+## Détails techniques { #technical-details }
+
+Juste un détail technique pour les nerds curieux. 🤓
+
+Sous le capot, dans la spécification technique ASGI, cela fait partie du protocole Lifespan, et il y définit des événements appelés `startup` et `shutdown`.
+
+/// info
+
+Vous pouvez en lire plus sur les gestionnaires `lifespan` de Starlette dans la documentation « Lifespan » de Starlette.
+
+Y compris comment gérer l'état de cycle de vie qui peut être utilisé dans d'autres parties de votre code.
+
+///
+
+## Sous-applications { #sub-applications }
+
+🚨 Gardez à l'esprit que ces événements de cycle de vie (démarrage et arrêt) ne seront exécutés que pour l'application principale, pas pour [Sous-applications - Montages](sub-applications.md){.internal-link target=_blank}.
diff --git a/docs/fr/docs/advanced/generate-clients.md b/docs/fr/docs/advanced/generate-clients.md
new file mode 100644
index 000000000..6f51ac7be
--- /dev/null
+++ b/docs/fr/docs/advanced/generate-clients.md
@@ -0,0 +1,208 @@
+# Générer des SDK { #generating-sdks }
+
+Parce que **FastAPI** est basé sur la spécification **OpenAPI**, ses API peuvent être décrites dans un format standard compris par de nombreux outils.
+
+Cela facilite la génération de **documentation** à jour, de bibliothèques clientes (**SDKs**) dans plusieurs langages, ainsi que de **tests** ou de **workflows d’automatisation** qui restent synchronisés avec votre code.
+
+Dans ce guide, vous apprendrez à générer un **SDK TypeScript** pour votre backend FastAPI.
+
+## Générateurs de SDK open source { #open-source-sdk-generators }
+
+Une option polyvalente est OpenAPI Generator, qui prend en charge **de nombreux langages de programmation** et peut générer des SDK à partir de votre spécification OpenAPI.
+
+Pour les **clients TypeScript**, Hey API est une solution dédiée, offrant une expérience optimisée pour l’écosystème TypeScript.
+
+Vous pouvez découvrir davantage de générateurs de SDK sur OpenAPI.Tools.
+
+/// tip | Astuce
+
+FastAPI génère automatiquement des spécifications **OpenAPI 3.1**, donc tout outil que vous utilisez doit prendre en charge cette version.
+
+///
+
+## Générateurs de SDK par les sponsors de FastAPI { #sdk-generators-from-fastapi-sponsors }
+
+Cette section met en avant des solutions **soutenues par des fonds** et **par des entreprises** qui sponsorisent FastAPI. Ces produits offrent **des fonctionnalités supplémentaires** et **des intégrations** en plus de SDK de haute qualité générés.
+
+En ✨ [**sponsorisant FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, ces entreprises contribuent à garantir que le framework et son **écosystème** restent sains et **durables**.
+
+Leur sponsoring démontre également un fort engagement envers la **communauté** FastAPI (vous), montrant qu’elles se soucient non seulement d’offrir un **excellent service**, mais aussi de soutenir un **framework robuste et florissant**, FastAPI. 🙇
+
+Par exemple, vous pourriez essayer :
+
+* Speakeasy
+* Stainless
+* liblab
+
+Certaines de ces solutions peuvent aussi être open source ou proposer des niveaux gratuits, afin que vous puissiez les essayer sans engagement financier. D’autres générateurs de SDK commerciaux existent et peuvent être trouvés en ligne. 🤓
+
+## Créer un SDK TypeScript { #create-a-typescript-sdk }
+
+Commençons par une application FastAPI simple :
+
+{* ../../docs_src/generate_clients/tutorial001_py310.py hl[7:9,12:13,16:17,21] *}
+
+Remarquez que les *chemins d'accès* définissent les modèles qu’ils utilisent pour le payload de requête et le payload de réponse, en utilisant les modèles `Item` et `ResponseMessage`.
+
+### Documentation de l’API { #api-docs }
+
+Si vous allez sur `/docs`, vous verrez qu’elle contient les **schémas** pour les données à envoyer dans les requêtes et reçues dans les réponses :
+
+
+
+Vous voyez ces schémas parce qu’ils ont été déclarés avec les modèles dans l’application.
+
+Ces informations sont disponibles dans le **schéma OpenAPI** de l’application, puis affichées dans la documentation de l’API.
+
+Ces mêmes informations issues des modèles, incluses dans OpenAPI, peuvent être utilisées pour **générer le code client**.
+
+### Hey API { #hey-api }
+
+Une fois que vous avez une application FastAPI avec les modèles, vous pouvez utiliser Hey API pour générer un client TypeScript. Le moyen le plus rapide de le faire est via npx.
+
+```sh
+npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client
+```
+
+Cela générera un SDK TypeScript dans `./src/client`.
+
+Vous pouvez apprendre à installer `@hey-api/openapi-ts` et lire à propos du résultat généré sur leur site.
+
+### Utiliser le SDK { #using-the-sdk }
+
+Vous pouvez maintenant importer et utiliser le code client. Cela pourrait ressembler à ceci, remarquez que vous obtenez l’autocomplétion pour les méthodes :
+
+
+
+Vous obtiendrez également l’autocomplétion pour le payload à envoyer :
+
+
+
+/// tip | Astuce
+
+Remarquez l’autocomplétion pour `name` et `price`, qui a été définie dans l’application FastAPI, dans le modèle `Item`.
+
+///
+
+Vous aurez des erreurs en ligne pour les données que vous envoyez :
+
+
+
+L’objet de réponse aura également l’autocomplétion :
+
+
+
+## Application FastAPI avec des tags { #fastapi-app-with-tags }
+
+Dans de nombreux cas, votre application FastAPI sera plus grande, et vous utiliserez probablement des tags pour séparer différents groupes de *chemins d'accès*.
+
+Par exemple, vous pourriez avoir une section pour les **items** et une autre section pour les **users**, et elles pourraient être séparées par des tags :
+
+{* ../../docs_src/generate_clients/tutorial002_py310.py hl[21,26,34] *}
+
+### Générer un client TypeScript avec des tags { #generate-a-typescript-client-with-tags }
+
+Si vous générez un client pour une application FastAPI utilisant des tags, il séparera normalement aussi le code client en fonction des tags.
+
+De cette façon, vous pourrez avoir les éléments ordonnés et correctement groupés côté client :
+
+
+
+Dans ce cas, vous avez :
+
+* `ItemsService`
+* `UsersService`
+
+### Noms des méthodes du client { #client-method-names }
+
+À l’heure actuelle, les noms de méthodes générés comme `createItemItemsPost` ne sont pas très propres :
+
+```TypeScript
+ItemsService.createItemItemsPost({name: "Plumbus", price: 5})
+```
+
+... c’est parce que le générateur de client utilise l’**operation ID** interne OpenAPI pour chaque *chemin d'accès*.
+
+OpenAPI exige que chaque operation ID soit unique parmi tous les *chemins d'accès*, donc FastAPI utilise le **nom de la fonction**, le **chemin**, et la **méthode/opération HTTP** pour générer cet operation ID, car de cette façon il peut s’assurer que les operation IDs sont uniques.
+
+Mais je vais vous montrer comment améliorer cela ensuite. 🤓
+
+## IDs d’opération personnalisés et meilleurs noms de méthodes { #custom-operation-ids-and-better-method-names }
+
+Vous pouvez **modifier** la façon dont ces operation IDs sont **générés** pour les simplifier et obtenir des **noms de méthodes plus simples** dans les clients.
+
+Dans ce cas, vous devez vous assurer que chaque operation ID est **unique** d’une autre manière.
+
+Par exemple, vous pouvez vous assurer que chaque *chemin d'accès* a un tag, puis générer l’operation ID à partir du **tag** et du **nom** du *chemin d'accès* (le nom de la fonction).
+
+### Fonction personnalisée de génération d’ID unique { #custom-generate-unique-id-function }
+
+FastAPI utilise un **ID unique** pour chaque *chemin d'accès*, qui est utilisé pour l’**operation ID** et également pour les noms des modèles personnalisés nécessaires, pour les requêtes ou les réponses.
+
+Vous pouvez personnaliser cette fonction. Elle prend un `APIRoute` et retourne une chaîne.
+
+Par exemple, ici elle utilise le premier tag (vous n’en aurez probablement qu’un) et le nom du *chemin d'accès* (le nom de la fonction).
+
+Vous pouvez ensuite passer cette fonction personnalisée à **FastAPI** via le paramètre `generate_unique_id_function` :
+
+{* ../../docs_src/generate_clients/tutorial003_py310.py hl[6:7,10] *}
+
+### Générer un client TypeScript avec des IDs d’opération personnalisés { #generate-a-typescript-client-with-custom-operation-ids }
+
+Maintenant, si vous régénérez le client, vous verrez qu’il possède des noms de méthodes améliorés :
+
+
+
+Comme vous le voyez, les noms de méthodes contiennent maintenant le tag puis le nom de la fonction ; ils n’incluent plus d’informations provenant du chemin d’URL et de l’opération HTTP.
+
+### Prétraiter la spécification OpenAPI pour le générateur de client { #preprocess-the-openapi-specification-for-the-client-generator }
+
+Le code généré contient encore des **informations dupliquées**.
+
+Nous savons déjà que cette méthode est liée aux **items** parce que ce mot figure dans `ItemsService` (issu du tag), mais nous avons encore le nom du tag préfixé dans le nom de la méthode. 😕
+
+Nous voudrons probablement le conserver pour OpenAPI en général, car cela garantira que les operation IDs sont **uniques**.
+
+Mais pour le client généré, nous pourrions **modifier** les operation IDs d’OpenAPI juste avant de générer les clients, simplement pour rendre ces noms de méthodes plus agréables et **plus clairs**.
+
+Nous pourrions télécharger le JSON OpenAPI dans un fichier `openapi.json` puis **supprimer ce tag préfixé** avec un script comme celui-ci :
+
+{* ../../docs_src/generate_clients/tutorial004_py310.py *}
+
+//// tab | Node.js
+
+```Javascript
+{!> ../../docs_src/generate_clients/tutorial004.js!}
+```
+
+////
+
+Avec cela, les operation IDs seraient renommés de `items-get_items` en simplement `get_items`, de sorte que le générateur de client puisse produire des noms de méthodes plus simples.
+
+### Générer un client TypeScript avec l’OpenAPI prétraité { #generate-a-typescript-client-with-the-preprocessed-openapi }
+
+Puisque le résultat final se trouve maintenant dans un fichier `openapi.json`, vous devez mettre à jour l’emplacement d’entrée :
+
+```sh
+npx @hey-api/openapi-ts -i ./openapi.json -o src/client
+```
+
+Après avoir généré le nouveau client, vous aurez désormais des **noms de méthodes propres**, avec toute l’**autocomplétion**, les **erreurs en ligne**, etc. :
+
+
+
+## Avantages { #benefits }
+
+En utilisant les clients générés automatiquement, vous obtiendrez de l’**autocomplétion** pour :
+
+* Méthodes.
+* Payloads de requête dans le corps, paramètres de requête, etc.
+* Payloads de réponse.
+
+Vous auriez également des **erreurs en ligne** pour tout.
+
+Et chaque fois que vous mettez à jour le code du backend et **régénérez** le frontend, il inclura les nouveaux *chemins d'accès* disponibles en tant que méthodes, supprimera les anciens, et tout autre changement sera reflété dans le code généré. 🤓
+
+Cela signifie aussi que si quelque chose change, cela sera **reflété** automatiquement dans le code client. Et si vous **bâtissez** le client, il échouera en cas de **discordance** dans les données utilisées.
+
+Ainsi, vous **détecterez de nombreuses erreurs** très tôt dans le cycle de développement au lieu d’attendre qu’elles apparaissent pour vos utilisateurs finaux en production puis de tenter de déboguer l’origine du problème. ✨
diff --git a/docs/fr/docs/advanced/middleware.md b/docs/fr/docs/advanced/middleware.md
new file mode 100644
index 000000000..934c91041
--- /dev/null
+++ b/docs/fr/docs/advanced/middleware.md
@@ -0,0 +1,97 @@
+# Utiliser des middlewares avancés { #advanced-middleware }
+
+Dans le tutoriel principal, vous avez vu comment ajouter des [middlewares personnalisés](../tutorial/middleware.md){.internal-link target=_blank} à votre application.
+
+Vous avez également vu comment gérer [CORS avec le `CORSMiddleware`](../tutorial/cors.md){.internal-link target=_blank}.
+
+Dans cette section, nous allons voir comment utiliser d'autres middlewares.
+
+## Ajouter des middlewares ASGI { #adding-asgi-middlewares }
+
+Comme **FastAPI** est basé sur Starlette et implémente la spécification ASGI, vous pouvez utiliser n'importe quel middleware ASGI.
+
+Un middleware n'a pas besoin d'être conçu pour FastAPI ou Starlette pour fonctionner, tant qu'il suit la spécification ASGI.
+
+En général, les middlewares ASGI sont des classes qui s'attendent à recevoir une application ASGI en premier argument.
+
+Ainsi, dans la documentation de middlewares ASGI tiers, on vous indiquera probablement de faire quelque chose comme :
+
+```Python
+from unicorn import UnicornMiddleware
+
+app = SomeASGIApp()
+
+new_app = UnicornMiddleware(app, some_config="rainbow")
+```
+
+Mais FastAPI (en fait Starlette) fournit une manière plus simple de le faire, qui garantit que les middlewares internes gèrent les erreurs serveur et que les gestionnaires d'exceptions personnalisés fonctionnent correctement.
+
+Pour cela, vous utilisez `app.add_middleware()` (comme dans l'exemple pour CORS).
+
+```Python
+from fastapi import FastAPI
+from unicorn import UnicornMiddleware
+
+app = FastAPI()
+
+app.add_middleware(UnicornMiddleware, some_config="rainbow")
+```
+
+`app.add_middleware()` reçoit une classe de middleware en premier argument, ainsi que tout argument supplémentaire à transmettre au middleware.
+
+## Utiliser les middlewares intégrés { #integrated-middlewares }
+
+**FastAPI** inclut plusieurs middlewares pour des cas d'usage courants ; voyons comment les utiliser.
+
+/// note | Détails techniques
+
+Pour les prochains exemples, vous pourriez aussi utiliser `from starlette.middleware.something import SomethingMiddleware`.
+
+**FastAPI** fournit plusieurs middlewares dans `fastapi.middleware` simplement pour vous faciliter la vie, en tant que développeur. Mais la plupart des middlewares disponibles viennent directement de Starlette.
+
+///
+
+## `HTTPSRedirectMiddleware` { #httpsredirectmiddleware }
+
+Impose que toutes les requêtes entrantes soient soit `https`, soit `wss`.
+
+Toute requête entrante en `http` ou `ws` sera redirigée vers le schéma sécurisé correspondant.
+
+{* ../../docs_src/advanced_middleware/tutorial001_py310.py hl[2,6] *}
+
+## `TrustedHostMiddleware` { #trustedhostmiddleware }
+
+Impose que toutes les requêtes entrantes aient un en-tête `Host` correctement défini, afin de se prémunir contre les attaques de type HTTP Host Header.
+
+{* ../../docs_src/advanced_middleware/tutorial002_py310.py hl[2,6:8] *}
+
+Les arguments suivants sont pris en charge :
+
+- `allowed_hosts` - Une liste de noms de domaine autorisés comme noms d'hôte. Les domaines génériques tels que `*.example.com` sont pris en charge pour faire correspondre les sous-domaines. Pour autoriser n'importe quel nom d'hôte, utilisez `allowed_hosts=["*"]` ou omettez le middleware.
+- `www_redirect` - Si défini à `True`, les requêtes vers les versions sans www des hôtes autorisés seront redirigées vers leurs équivalents avec www. Valeur par défaut : `True`.
+
+Si une requête entrante n'est pas valide, une réponse `400` sera envoyée.
+
+## `GZipMiddleware` { #gzipmiddleware }
+
+Gère les réponses GZip pour toute requête qui inclut « gzip » dans l'en-tête `Accept-Encoding`.
+
+Le middleware gérera les réponses standard et en streaming.
+
+{* ../../docs_src/advanced_middleware/tutorial003_py310.py hl[2,6] *}
+
+Les arguments suivants sont pris en charge :
+
+- `minimum_size` - Ne pas compresser en GZip les réponses dont la taille est inférieure à ce minimum en octets. Valeur par défaut : `500`.
+- `compresslevel` - Utilisé pendant la compression GZip. Entier compris entre 1 et 9. Valeur par défaut : `9`. Une valeur plus faible entraîne une compression plus rapide mais des fichiers plus volumineux, tandis qu'une valeur plus élevée entraîne une compression plus lente mais des fichiers plus petits.
+
+## Autres middlewares { #other-middlewares }
+
+Il existe de nombreux autres middlewares ASGI.
+
+Par exemple :
+
+- Le `ProxyHeadersMiddleware` d'Uvicorn
+- MessagePack
+
+Pour voir d'autres middlewares disponibles, consultez la documentation des middlewares de Starlette et la liste ASGI Awesome.
diff --git a/docs/fr/docs/advanced/openapi-callbacks.md b/docs/fr/docs/advanced/openapi-callbacks.md
new file mode 100644
index 000000000..669d9447a
--- /dev/null
+++ b/docs/fr/docs/advanced/openapi-callbacks.md
@@ -0,0 +1,186 @@
+# Callbacks OpenAPI { #openapi-callbacks }
+
+Vous pourriez créer une API avec un *chemin d'accès* qui déclenche une requête vers une *API externe* créée par quelqu'un d'autre (probablement la même personne développeuse qui utiliserait votre API).
+
+Le processus qui se produit lorsque votre application API appelle l’*API externe* s’appelle un « callback ». Parce que le logiciel écrit par la personne développeuse externe envoie une requête à votre API puis votre API « rappelle », en envoyant une requête à une *API externe* (probablement créée par la même personne développeuse).
+
+Dans ce cas, vous pourriez vouloir documenter à quoi cette API externe devrait ressembler. Quel *chemin d'accès* elle devrait avoir, quel corps elle devrait attendre, quelle réponse elle devrait renvoyer, etc.
+
+## Une application avec des callbacks { #an-app-with-callbacks }
+
+Voyons tout cela avec un exemple.
+
+Imaginez que vous développiez une application qui permet de créer des factures.
+
+Ces factures auront un `id`, un `title` (facultatif), un `customer` et un `total`.
+
+L’utilisateur de votre API (une personne développeuse externe) créera une facture dans votre API avec une requête POST.
+
+Ensuite votre API va (imaginons) :
+
+* Envoyer la facture à un client de la personne développeuse externe.
+* Encaisser l’argent.
+* Renvoyer une notification à l’utilisateur de l’API (la personne développeuse externe).
+ * Cela sera fait en envoyant une requête POST (depuis *votre API*) vers une *API externe* fournie par cette personne développeuse externe (c’est le « callback »).
+
+## L’application **FastAPI** normale { #the-normal-fastapi-app }
+
+Voyons d’abord à quoi ressemble l’application API normale avant d’ajouter le callback.
+
+Elle aura un *chemin d'accès* qui recevra un corps `Invoice`, et un paramètre de requête `callback_url` qui contiendra l’URL pour le callback.
+
+Cette partie est assez normale, la plupart du code vous est probablement déjà familier :
+
+{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[7:11,34:51] *}
+
+/// tip | Astuce
+
+Le paramètre de requête `callback_url` utilise un type Pydantic Url.
+
+///
+
+La seule nouveauté est `callbacks=invoices_callback_router.routes` comme argument du *décorateur de chemin d'accès*. Nous allons voir ce que c’est ensuite.
+
+## Documenter le callback { #documenting-the-callback }
+
+Le code réel du callback dépendra fortement de votre application API.
+
+Et il variera probablement beaucoup d’une application à l’autre.
+
+Cela pourrait être seulement une ou deux lignes de code, comme :
+
+```Python
+callback_url = "https://example.com/api/v1/invoices/events/"
+httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
+```
+
+Mais la partie la plus importante du callback est sans doute de vous assurer que l’utilisateur de votre API (la personne développeuse externe) implémente correctement l’*API externe*, conformément aux données que *votre API* va envoyer dans le corps de la requête du callback, etc.
+
+Ainsi, ce que nous allons faire ensuite, c’est ajouter le code pour documenter à quoi cette *API externe* devrait ressembler pour recevoir le callback de *votre API*.
+
+Cette documentation apparaîtra dans Swagger UI à `/docs` dans votre API, et permettra aux personnes développeuses externes de savoir comment construire l’*API externe*.
+
+Cet exemple n’implémente pas le callback lui-même (qui pourrait être une simple ligne de code), uniquement la partie documentation.
+
+/// tip | Astuce
+
+Le callback réel n’est qu’une requête HTTP.
+
+En implémentant vous-même le callback, vous pourriez utiliser quelque chose comme HTTPX ou Requests.
+
+///
+
+## Écrire le code de documentation du callback { #write-the-callback-documentation-code }
+
+Ce code ne sera pas exécuté dans votre application, nous en avons seulement besoin pour *documenter* à quoi devrait ressembler cette *API externe*.
+
+Mais vous savez déjà comment créer facilement une documentation automatique pour une API avec **FastAPI**.
+
+Nous allons donc utiliser ce même savoir pour documenter à quoi l’*API externe* devrait ressembler ... en créant le(s) *chemin(s) d'accès* que l’API externe devrait implémenter (ceux que votre API appellera).
+
+/// tip | Astuce
+
+Lorsque vous écrivez le code pour documenter un callback, il peut être utile d’imaginer que vous êtes cette *personne développeuse externe*. Et que vous implémentez actuellement l’*API externe*, pas *votre API*.
+
+Adopter temporairement ce point de vue (celui de la *personne développeuse externe*) peut vous aider à trouver plus évident où placer les paramètres, le modèle Pydantic pour le corps, pour la réponse, etc., pour cette *API externe*.
+
+///
+
+### Créer un `APIRouter` de callback { #create-a-callback-apirouter }
+
+Commencez par créer un nouveau `APIRouter` qui contiendra un ou plusieurs callbacks.
+
+{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[1,23] *}
+
+### Créer le *chemin d'accès* du callback { #create-the-callback-path-operation }
+
+Pour créer le *chemin d'accès* du callback, utilisez le même `APIRouter` que vous avez créé ci-dessus.
+
+Il devrait ressembler exactement à un *chemin d'accès* FastAPI normal :
+
+* Il devrait probablement déclarer le corps qu’il doit recevoir, par exemple `body: InvoiceEvent`.
+* Et il pourrait aussi déclarer la réponse qu’il doit renvoyer, par exemple `response_model=InvoiceEventReceived`.
+
+{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[14:16,19:20,26:30] *}
+
+Il y a 2 principales différences par rapport à un *chemin d'accès* normal :
+
+* Il n’a pas besoin d’avoir de code réel, car votre application n’appellera jamais ce code. Il sert uniquement à documenter l’*API externe*. La fonction peut donc simplement contenir `pass`.
+* Le *chemin* peut contenir une expression OpenAPI 3 (voir plus bas) où il peut utiliser des variables avec des paramètres et des parties de la requête originale envoyée à *votre API*.
+
+### L’expression du chemin de callback { #the-callback-path-expression }
+
+Le *chemin* du callback peut contenir une expression OpenAPI 3 qui peut inclure des parties de la requête originale envoyée à *votre API*.
+
+Dans ce cas, c’est la `str` :
+
+```Python
+"{$callback_url}/invoices/{$request.body.id}"
+```
+
+Ainsi, si l’utilisateur de votre API (la personne développeuse externe) envoie une requête à *votre API* vers :
+
+```
+https://yourapi.com/invoices/?callback_url=https://www.external.org/events
+```
+
+avec un corps JSON :
+
+```JSON
+{
+ "id": "2expen51ve",
+ "customer": "Mr. Richie Rich",
+ "total": "9999"
+}
+```
+
+alors *votre API* traitera la facture et, à un moment ultérieur, enverra une requête de callback à `callback_url` (l’*API externe*) :
+
+```
+https://www.external.org/events/invoices/2expen51ve
+```
+
+avec un corps JSON contenant quelque chose comme :
+
+```JSON
+{
+ "description": "Payment celebration",
+ "paid": true
+}
+```
+
+et elle s’attendra à une réponse de cette *API externe* avec un corps JSON comme :
+
+```JSON
+{
+ "ok": true
+}
+```
+
+/// tip | Astuce
+
+Remarquez que l’URL de callback utilisée contient l’URL reçue en paramètre de requête dans `callback_url` (`https://www.external.org/events`) et aussi l’`id` de la facture à l’intérieur du corps JSON (`2expen51ve`).
+
+///
+
+### Ajouter le routeur de callback { #add-the-callback-router }
+
+À ce stade, vous avez le(s) *chemin(s) d'accès de callback* nécessaire(s) (celui/ceux que la *personne développeuse externe* doit implémenter dans l’*API externe*) dans le routeur de callback que vous avez créé ci-dessus.
+
+Utilisez maintenant le paramètre `callbacks` dans *le décorateur de chemin d'accès de votre API* pour passer l’attribut `.routes` (qui est en fait juste une `list` de routes/*chemins d'accès*) depuis ce routeur de callback :
+
+{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *}
+
+/// tip | Astuce
+
+Remarquez que vous ne passez pas le routeur lui-même (`invoices_callback_router`) à `callback=`, mais l’attribut `.routes`, comme dans `invoices_callback_router.routes`.
+
+///
+
+### Vérifier la documentation { #check-the-docs }
+
+Vous pouvez maintenant démarrer votre application et aller sur http://127.0.0.1:8000/docs.
+
+Vous verrez votre documentation incluant une section « Callbacks » pour votre *chemin d'accès* qui montre à quoi l’*API externe* devrait ressembler :
+
+
diff --git a/docs/fr/docs/advanced/openapi-webhooks.md b/docs/fr/docs/advanced/openapi-webhooks.md
new file mode 100644
index 000000000..21b6f5f00
--- /dev/null
+++ b/docs/fr/docs/advanced/openapi-webhooks.md
@@ -0,0 +1,55 @@
+# Webhooks OpenAPI { #openapi-webhooks }
+
+Il existe des cas où vous voulez informer les utilisateurs de votre API que votre application peut appeler leur application (en envoyant une requête) avec des données, généralement pour notifier un type d'événement.
+
+Cela signifie qu'au lieu du processus habituel où vos utilisateurs envoient des requêtes à votre API, c'est votre API (ou votre application) qui peut envoyer des requêtes vers leur système (vers leur API, leur application).
+
+On appelle généralement cela un webhook.
+
+## Étapes des webhooks { #webhooks-steps }
+
+Le processus consiste généralement à définir dans votre code le message que vous enverrez, c'est-à-dire le corps de la requête.
+
+Vous définissez également, d'une manière ou d'une autre, à quels moments votre application enverra ces requêtes ou événements.
+
+Et vos utilisateurs définissent aussi, d'une manière ou d'une autre (par exemple dans un tableau de bord Web), l'URL à laquelle votre application doit envoyer ces requêtes.
+
+Toute la logique de gestion des URL des webhooks et le code qui envoie effectivement ces requêtes vous incombent. Vous l'implémentez comme vous le souhaitez dans votre propre code.
+
+## Documenter des webhooks avec FastAPI et OpenAPI { #documenting-webhooks-with-fastapi-and-openapi }
+
+Avec FastAPI, en utilisant OpenAPI, vous pouvez définir les noms de ces webhooks, les types d'opérations HTTP que votre application peut envoyer (par exemple `POST`, `PUT`, etc.) et les corps des requêtes que votre application enverra.
+
+Cela peut grandement faciliter la tâche de vos utilisateurs pour implémenter leurs API afin de recevoir vos requêtes de webhook ; ils pourront même peut-être générer automatiquement une partie de leur propre code d'API.
+
+/// info
+
+Les webhooks sont disponibles dans OpenAPI 3.1.0 et versions ultérieures, pris en charge par FastAPI `0.99.0` et versions ultérieures.
+
+///
+
+## Créer une application avec des webhooks { #an-app-with-webhooks }
+
+Lorsque vous créez une application FastAPI, il existe un attribut `webhooks` que vous pouvez utiliser pour définir des webhooks, de la même manière que vous définiriez des chemins d'accès, par exemple avec `@app.webhooks.post()`.
+
+{* ../../docs_src/openapi_webhooks/tutorial001_py310.py hl[9:12,15:20] *}
+
+Les webhooks que vous définissez apparaîtront dans le schéma **OpenAPI** et dans l'interface de **documentation** automatique.
+
+/// info
+
+L'objet `app.webhooks` est en fait simplement un `APIRouter`, le même type que vous utiliseriez pour structurer votre application en plusieurs fichiers.
+
+///
+
+Notez qu'avec les webhooks, vous ne déclarez pas réellement un chemin (comme `/items/`), le texte que vous y passez est simplement un identifiant du webhook (le nom de l'événement). Par exemple, dans `@app.webhooks.post("new-subscription")`, le nom du webhook est `new-subscription`.
+
+C'est parce qu'on s'attend à ce que vos utilisateurs définissent, par un autre moyen (par exemple un tableau de bord Web), le véritable chemin d'URL où ils souhaitent recevoir la requête de webhook.
+
+### Consulter la documentation { #check-the-docs }
+
+Vous pouvez maintenant démarrer votre application et aller sur http://127.0.0.1:8000/docs.
+
+Vous verrez que votre documentation contient les chemins d'accès habituels et désormais aussi des webhooks :
+
+
diff --git a/docs/fr/docs/advanced/path-operation-advanced-configuration.md b/docs/fr/docs/advanced/path-operation-advanced-configuration.md
index fc88f3363..b482f97cc 100644
--- a/docs/fr/docs/advanced/path-operation-advanced-configuration.md
+++ b/docs/fr/docs/advanced/path-operation-advanced-configuration.md
@@ -12,7 +12,7 @@ Vous pouvez définir l’OpenAPI `operationId` à utiliser dans votre chemin d
Vous devez vous assurer qu’il est unique pour chaque opération.
-{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py310.py hl[6] *}
### Utiliser le nom de la fonction de chemin d’accès comme operationId { #using-the-path-operation-function-name-as-the-operationid }
@@ -20,7 +20,7 @@ Si vous souhaitez utiliser les noms de fonction de vos API comme `operationId`,
Vous devez le faire après avoir ajouté tous vos chemins d’accès.
-{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2, 12:21, 24] *}
/// tip | Astuce
@@ -40,7 +40,7 @@ Même si elles se trouvent dans des modules différents (fichiers Python).
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_py39.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py310.py hl[6] *}
## Description avancée depuis la docstring { #advanced-description-from-docstring }
@@ -92,7 +92,7 @@ Vous pouvez étendre le schéma OpenAPI pour un chemin d’accès en utilisant l
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_py39.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py310.py hl[6] *}
Si vous ouvrez la documentation automatique de l’API, votre extension apparaîtra en bas du chemin d’accès spécifique.
@@ -139,9 +139,9 @@ Par exemple, vous pourriez décider de lire et de valider la requête avec votre
Vous pourriez le faire avec `openapi_extra` :
-{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py310.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 parsé 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.
+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 parsé 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.
@@ -153,7 +153,7 @@ Et vous pourriez le faire même si le type de données dans la requête n’est
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_py39.py hl[15:20, 22] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[15:20, 22] *}
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.
@@ -161,7 +161,7 @@ Ensuite, nous utilisons directement la requête et extrayons le corps en tant qu
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_py39.py hl[24:31] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[24:31] *}
/// tip | Astuce
diff --git a/docs/fr/docs/advanced/response-change-status-code.md b/docs/fr/docs/advanced/response-change-status-code.md
new file mode 100644
index 000000000..d08e87099
--- /dev/null
+++ b/docs/fr/docs/advanced/response-change-status-code.md
@@ -0,0 +1,31 @@
+# Réponse - Modifier le code d'état { #response-change-status-code }
+
+Vous avez probablement déjà lu que vous pouvez définir un [Code d'état de la réponse](../tutorial/response-status-code.md){.internal-link target=_blank} par défaut.
+
+Mais dans certains cas, vous devez renvoyer un code d'état différent de celui par défaut.
+
+## Cas d'utilisation { #use-case }
+
+Par exemple, imaginez que vous vouliez renvoyer par défaut un code d'état HTTP « OK » `200`.
+
+Mais si les données n'existent pas, vous voulez les créer et renvoyer un code d'état HTTP « CREATED » `201`.
+
+Mais vous souhaitez toujours pouvoir filtrer et convertir les données que vous renvoyez avec un `response_model`.
+
+Pour ces cas, vous pouvez utiliser un paramètre `Response`.
+
+## Utiliser un paramètre `Response` { #use-a-response-parameter }
+
+Vous pouvez déclarer un paramètre de type `Response` dans votre fonction de chemin d'accès (comme vous pouvez le faire pour les cookies et les en-têtes).
+
+Vous pouvez ensuite définir le `status_code` dans cet objet de réponse *temporaire*.
+
+{* ../../docs_src/response_change_status_code/tutorial001_py310.py hl[1,9,12] *}
+
+Vous pouvez ensuite renvoyer n'importe quel objet nécessaire, comme d'habitude (un `dict`, un modèle de base de données, etc.).
+
+Et si vous avez déclaré un `response_model`, il sera toujours utilisé pour filtrer et convertir l'objet que vous avez renvoyé.
+
+**FastAPI** utilisera cette réponse *temporaire* pour extraire le code d'état (ainsi que les cookies et les en-têtes), et les placera dans la réponse finale qui contient la valeur que vous avez renvoyée, filtrée par tout `response_model`.
+
+Vous pouvez également déclarer le paramètre `Response` dans des dépendances et y définir le code d'état. Mais gardez à l'esprit que la dernière valeur définie prévaut.
diff --git a/docs/fr/docs/advanced/response-cookies.md b/docs/fr/docs/advanced/response-cookies.md
new file mode 100644
index 000000000..d3e51f331
--- /dev/null
+++ b/docs/fr/docs/advanced/response-cookies.md
@@ -0,0 +1,51 @@
+# Cookies de réponse { #response-cookies }
+
+## Utiliser un paramètre `Response` { #use-a-response-parameter }
+
+Vous pouvez déclarer un paramètre de type `Response` dans votre fonction de chemin d'accès.
+
+Vous pouvez ensuite définir des cookies dans cet objet de réponse *temporaire*.
+
+{* ../../docs_src/response_cookies/tutorial002_py310.py hl[1, 8:9] *}
+
+Vous pouvez ensuite renvoyer n'importe quel objet dont vous avez besoin, comme d'habitude (un `dict`, un modèle de base de données, etc.).
+
+Et si vous avez déclaré un `response_model`, il sera toujours utilisé pour filtrer et convertir l'objet que vous avez renvoyé.
+
+**FastAPI** utilisera cette réponse *temporaire* pour extraire les cookies (ainsi que les en-têtes et le code d'état), et les placera dans la réponse finale qui contient la valeur que vous avez renvoyée, filtrée par tout `response_model`.
+
+Vous pouvez également déclarer le paramètre `Response` dans des dépendances, et y définir des cookies (et des en-têtes).
+
+## Renvoyer une `Response` directement { #return-a-response-directly }
+
+Vous pouvez également créer des cookies en renvoyant une `Response` directement dans votre code.
+
+Pour ce faire, vous pouvez créer une réponse comme décrit dans [Renvoyer une Response directement](response-directly.md){.internal-link target=_blank}.
+
+Définissez ensuite des cookies dessus, puis renvoyez-la :
+
+{* ../../docs_src/response_cookies/tutorial001_py310.py hl[10:12] *}
+
+/// tip | Astuce
+
+Gardez à l'esprit que si vous renvoyez une réponse directement au lieu d'utiliser le paramètre `Response`, FastAPI la renverra telle quelle.
+
+Vous devez donc vous assurer que vos données sont du type correct. Par exemple, qu'elles sont compatibles avec JSON si vous renvoyez une `JSONResponse`.
+
+Et également que vous n'envoyez pas de données qui auraient dû être filtrées par un `response_model`.
+
+///
+
+### En savoir plus { #more-info }
+
+/// note | Détails techniques
+
+Vous pouvez également utiliser `from starlette.responses import Response` ou `from starlette.responses import JSONResponse`.
+
+**FastAPI** fournit les mêmes `starlette.responses` que `fastapi.responses` simplement pour votre commodité, en tant que développeur. Mais la plupart des réponses disponibles proviennent directement de Starlette.
+
+Et comme `Response` peut être utilisé fréquemment pour définir des en-têtes et des cookies, **FastAPI** la met également à disposition via `fastapi.Response`.
+
+///
+
+Pour voir tous les paramètres et options disponibles, consultez la documentation de Starlette.
diff --git a/docs/fr/docs/advanced/response-directly.md b/docs/fr/docs/advanced/response-directly.md
index f35c39c06..4a4951864 100644
--- a/docs/fr/docs/advanced/response-directly.md
+++ b/docs/fr/docs/advanced/response-directly.md
@@ -22,7 +22,7 @@ En fait, vous pouvez retourner n'importe quelle `Response` ou n'importe quelle s
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.
+Elle ne fera aucune conversion de données avec les modèles Pydantic, elle ne convertira pas le contenu en un type quelconque, etc.
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.
@@ -54,7 +54,7 @@ Disons que vous voulez retourner une réponse en utilisant le préfixe `X-`.
+
+Mais si vous avez des en-têtes personnalisés que vous voulez qu'un client dans un navigateur puisse voir, vous devez les ajouter à vos configurations CORS (en savoir plus dans [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md){.internal-link target=_blank}), en utilisant le paramètre `expose_headers` documenté dans la documentation CORS de Starlette.
diff --git a/docs/fr/docs/advanced/security/http-basic-auth.md b/docs/fr/docs/advanced/security/http-basic-auth.md
new file mode 100644
index 000000000..a8742ce7c
--- /dev/null
+++ b/docs/fr/docs/advanced/security/http-basic-auth.md
@@ -0,0 +1,107 @@
+# Authentification HTTP Basic { #http-basic-auth }
+
+Pour les cas les plus simples, vous pouvez utiliser l'authentification HTTP Basic.
+
+Avec l'authentification HTTP Basic, l'application attend un en-tête contenant un nom d'utilisateur et un mot de passe.
+
+Si elle ne le reçoit pas, elle renvoie une erreur HTTP 401 « Unauthorized ».
+
+Et elle renvoie un en-tête `WWW-Authenticate` avec la valeur `Basic`, et un paramètre optionnel `realm`.
+
+Cela indique au navigateur d'afficher l'invite intégrée pour saisir un nom d'utilisateur et un mot de passe.
+
+Ensuite, lorsque vous saisissez ce nom d'utilisateur et ce mot de passe, le navigateur les envoie automatiquement dans l'en-tête.
+
+## Authentification HTTP Basic simple { #simple-http-basic-auth }
+
+- Importer `HTTPBasic` et `HTTPBasicCredentials`.
+- Créer un « schéma de sécurité » en utilisant `HTTPBasic`.
+- Utiliser ce `security` avec une dépendance dans votre chemin d'accès.
+- Cela renvoie un objet de type `HTTPBasicCredentials` :
+ - Il contient le `username` et le `password` envoyés.
+
+{* ../../docs_src/security/tutorial006_an_py310.py hl[4,8,12] *}
+
+Lorsque vous essayez d'ouvrir l'URL pour la première fois (ou cliquez sur le bouton « Execute » dans les documents) le navigateur vous demandera votre nom d'utilisateur et votre mot de passe :
+
+
+
+## Vérifier le nom d'utilisateur { #check-the-username }
+
+Voici un exemple plus complet.
+
+Utilisez une dépendance pour vérifier si le nom d'utilisateur et le mot de passe sont corrects.
+
+Pour cela, utilisez le module standard Python `secrets` pour vérifier le nom d'utilisateur et le mot de passe.
+
+`secrets.compare_digest()` doit recevoir des `bytes` ou une `str` ne contenant que des caractères ASCII (ceux de l'anglais), ce qui signifie qu'elle ne fonctionnerait pas avec des caractères comme `á`, comme dans `Sebastián`.
+
+Pour gérer cela, nous convertissons d'abord `username` et `password` en `bytes` en les encodant en UTF-8.
+
+Nous pouvons ensuite utiliser `secrets.compare_digest()` pour vérifier que `credentials.username` est « stanleyjobson » et que `credentials.password` est « swordfish ».
+
+{* ../../docs_src/security/tutorial007_an_py310.py hl[1,12:24] *}
+
+Cela serait équivalent à :
+
+```Python
+if not (credentials.username == "stanleyjobson") or not (credentials.password == "swordfish"):
+ # Renvoyer une erreur
+ ...
+```
+
+Mais en utilisant `secrets.compare_digest()`, cela sera sécurisé contre un type d'attaques appelé « attaques par chronométrage ».
+
+### Attaques par chronométrage { #timing-attacks }
+
+Mais qu'est-ce qu'une « attaque par chronométrage » ?
+
+Imaginons que des attaquants essaient de deviner le nom d'utilisateur et le mot de passe.
+
+Ils envoient alors une requête avec un nom d'utilisateur `johndoe` et un mot de passe `love123`.
+
+Le code Python de votre application serait alors équivalent à quelque chose comme :
+
+```Python
+if "johndoe" == "stanleyjobson" and "love123" == "swordfish":
+ ...
+```
+
+Mais au moment où Python compare le premier `j` de `johndoe` au premier `s` de `stanleyjobson`, il retournera `False`, car il sait déjà que ces deux chaînes ne sont pas identiques, en se disant qu'« il n'est pas nécessaire de gaspiller plus de calcul pour comparer le reste des lettres ». Et votre application dira « Nom d'utilisateur ou mot de passe incorrect ».
+
+Mais ensuite, les attaquants essaient avec le nom d'utilisateur `stanleyjobsox` et le mot de passe `love123`.
+
+Et le code de votre application fait quelque chose comme :
+
+```Python
+if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish":
+ ...
+```
+
+Python devra comparer tout `stanleyjobso` dans `stanleyjobsox` et `stanleyjobson` avant de réaliser que les deux chaînes ne sont pas identiques. Cela prendra donc quelques microsecondes supplémentaires pour répondre « Nom d'utilisateur ou mot de passe incorrect ».
+
+#### Le temps de réponse aide les attaquants { #the-time-to-answer-helps-the-attackers }
+
+À ce stade, en remarquant que le serveur a mis quelques microsecondes de plus à envoyer la réponse « Nom d'utilisateur ou mot de passe incorrect », les attaquants sauront qu'ils ont trouvé quelque chose de juste : certaines des premières lettres étaient correctes.
+
+Ils peuvent alors réessayer en sachant que c'est probablement quelque chose de plus proche de `stanleyjobsox` que de `johndoe`.
+
+#### Une attaque « professionnelle » { #a-professional-attack }
+
+Bien sûr, les attaquants n'essaieraient pas tout cela à la main ; ils écriraient un programme pour le faire, avec éventuellement des milliers ou des millions de tests par seconde. Ils obtiendraient une lettre correcte supplémentaire à la fois.
+
+Ce faisant, en quelques minutes ou heures, les attaquants devineraient le nom d'utilisateur et le mot de passe corrects, avec « l'aide » de notre application, simplement en se basant sur le temps de réponse.
+
+#### Corrigez-le avec `secrets.compare_digest()` { #fix-it-with-secrets-compare-digest }
+
+Mais dans notre code nous utilisons justement `secrets.compare_digest()`.
+
+En bref, il faudra le même temps pour comparer `stanleyjobsox` à `stanleyjobson` que pour comparer `johndoe` à `stanleyjobson`. Il en va de même pour le mot de passe.
+
+Ainsi, en utilisant `secrets.compare_digest()` dans le code de votre application, votre application sera protégée contre toute cette gamme d'attaques de sécurité.
+
+### Renvoyer l'erreur { #return-the-error }
+
+Après avoir détecté que les identifiants sont incorrects, renvoyez une `HTTPException` avec un code d'état 401 (le même que lorsque aucun identifiant n'est fourni) et ajoutez l'en-tête `WWW-Authenticate` pour que le navigateur affiche à nouveau l'invite de connexion :
+
+{* ../../docs_src/security/tutorial007_an_py310.py hl[26:30] *}
diff --git a/docs/fr/docs/advanced/security/index.md b/docs/fr/docs/advanced/security/index.md
new file mode 100644
index 000000000..e84fcef62
--- /dev/null
+++ b/docs/fr/docs/advanced/security/index.md
@@ -0,0 +1,19 @@
+# Sécurité avancée { #advanced-security }
+
+## Fonctionnalités supplémentaires { #additional-features }
+
+Il existe des fonctionnalités supplémentaires pour gérer la sécurité en plus de celles couvertes dans le [Tutoriel - Guide utilisateur : Sécurité](../../tutorial/security/index.md){.internal-link target=_blank}.
+
+/// tip | Astuce
+
+Les sections suivantes ne sont pas nécessairement « advanced ».
+
+Et il est possible que, pour votre cas d’utilisation, la solution se trouve dans l’une d’entre elles.
+
+///
+
+## Lire d’abord le tutoriel { #read-the-tutorial-first }
+
+Les sections suivantes partent du principe que vous avez déjà lu le [Tutoriel - Guide utilisateur : Sécurité](../../tutorial/security/index.md){.internal-link target=_blank} principal.
+
+Elles s’appuient toutes sur les mêmes concepts, mais permettent des fonctionnalités supplémentaires.
diff --git a/docs/fr/docs/advanced/security/oauth2-scopes.md b/docs/fr/docs/advanced/security/oauth2-scopes.md
new file mode 100644
index 000000000..c890a5129
--- /dev/null
+++ b/docs/fr/docs/advanced/security/oauth2-scopes.md
@@ -0,0 +1,274 @@
+# Scopes OAuth2 { #oauth2-scopes }
+
+Vous pouvez utiliser des scopes OAuth2 directement avec **FastAPI**, ils sont intégrés pour fonctionner de manière transparente.
+
+Cela vous permettrait d’avoir un système d’autorisations plus fin, conforme au standard OAuth2, intégré à votre application OpenAPI (et à la documentation de l’API).
+
+OAuth2 avec scopes est le mécanisme utilisé par de nombreux grands fournisseurs d’authentification, comme Facebook, Google, GitHub, Microsoft, X (Twitter), etc. Ils l’utilisent pour fournir des permissions spécifiques aux utilisateurs et aux applications.
+
+Chaque fois que vous « log in with » Facebook, Google, GitHub, Microsoft, X (Twitter), cette application utilise OAuth2 avec scopes.
+
+Dans cette section, vous verrez comment gérer l’authentification et l’autorisation avec le même OAuth2 avec scopes dans votre application **FastAPI**.
+
+/// warning | Alertes
+
+C’est une section plus ou moins avancée. Si vous débutez, vous pouvez la passer.
+
+Vous n’avez pas nécessairement besoin des scopes OAuth2, et vous pouvez gérer l’authentification et l’autorisation comme vous le souhaitez.
+
+Mais OAuth2 avec scopes peut s’intégrer élégamment à votre API (avec OpenAPI) et à votre documentation d’API.
+
+Néanmoins, c’est toujours à vous de faire appliquer ces scopes, ou toute autre exigence de sécurité/autorisation, selon vos besoins, dans votre code.
+
+Dans de nombreux cas, OAuth2 avec scopes peut être excessif.
+
+Mais si vous savez que vous en avez besoin, ou si vous êtes curieux, continuez à lire.
+
+///
+
+## Scopes OAuth2 et OpenAPI { #oauth2-scopes-and-openapi }
+
+La spécification OAuth2 définit des « scopes » comme une liste de chaînes séparées par des espaces.
+
+Le contenu de chacune de ces chaînes peut avoir n’importe quel format, mais ne doit pas contenir d’espaces.
+
+Ces scopes représentent des « permissions ».
+
+Dans OpenAPI (par ex. la documentation de l’API), vous pouvez définir des « schémas de sécurité ».
+
+Lorsqu’un de ces schémas de sécurité utilise OAuth2, vous pouvez aussi déclarer et utiliser des scopes.
+
+Chaque « scope » est juste une chaîne (sans espaces).
+
+Ils sont généralement utilisés pour déclarer des permissions de sécurité spécifiques, par exemple :
+
+* `users:read` ou `users:write` sont des exemples courants.
+* `instagram_basic` est utilisé par Facebook / Instagram.
+* `https://www.googleapis.com/auth/drive` est utilisé par Google.
+
+/// info
+
+Dans OAuth2, un « scope » est simplement une chaîne qui déclare une permission spécifique requise.
+
+Peu importe s’il contient d’autres caractères comme `:` ou si c’est une URL.
+
+Ces détails dépendent de l’implémentation.
+
+Pour OAuth2, ce ne sont que des chaînes.
+
+///
+
+## Vue d’ensemble { #global-view }
+
+Voyons d’abord rapidement les parties qui changent par rapport aux exemples du **Tutoriel - Guide utilisateur** pour [OAuth2 avec mot de passe (et hachage), Bearer avec jetons JWT](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. Cette fois, en utilisant des scopes OAuth2 :
+
+{* ../../docs_src/security/tutorial005_an_py310.py hl[5,9,13,47,65,106,108:116,122:126,130:136,141,157] *}
+
+Passons maintenant en revue ces changements étape par étape.
+
+## Déclarer le schéma de sécurité OAuth2 { #oauth2-security-scheme }
+
+Le premier changement est que nous déclarons maintenant le schéma de sécurité OAuth2 avec deux scopes disponibles, `me` et `items`.
+
+Le paramètre `scopes` reçoit un `dict` avec chaque scope en clé et la description en valeur :
+
+{* ../../docs_src/security/tutorial005_an_py310.py hl[63:66] *}
+
+Comme nous déclarons maintenant ces scopes, ils apparaîtront dans la documentation de l’API lorsque vous vous authentifiez/autorisez.
+
+Et vous pourrez sélectionner à quels scopes vous souhaitez accorder l’accès : `me` et `items`.
+
+C’est le même mécanisme utilisé lorsque vous donnez des permissions en vous connectant avec Facebook, Google, GitHub, etc. :
+
+
+
+## Jeton JWT avec scopes { #jwt-token-with-scopes }
+
+Modifiez maintenant le *chemin d’accès* du jeton pour renvoyer les scopes demandés.
+
+Nous utilisons toujours le même `OAuth2PasswordRequestForm`. Il inclut une propriété `scopes` avec une `list` de `str`, contenant chaque scope reçu dans la requête.
+
+Et nous renvoyons les scopes comme partie du jeton JWT.
+
+/// danger | Danger
+
+Pour simplifier, ici nous ajoutons directement au jeton les scopes reçus.
+
+Mais dans votre application, pour la sécurité, vous devez vous assurer de n’ajouter que les scopes que l’utilisateur est réellement autorisé à avoir, ou ceux que vous avez prédéfinis.
+
+///
+
+{* ../../docs_src/security/tutorial005_an_py310.py hl[157] *}
+
+## Déclarer des scopes dans les chemins d’accès et les dépendances { #declare-scopes-in-path-operations-and-dependencies }
+
+Nous déclarons maintenant que le *chemin d’accès* `/users/me/items/` nécessite le scope `items`.
+
+Pour cela, nous importons et utilisons `Security` depuis `fastapi`.
+
+Vous pouvez utiliser `Security` pour déclarer des dépendances (comme `Depends`), mais `Security` reçoit aussi un paramètre `scopes` avec une liste de scopes (chaînes).
+
+Dans ce cas, nous passons une fonction de dépendance `get_current_active_user` à `Security` (de la même manière que nous le ferions avec `Depends`).
+
+Mais nous passons aussi une `list` de scopes, ici avec un seul scope : `items` (il pourrait y en avoir plus).
+
+Et la fonction de dépendance `get_current_active_user` peut également déclarer des sous-dépendances, non seulement avec `Depends` mais aussi avec `Security`. En déclarant sa propre fonction de sous-dépendance (`get_current_user`), et davantage d’exigences de scopes.
+
+Dans ce cas, elle nécessite le scope `me` (elle pourrait en exiger plusieurs).
+
+/// note | Remarque
+
+Vous n’avez pas nécessairement besoin d’ajouter des scopes différents à différents endroits.
+
+Nous le faisons ici pour montrer comment **FastAPI** gère des scopes déclarés à différents niveaux.
+
+///
+
+{* ../../docs_src/security/tutorial005_an_py310.py hl[5,141,172] *}
+
+/// info | Détails techniques
+
+`Security` est en réalité une sous-classe de `Depends`, et elle n’a qu’un paramètre supplémentaire que nous verrons plus tard.
+
+Mais en utilisant `Security` au lieu de `Depends`, **FastAPI** saura qu’il peut déclarer des scopes de sécurité, les utiliser en interne et documenter l’API avec OpenAPI.
+
+Cependant, lorsque vous importez `Query`, `Path`, `Depends`, `Security` et d’autres depuis `fastapi`, ce sont en fait des fonctions qui renvoient des classes spéciales.
+
+///
+
+## Utiliser `SecurityScopes` { #use-securityscopes }
+
+Mettez maintenant à jour la dépendance `get_current_user`.
+
+C’est celle utilisée par les dépendances ci-dessus.
+
+C’est ici que nous utilisons le même schéma OAuth2 que nous avons créé auparavant, en le déclarant comme dépendance : `oauth2_scheme`.
+
+Comme cette fonction de dépendance n’a pas elle-même d’exigences de scope, nous pouvons utiliser `Depends` avec `oauth2_scheme`, nous n’avons pas à utiliser `Security` quand nous n’avons pas besoin de spécifier des scopes de sécurité.
+
+Nous déclarons également un paramètre spécial de type `SecurityScopes`, importé de `fastapi.security`.
+
+Cette classe `SecurityScopes` est similaire à `Request` (`Request` servait à obtenir directement l’objet requête).
+
+{* ../../docs_src/security/tutorial005_an_py310.py hl[9,106] *}
+
+## Utiliser les `scopes` { #use-the-scopes }
+
+Le paramètre `security_scopes` sera de type `SecurityScopes`.
+
+Il aura une propriété `scopes` avec une liste contenant tous les scopes requis par lui-même et par toutes les dépendances qui l’utilisent comme sous-dépendance. Cela signifie, tous les « dépendants » ... cela peut paraître déroutant, c’est expliqué à nouveau plus bas.
+
+L’objet `security_scopes` (de classe `SecurityScopes`) fournit aussi un attribut `scope_str` avec une chaîne unique, contenant ces scopes séparés par des espaces (nous allons l’utiliser).
+
+Nous créons une `HTTPException` que nous pouvons réutiliser (`raise`) plus tard à plusieurs endroits.
+
+Dans cette exception, nous incluons les scopes requis (le cas échéant) sous forme de chaîne séparée par des espaces (en utilisant `scope_str`). Nous plaçons cette chaîne contenant les scopes dans l’en-tête `WWW-Authenticate` (cela fait partie de la spécification).
+
+{* ../../docs_src/security/tutorial005_an_py310.py hl[106,108:116] *}
+
+## Vérifier le `username` et la structure des données { #verify-the-username-and-data-shape }
+
+Nous vérifions que nous obtenons un `username`, et extrayons les scopes.
+
+Nous validons ensuite ces données avec le modèle Pydantic (en capturant l’exception `ValidationError`), et si nous obtenons une erreur lors de la lecture du jeton JWT ou de la validation des données avec Pydantic, nous levons la `HTTPException` que nous avons créée auparavant.
+
+Pour cela, nous mettons à jour le modèle Pydantic `TokenData` avec une nouvelle propriété `scopes`.
+
+En validant les données avec Pydantic, nous pouvons nous assurer que nous avons, par exemple, exactement une `list` de `str` pour les scopes et un `str` pour le `username`.
+
+Au lieu, par exemple, d’un `dict`, ou autre chose, ce qui pourrait casser l’application plus tard et constituer un risque de sécurité.
+
+Nous vérifions également que nous avons un utilisateur avec ce nom d’utilisateur, et sinon, nous levons la même exception que précédemment.
+
+{* ../../docs_src/security/tutorial005_an_py310.py hl[47,117:129] *}
+
+## Vérifier les `scopes` { #verify-the-scopes }
+
+Nous vérifions maintenant que tous les scopes requis, par cette dépendance et tous les dépendants (y compris les *chemins d’accès*), sont inclus dans les scopes fournis dans le jeton reçu, sinon nous levons une `HTTPException`.
+
+Pour cela, nous utilisons `security_scopes.scopes`, qui contient une `list` avec tous ces scopes en `str`.
+
+{* ../../docs_src/security/tutorial005_an_py310.py hl[130:136] *}
+
+## Arbre de dépendances et scopes { #dependency-tree-and-scopes }
+
+Revoyons encore cet arbre de dépendances et les scopes.
+
+Comme la dépendance `get_current_active_user` a une sous-dépendance `get_current_user`, le scope « me » déclaré dans `get_current_active_user` sera inclus dans la liste des scopes requis dans `security_scopes.scopes` passé à `get_current_user`.
+
+Le *chemin d’accès* lui-même déclare également un scope, « items », il sera donc aussi présent dans la liste `security_scopes.scopes` passée à `get_current_user`.
+
+Voici à quoi ressemble la hiérarchie des dépendances et des scopes :
+
+* Le *chemin d’accès* `read_own_items` a :
+ * Des scopes requis `["items"]` avec la dépendance :
+ * `get_current_active_user` :
+ * La fonction de dépendance `get_current_active_user` a :
+ * Des scopes requis `["me"]` avec la dépendance :
+ * `get_current_user` :
+ * La fonction de dépendance `get_current_user` a :
+ * Aucun scope requis par elle-même.
+ * Une dépendance utilisant `oauth2_scheme`.
+ * Un paramètre `security_scopes` de type `SecurityScopes` :
+ * Ce paramètre `security_scopes` a une propriété `scopes` avec une `list` contenant tous les scopes déclarés ci-dessus, donc :
+ * `security_scopes.scopes` contiendra `["me", "items"]` pour le *chemin d’accès* `read_own_items`.
+ * `security_scopes.scopes` contiendra `["me"]` pour le *chemin d’accès* `read_users_me`, car il est déclaré dans la dépendance `get_current_active_user`.
+ * `security_scopes.scopes` contiendra `[]` (rien) pour le *chemin d’accès* `read_system_status`, car il n’a déclaré aucun `Security` avec des `scopes`, et sa dépendance, `get_current_user`, ne déclare pas non plus de `scopes`.
+
+/// tip | Astuce
+
+L’élément important et « magique » ici est que `get_current_user` aura une liste différente de `scopes` à vérifier pour chaque *chemin d’accès*.
+
+Tout dépend des `scopes` déclarés dans chaque *chemin d’accès* et chaque dépendance dans l’arbre de dépendances pour ce *chemin d’accès* spécifique.
+
+///
+
+## Détails supplémentaires sur `SecurityScopes` { #more-details-about-securityscopes }
+
+Vous pouvez utiliser `SecurityScopes` à n’importe quel endroit, et à de multiples endroits, il n’a pas besoin d’être dans la dépendance « root ».
+
+Il aura toujours les scopes de sécurité déclarés dans les dépendances `Security` actuelles et tous les dépendants pour **ce** *chemin d’accès* spécifique et **cet** arbre de dépendances spécifique.
+
+Comme `SecurityScopes` contient tous les scopes déclarés par les dépendants, vous pouvez l’utiliser pour vérifier qu’un jeton possède les scopes requis dans une fonction de dépendance centrale, puis déclarer des exigences de scopes différentes dans différents *chemins d’accès*.
+
+Elles seront vérifiées indépendamment pour chaque *chemin d’accès*.
+
+## Tester { #check-it }
+
+Si vous ouvrez la documentation de l’API, vous pouvez vous authentifier et spécifier quels scopes vous voulez autoriser.
+
+
+
+Si vous ne sélectionnez aucun scope, vous serez « authenticated », mais lorsque vous essayerez d’accéder à `/users/me/` ou `/users/me/items/`, vous obtiendrez une erreur indiquant que vous n’avez pas suffisamment de permissions. Vous pourrez toujours accéder à `/status/`.
+
+Et si vous sélectionnez le scope `me` mais pas le scope `items`, vous pourrez accéder à `/users/me/` mais pas à `/users/me/items/`.
+
+C’est ce qui arriverait à une application tierce qui tenterait d’accéder à l’un de ces *chemins d’accès* avec un jeton fourni par un utilisateur, selon le nombre de permissions que l’utilisateur a accordées à l’application.
+
+## À propos des intégrations tierces { #about-third-party-integrations }
+
+Dans cet exemple, nous utilisons le flux OAuth2 « password ».
+
+C’est approprié lorsque nous nous connectons à notre propre application, probablement avec notre propre frontend.
+
+Parce que nous pouvons lui faire confiance pour recevoir le `username` et le `password`, puisque nous le contrôlons.
+
+Mais si vous construisez une application OAuth2 à laquelle d’autres se connecteraient (c.-à-d., si vous construisez un fournisseur d’authentification équivalent à Facebook, Google, GitHub, etc.), vous devez utiliser l’un des autres flux.
+
+Le plus courant est le flux implicite.
+
+Le plus sûr est le flux « code », mais il est plus complexe à implémenter car il nécessite plus d’étapes. Comme il est plus complexe, de nombreux fournisseurs finissent par recommander le flux implicite.
+
+/// note | Remarque
+
+Il est courant que chaque fournisseur d’authentification nomme ses flux différemment, pour en faire une partie de sa marque.
+
+Mais au final, ils implémentent le même standard OAuth2.
+
+///
+
+**FastAPI** inclut des utilitaires pour tous ces flux d’authentification OAuth2 dans `fastapi.security.oauth2`.
+
+## `Security` dans les dépendances du décorateur `dependencies` { #security-in-decorator-dependencies }
+
+De la même manière que vous pouvez définir une `list` de `Depends` dans le paramètre `dependencies` du décorateur (comme expliqué dans [Dépendances dans les décorateurs de chemins d’accès](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), vous pouvez aussi utiliser `Security` avec des `scopes` à cet endroit.
diff --git a/docs/fr/docs/advanced/settings.md b/docs/fr/docs/advanced/settings.md
new file mode 100644
index 000000000..ed724bf4f
--- /dev/null
+++ b/docs/fr/docs/advanced/settings.md
@@ -0,0 +1,302 @@
+# Paramètres et variables d'environnement { #settings-and-environment-variables }
+
+Dans de nombreux cas, votre application peut avoir besoin de paramètres ou de configurations externes, par exemple des clés secrètes, des identifiants de base de données, des identifiants pour des services d'e-mail, etc.
+
+La plupart de ces paramètres sont variables (peuvent changer), comme les URL de base de données. Et beaucoup peuvent être sensibles, comme les secrets.
+
+C'est pourquoi il est courant de les fournir via des variables d'environnement lues par l'application.
+
+/// tip | Astuce
+
+Pour comprendre les variables d'environnement, vous pouvez lire [Variables d'environnement](../environment-variables.md){.internal-link target=_blank}.
+
+///
+
+## Types et validation { #types-and-validation }
+
+Ces variables d'environnement ne gèrent que des chaînes de texte, car elles sont externes à Python et doivent être compatibles avec d'autres programmes et le reste du système (et même avec différents systèmes d'exploitation, comme Linux, Windows, macOS).
+
+Cela signifie que toute valeur lue en Python depuis une variable d'environnement sera une `str`, et toute conversion vers un autre type ou toute validation doit être effectuée dans le code.
+
+## Pydantic `Settings` { #pydantic-settings }
+
+Heureusement, Pydantic fournit un excellent utilitaire pour gérer ces paramètres provenant des variables d'environnement avec Pydantic : gestion des paramètres.
+
+### Installer `pydantic-settings` { #install-pydantic-settings }
+
+D'abord, vous devez créer votre [environnement virtuel](../virtual-environments.md){.internal-link target=_blank}, l'activer, puis installer le paquet `pydantic-settings` :
+
+
+
+```console
+$ pip install pydantic-settings
+---> 100%
+```
+
+
+
+Il est également inclus lorsque vous installez les extras `all` avec :
+
+
+
+```console
+$ pip install "fastapi[all]"
+---> 100%
+```
+
+
+
+### Créer l'objet `Settings` { #create-the-settings-object }
+
+Importez `BaseSettings` depuis Pydantic et créez une sous-classe, comme pour un modèle Pydantic.
+
+De la même manière qu'avec les modèles Pydantic, vous déclarez des attributs de classe avec des annotations de type, et éventuellement des valeurs par défaut.
+
+Vous pouvez utiliser toutes les mêmes fonctionnalités et outils de validation que pour les modèles Pydantic, comme différents types de données et des validations supplémentaires avec `Field()`.
+
+{* ../../docs_src/settings/tutorial001_py310.py hl[2,5:8,11] *}
+
+/// tip | Astuce
+
+Si vous voulez quelque chose à copier-coller rapidement, n'utilisez pas cet exemple, utilisez le dernier ci-dessous.
+
+///
+
+Ensuite, lorsque vous créez une instance de cette classe `Settings` (dans ce cas, l'objet `settings`), Pydantic lira les variables d'environnement de manière insensible à la casse, donc une variable en majuscules `APP_NAME` sera tout de même lue pour l'attribut `app_name`.
+
+Il convertira ensuite et validera les données. Ainsi, lorsque vous utilisez cet objet `settings`, vous aurez des données des types que vous avez déclarés (par exemple, `items_per_user` sera un `int`).
+
+### Utiliser `settings` { #use-the-settings }
+
+Vous pouvez ensuite utiliser le nouvel objet `settings` dans votre application :
+
+{* ../../docs_src/settings/tutorial001_py310.py hl[18:20] *}
+
+### Exécuter le serveur { #run-the-server }
+
+Ensuite, vous exécutez le serveur en passant les configurations comme variables d'environnement ; par exemple, vous pouvez définir un `ADMIN_EMAIL` et `APP_NAME` avec :
+
+
+
+```console
+$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.py
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+/// tip | Astuce
+
+Pour définir plusieurs variables d'environnement pour une seule commande, séparez-les simplement par un espace et placez-les toutes avant la commande.
+
+///
+
+Ainsi, le paramètre `admin_email` sera défini sur « deadpool@example.com ».
+
+Le `app_name` sera « ChimichangApp ».
+
+Et `items_per_user` conservera sa valeur par défaut de `50`.
+
+## Paramètres dans un autre module { #settings-in-another-module }
+
+Vous pouvez placer ces paramètres dans un autre module comme vous l'avez vu dans [Applications plus grandes - Plusieurs fichiers](../tutorial/bigger-applications.md){.internal-link target=_blank}.
+
+Par exemple, vous pourriez avoir un fichier `config.py` avec :
+
+{* ../../docs_src/settings/app01_py310/config.py *}
+
+Puis l'utiliser dans un fichier `main.py` :
+
+{* ../../docs_src/settings/app01_py310/main.py hl[3,11:13] *}
+
+/// tip | Astuce
+
+Vous aurez également besoin d'un fichier `__init__.py` comme vous l'avez vu dans [Applications plus grandes - Plusieurs fichiers](../tutorial/bigger-applications.md){.internal-link target=_blank}.
+
+///
+
+## Paramètres dans une dépendance { #settings-in-a-dependency }
+
+Dans certains cas, il peut être utile de fournir les paramètres via une dépendance, au lieu d'avoir un objet global `settings` utilisé partout.
+
+Cela peut être particulièrement utile pendant les tests, car il est très facile de surcharger une dépendance avec vos propres paramètres personnalisés.
+
+### Le fichier de configuration { #the-config-file }
+
+En repartant de l'exemple précédent, votre fichier `config.py` pourrait ressembler à :
+
+{* ../../docs_src/settings/app02_an_py310/config.py hl[10] *}
+
+Notez que maintenant, nous ne créons pas d'instance par défaut `settings = Settings()`.
+
+### Le fichier principal de l'application { #the-main-app-file }
+
+Nous créons maintenant une dépendance qui renvoie un nouveau `config.Settings()`.
+
+{* ../../docs_src/settings/app02_an_py310/main.py hl[6,12:13] *}
+
+/// tip | Astuce
+
+Nous parlerons de `@lru_cache` dans un instant.
+
+Pour l'instant, vous pouvez supposer que `get_settings()` est une fonction normale.
+
+///
+
+Nous pouvons ensuite l'exiger depuis la fonction de chemin d'accès comme dépendance et l'utiliser où nous en avons besoin.
+
+{* ../../docs_src/settings/app02_an_py310/main.py hl[17,19:21] *}
+
+### Paramètres et tests { #settings-and-testing }
+
+Il devient alors très simple de fournir un autre objet de paramètres pendant les tests en créant une surcharge de dépendance pour `get_settings` :
+
+{* ../../docs_src/settings/app02_an_py310/test_main.py hl[9:10,13,21] *}
+
+Dans la surcharge de dépendance, nous définissons une nouvelle valeur pour `admin_email` lors de la création du nouvel objet `Settings`, puis nous renvoyons ce nouvel objet.
+
+Nous pouvons ensuite tester qu'il est bien utilisé.
+
+## Lire un fichier `.env` { #reading-a-env-file }
+
+Si vous avez de nombreux paramètres susceptibles de beaucoup changer, peut-être selon les environnements, il peut être utile de les placer dans un fichier, puis de les lire comme s'il s'agissait de variables d'environnement.
+
+Cette pratique est suffisamment courante pour avoir un nom ; ces variables d'environnement sont fréquemment placées dans un fichier `.env`, et le fichier est appelé un « dotenv ».
+
+/// tip | Astuce
+
+Un fichier commençant par un point (`.`) est un fichier caché dans les systèmes de type Unix, comme Linux et macOS.
+
+Mais un fichier dotenv n'a pas forcément exactement ce nom de fichier.
+
+///
+
+Pydantic prend en charge la lecture depuis ce type de fichiers en utilisant une bibliothèque externe. Vous pouvez en lire davantage ici : Pydantic Settings : prise en charge de Dotenv (.env).
+
+/// tip | Astuce
+
+Pour que cela fonctionne, vous devez exécuter `pip install python-dotenv`.
+
+///
+
+### Le fichier `.env` { #the-env-file }
+
+Vous pouvez avoir un fichier `.env` avec :
+
+```bash
+ADMIN_EMAIL="deadpool@example.com"
+APP_NAME="ChimichangApp"
+```
+
+### Lire les paramètres depuis `.env` { #read-settings-from-env }
+
+Puis mettre à jour votre `config.py` avec :
+
+{* ../../docs_src/settings/app03_an_py310/config.py hl[9] *}
+
+/// tip | Astuce
+
+L'attribut `model_config` est utilisé uniquement pour la configuration Pydantic. Vous pouvez en lire davantage ici : Pydantic : Concepts : Configuration.
+
+///
+
+Ici, nous définissons la configuration `env_file` à l'intérieur de votre classe Pydantic `Settings` et lui attribuons le nom du fichier dotenv que nous voulons utiliser.
+
+### Créer `Settings` une seule fois avec `lru_cache` { #creating-the-settings-only-once-with-lru-cache }
+
+Lire un fichier depuis le disque est normalement une opération coûteuse (lente), vous voudrez donc probablement le faire une seule fois puis réutiliser le même objet de paramètres, au lieu de le lire à chaque requête.
+
+Mais chaque fois que nous faisons :
+
+```Python
+Settings()
+```
+
+un nouvel objet `Settings` serait créé, et à sa création il lirait à nouveau le fichier `.env`.
+
+Si la fonction de dépendance était simplement :
+
+```Python
+def get_settings():
+ return Settings()
+```
+
+nous créerions cet objet pour chaque requête, et nous lirions le fichier `.env` pour chaque requête. ⚠️
+
+Mais comme nous utilisons le décorateur `@lru_cache` au-dessus, l'objet `Settings` sera créé une seule fois, la première fois qu'il est appelé. ✔️
+
+{* ../../docs_src/settings/app03_an_py310/main.py hl[1,11] *}
+
+Ensuite, pour tout appel ultérieur de `get_settings()` dans les dépendances pour les requêtes suivantes, au lieu d'exécuter le code interne de `get_settings()` et de créer un nouvel objet `Settings`, il renverra le même objet que celui retourné au premier appel, encore et encore.
+
+#### Détails techniques de `lru_cache` { #lru-cache-technical-details }
+
+`@lru_cache` modifie la fonction qu'il décore pour renvoyer la même valeur que celle qui a été retournée la première fois, au lieu de la recalculer en exécutant le code de la fonction à chaque fois.
+
+Ainsi, la fonction située en dessous sera exécutée une fois pour chaque combinaison d'arguments. Ensuite, les valeurs renvoyées par chacune de ces combinaisons d'arguments seront réutilisées à chaque fois que la fonction sera appelée avec exactement la même combinaison d'arguments.
+
+Par exemple, si vous avez une fonction :
+
+```Python
+@lru_cache
+def say_hi(name: str, salutation: str = "Ms."):
+ return f"Hello {salutation} {name}"
+```
+
+votre programme pourrait s'exécuter comme ceci :
+
+```mermaid
+sequenceDiagram
+
+participant code as Code
+participant function as say_hi()
+participant execute as Execute function
+
+ rect rgba(0, 255, 0, .1)
+ code ->> function: say_hi(name="Camila")
+ function ->> execute: execute function code
+ execute ->> code: return the result
+ end
+
+ rect rgba(0, 255, 255, .1)
+ code ->> function: say_hi(name="Camila")
+ function ->> code: return stored result
+ end
+
+ rect rgba(0, 255, 0, .1)
+ code ->> function: say_hi(name="Rick")
+ function ->> execute: execute function code
+ execute ->> code: return the result
+ end
+
+ rect rgba(0, 255, 0, .1)
+ code ->> function: say_hi(name="Rick", salutation="Mr.")
+ function ->> execute: execute function code
+ execute ->> code: return the result
+ end
+
+ rect rgba(0, 255, 255, .1)
+ code ->> function: say_hi(name="Rick")
+ function ->> code: return stored result
+ end
+
+ rect rgba(0, 255, 255, .1)
+ code ->> function: say_hi(name="Camila")
+ function ->> code: return stored result
+ end
+```
+
+Dans le cas de notre dépendance `get_settings()`, la fonction ne prend même aucun argument, elle renvoie donc toujours la même valeur.
+
+De cette façon, elle se comporte presque comme s'il s'agissait simplement d'une variable globale. Mais comme elle utilise une fonction de dépendance, nous pouvons alors la surcharger facilement pour les tests.
+
+`@lru_cache` fait partie de `functools` qui fait partie de la bibliothèque standard de Python, vous pouvez en lire davantage dans la documentation Python pour `@lru_cache`.
+
+## Récapitulatif { #recap }
+
+Vous pouvez utiliser Pydantic Settings pour gérer les paramètres ou configurations de votre application, avec toute la puissance des modèles Pydantic.
+
+* En utilisant une dépendance, vous pouvez simplifier les tests.
+* Vous pouvez utiliser des fichiers `.env`.
+* Utiliser `@lru_cache` vous permet d'éviter de relire le fichier dotenv à chaque requête, tout en vous permettant de le surcharger pendant les tests.
diff --git a/docs/fr/docs/advanced/sub-applications.md b/docs/fr/docs/advanced/sub-applications.md
new file mode 100644
index 000000000..777056040
--- /dev/null
+++ b/docs/fr/docs/advanced/sub-applications.md
@@ -0,0 +1,67 @@
+# Sous-applications - Montage { #sub-applications-mounts }
+
+Si vous avez besoin de deux applications FastAPI indépendantes, avec leur propre OpenAPI et leurs propres interfaces de la documentation, vous pouvez avoir une application principale et « monter » une (ou plusieurs) sous‑application(s).
+
+## Monter une application **FastAPI** { #mounting-a-fastapi-application }
+
+« Monter » signifie ajouter une application entièrement « indépendante » à un chemin spécifique, qui se chargera ensuite de tout gérer sous ce chemin, avec les _chemins d'accès_ déclarés dans cette sous‑application.
+
+### Application de premier niveau { #top-level-application }
+
+Créez d'abord l'application **FastAPI** principale (de premier niveau) et ses *chemins d'accès* :
+
+{* ../../docs_src/sub_applications/tutorial001_py310.py hl[3, 6:8] *}
+
+### Sous-application { #sub-application }
+
+Ensuite, créez votre sous‑application et ses *chemins d'accès*.
+
+Cette sous‑application est simplement une autre application FastAPI standard, mais c'est celle qui sera « montée » :
+
+{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 14:16] *}
+
+### Monter la sous-application { #mount-the-sub-application }
+
+Dans votre application de premier niveau, `app`, montez la sous‑application, `subapi`.
+
+Dans ce cas, elle sera montée au chemin `/subapi` :
+
+{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 19] *}
+
+### Vérifier la documentation API automatique { #check-the-automatic-api-docs }
+
+Exécutez maintenant la commande `fastapi` avec votre fichier :
+
+
+
+```console
+$ fastapi dev main.py
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+Puis ouvrez la documentation à http://127.0.0.1:8000/docs.
+
+Vous verrez la documentation API automatique pour l'application principale, n'incluant que ses propres _chemins d'accès_ :
+
+
+
+Ensuite, ouvrez la documentation de la sous‑application à http://127.0.0.1:8000/subapi/docs.
+
+Vous verrez la documentation API automatique pour la sous‑application, n'incluant que ses propres _chemins d'accès_, tous sous le préfixe de sous‑chemin correct `/subapi` :
+
+
+
+Si vous essayez d'interagir avec l'une ou l'autre des deux interfaces, elles fonctionneront correctement, car le navigateur pourra communiquer avec chaque application ou sous‑application spécifique.
+
+### Détails techniques : `root_path` { #technical-details-root-path }
+
+Lorsque vous montez une sous‑application comme ci‑dessus, FastAPI se charge de communiquer le chemin de montage à la sous‑application au moyen d'un mécanisme de la spécification ASGI appelé `root_path`.
+
+De cette manière, la sous‑application saura utiliser ce préfixe de chemin pour l'interface de documentation.
+
+La sous‑application peut également avoir ses propres sous‑applications montées et tout fonctionnera correctement, car FastAPI gère automatiquement tous ces `root_path`.
+
+Vous en apprendrez davantage sur `root_path` et sur la façon de l'utiliser explicitement dans la section [Derrière un proxy](behind-a-proxy.md){.internal-link target=_blank}.
diff --git a/docs/fr/docs/advanced/templates.md b/docs/fr/docs/advanced/templates.md
new file mode 100644
index 000000000..7c886ab69
--- /dev/null
+++ b/docs/fr/docs/advanced/templates.md
@@ -0,0 +1,126 @@
+# Templates { #templates }
+
+Vous pouvez utiliser n'importe quel moteur de templates avec **FastAPI**.
+
+Un choix courant est Jinja2, le même que celui utilisé par Flask et d'autres outils.
+
+Il existe des utilitaires pour le configurer facilement que vous pouvez utiliser directement dans votre application **FastAPI** (fournis par Starlette).
+
+## Installer les dépendances { #install-dependencies }
+
+Vous devez créer un [environnement virtuel](../virtual-environments.md){.internal-link target=_blank}, l'activer, puis installer `jinja2` :
+
+
+
+```console
+$ pip install jinja2
+
+---> 100%
+```
+
+
+
+## Utiliser `Jinja2Templates` { #using-jinja2templates }
+
+- Importez `Jinja2Templates`.
+- Créez un objet `templates` que vous pourrez réutiliser par la suite.
+- Déclarez un paramètre `Request` dans le *chemin d'accès* qui renverra un template.
+- Utilisez l'objet `templates` que vous avez créé pour rendre et retourner une `TemplateResponse`, en transmettant le nom du template, l'objet de requête et un dictionnaire de « context » avec des paires clé-valeur à utiliser dans le template Jinja2.
+
+{* ../../docs_src/templates/tutorial001_py310.py hl[4,11,15:18] *}
+
+/// note | Remarque
+
+Avant FastAPI 0.108.0 et Starlette 0.29.0, `name` était le premier paramètre.
+
+De plus, auparavant, dans les versions précédentes, l'objet `request` faisait partie des paires clé-valeur du contexte pour Jinja2.
+
+///
+
+/// tip | Astuce
+
+En déclarant `response_class=HTMLResponse`, l'interface de la documentation saura que la réponse sera en HTML.
+
+///
+
+/// note | Détails techniques
+
+Vous pouvez aussi utiliser `from starlette.templating import Jinja2Templates`.
+
+**FastAPI** expose le même `starlette.templating` sous `fastapi.templating` par simple commodité pour vous, développeur. Mais la plupart des réponses disponibles proviennent directement de Starlette. C'est également le cas pour `Request` et `StaticFiles`.
+
+///
+
+## Écrire des templates { #writing-templates }
+
+Vous pouvez ensuite écrire un template dans `templates/item.html`, par exemple :
+
+```jinja hl_lines="7"
+{!../../docs_src/templates/templates/item.html!}
+```
+
+### Valeurs de contexte du template { #template-context-values }
+
+Dans le HTML qui contient :
+
+{% raw %}
+
+```jinja
+Item ID: {{ id }}
+```
+
+{% endraw %}
+
+... il affichera l’`id` récupéré à partir du `dict` « context » que vous avez passé :
+
+```Python
+{"id": id}
+```
+
+Par exemple, avec un ID de `42`, cela rendrait :
+
+```html
+Item ID: 42
+```
+
+### Arguments de `url_for` dans le template { #template-url-for-arguments }
+
+Vous pouvez aussi utiliser `url_for()` dans le template ; elle prend en paramètres les mêmes arguments que ceux utilisés par votre *fonction de chemin d'accès*.
+
+Ainsi, la section suivante :
+
+{% raw %}
+
+```jinja
+
+```
+
+{% endraw %}
+
+... générera un lien vers la même URL que celle gérée par la *fonction de chemin d'accès* `read_item(id=id)`.
+
+Par exemple, avec un ID de `42`, cela rendrait :
+
+```html
+
+```
+
+## Templates et fichiers statiques { #templates-and-static-files }
+
+Vous pouvez aussi utiliser `url_for()` dans le template, par exemple avec les `StaticFiles` que vous avez montés avec `name="static"`.
+
+```jinja hl_lines="4"
+{!../../docs_src/templates/templates/item.html!}
+```
+
+Dans cet exemple, cela créera un lien vers un fichier CSS `static/styles.css` avec :
+
+```CSS hl_lines="4"
+{!../../docs_src/templates/static/styles.css!}
+```
+
+Et comme vous utilisez `StaticFiles`, ce fichier CSS est servi automatiquement par votre application **FastAPI** à l’URL `/static/styles.css`.
+
+## En savoir plus { #more-details }
+
+Pour plus de détails, y compris sur la façon de tester des templates, consultez la documentation de Starlette sur les templates.
diff --git a/docs/fr/docs/advanced/testing-dependencies.md b/docs/fr/docs/advanced/testing-dependencies.md
new file mode 100644
index 000000000..d6fc576bf
--- /dev/null
+++ b/docs/fr/docs/advanced/testing-dependencies.md
@@ -0,0 +1,52 @@
+# Tester des dépendances avec des surcharges { #testing-dependencies-with-overrides }
+
+## Surcharger des dépendances pendant les tests { #overriding-dependencies-during-testing }
+
+Il existe des cas où vous souhaiterez surcharger une dépendance pendant les tests.
+
+Vous ne voulez pas exécuter la dépendance originale (ni ses éventuelles sous‑dépendances).
+
+À la place, vous souhaitez fournir une dépendance différente, utilisée uniquement pendant les tests (éventuellement seulement pour certains tests), et qui fournira une valeur utilisable partout où l’on utilisait celle de la dépendance originale.
+
+### Cas d’usage : service externe { #use-cases-external-service }
+
+Par exemple, vous avez un fournisseur d’authentification externe à appeler.
+
+Vous lui envoyez un token et il renvoie un utilisateur authentifié.
+
+Ce fournisseur peut vous facturer à la requête, et l’appeler peut prendre plus de temps que si vous aviez un utilisateur factice fixe pour les tests.
+
+Vous voudrez probablement tester le fournisseur externe une fois, mais pas nécessairement l’appeler pour chaque test exécuté.
+
+Dans ce cas, vous pouvez surcharger la dépendance qui appelle ce fournisseur et utiliser une dépendance personnalisée qui renvoie un utilisateur factice, uniquement pour vos tests.
+
+### Utiliser l’attribut `app.dependency_overrides` { #use-the-app-dependency-overrides-attribute }
+
+Pour ces cas, votre **FastAPI** application possède un attribut `app.dependency_overrides` ; c’est un simple `dict`.
+
+Pour surcharger une dépendance lors des tests, vous mettez comme clé la dépendance originale (une fonction) et comme valeur votre surcharge de dépendance (une autre fonction).
+
+Ensuite, **FastAPI** appellera cette surcharge au lieu de la dépendance originale.
+
+{* ../../docs_src/dependency_testing/tutorial001_an_py310.py hl[26:27,30] *}
+
+/// tip | Astuce
+
+Vous pouvez définir une surcharge de dépendance pour une dépendance utilisée n’importe où dans votre application **FastAPI**.
+
+La dépendance originale peut être utilisée dans une fonction de chemin d'accès, un décorateur de chemin d'accès (quand vous n’utilisez pas la valeur de retour), un appel à `.include_router()`, etc.
+
+FastAPI pourra toujours la surcharger.
+
+///
+
+Vous pouvez ensuite réinitialiser vos surcharges (les supprimer) en affectant à `app.dependency_overrides` un `dict` vide :
+
+```Python
+app.dependency_overrides = {}
+```
+/// tip | Astuce
+
+Si vous souhaitez surcharger une dépendance uniquement pendant certains tests, vous pouvez définir la surcharge au début du test (dans la fonction de test) et la réinitialiser à la fin (à la fin de la fonction de test).
+
+///
diff --git a/docs/fr/docs/advanced/testing-events.md b/docs/fr/docs/advanced/testing-events.md
new file mode 100644
index 000000000..c4f9141b3
--- /dev/null
+++ b/docs/fr/docs/advanced/testing-events.md
@@ -0,0 +1,11 @@
+# Tester les événements : lifespan et startup - shutdown { #testing-events-lifespan-and-startup-shutdown }
+
+Lorsque vous avez besoin d'exécuter `lifespan` dans vos tests, vous pouvez utiliser `TestClient` avec une instruction `with` :
+
+{* ../../docs_src/app_testing/tutorial004_py310.py hl[9:15,18,27:28,30:32,41:43] *}
+
+Vous pouvez lire plus de détails dans [« Exécuter lifespan dans les tests sur le site de documentation officiel de Starlette. »](https://www.starlette.dev/lifespan/#running-lifespan-in-tests)
+
+Pour les événements dépréciés `startup` et `shutdown`, vous pouvez utiliser le `TestClient` comme suit :
+
+{* ../../docs_src/app_testing/tutorial003_py310.py hl[9:12,20:24] *}
diff --git a/docs/fr/docs/advanced/testing-websockets.md b/docs/fr/docs/advanced/testing-websockets.md
new file mode 100644
index 000000000..e9f97ab5f
--- /dev/null
+++ b/docs/fr/docs/advanced/testing-websockets.md
@@ -0,0 +1,13 @@
+# Tester les WebSockets { #testing-websockets }
+
+Vous pouvez utiliser le même `TestClient` pour tester les WebSockets.
+
+Pour cela, vous utilisez `TestClient` dans une instruction `with`, en vous connectant au WebSocket :
+
+{* ../../docs_src/app_testing/tutorial002_py310.py hl[27:31] *}
+
+/// note | Remarque
+
+Pour plus de détails, consultez la documentation de Starlette sur le test des WebSockets.
+
+///
diff --git a/docs/fr/docs/advanced/using-request-directly.md b/docs/fr/docs/advanced/using-request-directly.md
new file mode 100644
index 000000000..4df3f90e8
--- /dev/null
+++ b/docs/fr/docs/advanced/using-request-directly.md
@@ -0,0 +1,56 @@
+# Utiliser Request directement { #using-the-request-directly }
+
+Jusqu'à présent, vous avez déclaré les parties de la requête dont vous avez besoin, avec leurs types.
+
+En récupérant des données depuis :
+
+* Le chemin, sous forme de paramètres.
+* En-têtes.
+* Cookies.
+* etc.
+
+Et ce faisant, **FastAPI** valide ces données, les convertit et génère automatiquement la documentation de votre API.
+
+Mais il existe des situations où vous pouvez avoir besoin d'accéder directement à l'objet `Request`.
+
+## Détails sur l'objet `Request` { #details-about-the-request-object }
+
+Comme **FastAPI** est en fait **Starlette** en dessous, avec une couche de plusieurs outils au-dessus, vous pouvez utiliser directement l'objet `Request` de Starlette lorsque vous en avez besoin.
+
+Cela signifie aussi que si vous récupérez des données directement à partir de l'objet `Request` (par exemple, lire le corps), elles ne seront pas validées, converties ni documentées (avec OpenAPI, pour l'interface utilisateur automatique de l'API) par FastAPI.
+
+En revanche, tout autre paramètre déclaré normalement (par exemple, le corps avec un modèle Pydantic) sera toujours validé, converti, annoté, etc.
+
+Mais il existe des cas spécifiques où il est utile d'obtenir l'objet `Request`.
+
+## Utiliser l'objet `Request` directement { #use-the-request-object-directly }
+
+Imaginons que vous souhaitiez obtenir l'adresse IP/l'hôte du client dans votre fonction de chemin d'accès.
+
+Pour cela, vous devez accéder directement à la requête.
+
+{* ../../docs_src/using_request_directly/tutorial001_py310.py hl[1,7:8] *}
+
+En déclarant un paramètre de fonction de chemin d'accès de type `Request`, **FastAPI** saura passer la `Request` dans ce paramètre.
+
+/// tip | Astuce
+
+Notez que, dans ce cas, nous déclarons un paramètre de chemin en plus du paramètre de requête.
+
+Ainsi, le paramètre de chemin sera extrait, validé, converti vers le type spécifié et annoté avec OpenAPI.
+
+De la même façon, vous pouvez déclarer tout autre paramètre normalement, et en plus, obtenir aussi la `Request`.
+
+///
+
+## Documentation de `Request` { #request-documentation }
+
+Vous pouvez lire plus de détails sur l'objet `Request` sur le site de documentation officiel de Starlette.
+
+/// note | Détails techniques
+
+Vous pouvez également utiliser `from starlette.requests import Request`.
+
+**FastAPI** le fournit directement pour votre commodité, en tant que développeur. Mais il provient directement de Starlette.
+
+///
diff --git a/docs/fr/docs/advanced/websockets.md b/docs/fr/docs/advanced/websockets.md
new file mode 100644
index 000000000..6f5c3e703
--- /dev/null
+++ b/docs/fr/docs/advanced/websockets.md
@@ -0,0 +1,186 @@
+# WebSockets { #websockets }
+
+Vous pouvez utiliser API WebSockets avec **FastAPI**.
+
+## Installer `websockets` { #install-websockets }
+
+Vous devez créer un [environnement virtuel](../virtual-environments.md){.internal-link target=_blank}, l'activer, et installer `websockets` (une bibliothèque Python qui facilite l'utilisation du protocole « WebSocket ») :
+
+
+
+```console
+$ pip install websockets
+
+---> 100%
+```
+
+
+
+## Client WebSocket { #websockets-client }
+
+### En production { #in-production }
+
+Dans votre système de production, vous avez probablement un frontend créé avec un framework moderne comme React, Vue.js ou Angular.
+
+Et pour communiquer en utilisant WebSockets avec votre backend, vous utiliseriez probablement les outils fournis par votre frontend.
+
+Ou vous pouvez avoir une application mobile native qui communique directement avec votre backend WebSocket, en code natif.
+
+Ou vous pouvez avoir toute autre façon de communiquer avec l'endpoint WebSocket.
+
+---
+
+Mais pour cet exemple, nous utiliserons un document HTML très simple avec un peu de JavaScript, le tout dans une longue chaîne.
+
+Cela, bien entendu, n'est pas optimal et vous ne l'utiliseriez pas en production.
+
+En production, vous auriez l'une des options ci-dessus.
+
+Mais c'est la façon la plus simple de se concentrer sur la partie serveur des WebSockets et d'avoir un exemple fonctionnel :
+
+{* ../../docs_src/websockets/tutorial001_py310.py hl[2,6:38,41:43] *}
+
+## Créer un `websocket` { #create-a-websocket }
+
+Dans votre application **FastAPI**, créez un `websocket` :
+
+{* ../../docs_src/websockets/tutorial001_py310.py hl[1,46:47] *}
+
+/// note | Détails techniques
+
+Vous pourriez aussi utiliser `from starlette.websockets import WebSocket`.
+
+**FastAPI** fournit le même `WebSocket` directement, simplement pour vous faciliter la vie en tant que développeur. Mais il provient directement de Starlette.
+
+///
+
+## Attendre des messages et envoyer des messages { #await-for-messages-and-send-messages }
+
+Dans votre route WebSocket, vous pouvez `await` des messages et envoyer des messages.
+
+{* ../../docs_src/websockets/tutorial001_py310.py hl[48:52] *}
+
+Vous pouvez recevoir et envoyer des données binaires, texte et JSON.
+
+## Essayer { #try-it }
+
+Si votre fichier s'appelle `main.py`, exécutez votre application avec :
+
+
+
+```console
+$ fastapi dev main.py
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+Ouvrez votre navigateur à l'adresse http://127.0.0.1:8000.
+
+Vous verrez une page simple comme :
+
+
+
+Vous pouvez saisir des messages dans le champ de saisie et les envoyer :
+
+
+
+Et votre application **FastAPI** avec WebSockets vous répondra :
+
+
+
+Vous pouvez envoyer (et recevoir) de nombreux messages :
+
+
+
+Et tous utiliseront la même connexion WebSocket.
+
+## Utiliser `Depends` et autres { #using-depends-and-others }
+
+Dans les endpoints WebSocket, vous pouvez importer depuis `fastapi` et utiliser :
+
+* `Depends`
+* `Security`
+* `Cookie`
+* `Header`
+* `Path`
+* `Query`
+
+Ils fonctionnent de la même manière que pour les autres endpoints/*chemins d'accès* FastAPI :
+
+{* ../../docs_src/websockets/tutorial002_an_py310.py hl[68:69,82] *}
+
+/// info
+
+Comme il s'agit d'un WebSocket, il n'est pas vraiment logique de lever une `HTTPException`, nous levons plutôt une `WebSocketException`.
+
+Vous pouvez utiliser un code de fermeture parmi les codes valides définis dans la spécification.
+
+///
+
+### Essayez les WebSockets avec des dépendances { #try-the-websockets-with-dependencies }
+
+Si votre fichier s'appelle `main.py`, exécutez votre application avec :
+
+
+
+```console
+$ fastapi dev main.py
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+Ouvrez votre navigateur à l'adresse http://127.0.0.1:8000.
+
+Là, vous pouvez définir :
+
+* « Item ID », utilisé dans le chemin.
+* « Token » utilisé comme paramètre de requête.
+
+/// tip | Astuce
+
+Notez que le `token` de requête sera géré par une dépendance.
+
+///
+
+Avec cela, vous pouvez connecter le WebSocket puis envoyer et recevoir des messages :
+
+
+
+## Gérer les déconnexions et plusieurs clients { #handling-disconnections-and-multiple-clients }
+
+Lorsqu'une connexion WebSocket est fermée, l'instruction `await websocket.receive_text()` lèvera une exception `WebSocketDisconnect`, que vous pouvez ensuite intercepter et gérer comme dans cet exemple.
+
+{* ../../docs_src/websockets/tutorial003_py310.py hl[79:81] *}
+
+Pour l'essayer :
+
+* Ouvrez l'application dans plusieurs onglets du navigateur.
+* Écrivez des messages depuis ceux-ci.
+* Puis fermez l'un des onglets.
+
+Cela lèvera l'exception `WebSocketDisconnect`, et tous les autres clients recevront un message comme :
+
+```
+Client #1596980209979 left the chat
+```
+
+/// tip | Astuce
+
+L'application ci-dessus est un exemple minimal et simple pour montrer comment gérer et diffuser des messages à plusieurs connexions WebSocket.
+
+Mais gardez à l'esprit que, comme tout est géré en mémoire, dans une seule liste, cela ne fonctionnera que tant que le processus s'exécute et uniquement avec un seul processus.
+
+Si vous avez besoin de quelque chose de facile à intégrer avec FastAPI mais plus robuste, pris en charge par Redis, PostgreSQL ou autres, consultez encode/broadcaster.
+
+///
+
+## Plus d'informations { #more-info }
+
+Pour en savoir plus sur les options, consultez la documentation de Starlette concernant :
+
+* La classe `WebSocket`.
+* Gestion des WebSocket basée sur des classes.
diff --git a/docs/fr/docs/advanced/wsgi.md b/docs/fr/docs/advanced/wsgi.md
new file mode 100644
index 000000000..fc89819d2
--- /dev/null
+++ b/docs/fr/docs/advanced/wsgi.md
@@ -0,0 +1,51 @@
+# Inclure WSGI - Flask, Django, autres { #including-wsgi-flask-django-others }
+
+Vous pouvez monter des applications WSGI comme vous l'avez vu avec [Sous-applications - Montages](sub-applications.md){.internal-link target=_blank}, [Derrière un proxy](behind-a-proxy.md){.internal-link target=_blank}.
+
+Pour cela, vous pouvez utiliser `WSGIMiddleware` et l'utiliser pour envelopper votre application WSGI, par exemple Flask, Django, etc.
+
+## Utiliser `WSGIMiddleware` { #using-wsgimiddleware }
+
+/// info
+
+Cela nécessite l'installation de `a2wsgi`, par exemple avec `pip install a2wsgi`.
+
+///
+
+Vous devez importer `WSGIMiddleware` depuis `a2wsgi`.
+
+Ensuite, enveloppez l'application WSGI (par ex. Flask) avec le middleware.
+
+Puis, montez-la sous un chemin.
+
+{* ../../docs_src/wsgi/tutorial001_py310.py hl[1,3,23] *}
+
+/// note | Remarque
+
+Auparavant, il était recommandé d'utiliser `WSGIMiddleware` depuis `fastapi.middleware.wsgi`, mais il est désormais déprécié.
+
+Il est conseillé d'utiliser le package `a2wsgi` à la place. L'utilisation reste la même.
+
+Assurez-vous simplement que le package `a2wsgi` est installé et importez `WSGIMiddleware` correctement depuis `a2wsgi`.
+
+///
+
+## Vérifiez { #check-it }
+
+Désormais, chaque requête sous le chemin `/v1/` sera gérée par l'application Flask.
+
+Et le reste sera géré par **FastAPI**.
+
+Si vous l'exécutez et allez à http://localhost:8000/v1/, vous verrez la réponse de Flask :
+
+```txt
+Hello, World from Flask!
+```
+
+Et si vous allez à http://localhost:8000/v2, vous verrez la réponse de FastAPI :
+
+```JSON
+{
+ "message": "Hello World"
+}
+```
diff --git a/docs/fr/docs/alternatives.md b/docs/fr/docs/alternatives.md
index 9d8d85705..c344bd1f8 100644
--- a/docs/fr/docs/alternatives.md
+++ b/docs/fr/docs/alternatives.md
@@ -1,8 +1,8 @@
-# Alternatives, inspiration et comparaisons
+# Alternatives, inspiration et comparaisons { #alternatives-inspiration-and-comparisons }
Ce qui a inspiré **FastAPI**, comment il se compare à d'autres solutions et ce qu'il en a appris.
-## Intro
+## Intro { #intro }
**FastAPI** n'existerait pas sans les précédentes contributions d'autres projets.
@@ -13,11 +13,11 @@ fonctionnalités couvertes par **FastAPI** en utilisant de nombreux frameworks,
Mais à un moment donné il n'y avait pas d'autre option que de créer quelque chose qui offrait toutes ces
fonctionnalités, en reprenant et en combinant de la meilleure façon possible les meilleures idées des outils
-précédents, en utilisant des fonctionnalités du langage qui n'étaient même pas disponibles auparavant (type hints depuis Python 3.6+).
+précédents, en utilisant des fonctionnalités du langage qui n'étaient même pas disponibles auparavant (annotations de type depuis Python 3.6+).
-## Outils précédents
+## Outils précédents { #previous-tools }
-### Django
+### Django { #django }
C'est le framework Python le plus populaire et il bénéficie d'une grande confiance. Il est utilisé pour construire
des systèmes tel qu'Instagram.
@@ -26,18 +26,18 @@ Il est relativement fortement couplé aux bases de données relationnelles (comm
n'est pas très facile d'utiliser une base de données NoSQL (comme Couchbase, MongoDB, Cassandra, etc.) comme principal moyen de
stockage.
-Il a été créé pour générer le HTML en backend, pas pour créer des API consommées par un frontend moderne (comme React, Vue.js et Angular) ou par d'autres systèmes (comme les appareils IoT) communiquant avec lui.
+Il a été créé pour générer le HTML en backend, pas pour créer des API consommées par un frontend moderne (comme React, Vue.js et Angular) ou par d'autres systèmes (comme les appareils IoT) communiquant avec lui.
-### Django REST Framework
+### Django REST Framework { #django-rest-framework }
Django REST framework a été conçu comme une boîte à outils flexible permettant de construire des API Web à partir de Django, afin d'améliorer ses capacités en matière d'API.
Il est utilisé par de nombreuses entreprises, dont Mozilla, Red Hat et Eventbrite.
Il s'agissait de l'un des premiers exemples de **documentation automatique pour API**, et c'est précisément l'une des
-premières idées qui a inspiré "la recherche de" **FastAPI**.
+premières idées qui a inspiré « la recherche de » **FastAPI**.
-/// note
+/// note | Remarque
Django REST framework a été créé par Tom Christie. Le créateur de Starlette et Uvicorn, sur lesquels **FastAPI** est basé.
@@ -49,9 +49,9 @@ Avoir une interface de documentation automatique de l'API.
///
-### Flask
+### Flask { #flask }
-Flask est un "micro-framework", il ne comprend pas d'intégrations de bases de données ni beaucoup de choses qui sont fournies par défaut dans Django.
+Flask est un « micro‑framework », il ne comprend pas d'intégrations de bases de données ni beaucoup de choses qui sont fournies par défaut dans Django.
Cette simplicité et cette flexibilité permettent d'utiliser des bases de données NoSQL comme principal système de stockage de données.
@@ -60,20 +60,20 @@ technique par moments.
Il est aussi couramment utilisé pour d'autres applications qui n'ont pas nécessairement besoin d'une base de données, de gestion des utilisateurs ou de l'une des nombreuses fonctionnalités préinstallées dans Django. Bien que beaucoup de ces fonctionnalités puissent être ajoutées avec des plug-ins.
-Ce découplage des parties, et le fait d'être un "micro-framework" qui puisse être étendu pour couvrir exactement ce
+Ce découplage des parties, et le fait d'être un « micro‑framework » qui puisse être étendu pour couvrir exactement ce
qui est nécessaire, était une caractéristique clé que je voulais conserver.
-Compte tenu de la simplicité de Flask, il semblait bien adapté à la création d'API. La prochaine chose à trouver était un "Django REST Framework" pour Flask.
+Compte tenu de la simplicité de Flask, il semblait bien adapté à la création d'API. La prochaine chose à trouver était un « Django REST Framework » pour Flask.
/// check | A inspiré **FastAPI** à
-Être un micro-framework. Il est donc facile de combiner les outils et les pièces nécessaires.
+Être un micro‑framework. Il est donc facile de combiner les outils et les pièces nécessaires.
Proposer un système de routage simple et facile à utiliser.
///
-### Requests
+### Requests { #requests }
**FastAPI** n'est pas réellement une alternative à **Requests**. Leur cadre est très différent.
@@ -97,7 +97,7 @@ La façon dont vous l'utilisez est très simple. Par exemple, pour faire une req
response = requests.get("http://example.com/some/url")
```
-En contrepartie l'API _des opérations de chemin_ de FastAPI pourrait ressembler à ceci :
+L’opération de chemin d'accès correspondante dans **FastAPI** pourrait ressembler à ceci :
```Python hl_lines="1"
@app.get("/some/url")
@@ -109,13 +109,13 @@ Notez les similitudes entre `requests.get(...)` et `@app.get(...)`.
/// check | A inspiré **FastAPI** à
-Avoir une API simple et intuitive.
-
-Utiliser les noms de méthodes HTTP (opérations) directement, de manière simple et intuitive. \* Avoir des valeurs par défaut raisonnables, mais des personnalisations puissantes.
+* Avoir une API simple et intuitive.
+* Utiliser les noms de méthodes HTTP (opérations) directement, de manière simple et intuitive.
+* Avoir des valeurs par défaut raisonnables, mais des personnalisations puissantes.
///
-### Swagger / OpenAPI
+### Swagger / OpenAPI { #swagger-openapi }
La principale fonctionnalité que j'ai emprunté à Django REST Framework était la documentation automatique des API.
@@ -126,7 +126,7 @@ Swagger pour une API permettrait d'utiliser cette interface utilisateur web auto
À un moment donné, Swagger a été cédé à la Fondation Linux, puis a été rebaptisé OpenAPI.
-C'est pourquoi, lorsqu'on parle de la version 2.0, il est courant de dire "Swagger", et pour la version 3+ "OpenAPI".
+C'est pourquoi, lorsqu'on parle de la version 2.0, il est courant de dire « Swagger », et pour la version 3+ « OpenAPI ».
/// check | A inspiré **FastAPI** à
@@ -141,16 +141,15 @@ Ces deux-là ont été choisis parce qu'ils sont populaires et stables, mais en
///
-### Frameworks REST pour Flask
+### Frameworks REST pour Flask { #flask-rest-frameworks }
Il y a plusieurs frameworks REST pour Flask, mais après avoir investi du temps et du travail pour les étudier, j'ai
découvert que le développement de beaucoup d'entre eux sont suspendus ou abandonnés, avec plusieurs problèmes
permanents qui les rendent inadaptés.
-### Marshmallow
+### Marshmallow { #marshmallow }
-L'une des principales fonctionnalités nécessaires aux systèmes API est la "sérialisation" des données, qui consiste à prendre les données du code (Python) et à
+L'une des principales fonctionnalités nécessaires aux systèmes API est la « sérialisation » des données, qui consiste à prendre les données du code (Python) et à
les convertir en quelque chose qui peut être envoyé sur le réseau. Par exemple, convertir un objet contenant des
données provenant d'une base de données en un objet JSON. Convertir des objets `datetime` en strings, etc.
@@ -163,19 +162,17 @@ Sans un système de validation des données, vous devriez effectuer toutes les v
Ces fonctionnalités sont ce pourquoi Marshmallow a été construit. C'est une excellente bibliothèque, et je l'ai déjà beaucoup utilisée.
-Mais elle a été créée avant que les type hints n'existent en Python. Ainsi, pour définir chaque schéma, vous devez utiliser des utilitaires et des classes spécifiques fournies par Marshmallow.
+Mais elle a été créée avant que les annotations de type n'existent en Python. Ainsi, pour définir chaque schéma, vous devez utiliser des utilitaires et des classes spécifiques fournies par Marshmallow.
/// check | A inspiré **FastAPI** à
-Utilisez du code pour définir des "schémas" qui fournissent automatiquement les types de données et la validation.
+Utilisez du code pour définir des « schémas » qui fournissent automatiquement les types de données et la validation.
///
-### Webargs
+### Webargs { #webargs }
-Une autre grande fonctionnalité requise par les API est le parsing des données provenant des requêtes entrantes.
+Une autre grande fonctionnalité requise par les API est l’analyse des données provenant des requêtes entrantes.
Webargs est un outil qui a été créé pour fournir cela par-dessus plusieurs frameworks, dont Flask.
@@ -195,7 +192,7 @@ Disposer d'une validation automatique des données des requêtes entrantes.
///
-### APISpec
+### APISpec { #apispec }
Marshmallow et Webargs fournissent la validation, l'analyse et la sérialisation en tant que plug-ins.
@@ -225,7 +222,7 @@ Supporter la norme ouverte pour les API, OpenAPI.
///
-### Flask-apispec
+### Flask-apispec { #flask-apispec }
C'est un plug-in pour Flask, qui relie Webargs, Marshmallow et APISpec.
@@ -240,11 +237,11 @@ Cette combinaison de Flask, Flask-apispec avec Marshmallow et Webargs était ma
Son utilisation a conduit à la création de plusieurs générateurs Flask full-stack. Ce sont les principales stacks que
j'ai (ainsi que plusieurs équipes externes) utilisées jusqu'à présent :
-- https://github.com/tiangolo/full-stack
-- https://github.com/tiangolo/full-stack-flask-couchbase
-- https://github.com/tiangolo/full-stack-flask-couchdb
+* https://github.com/tiangolo/full-stack
+* https://github.com/tiangolo/full-stack-flask-couchbase
+* https://github.com/tiangolo/full-stack-flask-couchdb
-Ces mêmes générateurs full-stack ont servi de base aux [Générateurs de projets pour **FastAPI**](project-generation.md){.internal-link target=\_blank}.
+Ces mêmes générateurs full-stack ont servi de base aux [Générateurs de projets pour **FastAPI**](project-generation.md){.internal-link target=_blank}.
/// info
@@ -258,15 +255,15 @@ Générer le schéma OpenAPI automatiquement, à partir du même code qui défin
///
-### NestJS (et Angular)
+### NestJS (et Angular) { #nestjs-and-angular }
Ce n'est même pas du Python, NestJS est un framework JavaScript (TypeScript) NodeJS inspiré d'Angular.
Il réalise quelque chose de similaire à ce qui peut être fait avec Flask-apispec.
-Il possède un système d'injection de dépendances intégré, inspiré d'Angular 2. Il nécessite de pré-enregistrer les "injectables" (comme tous les autres systèmes d'injection de dépendances que je connais), donc, cela ajoute à la verbosité et à la répétition du code.
+Il possède un système d'injection de dépendances intégré, inspiré d'Angular 2. Il nécessite de pré-enregistrer les « injectables » (comme tous les autres systèmes d'injection de dépendances que je connais), donc, cela ajoute à la verbosité et à la répétition du code.
-Comme les paramètres sont décrits avec des types TypeScript (similaires aux type hints de Python), la prise en charge
+Comme les paramètres sont décrits avec des types TypeScript (similaires aux annotations de type de Python), la prise en charge
par l'éditeur est assez bonne.
Mais comme les données TypeScript ne sont pas préservées après la compilation en JavaScript, il ne peut pas compter sur les types pour définir la validation, la sérialisation et la documentation en même temps. En raison de cela et de certaines décisions de conception, pour obtenir la validation, la sérialisation et la génération automatique de schémas, il est nécessaire d'ajouter des décorateurs à de nombreux endroits. Cela devient donc assez verbeux.
@@ -281,7 +278,7 @@ Disposer d'un puissant système d'injection de dépendances. Trouver un moyen de
///
-### Sanic
+### Sanic { #sanic }
C'était l'un des premiers frameworks Python extrêmement rapides basés sur `asyncio`. Il a été conçu pour être très similaire à Flask.
@@ -301,14 +298,12 @@ C'est pourquoi **FastAPI** est basé sur Starlette, car il s'agit du framework l
///
-### Falcon
+### Falcon { #falcon }
Falcon est un autre framework Python haute performance, il est conçu pour être minimal, et est utilisé comme fondation pour d'autres frameworks comme Hug.
-Il utilise le standard précédent pour les frameworks web Python (WSGI) qui est synchrone, donc il ne peut pas gérer les WebSockets et d'autres cas d'utilisation. Néanmoins, il offre de très bonnes performances.
-
-Il est conçu pour avoir des fonctions qui reçoivent deux paramètres, une "requête" et une "réponse". Ensuite, vous
-"lisez" des parties de la requête et "écrivez" des parties dans la réponse. En raison de cette conception, il n'est
+Il est conçu pour avoir des fonctions qui reçoivent deux paramètres, une « requête » et une « réponse ». Ensuite, vous
+« lisez » des parties de la requête et « écrivez » des parties dans la réponse. En raison de cette conception, il n'est
pas possible de déclarer des paramètres de requête et des corps avec des indications de type Python standard comme paramètres de fonction.
Ainsi, la validation, la sérialisation et la documentation des données doivent être effectuées dans le code, et non pas automatiquement. Ou bien elles doivent être implémentées comme un framework au-dessus de Falcon, comme Hug. Cette même distinction se retrouve dans d'autres frameworks qui s'inspirent de la conception de Falcon, qui consiste à avoir un objet de requête et un objet de réponse comme paramètres.
@@ -323,20 +318,20 @@ Bien que dans FastAPI, il est facultatif, et est utilisé principalement pour d
///
-### Molten
+### Molten { #molten }
J'ai découvert Molten lors des premières étapes de développement de **FastAPI**. Et il a des idées assez similaires :
-- Basé sur les type hints Python.
-- Validation et documentation via ces types.
-- Système d'injection de dépendances.
+* Basé sur les annotations de type Python.
+* Validation et documentation via ces types.
+* Système d'injection de dépendances.
Il n'utilise pas une librairie tiers de validation, sérialisation et de documentation tel que Pydantic, il utilise son propre système. Ainsi, ces définitions de types de données ne sont pas réutilisables aussi facilement.
-Il nécessite une configuration un peu plus verbeuse. Et comme il est basé sur WSGI (au lieu dASGI), il n'est pas
+Il nécessite une configuration un peu plus verbeuse. Et comme il est basé sur WSGI (au lieu d'ASGI), il n'est pas
conçu pour profiter des hautes performances fournies par des outils comme Uvicorn, Starlette et Sanic.
-Le système d'injection de dépendances exige le pré-enregistrement des dépendances et les dépendances sont résolues sur la base des types déclarés. Ainsi, il n'est pas possible de déclarer plus d'un "composant" qui fournit un certain type.
+Le système d'injection de dépendances exige le pré-enregistrement des dépendances et les dépendances sont résolues sur la base des types déclarés. Ainsi, il n'est pas possible de déclarer plus d'un « composant » qui fournit un certain type.
Les routes sont déclarées à un seul endroit, en utilisant des fonctions déclarées à d'autres endroits (au lieu
d'utiliser des décorateurs qui peuvent être placés juste au-dessus de la fonction qui gère l'endpoint). Cette
@@ -345,15 +340,15 @@ qui sont relativement fortement couplées.
/// check | A inspiré **FastAPI** à
-Définir des validations supplémentaires pour les types de données utilisant la valeur "par défaut" des attributs du modèle. Ceci améliore le support de l'éditeur, et n'était pas disponible dans Pydantic auparavant.
+Définir des validations supplémentaires pour les types de données utilisant la valeur « par défaut » des attributs du modèle. Ceci améliore le support de l'éditeur, et n'était pas disponible dans Pydantic auparavant.
Cela a en fait inspiré la mise à jour de certaines parties de Pydantic, afin de supporter le même style de déclaration de validation (toute cette fonctionnalité est maintenant déjà disponible dans Pydantic).
///
-### Hug
+### Hug { #hug }
-Hug a été l'un des premiers frameworks à implémenter la déclaration des types de paramètres d'API en utilisant les type hints Python. C'était une excellente idée qui a inspiré d'autres outils à faire de même.
+Hug a été l'un des premiers frameworks à implémenter la déclaration des types de paramètres d'API en utilisant les annotations de type Python. C'était une excellente idée qui a inspiré d'autres outils à faire de même.
Il utilisait des types personnalisés dans ses déclarations au lieu des types Python standard, mais c'était tout de même un énorme pas en avant.
@@ -372,28 +367,28 @@ Hug a été créé par Timothy Crosley, le créateur de APIStar (<= 0.5)
+### APIStar (<= 0.5) { #apistar-0-5 }
Juste avant de décider de développer **FastAPI**, j'ai trouvé le serveur **APIStar**. Il contenait presque tout ce
que je recherchais et avait un beau design.
-C'était l'une des premières implémentations d'un framework utilisant les type hints Python pour déclarer les paramètres
+C'était l'une des premières implémentations d'un framework utilisant les annotations de type Python pour déclarer les paramètres
et les requêtes que j'ai vues (avant NestJS et Molten). Je l'ai trouvé plus ou moins en même temps que Hug. Mais APIStar utilisait le standard OpenAPI.
-Il disposait de la validation automatique, sérialisation des données et d'une génération de schéma OpenAPI basée sur les mêmes type hints à plusieurs endroits.
+Il disposait de la validation automatique, sérialisation des données et d'une génération de schéma OpenAPI basée sur les mêmes annotations de type à plusieurs endroits.
-La définition du schéma de corps de requête n'utilisait pas les mêmes type hints Python que Pydantic, il était un peu plus proche de Marshmallow, donc le support de l'éditeur n'était pas aussi bon, mais APIStar était quand même la meilleure option disponible.
+La définition du schéma de corps de requête n'utilisait pas les mêmes annotations de type Python que Pydantic, il était un peu plus proche de Marshmallow, donc le support de l'éditeur n'était pas aussi bon, mais APIStar était quand même la meilleure option disponible.
Il avait les meilleures performances d'après les benchmarks de l'époque (seulement surpassé par Starlette).
@@ -429,20 +424,20 @@ Et après avoir longtemps cherché un framework similaire et testé de nombreuse
Puis APIStar a cessé d'exister en tant que serveur et Starlette a été créé, et a constitué une meilleure base pour un tel système. Ce fut l'inspiration finale pour construire **FastAPI**.
-Je considère **FastAPI** comme un "successeur spirituel" d'APIStar, tout en améliorant et en augmentant les fonctionnalités, le système de typage et d'autres parties, sur la base des enseignements tirés de tous ces outils précédents.
+Je considère **FastAPI** comme un « successeur spirituel » d'APIStar, tout en améliorant et en augmentant les fonctionnalités, le système de typage et d'autres parties, sur la base des enseignements tirés de tous ces outils précédents.
///
-## Utilisés par **FastAPI**
+## Utilisés par **FastAPI** { #used-by-fastapi }
-### Pydantic
+### Pydantic { #pydantic }
-Pydantic est une bibliothèque permettant de définir la validation, la sérialisation et la documentation des données (à l'aide de JSON Schema) en se basant sur les Python type hints.
+Pydantic est une bibliothèque permettant de définir la validation, la sérialisation et la documentation des données (à l'aide de JSON Schema) en se basant sur les annotations de type Python.
Cela le rend extrêmement intuitif.
Il est comparable à Marshmallow. Bien qu'il soit plus rapide que Marshmallow dans les benchmarks. Et comme il est
-basé sur les mêmes type hints Python, le support de l'éditeur est grand.
+basé sur les mêmes annotations de type Python, le support de l'éditeur est grand.
/// check | **FastAPI** l'utilise pour
@@ -452,9 +447,9 @@ Gérer toute la validation des données, leur sérialisation et la documentation
///
-### Starlette
+### Starlette { #starlette }
-Starlette est un framework/toolkit léger ASGI, qui est idéal pour construire des services asyncio performants.
+Starlette est un framework/toolkit léger ASGI, qui est idéal pour construire des services asyncio performants.
Il est très simple et intuitif. Il est conçu pour être facilement extensible et avoir des composants modulaires.
@@ -462,29 +457,28 @@ Il offre :
- Des performances vraiment impressionnantes.
- Le support des WebSockets.
-- Le support de GraphQL.
- Les tâches d'arrière-plan.
- Les événements de démarrage et d'arrêt.
-- Un client de test basé sur request.
+- Un client de test basé sur HTTPX.
- CORS, GZip, fichiers statiques, streaming des réponses.
- Le support des sessions et des cookies.
- Une couverture de test à 100 %.
- 100 % de la base de code avec des annotations de type.
-- Zéro forte dépendance à d'autres packages.
+- Peu de dépendances strictes.
Starlette est actuellement le framework Python le plus rapide testé. Seulement dépassé par Uvicorn, qui n'est pas un framework, mais un serveur.
-Starlette fournit toutes les fonctionnalités de base d'un micro-framework web.
+Starlette fournit toutes les fonctionnalités de base d'un micro‑framework web.
Mais il ne fournit pas de validation automatique des données, de sérialisation ou de documentation.
-C'est l'une des principales choses que **FastAPI** ajoute par-dessus, le tout basé sur les type hints Python (en utilisant Pydantic). Cela, plus le système d'injection de dépendances, les utilitaires de sécurité, la génération de schémas OpenAPI, etc.
+C'est l'une des principales choses que **FastAPI** ajoute par-dessus, le tout basé sur les annotations de type Python (en utilisant Pydantic). Cela, plus le système d'injection de dépendances, les utilitaires de sécurité, la génération de schémas OpenAPI, etc.
/// note | Détails techniques
-ASGI est une nouvelle "norme" développée par les membres de l'équipe principale de Django. Il ne s'agit pas encore d'une "norme Python" (un PEP), bien qu'ils soient en train de le faire.
+ASGI est une nouvelle « norme » développée par les membres de l'équipe principale de Django. Il ne s'agit pas encore d'une « norme Python » (un PEP), bien qu'ils soient en train de le faire.
-Néanmoins, il est déjà utilisé comme "standard" par plusieurs outils. Cela améliore grandement l'interopérabilité, puisque vous pouvez remplacer Uvicorn par n'importe quel autre serveur ASGI (comme Daphne ou Hypercorn), ou vous pouvez ajouter des outils compatibles ASGI, comme `python-socketio`.
+Néanmoins, il est déjà utilisé comme « standard » par plusieurs outils. Cela améliore grandement l'interopérabilité, puisque vous pouvez remplacer Uvicorn par n'importe quel autre serveur ASGI (comme Daphne ou Hypercorn), ou vous pouvez ajouter des outils compatibles ASGI, comme `python-socketio`.
///
@@ -498,7 +492,7 @@ Ainsi, tout ce que vous pouvez faire avec Starlette, vous pouvez le faire direct
///
-### Uvicorn
+### Uvicorn { #uvicorn }
Uvicorn est un serveur ASGI rapide comme l'éclair, basé sur uvloop et httptools.
@@ -511,12 +505,12 @@ C'est le serveur recommandé pour Starlette et **FastAPI**.
Le serveur web principal pour exécuter les applications **FastAPI**.
-Vous pouvez le combiner avec Gunicorn, pour avoir un serveur multi-processus asynchrone.
+Vous pouvez également utiliser l'option de ligne de commande `--workers` pour avoir un serveur multi‑processus asynchrone.
Pour plus de détails, consultez la section [Déploiement](deployment/index.md){.internal-link target=_blank}.
///
-## Benchmarks et vitesse
+## Benchmarks et vitesse { #benchmarks-and-speed }
-Pour comprendre, comparer et voir la différence entre Uvicorn, Starlette et FastAPI, consultez la section sur les [Benchmarks](benchmarks.md){.internal-link target=\_blank}.
+Pour comprendre, comparer et voir la différence entre Uvicorn, Starlette et FastAPI, consultez la section sur les [Benchmarks](benchmarks.md){.internal-link target=_blank}.
diff --git a/docs/fr/docs/async.md b/docs/fr/docs/async.md
index 1437ae517..72923e03b 100644
--- a/docs/fr/docs/async.md
+++ b/docs/fr/docs/async.md
@@ -1,17 +1,18 @@
-# Concurrence et les mots-clés async et await
+# Concurrence et async / await { #concurrency-and-async-await }
-Cette page vise à fournir des détails sur la syntaxe `async def` pour les *fonctions de chemins* et quelques rappels sur le code asynchrone, la concurrence et le parallélisme.
+Détails sur la syntaxe `async def` pour les *fonctions de chemin d'accès* et quelques rappels sur le code asynchrone, la concurrence et le parallélisme.
-## Vous êtes pressés ?
+## Vous êtes pressés ? { #in-a-hurry }
-TL;DR :
+TL;DR :
Si vous utilisez des bibliothèques tierces qui nécessitent d'être appelées avec `await`, telles que :
```Python
results = await some_library()
```
-Alors, déclarez vos *fonctions de chemins* avec `async def` comme ceci :
+
+Alors, déclarez vos *fonctions de chemin d'accès* avec `async def` comme ceci :
```Python hl_lines="2"
@app.get('/')
@@ -20,7 +21,7 @@ async def read_results():
return results
```
-/// note
+/// note | Remarque
Vous pouvez uniquement utiliser `await` dans les fonctions créées avec `async def`.
@@ -28,7 +29,7 @@ Vous pouvez uniquement utiliser `await` dans les fonctions créées avec `async
---
-Si vous utilisez une bibliothèque externe qui communique avec quelque chose (une BDD, une API, un système de fichiers, etc.) et qui ne supporte pas l'utilisation d'`await` (ce qui est actuellement le cas pour la majorité des bibliothèques de BDD), alors déclarez vos *fonctions de chemin* normalement, avec le classique `def`, comme ceci :
+Si vous utilisez une bibliothèque externe qui communique avec quelque chose (une base de données, une API, le système de fichiers, etc.) et qui ne supporte pas l'utilisation d'`await` (ce qui est actuellement le cas pour la majorité des bibliothèques de base de données), alors déclarez vos *fonctions de chemin d'accès* normalement, avec le classique `def`, comme ceci :
```Python hl_lines="2"
@app.get('/')
@@ -39,7 +40,7 @@ def results():
---
-Si votre application n'a pas à communiquer avec une bibliothèque externe et pas à attendre de réponse, utilisez `async def`.
+Si votre application n'a pas à communiquer avec une autre chose et à attendre sa réponse, utilisez `async def`, même si vous n'avez pas besoin d'utiliser `await` à l'intérieur.
---
@@ -47,15 +48,15 @@ Si vous ne savez pas, utilisez seulement `def` comme vous le feriez habituelleme
---
-**Note** : vous pouvez mélanger `def` et `async def` dans vos *fonctions de chemin* autant que nécessaire, **FastAPI** saura faire ce qu'il faut avec.
+Note : vous pouvez mélanger `def` et `async def` dans vos *fonctions de chemin d'accès* autant que nécessaire, et définir chacune avec l’option la plus adaptée pour vous. FastAPI fera ce qu'il faut avec elles.
-Au final, peu importe le cas parmi ceux ci-dessus, **FastAPI** fonctionnera de manière asynchrone et sera extrêmement rapide.
+Au final, peu importe le cas parmi ceux ci-dessus, FastAPI fonctionnera de manière asynchrone et sera extrêmement rapide.
-Mais si vous suivez bien les instructions ci-dessus, alors **FastAPI** pourra effectuer quelques optimisations et ainsi améliorer les performances.
+Mais si vous suivez bien les instructions ci-dessus, il pourra effectuer quelques optimisations et ainsi améliorer les performances.
-## Détails techniques
+## Détails techniques { #technical-details }
-Les versions modernes de Python supportent le **code asynchrone** grâce aux **"coroutines"** avec les syntaxes **`async` et `await`**.
+Les versions modernes de Python supportent le **code asynchrone** grâce aux **« coroutines »** avec les syntaxes **`async` et `await`**.
Analysons les différentes parties de cette phrase dans les sections suivantes :
@@ -63,46 +64,46 @@ Analysons les différentes parties de cette phrase dans les sections suivantes :
* **`async` et `await`**
* **Coroutines**
-## Code asynchrone
+## Code asynchrone { #asynchronous-code }
-Faire du code asynchrone signifie que le langage 💬 est capable de dire à l'ordinateur / au programme 🤖 qu'à un moment du code, il 🤖 devra attendre que *quelque chose d'autre* se termine autre part. Disons que ce *quelque chose d'autre* est appelé "fichier-lent" 📝.
+Faire du code asynchrone signifie que le langage 💬 est capable de dire à l'ordinateur / au programme 🤖 qu'à un moment du code, il 🤖 devra attendre que *quelque chose d'autre* se termine autre part. Disons que ce *quelque chose d'autre* est appelé « slow-file » 📝.
-Donc, pendant ce temps, l'ordinateur pourra effectuer d'autres tâches, pendant que "fichier-lent" 📝 se termine.
+Donc, pendant ce temps, l'ordinateur pourra effectuer d'autres tâches, pendant que « slow-file » 📝 se termine.
Ensuite l'ordinateur / le programme 🤖 reviendra à chaque fois qu'il en a la chance que ce soit parce qu'il attend à nouveau, ou car il 🤖 a fini tout le travail qu'il avait à faire. Il 🤖 regardera donc si les tâches qu'il attend ont terminé d'être effectuées.
-Ensuite, il 🤖 prendra la première tâche à finir (disons, notre "fichier-lent" 📝) et continuera à faire avec cette dernière ce qu'il était censé.
+Ensuite, il 🤖 prendra la première tâche à finir (disons, notre « slow-file » 📝) et continuera à faire avec cette dernière ce qu'il était censé.
-Ce "attendre quelque chose d'autre" fait généralement référence à des opérations I/O qui sont relativement "lentes" (comparées à la vitesse du processeur et de la mémoire RAM) telles qu'attendre que :
+Ce « attendre quelque chose d'autre » fait généralement référence à des opérations I/O qui sont relativement « lentes » (comparées à la vitesse du processeur et de la mémoire RAM) telles qu'attendre que :
* de la donnée soit envoyée par le client à travers le réseau
* de la donnée envoyée depuis votre programme soit reçue par le client à travers le réseau
* le contenu d'un fichier sur le disque soit lu par le système et passé à votre programme
* le contenu que votre programme a passé au système soit écrit sur le disque
* une opération effectuée à distance par une API se termine
-* une opération en BDD se termine
-* une requête à une BDD renvoie un résultat
+* une opération en base de données se termine
+* une requête à une base de données renvoie un résultat
* etc.
-Le temps d'exécution étant consommé majoritairement par l'attente d'opérations I/O on appelle ceci des opérations "I/O bound".
+Le temps d'exécution étant consommé majoritairement par l'attente d'opérations I/O, on appelle ceci des opérations « I/O bound ».
-Ce concept se nomme l'"asynchronisme" car l'ordinateur / le programme n'a pas besoin d'être "synchronisé" avec la tâche, attendant le moment exact où cette dernière se terminera en ne faisant rien, pour être capable de récupérer le résultat de la tâche et l'utiliser dans la suite des opérations.
+Ce concept se nomme « asynchrone » car l'ordinateur / le programme n'a pas besoin d'être « synchronisé » avec la tâche, attendant le moment exact où cette dernière se terminera en ne faisant rien, pour être capable de récupérer le résultat de la tâche et l'utiliser dans la suite des opérations.
-À la place, en étant "asynchrone", une fois terminée, une tâche peut légèrement attendre (quelques microsecondes) que l'ordinateur / le programme finisse ce qu'il était en train de faire, et revienne récupérer le résultat.
+À la place, en étant « asynchrone », une fois terminée, une tâche peut légèrement attendre (quelques microsecondes) que l'ordinateur / le programme finisse ce qu'il était en train de faire, et revienne récupérer le résultat.
-Pour parler de tâches "synchrones" (en opposition à "asynchrones"), on utilise souvent le terme "séquentiel", car l'ordinateur / le programme va effectuer toutes les étapes d'une tâche séquentiellement avant de passer à une autre tâche, même si ces étapes impliquent de l'attente.
+Pour parler de tâches « synchrones » (en opposition à « asynchrones »), on utilise souvent le terme « séquentiel », car l'ordinateur / le programme va effectuer toutes les étapes d'une tâche séquentiellement avant de passer à une autre tâche, même si ces étapes impliquent de l'attente.
-### Concurrence et Burgers
+### Concurrence et Burgers { #concurrency-and-burgers }
-L'idée de code **asynchrone** décrite ci-dessus est parfois aussi appelée **"concurrence"**. Ce qui est différent du **"parallélisme"**.
+L'idée de code **asynchrone** décrite ci-dessus est parfois aussi appelée **« concurrence »**. Ce qui est différent du **« parallélisme »**.
-La **concurrence** et le **parallélisme** sont tous deux liés à l'idée de "différentes choses arrivant plus ou moins au même moment".
+La **concurrence** et le **parallélisme** sont tous deux liés à l'idée de « différentes choses arrivant plus ou moins au même moment ».
Mais les détails entre la **concurrence** et le **parallélisme** diffèrent sur de nombreux points.
Pour expliquer la différence, voici une histoire de burgers :
-#### Burgers concurrents
+### Burgers concurrents { #concurrent-burgers }
Vous amenez votre crush 😍 dans votre fast food 🍔 favori, et faites la queue pendant que le serveur 💁 prend les commandes des personnes devant vous.
@@ -122,13 +123,13 @@ Le serveur 💁 vous donne le numéro assigné à votre commande.
-Pendant que vous attendez, vous allez choisir une table avec votre crush 😍, vous discutez avec votre crush 😍 pendant un long moment (les burgers étant "magnifiques" ils sont très longs à préparer ✨🍔✨).
+Pendant que vous attendez, vous allez choisir une table avec votre crush 😍, vous discutez avec votre crush 😍 pendant un long moment (les burgers étant « magnifiques » ils sont très longs à préparer ✨🍔✨).
Pendant que vous êtes assis à table, en attendant que les burgers 🍔 soient prêts, vous pouvez passer ce temps à admirer à quel point votre crush 😍 est géniale, mignonne et intelligente ✨😍✨.
-Pendant que vous discutez avec votre crush 😍, de temps en temps vous jetez un coup d'oeil au nombre affiché au-dessus du comptoir pour savoir si c'est à votre tour d'être servis.
+Pendant que vous discutez avec votre crush 😍, de temps en temps vous jetez un coup d’œil au nombre affiché au-dessus du comptoir pour savoir si c'est à votre tour d'être servis.
Jusqu'au moment où c'est (enfin) votre tour. Vous allez au comptoir, récupérez vos burgers 🍔 et revenez à votre table.
@@ -148,23 +149,23 @@ Illustrations proposées par
@@ -212,7 +213,7 @@ Illustrations proposées par (tout ça grâce à Starlette).
+Et comme on peut avoir du parallélisme et de l'asynchronicité en même temps, on obtient des performances plus hautes que la plupart des frameworks NodeJS testés et égales à celles du Go, qui est un langage compilé plus proche du C (tout ça grâce à Starlette).
-### Est-ce que la concurrence est mieux que le parallélisme ?
+### Est-ce que la concurrence est mieux que le parallélisme ? { #is-concurrency-better-than-parallelism }
Nope ! C'est ça la morale de l'histoire.
@@ -276,11 +277,11 @@ Mais dans ce cas, si pouviez amener 8 ex-serveurs/cuisiniers/devenus-nettoyeurs
Dans ce scénario, chacun des nettoyeurs (vous y compris) serait un processeur, faisant sa partie du travail.
-Et comme la plupart du temps d'exécution est pris par du "vrai" travail (et non de l'attente), et que le travail dans un ordinateur est fait par un CPU, ce sont des problèmes dits "CPU bound".
+Et comme la plupart du temps d'exécution est pris par du « vrai » travail (et non de l'attente), et que le travail dans un ordinateur est fait par un CPU, ce sont des problèmes dits « CPU bound ».
---
-Des exemples communs d'opérations "CPU bounds" sont les procédés qui requièrent des traitements mathématiques complexes.
+Des exemples communs d'opérations « CPU bound » sont les procédés qui requièrent des traitements mathématiques complexes.
Par exemple :
@@ -289,19 +290,19 @@ Par exemple :
* L'apprentissage automatique (ou **Machine Learning**) : cela nécessite de nombreuses multiplications de matrices et vecteurs. Imaginez une énorme feuille de calcul remplie de nombres que vous multiplierez entre eux tous au même moment.
* L'apprentissage profond (ou **Deep Learning**) : est un sous-domaine du **Machine Learning**, donc les mêmes raisons s'appliquent. Avec la différence qu'il n'y a pas une unique feuille de calcul de nombres à multiplier, mais une énorme quantité d'entre elles, et dans de nombreux cas, on utilise un processeur spécial pour construire et / ou utiliser ces modèles.
-### Concurrence + Parallélisme : Web + Machine Learning
+### Concurrence + Parallélisme : Web + Machine Learning { #concurrency-parallelism-web-machine-learning }
Avec **FastAPI** vous pouvez bénéficier de la concurrence qui est très courante en développement web (c'est l'attrait principal de NodeJS).
-Mais vous pouvez aussi profiter du parallélisme et multiprocessing afin de gérer des charges **CPU bound** qui sont récurrentes dans les systèmes de *Machine Learning*.
+Mais vous pouvez aussi profiter du parallélisme et du multiprocessing (plusieurs processus s'exécutant en parallèle) afin de gérer des charges **CPU bound** qui sont récurrentes dans les systèmes de *Machine Learning*.
Ça, ajouté au fait que Python soit le langage le plus populaire pour la **Data Science**, le **Machine Learning** et surtout le **Deep Learning**, font de **FastAPI** un très bon choix pour les APIs et applications de **Data Science** / **Machine Learning**.
Pour comprendre comment mettre en place ce parallélisme en production, allez lire la section [Déploiement](deployment/index.md){.internal-link target=_blank}.
-## `async` et `await`
+## `async` et `await` { #async-and-await }
-Les versions modernes de Python ont une manière très intuitive de définir le code asynchrone, tout en gardant une apparence de code "séquentiel" classique en laissant Python faire l'attente pour vous au bon moment.
+Les versions modernes de Python ont une manière très intuitive de définir le code asynchrone, tout en gardant une apparence de code « séquentiel » classique en laissant Python faire l'attente pour vous au bon moment.
Pour une opération qui nécessite de l'attente avant de donner un résultat et qui supporte ces nouvelles fonctionnalités Python, vous pouvez l'utiliser comme tel :
@@ -319,12 +320,12 @@ async def get_burgers(number: int):
return burgers
```
-...et non `def` :
+... et non `def` :
```Python hl_lines="2"
# Ceci n'est pas asynchrone
def get_sequential_burgers(number: int):
- # Opérations asynchrones pour créer les burgers
+ # Opérations séquentielles pour créer les burgers
return burgers
```
@@ -339,7 +340,7 @@ burgers = get_burgers(2)
---
-Donc, si vous utilisez une bibliothèque qui nécessite que ses fonctions soient appelées avec `await`, vous devez définir la *fonction de chemin* en utilisant `async def` comme dans :
+Donc, si vous utilisez une bibliothèque qui nécessite que ses fonctions soient appelées avec `await`, vous devez définir la *fonction de chemin d'accès* en utilisant `async def` comme dans :
```Python hl_lines="2-3"
@app.get('/burgers')
@@ -348,52 +349,61 @@ async def read_burgers():
return burgers
```
-### Plus de détails techniques
+### Plus de détails techniques { #more-technical-details }
Vous avez donc compris que `await` peut seulement être utilisé dans des fonctions définies avec `async def`.
Mais en même temps, les fonctions définies avec `async def` doivent être appelées avec `await` et donc dans des fonctions définies elles aussi avec `async def`.
-Vous avez donc remarqué ce paradoxe d'oeuf et de la poule, comment appelle-t-on la première fonction `async` ?
+Vous avez donc remarqué ce paradoxe d'œuf et de la poule, comment appelle-t-on la première fonction `async` ?
-Si vous utilisez **FastAPI**, pas besoin de vous en inquiéter, car cette "première" fonction sera votre *fonction de chemin* ; et **FastAPI** saura comment arriver au résultat attendu.
+Si vous utilisez **FastAPI**, pas besoin de vous en inquiéter, car cette « première » fonction sera votre *fonction de chemin d'accès* ; et **FastAPI** saura comment arriver au résultat attendu.
-Mais si vous utilisez `async` / `await` sans **FastAPI**, allez jetez un coup d'oeil à la documentation officielle de Python.
+Mais si vous souhaitez utiliser `async` / `await` sans FastAPI, vous pouvez également le faire.
-### Autres formes de code asynchrone
+### Écrire votre propre code async { #write-your-own-async-code }
+
+Starlette (et **FastAPI**) s’appuie sur AnyIO, ce qui le rend compatible à la fois avec la bibliothèque standard asyncio de Python et avec Trio.
+
+En particulier, vous pouvez utiliser directement AnyIO pour vos cas d’usage de concurrence avancés qui nécessitent des schémas plus élaborés dans votre propre code.
+
+Et même si vous n’utilisiez pas FastAPI, vous pourriez aussi écrire vos propres applications async avec AnyIO pour une grande compatibilité et pour bénéficier de ses avantages (par ex. la « structured concurrency »).
+
+J’ai créé une autre bibliothèque au-dessus d’AnyIO, comme une fine surcouche, pour améliorer un peu les annotations de type et obtenir une meilleure **autocomplétion**, des **erreurs en ligne**, etc. Elle propose également une introduction et un tutoriel accessibles pour vous aider à **comprendre** et écrire **votre propre code async** : Asyncer. Elle sera particulièrement utile si vous devez **combiner du code async avec du code classique** (bloquant/synchrone).
+
+### Autres formes de code asynchrone { #other-forms-of-asynchronous-code }
L'utilisation d'`async` et `await` est relativement nouvelle dans ce langage.
Mais cela rend la programmation asynchrone bien plus simple.
-Cette même syntaxe (ou presque) était aussi incluse dans les versions modernes de Javascript (dans les versions navigateur et NodeJS).
+Cette même syntaxe (ou presque) a aussi été incluse récemment dans les versions modernes de JavaScript (dans les navigateurs et NodeJS).
Mais avant ça, gérer du code asynchrone était bien plus complexe et difficile.
-Dans les versions précédentes de Python, vous auriez utilisé des *threads* ou Gevent. Mais le code aurait été bien plus difficile à comprendre, débugger, et concevoir.
+Dans les versions précédentes de Python, vous auriez utilisé des threads ou Gevent. Mais le code aurait été bien plus difficile à comprendre, débugger, et concevoir.
-Dans les versions précédentes de Javascript NodeJS / Navigateur, vous auriez utilisé des "callbacks". Menant potentiellement à ce que l'on appelle le "callback hell".
+Dans les versions précédentes de JavaScript côté navigateur / NodeJS, vous auriez utilisé des « callbacks ». Menant potentiellement à ce que l'on appelle le « callback hell ».
+## Coroutines { #coroutines }
-## Coroutines
+« Coroutine » est juste un terme élaboré pour désigner ce qui est retourné par une fonction définie avec `async def`. Python sait que c'est comme une fonction classique qui va démarrer à un moment et terminer à un autre, mais qu'elle peut aussi être mise en pause ⏸, du moment qu'il y a un `await` dans son contenu.
-**Coroutine** est juste un terme élaboré pour désigner ce qui est retourné par une fonction définie avec `async def`. Python sait que c'est comme une fonction classique qui va démarrer à un moment et terminer à un autre, mais qu'elle peut aussi être mise en pause ⏸, du moment qu'il y a un `await` dans son contenu.
+Mais toutes ces fonctionnalités d'utilisation de code asynchrone avec `async` et `await` sont souvent résumées comme l'utilisation des « coroutines ». On peut comparer cela à la principale fonctionnalité clé de Go, les « Goroutines ».
-Mais toutes ces fonctionnalités d'utilisation de code asynchrone avec `async` et `await` sont souvent résumées comme l'utilisation des *coroutines*. On peut comparer cela à la principale fonctionnalité clé de Go, les "Goroutines".
-
-## Conclusion
+## Conclusion { #conclusion }
Reprenons la phrase du début de la page :
-> Les versions modernes de Python supportent le **code asynchrone** grâce aux **"coroutines"** avec les syntaxes **`async` et `await`**.
+> Les versions modernes de Python supportent le **code asynchrone** grâce aux **« coroutines »** avec les syntaxes **`async` et `await`**.
Ceci devrait être plus compréhensible désormais. ✨
-Tout ceci est donc ce qui donne sa force à **FastAPI** (à travers Starlette) et lui permet d'avoir des performances aussi impressionnantes.
+Tout ceci est donc ce qui donne sa force à FastAPI (à travers Starlette) et lui permet d'avoir une performance aussi impressionnante.
-## Détails très techniques
+## Détails très techniques { #very-technical-details }
-/// warning | Attention !
+/// warning | Alertes
Vous pouvez probablement ignorer cela.
@@ -403,32 +413,32 @@ Si vous avez de bonnes connaissances techniques (coroutines, threads, code bloqu
///
-### Fonctions de chemin
+### Fonctions de chemin d'accès { #path-operation-functions }
-Quand vous déclarez une *fonction de chemin* avec un `def` normal et non `async def`, elle est exécutée dans un groupe de threads (threadpool) externe qui est ensuite attendu, plutôt que d'être appelée directement (car cela bloquerait le serveur).
+Quand vous déclarez une *fonction de chemin d'accès* avec un `def` normal et non `async def`, elle est exécutée dans un groupe de threads (threadpool) externe qui est ensuite attendu, plutôt que d'être appelée directement (car cela bloquerait le serveur).
-Si vous venez d'un autre framework asynchrone qui ne fonctionne pas comme de la façon décrite ci-dessus et que vous êtes habitués à définir des *fonctions de chemin* basiques avec un simple `def` pour un faible gain de performance (environ 100 nanosecondes), veuillez noter que dans **FastAPI**, l'effet serait plutôt contraire. Dans ces cas-là, il vaut mieux utiliser `async def` à moins que votre *fonction de chemin* utilise du code qui effectue des opérations I/O bloquantes.
+Si vous venez d'un autre framework asynchrone qui ne fonctionne pas comme de la façon décrite ci-dessus et que vous êtes habitué à définir des *fonctions de chemin d'accès* basiques et purement calculatoires avec un simple `def` pour un faible gain de performance (environ 100 nanosecondes), veuillez noter que dans **FastAPI**, l'effet serait plutôt contraire. Dans ces cas-là, il vaut mieux utiliser `async def` à moins que votre *fonction de chemin d'accès* utilise du code qui effectue des opérations I/O bloquantes.
Au final, dans les deux situations, il est fort probable que **FastAPI** soit tout de même [plus rapide](index.md#performance){.internal-link target=_blank} que (ou au moins de vitesse égale à) votre framework précédent.
-### Dépendances
+### Dépendances { #dependencies }
-La même chose s'applique aux dépendances. Si une dépendance est définie avec `def` plutôt que `async def`, elle est exécutée dans la threadpool externe.
+La même chose s'applique aux [dépendances](tutorial/dependencies/index.md){.internal-link target=_blank}. Si une dépendance est définie avec `def` plutôt que `async def`, elle est exécutée dans la threadpool externe.
-### Sous-dépendances
+### Sous-dépendances { #sub-dependencies }
-Vous pouvez avoir de multiples dépendances et sous-dépendances dépendant les unes des autres (en tant que paramètres de la définition de la *fonction de chemin*), certaines créées avec `async def` et d'autres avec `def`. Cela fonctionnerait aussi, et celles définies avec un simple `def` seraient exécutées sur un thread externe (venant de la threadpool) plutôt que d'être "attendues".
+Vous pouvez avoir de multiples dépendances et [sous-dépendances](tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank} dépendant les unes des autres (en tant que paramètres de la définition de la *fonction de chemin d'accès*), certaines créées avec `async def` et d'autres avec `def`. Cela fonctionnerait aussi, et celles définies avec un simple `def` seraient exécutées sur un thread externe (venant de la threadpool) plutôt que d'être « attendues ».
-### Autres fonctions utilitaires
+### Autres fonctions utilitaires { #other-utility-functions }
-Toute autre fonction utilitaire que vous appelez directement peut être créée avec un classique `def` ou avec `async def` et **FastAPI** n'aura pas d'impact sur la façon dont vous l'appelez.
+Toute autre fonction utilitaire que vous appelez directement peut être créée avec un classique `def` ou avec `async def` et FastAPI n'aura pas d'impact sur la façon dont vous l'appelez.
-Contrairement aux fonctions que **FastAPI** appelle pour vous : les *fonctions de chemin* et dépendances.
+Contrairement aux fonctions que FastAPI appelle pour vous : les *fonctions de chemin d'accès* et dépendances.
-Si votre fonction utilitaire est une fonction classique définie avec `def`, elle sera appelée directement (telle qu'écrite dans votre code), pas dans une threadpool, si la fonction est définie avec `async def` alors vous devrez attendre (avec `await`) que cette fonction se termine avant de passer à la suite du code.
+Si votre fonction utilitaire est une fonction classique définie avec `def`, elle sera appelée directement (telle qu'écrite dans votre code), pas dans une threadpool ; si la fonction est définie avec `async def` alors vous devrez attendre (avec `await`) que cette fonction se termine avant de passer à la suite du code.
---
Encore une fois, ce sont des détails très techniques qui peuvent être utiles si vous venez ici les chercher.
-Sinon, les instructions de la section Vous êtes pressés ? ci-dessus sont largement suffisantes.
+Sinon, les instructions de la section Vous êtes pressés ? ci-dessus sont largement suffisantes.
diff --git a/docs/fr/docs/deployment/cloud.md b/docs/fr/docs/deployment/cloud.md
new file mode 100644
index 000000000..798a72a74
--- /dev/null
+++ b/docs/fr/docs/deployment/cloud.md
@@ -0,0 +1,24 @@
+# Déployer FastAPI sur des fournisseurs cloud { #deploy-fastapi-on-cloud-providers }
+
+Vous pouvez utiliser pratiquement n'importe quel fournisseur cloud pour déployer votre application FastAPI.
+
+Dans la plupart des cas, les principaux fournisseurs cloud proposent des guides pour déployer FastAPI avec leurs services.
+
+## FastAPI Cloud { #fastapi-cloud }
+
+**FastAPI Cloud** est créée par le même auteur et l'équipe à l'origine de **FastAPI**.
+
+Elle simplifie le processus de **création**, de **déploiement** et **d'accès** à une API avec un effort minimal.
+
+Elle apporte la même **expérience développeur** que celle de la création d'applications avec FastAPI au **déploiement** de celles-ci dans le cloud. 🎉
+
+FastAPI Cloud est le sponsor principal et le financeur des projets open source *FastAPI and friends*. ✨
+
+## Fournisseurs cloud - Sponsors { #cloud-providers-sponsors }
+
+D'autres fournisseurs cloud ✨ [**parrainent FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨ également. 🙇
+
+Vous pouvez également envisager ces fournisseurs pour suivre leurs guides et essayer leurs services :
+
+* Render
+* Railway
diff --git a/docs/fr/docs/deployment/concepts.md b/docs/fr/docs/deployment/concepts.md
new file mode 100644
index 000000000..59b8ddd1b
--- /dev/null
+++ b/docs/fr/docs/deployment/concepts.md
@@ -0,0 +1,321 @@
+# Concepts de déploiement { #deployments-concepts }
+
+Lorsque vous déployez une application **FastAPI**, ou en fait n'importe quel type de web API, il existe plusieurs concepts qui vous importent probablement, et en les utilisant vous pouvez trouver la manière la **plus appropriée** de **déployer votre application**.
+
+Parmi les concepts importants, on trouve :
+
+* Sécurité - HTTPS
+* Exécuter au démarrage
+* Redémarrages
+* Réplication (le nombre de processus en cours d'exécution)
+* Mémoire
+* Étapes préalables avant de démarrer
+
+Nous allons voir comment ils affectent les **déploiements**.
+
+Au final, l'objectif ultime est de pouvoir **servir vos clients d'API** de manière **sécurisée**, d'**éviter les interruptions**, et d'utiliser les **ressources de calcul** (par exemple des serveurs/VM distants) aussi efficacement que possible. 🚀
+
+Je vais vous en dire un peu plus ici sur ces **concepts**, ce qui devrait vous donner l'**intuition** nécessaire pour décider comment déployer votre API dans des environnements très différents, voire même dans des environnements **futurs** qui n'existent pas encore.
+
+En tenant compte de ces concepts, vous serez en mesure **d'évaluer et de concevoir** la meilleure façon de déployer **vos propres API**.
+
+Dans les chapitres suivants, je vous donnerai des **recettes concrètes** pour déployer des applications FastAPI.
+
+Mais pour l'instant, voyons ces **idées conceptuelles** importantes. Ces concepts s'appliquent aussi à tout autre type de web API. 💡
+
+## Sécurité - HTTPS { #security-https }
+
+Dans le [chapitre précédent à propos de HTTPS](https.md){.internal-link target=_blank}, nous avons vu comment HTTPS fournit le chiffrement pour votre API.
+
+Nous avons également vu que HTTPS est normalement fourni par un composant **externe** à votre serveur d'application, un **TLS Termination Proxy**.
+
+Et il doit y avoir quelque chose chargé de **renouveler les certificats HTTPS** ; cela peut être le même composant ou quelque chose de différent.
+
+### Exemples d’outils pour HTTPS { #example-tools-for-https }
+
+Parmi les outils que vous pourriez utiliser comme TLS Termination Proxy :
+
+* Traefik
+ * Gère automatiquement le renouvellement des certificats ✨
+* Caddy
+ * Gère automatiquement le renouvellement des certificats ✨
+* Nginx
+ * Avec un composant externe comme Certbot pour le renouvellement des certificats
+* HAProxy
+ * Avec un composant externe comme Certbot pour le renouvellement des certificats
+* Kubernetes avec un Ingress Controller comme Nginx
+ * Avec un composant externe comme cert-manager pour le renouvellement des certificats
+* Pris en charge en interne par un fournisseur cloud dans le cadre de ses services (lisez ci-dessous 👇)
+
+Une autre option consiste à utiliser un **service cloud** qui fait davantage de travail, y compris la mise en place de HTTPS. Il peut avoir certaines restrictions ou vous facturer davantage, etc. Mais dans ce cas, vous n'auriez pas à configurer vous‑même un TLS Termination Proxy.
+
+Je vous montrerai des exemples concrets dans les prochains chapitres.
+
+---
+
+Les concepts suivants à considérer concernent tous le programme qui exécute votre API réelle (par ex. Uvicorn).
+
+## Programme et processus { #program-and-process }
+
+Nous allons beaucoup parler du « **processus** » en cours d'exécution, il est donc utile d'être clair sur ce que cela signifie, et sur la différence avec le mot « **programme** ».
+
+### Qu'est-ce qu'un programme { #what-is-a-program }
+
+Le mot **programme** est couramment utilisé pour décrire plusieurs choses :
+
+* Le **code** que vous écrivez, les **fichiers Python**.
+* Le **fichier** qui peut être **exécuté** par le système d'exploitation, par exemple : `python`, `python.exe` ou `uvicorn`.
+* Un programme particulier lorsqu'il **s'exécute** sur le système d'exploitation, utilisant le CPU et stockant des choses en mémoire. On appelle aussi cela un **processus**.
+
+### Qu'est-ce qu'un processus { #what-is-a-process }
+
+Le mot **processus** est normalement utilisé de manière plus spécifique, en ne se référant qu'à l'élément qui s'exécute dans le système d'exploitation (comme dans le dernier point ci‑dessus) :
+
+* Un programme particulier lorsqu'il **s'exécute** sur le système d'exploitation.
+ * Cela ne se réfère ni au fichier, ni au code ; cela se réfère **spécifiquement** à l'élément qui est **exécuté** et géré par le système d'exploitation.
+* N'importe quel programme, n'importe quel code, **ne peut faire des choses** que lorsqu'il est **exécuté**. Donc, lorsqu'il y a un **processus en cours**.
+* Le processus peut être **arrêté** (ou « tué ») par vous ou par le système d'exploitation. À ce moment‑là, il cesse de s'exécuter/d'être exécuté, et il **ne peut plus rien faire**.
+* Chaque application que vous avez en cours d'exécution sur votre ordinateur a un processus derrière elle, chaque programme lancé, chaque fenêtre, etc. Et il y a normalement de nombreux processus exécutés **en même temps** tant qu'un ordinateur est allumé.
+* Il peut y avoir **plusieurs processus** du **même programme** exécutés simultanément.
+
+Si vous ouvrez le « gestionnaire des tâches » ou le « moniteur système » (ou des outils similaires) de votre système d'exploitation, vous verrez nombre de ces processus en cours d'exécution.
+
+Et, par exemple, vous verrez probablement qu'il y a plusieurs processus exécutant le même navigateur (Firefox, Chrome, Edge, etc.). Ils exécutent normalement un processus par onglet, plus quelques processus supplémentaires.
+
+
+
+---
+
+Maintenant que nous connaissons la différence entre les termes **processus** et **programme**, continuons à parler des déploiements.
+
+## Exécuter au démarrage { #running-on-startup }
+
+Dans la plupart des cas, lorsque vous créez une web API, vous voulez qu'elle **tourne en permanence**, sans interruption, afin que vos clients puissent toujours y accéder. Bien sûr, sauf si vous avez une raison spécifique de ne vouloir l'exécuter que dans certaines situations, mais la plupart du temps vous la voulez constamment en cours et **disponible**.
+
+### Sur un serveur distant { #in-a-remote-server }
+
+Lorsque vous configurez un serveur distant (un serveur cloud, une machine virtuelle, etc.), la chose la plus simple à faire est d'utiliser `fastapi run` (qui utilise Uvicorn) ou quelque chose de similaire, manuellement, de la même manière que lorsque vous développez en local.
+
+Et cela fonctionnera et sera utile **pendant le développement**.
+
+Mais si votre connexion au serveur est coupée, le **processus en cours** va probablement s'arrêter.
+
+Et si le serveur est redémarré (par exemple après des mises à jour, ou des migrations chez le fournisseur cloud) vous **ne le remarquerez probablement pas**. Et à cause de cela, vous ne saurez même pas que vous devez redémarrer le processus manuellement. Ainsi, votre API restera tout simplement à l'arrêt. 😱
+
+### Lancer automatiquement au démarrage { #run-automatically-on-startup }
+
+En général, vous voudrez probablement que le programme serveur (par ex. Uvicorn) soit démarré automatiquement au démarrage du serveur, et sans aucune **intervention humaine**, afin d'avoir en permanence un processus exécutant votre API (par ex. Uvicorn exécutant votre app FastAPI).
+
+### Programme séparé { #separate-program }
+
+Pour y parvenir, vous aurez normalement un **programme séparé** qui s'assure que votre application est lancée au démarrage. Et dans de nombreux cas, il s'assurera également que d'autres composants ou applications sont également lancés, par exemple une base de données.
+
+### Exemples d’outils pour lancer au démarrage { #example-tools-to-run-at-startup }
+
+Voici quelques exemples d'outils capables de faire ce travail :
+
+* Docker
+* Kubernetes
+* Docker Compose
+* Docker en mode Swarm
+* Systemd
+* Supervisor
+* Pris en charge en interne par un fournisseur cloud dans le cadre de ses services
+* Autres ...
+
+Je vous donnerai des exemples plus concrets dans les prochains chapitres.
+
+## Redémarrages { #restarts }
+
+De la même manière que vous voulez vous assurer que votre application est lancée au démarrage, vous voulez probablement aussi vous assurer qu'elle est **redémarrée** après des échecs.
+
+### Nous faisons des erreurs { #we-make-mistakes }
+
+Nous, humains, faisons des **erreurs**, tout le temps. Les logiciels ont presque *toujours* des **bugs** cachés à différents endroits. 🐛
+
+Et nous, développeurs, continuons à améliorer le code au fur et à mesure que nous trouvons ces bugs et que nous implémentons de nouvelles fonctionnalités (en ajoutant éventuellement de nouveaux bugs aussi 😅).
+
+### Petites erreurs gérées automatiquement { #small-errors-automatically-handled }
+
+Lors de la création de web API avec FastAPI, s'il y a une erreur dans notre code, FastAPI la contiendra normalement à la seule requête qui a déclenché l'erreur. 🛡
+
+Le client recevra un **500 Internal Server Error** pour cette requête, mais l'application continuera de fonctionner pour les requêtes suivantes au lieu de simplement s'effondrer complètement.
+
+### Erreurs plus importantes - plantages { #bigger-errors-crashes }
+
+Néanmoins, il peut y avoir des cas où nous écrivons du code qui **fait planter l'application entière**, faisant planter Uvicorn et Python. 💥
+
+Et malgré cela, vous ne voudrez probablement pas que l'application reste à l'arrêt parce qu'il y a eu une erreur à un endroit ; vous voudrez probablement qu'elle **continue de tourner**, au moins pour les *chemins d'accès* qui ne sont pas cassés.
+
+### Redémarrer après un plantage { #restart-after-crash }
+
+Mais dans ces cas avec de très mauvaises erreurs qui font planter le **processus** en cours, vous voudrez un composant externe chargé de **redémarrer** le processus, au moins quelques fois ...
+
+/// tip | Astuce
+
+... Bien que si l'application entière **plante immédiatement**, il n'est probablement pas logique de continuer à la redémarrer indéfiniment. Mais dans ces cas, vous le remarquerez probablement pendant le développement, ou au moins juste après le déploiement.
+
+Concentrons‑nous donc sur les cas principaux, où elle pourrait planter entièrement dans certaines situations particulières **à l'avenir**, et où il est toujours logique de la redémarrer.
+
+///
+
+Vous voudrez probablement que l'élément chargé de redémarrer votre application soit un **composant externe**, car à ce stade, l'application elle‑même avec Uvicorn et Python a déjà planté, donc il n'y a rien dans le même code de la même app qui pourrait y faire quoi que ce soit.
+
+### Exemples d’outils pour redémarrer automatiquement { #example-tools-to-restart-automatically }
+
+Dans la plupart des cas, le même outil qui est utilisé pour **lancer le programme au démarrage** est également utilisé pour gérer les **redémarrages** automatiques.
+
+Par exemple, cela peut être géré par :
+
+* Docker
+* Kubernetes
+* Docker Compose
+* Docker en mode Swarm
+* Systemd
+* Supervisor
+* Pris en charge en interne par un fournisseur cloud dans le cadre de ses services
+* Autres ...
+
+## Réplication - Processus et mémoire { #replication-processes-and-memory }
+
+Avec une application FastAPI, en utilisant un programme serveur comme la commande `fastapi` qui exécute Uvicorn, l'exécuter une fois dans **un processus** peut servir plusieurs clients simultanément.
+
+Mais dans de nombreux cas, vous voudrez exécuter plusieurs processus de travail en même temps.
+
+### Multiples processus - Workers { #multiple-processes-workers }
+
+Si vous avez plus de clients que ce qu'un seul processus peut gérer (par exemple si la machine virtuelle n'est pas très grande) et que vous avez **plusieurs cœurs** dans le CPU du serveur, alors vous pouvez avoir **plusieurs processus** exécutant la même application simultanément, et distribuer toutes les requêtes entre eux.
+
+Quand vous exécutez **plusieurs processus** du même programme d'API, on les appelle couramment des **workers**.
+
+### Processus workers et ports { #worker-processes-and-ports }
+
+Rappelez‑vous, d'après les documents [À propos de HTTPS](https.md){.internal-link target=_blank}, qu'un seul processus peut écouter une combinaison de port et d'adresse IP sur un serveur ?
+
+C'est toujours vrai.
+
+Donc, pour pouvoir avoir **plusieurs processus** en même temps, il doit y avoir un **seul processus à l'écoute sur un port** qui transmet ensuite la communication à chaque processus worker d'une manière ou d'une autre.
+
+### Mémoire par processus { #memory-per-process }
+
+Maintenant, lorsque le programme charge des choses en mémoire, par exemple, un modèle de machine learning dans une variable, ou le contenu d'un gros fichier dans une variable, tout cela **consomme une partie de la mémoire (RAM)** du serveur.
+
+Et plusieurs processus **ne partagent normalement pas de mémoire**. Cela signifie que chaque processus en cours a ses propres éléments, variables et mémoire. Et si vous consommez une grande quantité de mémoire dans votre code, **chaque processus** consommera une quantité équivalente de mémoire.
+
+### Mémoire du serveur { #server-memory }
+
+Par exemple, si votre code charge un modèle de Machine Learning de **1 Go**, lorsque vous exécutez un processus avec votre API, il consommera au moins 1 Go de RAM. Et si vous démarrez **4 processus** (4 workers), chacun consommera 1 Go de RAM. Donc au total, votre API consommera **4 Go de RAM**.
+
+Et si votre serveur distant ou votre machine virtuelle n'a que 3 Go de RAM, essayer de charger plus de 4 Go de RAM posera problème. 🚨
+
+### Multiples processus - Un exemple { #multiple-processes-an-example }
+
+Dans cet exemple, il y a un **processus gestionnaire** qui démarre et contrôle deux **processus workers**.
+
+Ce processus gestionnaire serait probablement celui qui écoute sur le **port** de l'IP. Et il transmettrait toute la communication aux processus workers.
+
+Ces processus workers seraient ceux qui exécutent votre application, ils effectueraient les calculs principaux pour recevoir une **requête** et renvoyer une **réponse**, et ils chargeraient tout ce que vous mettez dans des variables en RAM.
+
+
+
+Et bien sûr, la même machine aurait probablement **d'autres processus** en cours d'exécution également, en plus de votre application.
+
+Un détail intéressant est que le pourcentage de **CPU utilisé** par chaque processus peut **varier** fortement dans le temps, mais la **mémoire (RAM)** reste normalement plus ou moins **stable**.
+
+Si vous avez une API qui effectue une quantité comparable de calculs à chaque fois et que vous avez beaucoup de clients, alors l'**utilisation du CPU** sera probablement *également stable* (au lieu de monter et descendre rapidement en permanence).
+
+### Exemples d’outils et de stratégies de réplication { #examples-of-replication-tools-and-strategies }
+
+Il peut y avoir plusieurs approches pour y parvenir, et je vous en dirai plus sur des stratégies spécifiques dans les prochains chapitres, par exemple en parlant de Docker et des conteneurs.
+
+La principale contrainte à considérer est qu'il doit y avoir un **seul** composant gérant le **port** sur l'**IP publique**. Et il doit ensuite avoir un moyen de **transmettre** la communication aux **processus/workers** répliqués.
+
+Voici quelques combinaisons et stratégies possibles :
+
+* **Uvicorn** avec `--workers`
+ * Un **gestionnaire de processus** Uvicorn écouterait sur l'**IP** et le **port**, et il démarrerait **plusieurs processus workers Uvicorn**.
+* **Kubernetes** et autres systèmes **de conteneurs** distribués
+ * Quelque chose dans la couche **Kubernetes** écouterait sur l'**IP** et le **port**. La réplication se ferait en ayant **plusieurs conteneurs**, chacun avec **un processus Uvicorn** en cours.
+* **Services cloud** qui s'en chargent pour vous
+ * Le service cloud **gérera probablement la réplication pour vous**. Il vous permettra éventuellement de définir **un processus à exécuter**, ou une **image de conteneur** à utiliser ; dans tous les cas, ce sera très probablement **un seul processus Uvicorn**, et le service cloud sera chargé de le répliquer.
+
+/// tip | Astuce
+
+Ne vous inquiétez pas si certains de ces éléments concernant les **conteneurs**, Docker ou Kubernetes ne sont pas encore très clairs.
+
+Je vous en dirai plus sur les images de conteneurs, Docker, Kubernetes, etc. dans un chapitre à venir : [FastAPI dans des conteneurs - Docker](docker.md){.internal-link target=_blank}.
+
+///
+
+## Étapes préalables avant de démarrer { #previous-steps-before-starting }
+
+Il existe de nombreux cas où vous souhaitez effectuer certaines étapes **avant de démarrer** votre application.
+
+Par exemple, vous pourriez vouloir exécuter des **migrations de base de données**.
+
+Mais dans la plupart des cas, vous voudrez effectuer ces étapes **une seule fois**.
+
+Vous voudrez donc avoir un **processus unique** pour effectuer ces **étapes préalables**, avant de démarrer l'application.
+
+Et vous devez vous assurer que c'est un processus unique qui exécute ces étapes préalables *même si*, ensuite, vous démarrez **plusieurs processus** (plusieurs workers) pour l'application elle‑même. Si ces étapes étaient exécutées par **plusieurs processus**, ils **dupliqueraient** le travail en l'exécutant **en parallèle**, et si les étapes étaient délicates comme une migration de base de données, elles pourraient entrer en conflit les unes avec les autres.
+
+Bien sûr, il y a des cas où il n'y a aucun problème à exécuter les étapes préalables plusieurs fois ; dans ce cas, c'est beaucoup plus simple à gérer.
+
+/// tip | Astuce
+
+Gardez aussi à l'esprit que selon votre configuration, dans certains cas vous **n'aurez peut‑être même pas besoin d'étapes préalables** avant de démarrer votre application.
+
+Dans ce cas, vous n'auriez pas à vous soucier de tout cela. 🤷
+
+///
+
+### Exemples de stratégies pour les étapes préalables { #examples-of-previous-steps-strategies }
+
+Cela **dépendra fortement** de la manière dont vous **déployez votre système**, et sera probablement lié à votre manière de démarrer les programmes, de gérer les redémarrages, etc.
+
+Voici quelques idées possibles :
+
+* Un « Init Container » dans Kubernetes qui s'exécute avant votre conteneur d'application
+* Un script bash qui exécute les étapes préalables puis démarre votre application
+ * Vous aurez toujours besoin d'un moyen de démarrer/redémarrer *ce* script bash, de détecter les erreurs, etc.
+
+/// tip | Astuce
+
+Je vous donnerai des exemples plus concrets pour faire cela avec des conteneurs dans un chapitre à venir : [FastAPI dans des conteneurs - Docker](docker.md){.internal-link target=_blank}.
+
+///
+
+## Utilisation des ressources { #resource-utilization }
+
+Votre ou vos serveurs constituent une **ressource** que vos programmes peuvent consommer ou **utiliser** : le temps de calcul des CPU et la mémoire RAM disponible.
+
+Quelle quantité des ressources système voulez‑vous consommer/utiliser ? Il peut être facile de penser « pas beaucoup », mais en réalité, vous voudrez probablement consommer **le plus possible sans planter**.
+
+Si vous payez pour 3 serveurs mais que vous n'utilisez qu'un petit peu de leur RAM et CPU, vous **gaspillez probablement de l'argent** 💸, et **gaspillez probablement l'électricité des serveurs** 🌎, etc.
+
+Dans ce cas, il pourrait être préférable de n'avoir que 2 serveurs et d'utiliser un pourcentage plus élevé de leurs ressources (CPU, mémoire, disque, bande passante réseau, etc.).
+
+À l'inverse, si vous avez 2 serveurs et que vous utilisez **100 % de leur CPU et de leur RAM**, à un moment donné un processus demandera plus de mémoire, et le serveur devra utiliser le disque comme « mémoire » (ce qui peut être des milliers de fois plus lent), voire **planter**. Ou un processus pourrait avoir besoin de faire un calcul et devrait attendre que le CPU soit à nouveau libre.
+
+Dans ce cas, il serait préférable d'obtenir **un serveur supplémentaire** et d'y exécuter certains processus afin qu'ils aient tous **suffisamment de RAM et de temps CPU**.
+
+Il est également possible que, pour une raison quelconque, vous ayez un **pic** d'utilisation de votre API. Peut‑être qu'elle devient virale, ou peut‑être que d'autres services ou bots commencent à l'utiliser. Et vous voudrez peut‑être disposer de ressources supplémentaires pour être en sécurité dans ces cas.
+
+Vous pouvez définir un **chiffre arbitraire** comme cible, par exemple **entre 50 % et 90 %** d'utilisation des ressources. L'idée est que ce sont probablement les principaux éléments que vous voudrez mesurer et utiliser pour ajuster vos déploiements.
+
+Vous pouvez utiliser des outils simples comme `htop` pour voir le CPU et la RAM utilisés sur votre serveur ou la quantité utilisée par chaque processus. Ou vous pouvez utiliser des outils de supervision plus complexes, éventuellement distribués sur plusieurs serveurs, etc.
+
+## Récapitulatif { #recap }
+
+Vous venez de lire ici certains des principaux concepts que vous devrez probablement garder à l'esprit lorsque vous décidez comment déployer votre application :
+
+* Sécurité - HTTPS
+* Exécuter au démarrage
+* Redémarrages
+* Réplication (le nombre de processus en cours d'exécution)
+* Mémoire
+* Étapes préalables avant de démarrer
+
+Comprendre ces idées et comment les appliquer devrait vous donner l'intuition nécessaire pour prendre toutes les décisions lors de la configuration et de l'ajustement de vos déploiements. 🤓
+
+Dans les sections suivantes, je vous donnerai des exemples plus concrets de stratégies possibles à suivre. 🚀
diff --git a/docs/fr/docs/deployment/docker.md b/docs/fr/docs/deployment/docker.md
index ec30f9607..2d86d4a40 100644
--- a/docs/fr/docs/deployment/docker.md
+++ b/docs/fr/docs/deployment/docker.md
@@ -14,7 +14,7 @@ Vous êtes pressé et vous connaissez déjà tout ça ? Allez directement au [`D
Aperçu du Dockerfile 👀
```Dockerfile
-FROM python:3.9
+FROM python:3.14
WORKDIR /code
@@ -166,7 +166,7 @@ Maintenant, dans le même répertoire de projet, créez un fichier `Dockerfile`
```{ .dockerfile .annotate }
# (1)!
-FROM python:3.9
+FROM python:3.14
# (2)!
WORKDIR /code
@@ -390,7 +390,7 @@ Si votre FastAPI est un seul fichier, par exemple `main.py` sans répertoire `./
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
+FROM python:3.14
WORKDIR /code
@@ -454,7 +454,7 @@ Sans utiliser de conteneurs, faire en sorte que les applications s'exécutent au
## Réplication - Nombre de processus { #replication-number-of-processes }
-Si vous avez un cluster 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.
+Si vous avez un cluster 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**.
@@ -499,7 +499,7 @@ Bien sûr, il existe des **cas particuliers** où vous pourriez vouloir avoir **
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
+FROM python:3.14
WORKDIR /code
diff --git a/docs/fr/docs/deployment/fastapicloud.md b/docs/fr/docs/deployment/fastapicloud.md
new file mode 100644
index 000000000..72f275cf6
--- /dev/null
+++ b/docs/fr/docs/deployment/fastapicloud.md
@@ -0,0 +1,65 @@
+# FastAPI Cloud { #fastapi-cloud }
+
+Vous pouvez déployer votre application FastAPI sur FastAPI Cloud avec une **seule commande**, allez vous inscrire sur la liste d’attente si ce n’est pas déjà fait. 🚀
+
+## Se connecter { #login }
+
+Vous devez vous assurer que vous avez déjà un compte **FastAPI Cloud** (nous vous avons invité depuis la liste d’attente 😉).
+
+Connectez-vous ensuite :
+
+
+
+```console
+$ fastapi login
+
+You are logged in to FastAPI Cloud 🚀
+```
+
+
+
+## Déployer { #deploy }
+
+Déployez maintenant votre application, avec une **seule commande** :
+
+
+
+```console
+$ fastapi deploy
+
+Deploying to FastAPI Cloud...
+
+✅ Deployment successful!
+
+🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
+```
+
+
+
+C’est tout ! Vous pouvez maintenant accéder à votre application à cette URL. ✨
+
+## À propos de FastAPI Cloud { #about-fastapi-cloud }
+
+**FastAPI Cloud** est développé par le même auteur et la même équipe à l’origine de **FastAPI**.
+
+Cela simplifie le processus de **création**, de **déploiement** et **d’accès** à une API avec un effort minimal.
+
+Cela apporte la même **expérience développeur** que pour créer des applications avec FastAPI au **déploiement** dans le cloud. 🎉
+
+Cela prend également en charge la plupart des éléments nécessaires lors du déploiement d’une application, notamment :
+
+* HTTPS
+* Réplication, avec mise à l’échelle automatique basée sur les requêtes
+* etc.
+
+FastAPI Cloud est le sponsor principal et le 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 déployer des applications FastAPI avec eux. 🤓
+
+## Déployer votre propre serveur { #deploy-your-own-server }
+
+Je vous expliquerai également plus loin dans ce guide de **Déploiement** tous les détails, afin que vous compreniez ce qui se passe, ce qui doit être fait, et comment déployer des applications FastAPI par vous-même, y compris sur vos propres serveurs. 🤓
diff --git a/docs/fr/docs/deployment/https.md b/docs/fr/docs/deployment/https.md
index 74d38cdb9..1b3c7be56 100644
--- a/docs/fr/docs/deployment/https.md
+++ b/docs/fr/docs/deployment/https.md
@@ -65,7 +65,7 @@ Voici un exemple de ce à quoi pourrait ressembler une API HTTPS, étape par ét
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** fixe.
+Vous obtiendriez probablement un serveur cloud (une machine virtuelle) ou quelque chose de similaire, et il aurait une adresse IP publique fixe.
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**.
diff --git a/docs/fr/docs/deployment/server-workers.md b/docs/fr/docs/deployment/server-workers.md
new file mode 100644
index 000000000..338a5003d
--- /dev/null
+++ b/docs/fr/docs/deployment/server-workers.md
@@ -0,0 +1,139 @@
+# Workers du serveur - Uvicorn avec workers { #server-workers-uvicorn-with-workers }
+
+Reprenons ces concepts de déploiement vus précédemment :
+
+* 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 avant le démarrage
+
+Jusqu'à présent, avec tous les tutoriels dans les documents, vous avez probablement exécuté un programme serveur, par exemple avec la commande `fastapi`, qui lance Uvicorn en exécutant un seul processus.
+
+Lors du déploiement d'applications, vous voudrez probablement avoir une réplication de processus pour tirer parti de plusieurs cœurs et pouvoir gérer davantage de requêtes.
+
+Comme vous l'avez vu dans le chapitre précédent sur les [Concepts de déploiement](concepts.md){.internal-link target=_blank}, il existe plusieurs stratégies possibles.
+
+Ici, je vais vous montrer comment utiliser Uvicorn avec des processus workers en utilisant la commande `fastapi` ou directement la commande `uvicorn`.
+
+/// info | Info
+
+Si vous utilisez des conteneurs, par exemple avec Docker ou Kubernetes, je vous en dirai plus à ce sujet dans le prochain chapitre : [FastAPI dans des conteneurs - Docker](docker.md){.internal-link target=_blank}.
+
+En particulier, lorsque vous exécutez sur Kubernetes, vous ne voudrez probablement pas utiliser de workers et plutôt exécuter un seul processus Uvicorn par conteneur, mais je vous en parlerai plus en détail dans ce chapitre.
+
+///
+
+## Utiliser plusieurs workers { #multiple-workers }
+
+Vous pouvez démarrer plusieurs workers avec l'option de ligne de commande `--workers` :
+
+//// tab | `fastapi`
+
+Si vous utilisez la commande `fastapi` :
+
+
+
+```console
+$ fastapi run --workers 4 main.py
+
+ FastAPI Starting production server 🚀
+
+ Searching for package file structure from directories with
+ __init__.py files
+ Importing from /home/user/code/awesomeapp
+
+ module 🐍 main.py
+
+ code Importing the FastAPI app object from the module with the
+ following code:
+
+ from main import app
+
+ app Using import string: main:app
+
+ server Server started at http://0.0.0.0:8000
+ server Documentation at http://0.0.0.0:8000/docs
+
+ Logs:
+
+ INFO Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to
+ quit)
+ INFO Started parent process [27365]
+ INFO Started server process [27368]
+ INFO Started server process [27369]
+ INFO Started server process [27370]
+ INFO Started server process [27367]
+ INFO Waiting for application startup.
+ INFO Waiting for application startup.
+ INFO Waiting for application startup.
+ INFO Waiting for application startup.
+ INFO Application startup complete.
+ INFO Application startup complete.
+ INFO Application startup complete.
+ INFO Application startup complete.
+```
+
+
+
+////
+
+//// tab | `uvicorn`
+
+Si vous préférez utiliser directement la commande `uvicorn` :
+
+
+
+```console
+$ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
+INFO: Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)
+INFO: Started parent process [27365]
+INFO: Started server process [27368]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+INFO: Started server process [27369]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+INFO: Started server process [27370]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+INFO: Started server process [27367]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+```
+
+
+
+////
+
+La seule option nouvelle ici est `--workers` qui indique à Uvicorn de démarrer 4 processus workers.
+
+Vous pouvez aussi voir qu'il affiche le PID de chaque processus, `27365` pour le processus parent (c'est le gestionnaire de processus) et un pour chaque processus worker : `27368`, `27369`, `27370` et `27367`.
+
+## Concepts de déploiement { #deployment-concepts }
+
+Ici, vous avez vu comment utiliser plusieurs workers pour paralléliser l'exécution de l'application, tirer parti de plusieurs cœurs du CPU et être en mesure de servir davantage de requêtes.
+
+Dans la liste des concepts de déploiement ci-dessus, l'utilisation de workers aide principalement à la partie réplication, et un peu aux redémarrages, mais vous devez toujours vous occuper des autres :
+
+* 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 avant le démarrage
+
+## Conteneurs et Docker { #containers-and-docker }
+
+Dans le prochain chapitre sur [FastAPI dans des conteneurs - Docker](docker.md){.internal-link target=_blank}, j'expliquerai quelques stratégies que vous pourriez utiliser pour gérer les autres concepts de déploiement.
+
+Je vous montrerai comment créer votre propre image à partir de zéro pour exécuter un seul processus Uvicorn. C'est un processus simple et c'est probablement ce que vous voudrez faire lorsque vous utilisez un système distribué de gestion de conteneurs comme Kubernetes.
+
+## Récapitulatif { #recap }
+
+Vous pouvez utiliser plusieurs processus workers avec l'option CLI `--workers` des commandes `fastapi` ou `uvicorn` pour tirer parti des CPU multicœurs, et exécuter plusieurs processus en parallèle.
+
+Vous pourriez utiliser ces outils et idées si vous mettez en place votre propre système de déploiement tout en prenant vous-même en charge les autres concepts de déploiement.
+
+Consultez le prochain chapitre pour en savoir plus sur FastAPI avec des conteneurs (par exemple Docker et Kubernetes). Vous verrez que ces outils offrent aussi des moyens simples de résoudre les autres concepts de déploiement. ✨
diff --git a/docs/fr/docs/environment-variables.md b/docs/fr/docs/environment-variables.md
new file mode 100644
index 000000000..57479852a
--- /dev/null
+++ b/docs/fr/docs/environment-variables.md
@@ -0,0 +1,298 @@
+# Variables d'environnement { #environment-variables }
+
+/// tip | Astuce
+
+Si vous savez déjà ce que sont les « variables d'environnement » et comment les utiliser, vous pouvez passer cette section.
+
+///
+
+Une variable d'environnement (également appelée « env var ») est une variable qui vit en dehors du code Python, dans le système d'exploitation, et qui peut être lue par votre code Python (ou par d'autres programmes également).
+
+Les variables d'environnement peuvent être utiles pour gérer des **paramètres** d'application, dans le cadre de l'**installation** de Python, etc.
+
+## Créer et utiliser des variables d'environnement { #create-and-use-env-vars }
+
+Vous pouvez créer et utiliser des variables d'environnement dans le **shell (terminal)**, sans avoir besoin de Python :
+
+//// tab | Linux, macOS, Windows Bash
+
+
+
+```console
+// Vous pouvez créer une variable d'environnement MY_NAME avec
+$ export MY_NAME="Wade Wilson"
+
+// Vous pouvez ensuite l'utiliser avec d'autres programmes, par exemple
+$ echo "Hello $MY_NAME"
+
+Hello Wade Wilson
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+// Créer une variable d'environnement MY_NAME
+$ $Env:MY_NAME = "Wade Wilson"
+
+// L'utiliser avec d'autres programmes, par exemple
+$ echo "Hello $Env:MY_NAME"
+
+Hello Wade Wilson
+```
+
+
+
+////
+
+## Lire des variables d'environnement en Python { #read-env-vars-in-python }
+
+Vous pouvez également créer des variables d'environnement **en dehors** de Python, dans le terminal (ou par tout autre moyen), puis les **lire en Python**.
+
+Par exemple, vous pouvez avoir un fichier `main.py` contenant :
+
+```Python hl_lines="3"
+import os
+
+name = os.getenv("MY_NAME", "World")
+print(f"Hello {name} from Python")
+```
+
+/// tip | Astuce
+
+Le deuxième argument de `os.getenv()` est la valeur par défaut à retourner.
+
+S'il n'est pas fourni, c'est `None` par défaut ; ici, nous fournissons `"World"` comme valeur par défaut à utiliser.
+
+///
+
+Vous pouvez ensuite exécuter ce programme Python :
+
+//// tab | Linux, macOS, Windows Bash
+
+
+
+```console
+// Ici, nous ne définissons pas encore la variable d'environnement
+$ python main.py
+
+// Comme nous ne l'avons pas définie, nous obtenons la valeur par défaut
+
+Hello World from Python
+
+// Mais si nous créons d'abord une variable d'environnement
+$ export MY_NAME="Wade Wilson"
+
+// Puis que nous relançons le programme
+$ python main.py
+
+// Il peut maintenant lire la variable d'environnement
+
+Hello Wade Wilson from Python
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+// Ici, nous ne définissons pas encore la variable d'environnement
+$ python main.py
+
+// Comme nous ne l'avons pas définie, nous obtenons la valeur par défaut
+
+Hello World from Python
+
+// Mais si nous créons d'abord une variable d'environnement
+$ $Env:MY_NAME = "Wade Wilson"
+
+// Puis que nous relançons le programme
+$ python main.py
+
+// Il peut maintenant lire la variable d'environnement
+
+Hello Wade Wilson from Python
+```
+
+
+
+////
+
+Comme les variables d'environnement peuvent être définies en dehors du code, mais lues par le code, et qu'elles n'ont pas besoin d'être stockées (validées dans `git`) avec le reste des fichiers, il est courant de les utiliser pour les configurations ou les **paramètres**.
+
+Vous pouvez également créer une variable d'environnement uniquement pour l'**invocation d'un programme spécifique**, qui ne sera disponible que pour ce programme et uniquement pendant sa durée d'exécution.
+
+Pour cela, créez-la juste avant le programme, sur la même ligne :
+
+
+
+```console
+// Créer en ligne une variable d'environnement MY_NAME pour cet appel de programme
+$ MY_NAME="Wade Wilson" python main.py
+
+// Il peut maintenant lire la variable d'environnement
+
+Hello Wade Wilson from Python
+
+// La variable d'environnement n'existe plus ensuite
+$ python main.py
+
+Hello World from Python
+```
+
+
+
+/// tip | Astuce
+
+Vous pouvez en lire davantage sur The Twelve-Factor App : Config.
+
+///
+
+## Gérer les types et la validation { #types-and-validation }
+
+Ces variables d'environnement ne peuvent gérer que des **chaînes de texte**, car elles sont externes à Python et doivent être compatibles avec les autres programmes et le reste du système (et même avec différents systèmes d'exploitation, comme Linux, Windows, macOS).
+
+Cela signifie que **toute valeur** lue en Python à partir d'une variable d'environnement **sera une `str`**, et que toute conversion vers un autre type ou toute validation doit être effectuée dans le code.
+
+Vous en apprendrez davantage sur l'utilisation des variables d'environnement pour gérer les **paramètres d'application** dans le [Guide utilisateur avancé - Paramètres et variables d'environnement](./advanced/settings.md){.internal-link target=_blank}.
+
+## Variable d'environnement `PATH` { #path-environment-variable }
+
+Il existe une **variable d'environnement spéciale** appelée **`PATH`** qui est utilisée par les systèmes d'exploitation (Linux, macOS, Windows) pour trouver les programmes à exécuter.
+
+La valeur de la variable `PATH` est une longue chaîne composée de répertoires séparés par deux-points `:` sous Linux et macOS, et par point-virgule `;` sous Windows.
+
+Par exemple, la variable d'environnement `PATH` peut ressembler à ceci :
+
+//// tab | Linux, macOS
+
+```plaintext
+/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
+```
+
+Cela signifie que le système doit rechercher les programmes dans les répertoires :
+
+* `/usr/local/bin`
+* `/usr/bin`
+* `/bin`
+* `/usr/sbin`
+* `/sbin`
+
+////
+
+//// tab | Windows
+
+```plaintext
+C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32
+```
+
+Cela signifie que le système doit rechercher les programmes dans les répertoires :
+
+* `C:\Program Files\Python312\Scripts`
+* `C:\Program Files\Python312`
+* `C:\Windows\System32`
+
+////
+
+Lorsque vous tapez une **commande** dans le terminal, le système d'exploitation **cherche** le programme dans **chacun de ces répertoires** listés dans la variable d'environnement `PATH`.
+
+Par exemple, lorsque vous tapez `python` dans le terminal, le système d'exploitation cherche un programme nommé `python` dans le **premier répertoire** de cette liste.
+
+S'il le trouve, alors il **l'utilise**. Sinon, il continue à chercher dans les **autres répertoires**.
+
+### Installer Python et mettre à jour `PATH` { #installing-python-and-updating-the-path }
+
+Lorsque vous installez Python, il est possible que l'on vous demande si vous souhaitez mettre à jour la variable d'environnement `PATH`.
+
+//// tab | Linux, macOS
+
+Supposons que vous installiez Python et qu'il se retrouve dans un répertoire `/opt/custompython/bin`.
+
+Si vous acceptez de mettre à jour la variable d'environnement `PATH`, l'installateur ajoutera `/opt/custompython/bin` à la variable d'environnement `PATH`.
+
+Cela pourrait ressembler à ceci :
+
+```plaintext
+/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin
+```
+
+Ainsi, lorsque vous tapez `python` dans le terminal, le système trouvera le programme Python dans `/opt/custompython/bin` (le dernier répertoire) et utilisera celui-là.
+
+////
+
+//// tab | Windows
+
+Supposons que vous installiez Python et qu'il se retrouve dans un répertoire `C:\opt\custompython\bin`.
+
+Si vous acceptez de mettre à jour la variable d'environnement `PATH`, l'installateur ajoutera `C:\opt\custompython\bin` à la variable d'environnement `PATH`.
+
+```plaintext
+C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin
+```
+
+Ainsi, lorsque vous tapez `python` dans le terminal, le système trouvera le programme Python dans `C:\opt\custompython\bin` (le dernier répertoire) et utilisera celui-là.
+
+////
+
+Ainsi, si vous tapez :
+
+
+
+```console
+$ python
+```
+
+
+
+//// tab | Linux, macOS
+
+Le système va **trouver** le programme `python` dans `/opt/custompython/bin` et l'exécuter.
+
+Cela reviendrait à peu près à taper :
+
+
+
+```console
+$ /opt/custompython/bin/python
+```
+
+
+
+////
+
+//// tab | Windows
+
+Le système va **trouver** le programme `python` dans `C:\opt\custompython\bin\python` et l'exécuter.
+
+Cela reviendrait à peu près à taper :
+
+
+
+```console
+$ C:\opt\custompython\bin\python
+```
+
+
+
+////
+
+Ces informations vous seront utiles lors de l'apprentissage des [Environnements virtuels](virtual-environments.md){.internal-link target=_blank}.
+
+## Conclusion { #conclusion }
+
+Avec cela, vous devriez avoir une compréhension de base de ce que sont les **variables d'environnement** et de la façon de les utiliser en Python.
+
+Vous pouvez également en lire davantage sur la page Wikipédia dédiée aux variables d'environnement.
+
+Dans de nombreux cas, il n'est pas évident de voir immédiatement en quoi les variables d'environnement seraient utiles et applicables. Mais elles réapparaissent dans de nombreux scénarios lorsque vous développez, il est donc bon de les connaître.
+
+Par exemple, vous aurez besoin de ces informations dans la section suivante, sur les [Environnements virtuels](virtual-environments.md).
diff --git a/docs/fr/docs/fastapi-cli.md b/docs/fr/docs/fastapi-cli.md
new file mode 100644
index 000000000..9f31e8a2f
--- /dev/null
+++ b/docs/fr/docs/fastapi-cli.md
@@ -0,0 +1,75 @@
+# FastAPI CLI { #fastapi-cli }
+
+**FastAPI CLI** est un programme en ligne de commande que vous pouvez utiliser pour servir votre application FastAPI, gérer votre projet FastAPI, et plus encore.
+
+Lorsque vous installez FastAPI (par exemple avec `pip install "fastapi[standard]"`), cela inclut un package appelé `fastapi-cli` ; ce package fournit la commande `fastapi` dans le terminal.
+
+Pour exécuter votre application FastAPI en développement, vous pouvez utiliser la commande `fastapi dev` :
+
+
+
+```console
+$ fastapi dev main.py
+
+ FastAPI Starting development server 🚀
+
+ Searching for package file structure from directories with
+ __init__.py files
+ Importing from /home/user/code/awesomeapp
+
+ module 🐍 main.py
+
+ code Importing the FastAPI app object from the module with the
+ following code:
+
+ from main import app
+
+ app Using import string: main:app
+
+ server Server started at http://127.0.0.1:8000
+ server Documentation at http://127.0.0.1:8000/docs
+
+ tip Running in development mode, for production use:
+ fastapi run
+
+ Logs:
+
+ 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 [383138] using WatchFiles
+ INFO Started server process [383153]
+ INFO Waiting for application startup.
+ INFO Application startup complete.
+```
+
+
+
+Le programme en ligne de commande nommé `fastapi` est **FastAPI CLI**.
+
+FastAPI CLI prend le chemin vers votre programme Python (par exemple `main.py`), détecte automatiquement l’instance `FastAPI` (généralement nommée `app`), détermine la procédure d’importation correcte, puis la sert.
+
+Pour la production, vous utiliserez plutôt `fastapi run`. 🚀
+
+En interne, **FastAPI CLI** utilise Uvicorn, un serveur ASGI haute performance, prêt pour la production. 😎
+
+## `fastapi dev` { #fastapi-dev }
+
+L’exécution de `fastapi dev` lance le mode développement.
+
+Par défaut, l’**auto-reload** est activé et recharge automatiquement le serveur lorsque vous modifiez votre code. Cela consomme des ressources et peut être moins stable que lorsqu’il est désactivé. Vous devez l’utiliser uniquement pour le développement. Il écoute aussi sur l’adresse IP `127.0.0.1`, qui est l’adresse IP permettant à votre machine de communiquer uniquement avec elle‑même (`localhost`).
+
+## `fastapi run` { #fastapi-run }
+
+Exécuter `fastapi run` démarre FastAPI en mode production par défaut.
+
+Par défaut, l’**auto-reload** est désactivé. Il écoute aussi sur l’adresse IP `0.0.0.0`, ce qui signifie toutes les adresses IP disponibles ; de cette manière, il sera accessible publiquement à toute personne pouvant communiquer avec la machine. C’est ainsi que vous l’exécutez normalement en production, par exemple dans un conteneur.
+
+Dans la plupart des cas, vous avez (et devez avoir) un « termination proxy » au‑dessus qui gère le HTTPS pour vous ; cela dépend de la façon dont vous déployez votre application : votre fournisseur peut le faire pour vous, ou vous devrez le configurer vous‑même.
+
+/// tip | Astuce
+
+Vous pouvez en savoir plus à ce sujet dans la [documentation de déploiement](deployment/index.md){.internal-link target=_blank}.
+
+///
diff --git a/docs/fr/docs/features.md b/docs/fr/docs/features.md
index bc63e11b4..e5e809940 100644
--- a/docs/fr/docs/features.md
+++ b/docs/fr/docs/features.md
@@ -1,43 +1,43 @@
-# Fonctionnalités
+# Fonctionnalités { #features }
-## Fonctionnalités de FastAPI
+## Fonctionnalités de FastAPI { #fastapi-features }
-**FastAPI** vous offre ceci:
+**FastAPI** vous offre les éléments suivants :
-### Basé sur des standards ouverts
+### Basé sur des standards ouverts { #based-on-open-standards }
-* OpenAPI pour la création d'API, incluant la déclaration de path operations, paramètres, corps de requêtes, sécurité, etc.
-* Documentation automatique des modèles de données avec JSON Schema (comme OpenAPI est aussi basée sur JSON Schema).
-* Conçue avec ces standards après une analyse méticuleuse. Plutôt qu'en rajoutant des surcouches après coup.
-* Cela permet d'utiliser de la **génération automatique de code client** dans beaucoup de langages.
+* OpenAPI pour la création d'API, incluant la déclaration de chemin opérations, paramètres, corps de requêtes, sécurité, etc.
+* Documentation automatique des modèles de données avec JSON Schema (puisque OpenAPI est lui-même basé sur JSON Schema).
+* Conçu autour de ces standards, après une étude méticuleuse. Plutôt qu'une couche ajoutée après coup.
+* Cela permet également d'utiliser la **génération automatique de code client** dans de nombreux langages.
-### Documentation automatique
+### Documentation automatique { #automatic-docs }
-Documentation d'API interactive et interface web d'exploration. Comme le framework est basé sur OpenAPI, de nombreuses options sont disponibles. Deux d'entre-elles sont incluses par défaut.
+Documentation d'API interactive et interfaces web d'exploration. Comme le framework est basé sur OpenAPI, plusieurs options existent, 2 incluses par défaut.
-* Swagger UI, propose une documentation interactive. Vous permet de directement tester l'API depuis votre navigateur.
+* Swagger UI, avec exploration interactive, appelez et testez votre API directement depuis le navigateur.

-* Une autre documentation d'API est fournie par ReDoc.
+* Documentation d'API alternative avec ReDoc.

-### Faite en python moderne
+### Uniquement du Python moderne { #just-modern-python }
-Tout est basé sur la déclaration de type standard de **Python 3.8** (grâce à Pydantic). Pas de nouvelles syntaxes à apprendre. Juste du Python standard et moderne.
+Tout est basé sur les déclarations de **types Python** standard (grâce à Pydantic). Aucune nouvelle syntaxe à apprendre. Juste du Python moderne standard.
-Si vous souhaitez un rappel de 2 minutes sur l'utilisation des types en Python (même si vous ne comptez pas utiliser FastAPI), jetez un oeil au tutoriel suivant: [Python Types](python-types.md){.internal-link target=_blank}.
+Si vous avez besoin d'un rappel de 2 minutes sur l'utilisation des types en Python (même si vous n'utilisez pas FastAPI), consultez le court tutoriel : [Types Python](python-types.md){.internal-link target=_blank}.
-Vous écrivez du python standard avec des annotations de types:
+Vous écrivez du Python standard avec des types :
```Python
from datetime import date
from pydantic import BaseModel
-# Déclare une variable comme étant une str
-# et profitez de l'aide de votre IDE dans cette fonction
+# Déclarez une variable comme étant une str
+# et profitez de l'aide de l'éditeur dans cette fonction
def main(user_id: str):
return user_id
@@ -48,7 +48,8 @@ class User(BaseModel):
name: str
joined: date
```
-Qui peuvent ensuite être utilisés comme cela:
+
+Qui peuvent ensuite être utilisés comme ceci :
```Python
my_user: User = User(id=3, name="John Doe", joined="2018-07-19")
@@ -64,138 +65,137 @@ my_second_user: User = User(**second_user_data)
/// info
-`**second_user_data` signifie:
+`**second_user_data` signifie :
-Utilise les clés et valeurs du dictionnaire `second_user_data` directement comme des arguments clé-valeur. C'est équivalent à: `User(id=4, name="Mary", joined="2018-11-30")`
+Passez les clés et valeurs du dictionnaire `second_user_data` directement comme arguments clé-valeur, équivalent à : `User(id=4, name="Mary", joined="2018-11-30")`
///
-### Support d'éditeurs
+### Support des éditeurs { #editor-support }
-Tout le framework a été conçu pour être facile et intuitif d'utilisation, toutes les décisions de design ont été testées sur de nombreux éditeurs avant même de commencer le développement final afin d'assurer la meilleure expérience de développement possible.
+Tout le framework a été conçu pour être facile et intuitif à utiliser, toutes les décisions ont été testées sur plusieurs éditeurs avant même de commencer le développement, pour assurer la meilleure expérience de développement.
-Dans le dernier sondage effectué auprès de développeurs python il était clair que la fonctionnalité la plus utilisée est "l’autocomplétion".
+Dans les enquêtes auprès des développeurs Python, il est clair que l’une des fonctionnalités les plus utilisées est « autocomplétion ».
-Tout le framework **FastAPI** a été conçu avec cela en tête. L'autocomplétion fonctionne partout.
+L'ensemble du framework **FastAPI** est conçu pour satisfaire cela. L'autocomplétion fonctionne partout.
-Vous devrez rarement revenir à la documentation.
+Vous aurez rarement besoin de revenir aux documents.
-Voici comment votre éditeur peut vous aider:
+Voici comment votre éditeur peut vous aider :
-* dans Visual Studio Code:
+* dans Visual Studio Code :

-* dans PyCharm:
+* dans PyCharm :

-Vous aurez des propositions de complétion que vous n'auriez jamais imaginées. Par exemple la clé `prix` dans le corps d'un document JSON (qui est peut-être imbriqué) venant d'une requête.
+Vous obtiendrez de l'autocomplétion dans du code que vous auriez pu considérer impossible auparavant. Par exemple, la clé `price` à l'intérieur d'un corps JSON (qui aurait pu être imbriqué) provenant d'une requête.
-Plus jamais vous ne vous tromperez en tapant le nom d'une clé, vous ne ferez des aller-retour entre votre code et la documentation ou vous ne scrollerez de haut en bas afin d'enfin savoir si vous devez taper `username` ou `user_name`.
+Fini de taper des noms de clés erronés, de faire des allers-retours entre les documents, ou de faire défiler vers le haut et vers le bas pour savoir si vous avez finalement utilisé `username` ou `user_name`.
-### Court
+### Court { #short }
-Des **valeurs par défaut** sont définies pour tout, des configurations optionnelles sont présentent partout. Tous ces paramètres peuvent être ajustés afin de faire ce que vous voulez et définir l'API dont vous avez besoin.
+Des **valeurs par défaut** sensées pour tout, avec des configurations optionnelles partout. Tous les paramètres peuvent être ajustés finement pour faire ce dont vous avez besoin et définir l'API dont vous avez besoin.
-Mais, **tout fonctionne** par défaut.
+Mais par défaut, tout **« just works »**.
-### Validation
+### Validation { #validation }
-* Validation pour la plupart (ou tous?) les **types de données** Python incluant:
+* Validation pour la plupart (ou tous ?) des **types de données** Python, y compris :
* objets JSON (`dict`).
- * listes JSON (`list`) définissant des types d'éléments.
- * Champs String (`str`), définition de longueur minimum ou maximale.
- * Nombres (`int`, `float`) avec valeur minimale and maximale, etc.
+ * tableaux JSON (`list`) définissant les types d'éléments.
+ * champs String (`str`), définition des longueurs minimale et maximale.
+ * nombres (`int`, `float`) avec valeurs minimale et maximale, etc.
-* Validation pour des types plus exotiques, tel que:
+* Validation pour des types plus exotiques, comme :
* URL.
* Email.
* UUID.
- * ...et autres.
+ * ... et autres.
-Toutes les validations sont gérées par le bien établi et robuste **Pydantic**.
+Toutes les validations sont gérées par le **Pydantic** bien établi et robuste.
-### Sécurité et authentification
+### Sécurité et authentification { #security-and-authentication }
-La sécurité et l'authentification sont intégrées. Sans aucun compromis avec les bases de données ou les modèles de données.
+Sécurité et authentification intégrées. Sans aucun compromis avec les bases de données ou les modèles de données.
-Tous les protocoles de sécurités sont définis dans OpenAPI, incluant:
+Tous les schémas de sécurité définis dans OpenAPI, y compris :
* HTTP Basic.
-* **OAuth2** (aussi avec **JWT tokens**). Jetez un oeil au tutoriel [OAuth2 avec JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}.
-* Clés d'API dans:
- * Le header.
- * Les paramètres de requêtes.
- * Les cookies, etc.
+* **OAuth2** (également avec des **tokens JWT**). Consultez le tutoriel [OAuth2 avec JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}.
+* Clés d'API dans :
+ * les en-têtes.
+ * les paramètres de requête.
+ * les cookies, etc.
-Plus toutes les fonctionnalités de sécurités venant de Starlette (incluant les **cookies de sessions**).
+Plus toutes les fonctionnalités de sécurité de Starlette (y compris les **cookies de session**).
-Le tout conçu en composant réutilisable facilement intégrable à vos systèmes, data stores, base de données relationnelle ou NoSQL, etc.
+Le tout construit comme des outils et composants réutilisables, faciles à intégrer à vos systèmes, magasins de données, bases de données relationnelles et NoSQL, etc.
-### Injection de dépendances
+### Injection de dépendances { #dependency-injection }
-FastAPI contient un système simple mais extrêmement puissant d'Injection de Dépendances.
+FastAPI inclut un système d’Injection de dépendances extrêmement simple à utiliser, mais extrêmement puissant.
-* Même les dépendances peuvent avoir des dépendances, créant une hiérarchie ou un **"graph" de dépendances**
-* Tout est **automatiquement géré** par le framework
-* Toutes les dépendances peuvent exiger des données d'une requêtes et **Augmenter les contraintes d'un path operation** et de la documentation automatique.
-* **Validation automatique** même pour les paramètres de *path operation* définis dans les dépendances.
-* Supporte les systèmes d'authentification d'utilisateurs complexes, les **connexions de base de données**, etc.
-* **Aucun compromis** avec les bases de données, les frontends, etc. Mais une intégration facile avec n'importe lequel d'entre eux.
+* Même les dépendances peuvent avoir des dépendances, créant une hiérarchie ou un **« graphe » de dépendances**.
+* Le tout **géré automatiquement** par le framework.
+* Toutes les dépendances peuvent exiger des données des requêtes et **augmenter les contraintes du chemin d'accès** ainsi que la documentation automatique.
+* **Validation automatique** même pour les paramètres de *chemin d'accès* définis dans les dépendances.
+* Prise en charge des systèmes d'authentification d'utilisateurs complexes, des **connexions de base de données**, etc.
+* **Aucun compromis** avec les bases de données, les frontends, etc. Mais une intégration facile avec tous.
-### "Plug-ins" illimités
+### « Plug-ins » illimités { #unlimited-plug-ins }
-Ou, en d'autres termes, pas besoin d'eux, importez le code que vous voulez et utilisez le.
+Ou, autrement dit, pas besoin d'eux, importez et utilisez le code dont vous avez besoin.
-Tout intégration est conçue pour être si simple à utiliser (avec des dépendances) que vous pouvez créer un "plug-in" pour votre application en deux lignes de code utilisant la même syntaxe que celle de vos *path operations*
+Toute intégration est conçue pour être si simple à utiliser (avec des dépendances) que vous pouvez créer un « plug-in » pour votre application en 2 lignes de code en utilisant la même structure et la même syntaxe que pour vos *chemins d'accès*.
-### Testé
+### Testé { #tested }
-* 100% de couverture de test.
-* 100% d'annotations de type dans le code.
-* Utilisé dans des applications mises en production.
+* 100 % de couverture de test.
+* 100 % de base de code annotée avec des types.
+* Utilisé dans des applications en production.
-## Fonctionnalités de Starlette
+## Fonctionnalités de Starlette { #starlette-features }
-**FastAPI** est complètement compatible (et basé sur) Starlette. Le code utilisant Starlette que vous ajouterez fonctionnera donc aussi.
+**FastAPI** est entièrement compatible avec (et basé sur) Starlette. Donc, tout code Starlette additionnel que vous avez fonctionnera aussi.
-En fait, `FastAPI` est un sous composant de `Starlette`. Donc, si vous savez déjà comment utiliser Starlette, la plupart des fonctionnalités fonctionneront de la même manière.
+`FastAPI` est en fait une sous-classe de `Starlette`. Ainsi, si vous connaissez ou utilisez déjà Starlette, la plupart des fonctionnalités fonctionneront de la même manière.
-Avec **FastAPI** vous aurez toutes les fonctionnalités de **Starlette** (FastAPI est juste Starlette sous stéroïdes):
+Avec **FastAPI** vous obtenez toutes les fonctionnalités de **Starlette** (puisque FastAPI est juste Starlette sous stéroïdes) :
-* Des performances vraiment impressionnantes. C'est l'un des framework Python les plus rapide, à égalité avec **NodeJS** et **GO**.
-* Le support des **WebSockets**.
-* Le support de **GraphQL**.
-* Les tâches d'arrière-plan.
-* Des évènements de démarrages et d'arrêt.
-* Un client de test basé sur `request`
-* **CORS**, GZip, Static Files, Streaming responses.
-* Le support des **Sessions et Cookies**.
-* Une couverture de test à 100 %.
-* 100 % de la base de code avec des annotations de type.
+* Des performances vraiment impressionnantes. C'est l’un des frameworks Python les plus rapides disponibles, à l’égal de **NodeJS** et **Go**.
+* Prise en charge des **WebSocket**.
+* Tâches d'arrière-plan dans le processus.
+* Évènements de démarrage et d'arrêt.
+* Client de test basé sur HTTPX.
+* **CORS**, GZip, fichiers statiques, réponses en streaming.
+* Prise en charge des **Sessions et Cookies**.
+* Couverture de test à 100 %.
+* Base de code annotée à 100 % avec des types.
-## Fonctionnalités de Pydantic
+## Fonctionnalités de Pydantic { #pydantic-features }
-**FastAPI** est totalement compatible avec (et basé sur) Pydantic. Le code utilisant Pydantic que vous ajouterez fonctionnera donc aussi.
+**FastAPI** est entièrement compatible avec (et basé sur) Pydantic. Donc, tout code Pydantic additionnel que vous avez fonctionnera aussi.
-Inclus des librairies externes basées, aussi, sur Pydantic, servent d'ORMs, ODMs pour les bases de données.
+Y compris des bibliothèques externes également basées sur Pydantic, servant d’ORM, d’ODM pour les bases de données.
-Cela signifie aussi que, dans la plupart des cas, vous pouvez fournir l'objet reçu d'une requête **directement à la base de données**, comme tout est validé automatiquement.
+Cela signifie également que, dans de nombreux cas, vous pouvez passer l'objet que vous recevez d'une requête **directement à la base de données**, puisque tout est validé automatiquement.
-Inversement, dans la plupart des cas vous pourrez juste envoyer l'objet récupéré de la base de données **directement au client**
+L’inverse est également vrai, dans de nombreux cas, vous pouvez simplement passer l'objet que vous récupérez de la base de données **directement au client**.
-Avec **FastAPI** vous aurez toutes les fonctionnalités de **Pydantic** (comme FastAPI est basé sur Pydantic pour toutes les manipulations de données):
+Avec **FastAPI** vous obtenez toutes les fonctionnalités de **Pydantic** (puisque FastAPI est basé sur Pydantic pour toute la gestion des données) :
-* **Pas de prise de tête**:
- * Pas de nouveau langage de définition de schéma à apprendre.
- * Si vous connaissez le typage en python vous savez comment utiliser Pydantic.
-* Aide votre **IDE/linter/cerveau**:
- * Parce que les structures de données de pydantic consistent seulement en une instance de classe que vous définissez; l'auto-complétion, le linting, mypy et votre intuition devrait être largement suffisante pour valider vos données.
-* Valide les **structures complexes**:
- * Utilise les modèles hiérarchique de Pydantic, le `typage` Python pour les `Lists`, `Dict`, etc.
- * Et les validateurs permettent aux schémas de données complexes d'être clairement et facilement définis, validés et documentés sous forme d'un schéma JSON.
- * Vous pouvez avoir des objets **JSON fortement imbriqués** tout en ayant, pour chacun, de la validation et des annotations.
-* **Renouvelable**:
- * Pydantic permet de définir de nouveaux types de données ou vous pouvez étendre la validation avec des méthodes sur un modèle décoré avec le décorateur de validation
-* 100% de couverture de test.
+* **Pas de prise de tête** :
+ * Pas de micro-langage de définition de schéma à apprendre.
+ * Si vous connaissez les types Python vous savez utiliser Pydantic.
+* Fonctionne bien avec votre **IDE/linter/cerveau** :
+ * Parce que les structures de données de Pydantic sont simplement des instances de classes que vous définissez ; l'autocomplétion, le linting, mypy et votre intuition devraient tous bien fonctionner avec vos données validées.
+* Valider des **structures complexes** :
+ * Utilisation de modèles Pydantic hiérarchiques, de `List` et `Dict` du `typing` Python, etc.
+ * Et les validateurs permettent de définir, vérifier et documenter clairement et facilement des schémas de données complexes en tant que JSON Schema.
+ * Vous pouvez avoir des objets **JSON fortement imbriqués** et les faire tous valider et annoter.
+* **Extensible** :
+ * Pydantic permet de définir des types de données personnalisés ou vous pouvez étendre la validation avec des méthodes sur un modèle décoré avec le décorateur de validation.
+* Couverture de test à 100 %.
diff --git a/docs/fr/docs/help-fastapi.md b/docs/fr/docs/help-fastapi.md
index 9b75f463b..08d9a7a72 100644
--- a/docs/fr/docs/help-fastapi.md
+++ b/docs/fr/docs/help-fastapi.md
@@ -1,103 +1,255 @@
-# Help FastAPI - Obtenir de l'aide
+# Aider FastAPI - Obtenir de l'aide { #help-fastapi-get-help }
Aimez-vous **FastAPI** ?
-Vous souhaitez aider FastAPI, les autres utilisateurs et l'auteur ?
+Souhaitez-vous aider FastAPI, les autres utilisateurs et l'auteur ?
-Ou souhaitez-vous obtenir de l'aide avec le **FastAPI** ?
+Ou souhaitez-vous obtenir de l'aide avec **FastAPI** ?
Il existe des moyens très simples d'aider (plusieurs ne nécessitent qu'un ou deux clics).
-Il existe également plusieurs façons d'obtenir de l'aide.
+Et il existe aussi plusieurs façons d'obtenir de l'aide.
-## Star **FastAPI** sur GitHub
+## S'abonner à la newsletter { #subscribe-to-the-newsletter }
-Vous pouvez "star" FastAPI dans GitHub (en cliquant sur le bouton étoile en haut à droite) : https://github.com/fastapi/fastapi. ⭐️
+Vous pouvez vous abonner à la (peu fréquente) [newsletter **FastAPI and friends**](newsletter.md){.internal-link target=_blank} pour rester informé à propos :
-En ajoutant une étoile, les autres utilisateurs pourront la trouver plus facilement et constater qu'elle a déjà été utile à d'autres.
+* Nouvelles sur FastAPI et ses amis 🚀
+* Guides 📝
+* Fonctionnalités ✨
+* Changements majeurs 🚨
+* Astuces et conseils ✅
-## Watch le dépôt GitHub pour les releases
+## Suivre FastAPI sur X (Twitter) { #follow-fastapi-on-x-twitter }
-Vous pouvez "watch" FastAPI dans GitHub (en cliquant sur le bouton "watch" en haut à droite) : https://github.com/fastapi/fastapi. 👀
+Suivez @fastapi sur **X (Twitter)** pour obtenir les dernières nouvelles sur **FastAPI**. 🐦
-Vous pouvez y sélectionner "Releases only".
+## Mettre une étoile à **FastAPI** sur GitHub { #star-fastapi-in-github }
-Ainsi, vous recevrez des notifications (dans votre courrier électronique) chaque fois qu'il y aura une nouvelle version de **FastAPI** avec des corrections de bugs et de nouvelles fonctionnalités.
+Vous pouvez « star » FastAPI sur GitHub (en cliquant sur le bouton étoile en haut à droite) : https://github.com/fastapi/fastapi. ⭐️
-## Se rapprocher de l'auteur
+En ajoutant une étoile, les autres utilisateurs pourront le trouver plus facilement et voir qu'il a déjà été utile à d'autres.
-Vous pouvez vous rapprocher de moi (Sebastián Ramírez / `tiangolo`), l'auteur.
+## Suivre le dépôt GitHub pour les releases { #watch-the-github-repository-for-releases }
-Vous pouvez :
+Vous pouvez « watch » FastAPI sur GitHub (en cliquant sur le bouton « watch » en haut à droite) : https://github.com/fastapi/fastapi. 👀
+
+Vous pouvez y sélectionner « Releases only ».
+
+Ainsi, vous recevrez des notifications (par e‑mail) chaque fois qu'il y aura une nouvelle release (une nouvelle version) de **FastAPI** avec des corrections de bugs et de nouvelles fonctionnalités.
+
+## Entrer en contact avec l'auteur { #connect-with-the-author }
+
+Vous pouvez entrer en contact avec moi (Sebastián Ramírez / `tiangolo`), l'auteur.
+
+Vous pouvez :
* Me suivre sur **GitHub**.
* Voir d'autres projets Open Source que j'ai créés et qui pourraient vous aider.
- * Suivez-moi pour voir quand je crée un nouveau projet Open Source.
-* Me suivre sur **X (Twitter)**.
- * Dites-moi comment vous utilisez FastAPI (j'adore entendre ça).
- * Entendre quand je fais des annonces ou que je lance de nouveaux outils.
-* Vous connectez à moi sur **LinkedIn**.
- * Etre notifié quand je fais des annonces ou que je lance de nouveaux outils (bien que j'utilise plus souvent X (Twitter) 🤷♂).
-* Lire ce que j’écris (ou me suivre) sur **Dev.to** ou **Medium**.
- * Lire d'autres idées, articles, et sur les outils que j'ai créés.
- * Suivez-moi pour lire quand je publie quelque chose de nouveau.
+ * Me suivre pour voir quand je crée un nouveau projet Open Source.
+* Me suivre sur **X (Twitter)** ou sur Mastodon.
+ * Me dire comment vous utilisez FastAPI (j'adore l'entendre).
+ * Être informé quand je fais des annonces ou publie de nouveaux outils.
+ * Vous pouvez aussi suivre @fastapi sur X (Twitter) (un compte séparé).
+* Me suivre sur **LinkedIn**.
+ * Être informé quand je fais des annonces ou publie de nouveaux outils (même si j'utilise plus souvent X (Twitter) 🤷♂).
+* Lire ce que j'écris (ou me suivre) sur **Dev.to** ou **Medium**.
+ * Lire d'autres idées, des articles, et découvrir des outils que j'ai créés.
+ * Me suivre pour lire quand je publie quelque chose de nouveau.
-## Tweeter sur **FastAPI**
+## Tweeter à propos de **FastAPI** { #tweet-about-fastapi }
-Tweetez à propos de **FastAPI** et faites-moi savoir, ainsi qu'aux autres, pourquoi vous aimez ça. 🎉
+Tweetez à propos de **FastAPI** et faites savoir à moi et aux autres pourquoi vous l'appréciez. 🎉
-J'aime entendre parler de l'utilisation du **FastAPI**, de ce que vous avez aimé dedans, dans quel projet/entreprise l'utilisez-vous, etc.
+J'adore entendre comment **FastAPI** est utilisé, ce que vous avez aimé, dans quel projet/quelle entreprise vous l'utilisez, etc.
-## Voter pour FastAPI
+## Voter pour FastAPI { #vote-for-fastapi }
* Votez pour **FastAPI** sur Slant.
-* Votez pour **FastAPI** sur AlternativeTo.
-* Votez pour **FastAPI** sur awesome-rest.
+* Votez pour **FastAPI** sur AlternativeTo.
+* Indiquez que vous utilisez **FastAPI** sur StackShare.
-## Aider les autres à résoudre les problèmes dans GitHub
+## Aider les autres avec des questions sur GitHub { #help-others-with-questions-in-github }
-Vous pouvez voir les problèmes existants et essayer d'aider les autres, la plupart du temps il s'agit de questions dont vous connaissez peut-être déjà la réponse. 🤓
+Vous pouvez essayer d'aider les autres avec leurs questions dans :
-## Watch le dépôt GitHub
+* GitHub Discussions
+* GitHub Issues
-Vous pouvez "watch" FastAPI dans GitHub (en cliquant sur le bouton "watch" en haut à droite) : https://github.com/fastapi/fastapi. 👀
+Dans de nombreux cas, vous connaissez peut-être déjà la réponse à ces questions. 🤓
-Si vous sélectionnez "Watching" au lieu de "Releases only", vous recevrez des notifications lorsque quelqu'un crée une nouvelle Issue.
+Si vous aidez beaucoup de personnes avec leurs questions, vous deviendrez un [Expert FastAPI](fastapi-people.md#fastapi-experts){.internal-link target=_blank} officiel. 🎉
-Vous pouvez alors essayer de les aider à résoudre ces problèmes.
+N'oubliez pas, le point le plus important est : essayez d'être aimable. Les gens viennent avec leurs frustrations et, dans bien des cas, ne posent pas la question de la meilleure façon, mais faites de votre mieux pour rester aimable. 🤗
-## Créer une Issue
+L'idée est que la communauté **FastAPI** soit bienveillante et accueillante. En même temps, n'acceptez pas l'intimidation ni les comportements irrespectueux envers les autres. Nous devons prendre soin les uns des autres.
-Vous pouvez créer une Issue dans le dépôt GitHub, par exemple pour :
+---
-* Poser une question ou s'informer sur un problème.
-* Suggérer une nouvelle fonctionnalité.
+Voici comment aider les autres avec des questions (dans les discussions ou les issues) :
-**Note** : si vous créez un problème, alors je vais vous demander d'aider aussi les autres. 😉
+### Comprendre la question { #understand-the-question }
-## Créer une Pull Request
+* Vérifiez si vous comprenez quel est l’**objectif** et le cas d'utilisation de la personne qui pose la question.
-Vous pouvez créer une Pull Request, par exemple :
+* Ensuite, vérifiez si la question (la grande majorité sont des questions) est **claire**.
-* Pour corriger une faute de frappe que vous avez trouvée sur la documentation.
+* Dans de nombreux cas, la question porte sur une solution imaginaire de l'utilisateur, mais il pourrait y en avoir une **meilleure**. Si vous comprenez mieux le problème et le cas d'utilisation, vous pourriez suggérer une **solution alternative** plus adaptée.
+
+* Si vous ne comprenez pas la question, demandez plus de **détails**.
+
+### Reproduire le problème { #reproduce-the-problem }
+
+Dans la plupart des cas et pour la plupart des questions, il y a quelque chose lié au **code original** de la personne.
+
+Dans de nombreux cas, elle ne copiera qu'un fragment de code, mais ce n'est pas suffisant pour **reproduire le problème**.
+
+* Vous pouvez leur demander de fournir un exemple minimal, complet et vérifiable, que vous pouvez **copier‑coller** et exécuter localement pour voir la même erreur ou le même comportement qu'ils observent, ou pour mieux comprendre leur cas d'utilisation.
+
+* Si vous vous sentez très généreux, vous pouvez essayer de **créer un tel exemple** vous‑même, simplement à partir de la description du problème. Gardez simplement à l'esprit que cela peut prendre beaucoup de temps et qu'il peut être préférable de leur demander d'abord de clarifier le problème.
+
+### Suggérer des solutions { #suggest-solutions }
+
+* Après avoir compris la question, vous pouvez leur donner une **réponse** possible.
+
+* Dans de nombreux cas, il est préférable de comprendre leur **problème sous‑jacent ou cas d'utilisation**, car il pourrait exister une meilleure façon de le résoudre que ce qu'ils essaient de faire.
+
+### Demander la clôture { #ask-to-close }
+
+S'ils répondent, il y a de fortes chances que vous ayez résolu leur problème, bravo, **vous êtes un héros** ! 🦸
+
+* Maintenant, si cela a résolu leur problème, vous pouvez leur demander de :
+
+ * Dans GitHub Discussions : marquer le commentaire comme **réponse**.
+ * Dans GitHub Issues : **fermer** l'issue.
+
+## Suivre le dépôt GitHub { #watch-the-github-repository }
+
+Vous pouvez « watch » FastAPI sur GitHub (en cliquant sur le bouton « watch » en haut à droite) : https://github.com/fastapi/fastapi. 👀
+
+Si vous sélectionnez « Watching » au lieu de « Releases only », vous recevrez des notifications lorsque quelqu'un crée une nouvelle issue ou question. Vous pouvez aussi préciser que vous ne souhaitez être notifié que pour les nouvelles issues, ou les discussions, ou les PR, etc.
+
+Vous pouvez alors essayer de les aider à résoudre ces questions.
+
+## Poser des questions { #ask-questions }
+
+Vous pouvez créer une nouvelle question dans le dépôt GitHub, par exemple pour :
+
+* Poser une **question** ou demander à propos d'un **problème**.
+* Suggérer une nouvelle **fonctionnalité**.
+
+**Remarque** : si vous le faites, je vais vous demander d'aider aussi les autres. 😉
+
+## Relire des Pull Requests { #review-pull-requests }
+
+Vous pouvez m'aider à relire les pull requests des autres.
+
+Encore une fois, essayez autant que possible d'être aimable. 🤗
+
+---
+
+Voici ce à garder à l'esprit et comment relire une pull request :
+
+### Comprendre le problème { #understand-the-problem }
+
+* D'abord, assurez‑vous de **comprendre le problème** que la pull request essaie de résoudre. Il peut y avoir une discussion plus longue dans une GitHub Discussion ou une issue.
+
+* Il y a aussi de bonnes chances que la pull request ne soit pas réellement nécessaire parce que le problème peut être résolu d'une **autre manière**. Vous pouvez alors le suggérer ou poser la question.
+
+### Ne pas s'inquiéter du style { #dont-worry-about-style }
+
+* Ne vous souciez pas trop des choses comme les styles de messages de commit, je ferai un squash and merge en personnalisant le commit manuellement.
+
+* Ne vous inquiétez pas non plus des règles de style, il existe déjà des outils automatisés qui vérifient cela.
+
+Et s'il y a d'autres besoins de style ou de cohérence, je le demanderai directement, ou j'ajouterai des commits par‑dessus avec les changements nécessaires.
+
+### Vérifier le code { #check-the-code }
+
+* Vérifiez et lisez le code, voyez s'il a du sens, **exécutez‑le localement** et voyez s'il résout effectivement le problème.
+
+* Ensuite, **commentez** en disant que vous l'avez fait, c'est ainsi que je saurai que vous l'avez vraiment vérifié.
+
+/// info
+
+Malheureusement, je ne peux pas simplement faire confiance aux PR qui ont juste plusieurs approbations.
+
+Plusieurs fois, il est arrivé qu'il y ait des PR avec 3, 5 ou plus approbations, probablement parce que la description est attrayante, mais lorsque je vérifie les PR, elles sont en fait cassées, ont un bug, ou ne résolvent pas le problème qu'elles prétendent résoudre. 😅
+
+Donc, il est vraiment important que vous lisiez et exécutiez le code, et que vous me le disiez dans les commentaires. 🤓
+
+///
+
+* Si la PR peut être simplifiée d'une certaine manière, vous pouvez le demander, mais il n'est pas nécessaire d'être trop pointilleux, il peut y avoir beaucoup de points de vue subjectifs (et j'aurai les miens aussi 🙈), donc il est préférable de vous concentrer sur les choses fondamentales.
+
+### Tests { #tests }
+
+* Aidez‑moi à vérifier que la PR a des **tests**.
+
+* Vérifiez que les tests **échouent** avant la PR. 🚨
+
+* Puis vérifiez que les tests **réussissent** après la PR. ✅
+
+* Beaucoup de PR n'ont pas de tests, vous pouvez leur **rappeler** d'ajouter des tests, ou même **suggérer** des tests vous‑même. C'est l'une des choses qui consomment le plus de temps et vous pouvez beaucoup aider.
+
+* Commentez aussi ce que vous avez essayé, ainsi je saurai que vous l'avez vérifié. 🤓
+
+## Créer une Pull Request { #create-a-pull-request }
+
+Vous pouvez [contribuer](contributing.md){.internal-link target=_blank} au code source avec des Pull Requests, par exemple :
+
+* Corriger une coquille que vous avez trouvée dans la documentation.
+* Partager un article, une vidéo ou un podcast que vous avez créé ou trouvé à propos de FastAPI en modifiant ce fichier.
+ * Vous devez vous assurer d'ajouter votre lien au début de la section correspondante.
+* Aider à [traduire la documentation](contributing.md#translations){.internal-link target=_blank} dans votre langue.
+ * Vous pouvez aussi aider à relire les traductions créées par d'autres.
* Proposer de nouvelles sections de documentation.
-* Pour corriger une Issue/Bug existant.
-* Pour ajouter une nouvelle fonctionnalité.
+* Corriger une issue/un bug existant.
+ * Vous devez ajouter des tests.
+* Ajouter une nouvelle fonctionnalité.
+ * Vous devez ajouter des tests.
+ * Vous devez ajouter de la documentation si c'est pertinent.
-## Parrainer l'auteur
+## Aider à maintenir FastAPI { #help-maintain-fastapi }
-Vous pouvez également soutenir financièrement l'auteur (moi) via GitHub sponsors.
+Aidez‑moi à maintenir **FastAPI** ! 🤓
-Là, vous pourriez m'offrir un café ☕️ pour me remercier 😄.
+Il y a beaucoup de travail à faire, et pour la plupart, **VOUS** pouvez le faire.
-## Sponsoriser les outils qui font fonctionner FastAPI
+Les principales tâches que vous pouvez faire dès maintenant sont :
-Comme vous l'avez vu dans la documentation, FastAPI se tient sur les épaules des géants, Starlette et Pydantic.
+* [Aider les autres avec des questions sur GitHub](#help-others-with-questions-in-github){.internal-link target=_blank} (voir la section ci‑dessus).
+* [Relire des Pull Requests](#review-pull-requests){.internal-link target=_blank} (voir la section ci‑dessus).
-Vous pouvez également parrainer :
+Ces deux tâches sont celles qui **consomment le plus de temps**. C'est le travail principal de la maintenance de FastAPI.
-* Samuel Colvin (Pydantic)
-* Encode (Starlette, Uvicorn)
+Si vous pouvez m'aider avec cela, **vous m'aidez à maintenir FastAPI** et à vous assurer qu'il continue **d'avancer plus vite et mieux**. 🚀
+
+## Rejoindre le chat { #join-the-chat }
+
+Rejoignez le 👥 serveur Discord 👥 et échangez avec d'autres membres de la communauté FastAPI.
+
+/// tip | Astuce
+
+Pour les questions, posez‑les dans GitHub Discussions, vous avez bien plus de chances de recevoir de l'aide par les [Experts FastAPI](fastapi-people.md#fastapi-experts){.internal-link target=_blank}.
+
+Utilisez le chat uniquement pour d'autres conversations générales.
+
+///
+
+### N'utilisez pas le chat pour les questions { #dont-use-the-chat-for-questions }
+
+Gardez à l'esprit que, comme les chats permettent une « conversation libre », il est facile de poser des questions trop générales et plus difficiles à répondre ; vous pourriez donc ne pas recevoir de réponses.
+
+Sur GitHub, le modèle vous guidera pour rédiger la bonne question afin que vous puissiez plus facilement obtenir une bonne réponse, ou même résoudre le problème vous‑même avant de demander. Et sur GitHub, je peux m'assurer de toujours tout répondre, même si cela prend du temps. Je ne peux pas personnellement faire cela avec les systèmes de chat. 😅
+
+Les conversations dans les systèmes de chat ne sont pas non plus aussi facilement recherchables que sur GitHub, donc les questions et réponses peuvent se perdre dans la conversation. Et seules celles sur GitHub comptent pour devenir un [Expert FastAPI](fastapi-people.md#fastapi-experts){.internal-link target=_blank}, vous aurez donc très probablement plus d'attention sur GitHub.
+
+D'un autre côté, il y a des milliers d'utilisateurs dans les systèmes de chat, il y a donc de fortes chances que vous trouviez presque toujours quelqu'un avec qui parler. 😄
+
+## Sponsoriser l'auteur { #sponsor-the-author }
+
+Si votre **produit/entreprise** dépend de **FastAPI** ou y est lié et que vous souhaitez atteindre ses utilisateurs, vous pouvez sponsoriser l'auteur (moi) via GitHub sponsors. Selon le niveau, vous pourriez obtenir des avantages supplémentaires, comme un badge dans la documentation. 🎁
---
diff --git a/docs/fr/docs/history-design-future.md b/docs/fr/docs/history-design-future.md
index 15be545ee..300f2e0f5 100644
--- a/docs/fr/docs/history-design-future.md
+++ b/docs/fr/docs/history-design-future.md
@@ -1,4 +1,4 @@
-# Histoire, conception et avenir
+# Histoire, conception et avenir { #history-design-and-future }
Il y a quelque temps, un utilisateur de **FastAPI** a demandé :
@@ -6,7 +6,7 @@ Il y a quelque temps,
@@ -28,7 +28,7 @@ Mais à un moment donné, il n'y avait pas d'autre option que de créer quelque
-## Recherche
+## Recherche { #investigation }
En utilisant toutes les alternatives précédentes, j'ai eu la chance d'apprendre de toutes, de prendre des idées, et de les combiner de la meilleure façon que j'ai pu trouver pour moi-même et les équipes de développeurs avec lesquelles j'ai travaillé.
@@ -38,9 +38,9 @@ De plus, la meilleure approche était d'utiliser des normes déjà existantes.
Ainsi, avant même de commencer à coder **FastAPI**, j'ai passé plusieurs mois à étudier les spécifications d'OpenAPI, JSON Schema, OAuth2, etc. Comprendre leurs relations, leurs similarités et leurs différences.
-## Conception
+## Conception { #design }
-Ensuite, j'ai passé du temps à concevoir l'"API" de développeur que je voulais avoir en tant qu'utilisateur (en tant que développeur utilisant FastAPI).
+Ensuite, j'ai passé du temps à concevoir l'« API » de développeur que je voulais avoir en tant qu'utilisateur (en tant que développeur utilisant FastAPI).
J'ai testé plusieurs idées dans les éditeurs Python les plus populaires : PyCharm, VS Code, les éditeurs basés sur Jedi.
@@ -48,11 +48,11 @@ D'après la dernière **Pydantic** pour ses avantages.
@@ -60,11 +60,11 @@ J'y ai ensuite contribué, pour le rendre entièrement compatible avec JSON Sche
Pendant le développement, j'ai également contribué à **Starlette**, l'autre exigence clé.
-## Développement
+## Développement { #development }
Au moment où j'ai commencé à créer **FastAPI** lui-même, la plupart des pièces étaient déjà en place, la conception était définie, les exigences et les outils étaient prêts, et la connaissance des normes et des spécifications était claire et fraîche.
-## Futur
+## Futur { #future }
À ce stade, il est déjà clair que **FastAPI** et ses idées sont utiles pour de nombreuses personnes.
@@ -76,4 +76,4 @@ Mais il y a encore de nombreuses améliorations et fonctionnalités à venir.
**FastAPI** a un grand avenir devant lui.
-Et [votre aide](help-fastapi.md){.internal-link target=\_blank} est grandement appréciée.
+Et [votre aide](help-fastapi.md){.internal-link target=_blank} est grandement appréciée.
diff --git a/docs/fr/docs/how-to/authentication-error-status-code.md b/docs/fr/docs/how-to/authentication-error-status-code.md
new file mode 100644
index 000000000..b8e87ee71
--- /dev/null
+++ b/docs/fr/docs/how-to/authentication-error-status-code.md
@@ -0,0 +1,17 @@
+# Utiliser les anciens codes d'erreur d'authentification 403 { #use-old-403-authentication-error-status-codes }
+
+Avant FastAPI version `0.122.0`, lorsque les utilitaires de sécurité intégrés renvoyaient une erreur au client après un échec d'authentification, ils utilisaient le code d'état HTTP `403 Forbidden`.
+
+À partir de FastAPI version `0.122.0`, ils utilisent le code d'état HTTP plus approprié `401 Unauthorized`, et renvoient un en-tête `WWW-Authenticate` pertinent dans la réponse, conformément aux spécifications HTTP, RFC 7235, RFC 9110.
+
+Mais si, pour une raison quelconque, vos clients dépendent de l'ancien comportement, vous pouvez y revenir en surchargeant la méthode `make_not_authenticated_error` dans vos classes de sécurité.
+
+Par exemple, vous pouvez créer une sous-classe de `HTTPBearer` qui renvoie une erreur `403 Forbidden` au lieu de l'erreur par défaut `401 Unauthorized` :
+
+{* ../../docs_src/authentication_error_status_code/tutorial001_an_py310.py hl[9:13] *}
+
+/// tip | Astuce
+
+Remarquez que la fonction renvoie l'instance de l'exception, elle ne la lève pas. La levée est effectuée dans le reste du code interne.
+
+///
diff --git a/docs/fr/docs/how-to/conditional-openapi.md b/docs/fr/docs/how-to/conditional-openapi.md
new file mode 100644
index 000000000..61aa187cc
--- /dev/null
+++ b/docs/fr/docs/how-to/conditional-openapi.md
@@ -0,0 +1,56 @@
+# Configurer OpenAPI de manière conditionnelle { #conditional-openapi }
+
+Si nécessaire, vous pouvez utiliser des paramètres et des variables d'environnement pour configurer OpenAPI de manière conditionnelle selon l'environnement, et même le désactiver complètement.
+
+## À propos de la sécurité, des API et de la documentation { #about-security-apis-and-docs }
+
+Masquer vos interfaces utilisateur de la documentation en production ne devrait pas être la manière de protéger votre API.
+
+Cela n'ajoute aucune sécurité supplémentaire à votre API, les *chemins d'accès* resteront disponibles là où ils se trouvent.
+
+S'il y a une faille de sécurité dans votre code, elle existera toujours.
+
+Masquer la documentation rend simplement plus difficile la compréhension de la manière d'interagir avec votre API et pourrait aussi rendre son débogage en production plus difficile. Cela pourrait être considéré simplement comme une forme de Sécurité par l'obscurité.
+
+Si vous voulez sécuriser votre API, il y a plusieurs meilleures approches possibles, par exemple :
+
+* Vous devez vous assurer d'avoir des modèles Pydantic bien définis pour le corps de la requête et la réponse.
+* Configurez toutes les autorisations et tous les rôles nécessaires à l'aide de dépendances.
+* Ne stockez jamais de mots de passe en clair, seulement des hachages de mots de passe.
+* Implémentez et utilisez des outils cryptographiques reconnus, comme pwdlib et des jetons JWT, ... etc.
+* Ajoutez des contrôles d'autorisation plus granulaires avec des scopes OAuth2 lorsque nécessaire.
+* ... etc.
+
+Néanmoins, vous pourriez avoir un cas d'utilisation très spécifique où vous devez vraiment désactiver la documentation de l'API pour un certain environnement (par exemple pour la production) ou selon des configurations provenant de variables d'environnement.
+
+## Configurer OpenAPI de manière conditionnelle avec des paramètres et des variables d'environnement { #conditional-openapi-from-settings-and-env-vars }
+
+Vous pouvez facilement utiliser les mêmes paramètres Pydantic pour configurer votre OpenAPI généré et les interfaces utilisateur de la documentation.
+
+Par exemple :
+
+{* ../../docs_src/conditional_openapi/tutorial001_py310.py hl[6,11] *}
+
+Ici nous déclarons le paramètre `openapi_url` avec la même valeur par défaut `"/openapi.json"`.
+
+Nous l'utilisons ensuite lors de la création de l'application `FastAPI`.
+
+Vous pouvez alors désactiver OpenAPI (y compris les interfaces utilisateur de la documentation) en définissant la variable d'environnement `OPENAPI_URL` sur la chaîne vide, comme ceci :
+
+
+
+```console
+$ OPENAPI_URL= uvicorn main:app
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+Ensuite, si vous allez aux URL `/openapi.json`, `/docs` ou `/redoc`, vous obtiendrez simplement une erreur `404 Not Found` comme :
+
+```JSON
+{
+ "detail": "Not Found"
+}
+```
diff --git a/docs/fr/docs/how-to/configure-swagger-ui.md b/docs/fr/docs/how-to/configure-swagger-ui.md
new file mode 100644
index 000000000..73d0f00e8
--- /dev/null
+++ b/docs/fr/docs/how-to/configure-swagger-ui.md
@@ -0,0 +1,70 @@
+# Configurer Swagger UI { #configure-swagger-ui }
+
+Vous pouvez configurer des paramètres supplémentaires de Swagger UI.
+
+Pour les configurer, passez l'argument `swagger_ui_parameters` lors de la création de l'objet d'application `FastAPI()` ou à la fonction `get_swagger_ui_html()`.
+
+`swagger_ui_parameters` reçoit un dictionnaire avec les configurations passées directement à Swagger UI.
+
+FastAPI convertit les configurations en **JSON** pour les rendre compatibles avec JavaScript, car c'est ce dont Swagger UI a besoin.
+
+## Désactiver la coloration syntaxique { #disable-syntax-highlighting }
+
+Par exemple, vous pourriez désactiver la coloration syntaxique dans Swagger UI.
+
+Sans modifier les paramètres, la coloration syntaxique est activée par défaut :
+
+
+
+Mais vous pouvez la désactiver en définissant `syntaxHighlight` à `False` :
+
+{* ../../docs_src/configure_swagger_ui/tutorial001_py310.py hl[3] *}
+
+... et ensuite Swagger UI n'affichera plus la coloration syntaxique :
+
+
+
+## Modifier le thème { #change-the-theme }
+
+De la même manière, vous pouvez définir le thème de la coloration syntaxique avec la clé « syntaxHighlight.theme » (remarquez le point au milieu) :
+
+{* ../../docs_src/configure_swagger_ui/tutorial002_py310.py hl[3] *}
+
+Cette configuration modifierait le thème de couleurs de la coloration syntaxique :
+
+
+
+## Modifier les paramètres Swagger UI par défaut { #change-default-swagger-ui-parameters }
+
+FastAPI inclut des paramètres de configuration par défaut adaptés à la plupart des cas d'utilisation.
+
+Il inclut ces configurations par défaut :
+
+{* ../../fastapi/openapi/docs.py ln[9:24] hl[18:24] *}
+
+Vous pouvez remplacer n'importe lequel d'entre eux en définissant une valeur différente dans l'argument `swagger_ui_parameters`.
+
+Par exemple, pour désactiver `deepLinking`, vous pourriez passer ces paramètres à `swagger_ui_parameters` :
+
+{* ../../docs_src/configure_swagger_ui/tutorial003_py310.py hl[3] *}
+
+## Autres paramètres de Swagger UI { #other-swagger-ui-parameters }
+
+Pour voir toutes les autres configurations possibles que vous pouvez utiliser, lisez la documentation officielle des paramètres de Swagger UI.
+
+## Paramètres JavaScript uniquement { #javascript-only-settings }
+
+Swagger UI permet également d'autres configurations qui sont des objets réservés à JavaScript (par exemple, des fonctions JavaScript).
+
+FastAPI inclut aussi ces paramètres `presets` réservés à JavaScript :
+
+```JavaScript
+presets: [
+ SwaggerUIBundle.presets.apis,
+ SwaggerUIBundle.SwaggerUIStandalonePreset
+]
+```
+
+Ce sont des objets **JavaScript**, pas des chaînes, vous ne pouvez donc pas les passer directement depuis du code Python.
+
+Si vous devez utiliser des configurations réservées à JavaScript comme celles-ci, vous pouvez utiliser l'une des méthodes ci-dessus. Surchargez entièrement le *chemin d'accès* Swagger UI et écrivez manuellement tout JavaScript nécessaire.
diff --git a/docs/fr/docs/how-to/custom-docs-ui-assets.md b/docs/fr/docs/how-to/custom-docs-ui-assets.md
new file mode 100644
index 000000000..d239a9696
--- /dev/null
+++ b/docs/fr/docs/how-to/custom-docs-ui-assets.md
@@ -0,0 +1,185 @@
+# Héberger en propre les ressources statiques de l’UI des docs personnalisées { #custom-docs-ui-static-assets-self-hosting }
+
+Les documents de l’API utilisent **Swagger UI** et **ReDoc**, et chacune nécessite des fichiers JavaScript et CSS.
+
+Par défaut, ces fichiers sont servis depuis un CDN.
+
+Mais il est possible de le personnaliser : vous pouvez définir un CDN spécifique, ou servir vous‑même les fichiers.
+
+## Configurer un CDN personnalisé pour JavaScript et CSS { #custom-cdn-for-javascript-and-css }
+
+Supposons que vous souhaitiez utiliser un autre CDN, par exemple vous voulez utiliser `https://unpkg.com/`.
+
+Cela peut être utile si, par exemple, vous vivez dans un pays qui restreint certaines URL.
+
+### Désactiver les docs automatiques { #disable-the-automatic-docs }
+
+La première étape consiste à désactiver les docs automatiques, car par défaut elles utilisent le CDN par défaut.
+
+Pour les désactiver, définissez leurs URL sur `None` lors de la création de votre application `FastAPI` :
+
+{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[8] *}
+
+### Inclure les docs personnalisées { #include-the-custom-docs }
+
+Vous pouvez maintenant créer les chemins d'accès pour les docs personnalisées.
+
+Vous pouvez réutiliser les fonctions internes de FastAPI pour créer les pages HTML de la documentation et leur passer les arguments nécessaires :
+
+- `openapi_url` : l’URL où la page HTML des docs peut récupérer le schéma OpenAPI de votre API. Vous pouvez utiliser ici l’attribut `app.openapi_url`.
+- `title` : le titre de votre API.
+- `oauth2_redirect_url` : vous pouvez utiliser `app.swagger_ui_oauth2_redirect_url` ici pour utiliser la valeur par défaut.
+- `swagger_js_url` : l’URL où la page HTML de Swagger UI peut récupérer le fichier **JavaScript**. C’est l’URL du CDN personnalisé.
+- `swagger_css_url` : l’URL où la page HTML de Swagger UI peut récupérer le fichier **CSS**. C’est l’URL du CDN personnalisé.
+
+Et de même pour ReDoc ...
+
+{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[2:6,11:19,22:24,27:33] *}
+
+/// tip | Astuce
+
+Le chemin d'accès pour `swagger_ui_redirect` est un assistant lorsque vous utilisez OAuth2.
+
+Si vous intégrez votre API à un fournisseur OAuth2, vous pourrez vous authentifier et revenir aux docs de l’API avec les identifiants acquis. Et interagir avec elle en utilisant la véritable authentification OAuth2.
+
+Swagger UI s’en chargera en arrière‑plan pour vous, mais il a besoin de cet assistant « redirect ».
+
+///
+
+### Créer un chemin d'accès pour tester { #create-a-path-operation-to-test-it }
+
+Maintenant, pour pouvoir vérifier que tout fonctionne, créez un chemin d'accès :
+
+{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[36:38] *}
+
+### Tester { #test-it }
+
+Vous devriez maintenant pouvoir aller à vos docs sur http://127.0.0.1:8000/docs, puis recharger la page : elle chargera ces ressources depuis le nouveau CDN.
+
+## Héberger en propre JavaScript et CSS pour les docs { #self-hosting-javascript-and-css-for-docs }
+
+Héberger vous‑même le JavaScript et le CSS peut être utile si, par exemple, votre application doit continuer de fonctionner même hors ligne, sans accès Internet ouvert, ou sur un réseau local.
+
+Vous verrez ici comment servir ces fichiers vous‑même, dans la même application FastAPI, et configurer les docs pour les utiliser.
+
+### Structure des fichiers du projet { #project-file-structure }
+
+Supposons que la structure de vos fichiers de projet ressemble à ceci :
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+```
+
+Créez maintenant un répertoire pour stocker ces fichiers statiques.
+
+Votre nouvelle structure de fichiers pourrait ressembler à ceci :
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+└── static/
+```
+
+### Télécharger les fichiers { #download-the-files }
+
+Téléchargez les fichiers statiques nécessaires aux docs et placez‑les dans ce répertoire `static/`.
+
+Vous pouvez probablement cliquer avec le bouton droit sur chaque lien et choisir une option similaire à « Enregistrer le lien sous ... ».
+
+**Swagger UI** utilise les fichiers :
+
+- `swagger-ui-bundle.js`
+- `swagger-ui.css`
+
+Et **ReDoc** utilise le fichier :
+
+- `redoc.standalone.js`
+
+Après cela, votre structure de fichiers pourrait ressembler à :
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+└── static
+ ├── redoc.standalone.js
+ ├── swagger-ui-bundle.js
+ └── swagger-ui.css
+```
+
+### Servir les fichiers statiques { #serve-the-static-files }
+
+- Importer `StaticFiles`.
+- « Monter » une instance `StaticFiles()` sur un chemin spécifique.
+
+{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[7,11] *}
+
+### Tester les fichiers statiques { #test-the-static-files }
+
+Démarrez votre application et rendez‑vous sur http://127.0.0.1:8000/static/redoc.standalone.js.
+
+Vous devriez voir un très long fichier JavaScript pour **ReDoc**.
+
+Il pourrait commencer par quelque chose comme :
+
+```JavaScript
+/*! For license information please see redoc.standalone.js.LICENSE.txt */
+!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("null")):
+...
+```
+
+Cela confirme que vous parvenez à servir des fichiers statiques depuis votre application et que vous avez placé les fichiers statiques des docs au bon endroit.
+
+Nous pouvons maintenant configurer l’application pour utiliser ces fichiers statiques pour les docs.
+
+### Désactiver les docs automatiques pour les fichiers statiques { #disable-the-automatic-docs-for-static-files }
+
+Comme lors de l’utilisation d’un CDN personnalisé, la première étape consiste à désactiver les docs automatiques, car elles utilisent un CDN par défaut.
+
+Pour les désactiver, définissez leurs URL sur `None` lors de la création de votre application `FastAPI` :
+
+{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[9] *}
+
+### Inclure les docs personnalisées pour les fichiers statiques { #include-the-custom-docs-for-static-files }
+
+Et comme avec un CDN personnalisé, vous pouvez maintenant créer les chemins d'accès pour les docs personnalisées.
+
+Là encore, vous pouvez réutiliser les fonctions internes de FastAPI pour créer les pages HTML de la documentation et leur passer les arguments nécessaires :
+
+- `openapi_url` : l’URL où la page HTML des docs peut récupérer le schéma OpenAPI de votre API. Vous pouvez utiliser ici l’attribut `app.openapi_url`.
+- `title` : le titre de votre API.
+- `oauth2_redirect_url` : vous pouvez utiliser `app.swagger_ui_oauth2_redirect_url` ici pour utiliser la valeur par défaut.
+- `swagger_js_url` : l’URL où la page HTML de Swagger UI peut récupérer le fichier **JavaScript**. **C’est celui que votre propre application sert désormais**.
+- `swagger_css_url` : l’URL où la page HTML de Swagger UI peut récupérer le fichier **CSS**. **C’est celui que votre propre application sert désormais**.
+
+Et de même pour ReDoc ...
+
+{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[2:6,14:22,25:27,30:36] *}
+
+/// tip | Astuce
+
+Le chemin d'accès pour `swagger_ui_redirect` est un assistant lorsque vous utilisez OAuth2.
+
+Si vous intégrez votre API à un fournisseur OAuth2, vous pourrez vous authentifier et revenir aux docs de l’API avec les identifiants acquis. Et interagir avec elle en utilisant la véritable authentification OAuth2.
+
+Swagger UI s’en chargera en arrière‑plan pour vous, mais il a besoin de cet assistant « redirect ».
+
+///
+
+### Créer un chemin d'accès pour tester les fichiers statiques { #create-a-path-operation-to-test-static-files }
+
+Maintenant, pour pouvoir vérifier que tout fonctionne, créez un chemin d'accès :
+
+{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[39:41] *}
+
+### Tester l’UI avec des fichiers statiques { #test-static-files-ui }
+
+Vous devriez maintenant pouvoir couper votre Wi‑Fi, aller à vos docs sur http://127.0.0.1:8000/docs et recharger la page.
+
+Et même sans Internet, vous pourrez voir la documentation de votre API et interagir avec elle.
diff --git a/docs/fr/docs/how-to/custom-request-and-route.md b/docs/fr/docs/how-to/custom-request-and-route.md
new file mode 100644
index 000000000..506187d9f
--- /dev/null
+++ b/docs/fr/docs/how-to/custom-request-and-route.md
@@ -0,0 +1,109 @@
+# Personnaliser les classes Request et APIRoute { #custom-request-and-apiroute-class }
+
+Dans certains cas, vous pouvez vouloir surcharger la logique utilisée par les classes `Request` et `APIRoute`.
+
+En particulier, cela peut être une bonne alternative à une logique dans un middleware.
+
+Par exemple, si vous voulez lire ou manipuler le corps de la requête avant qu'il ne soit traité par votre application.
+
+/// danger | Danger
+
+Ceci est une fonctionnalité « avancée ».
+
+Si vous débutez avec **FastAPI**, vous pouvez ignorer cette section.
+
+///
+
+## Cas d'utilisation { #use-cases }
+
+Voici quelques cas d'utilisation :
+
+* Convertir des corps de requête non JSON en JSON (par exemple `msgpack`).
+* Décompresser des corps de requête compressés en gzip.
+* Journaliser automatiquement tous les corps de requête.
+
+## Gérer les encodages personnalisés du corps de la requête { #handling-custom-request-body-encodings }
+
+Voyons comment utiliser une sous-classe personnalisée de `Request` pour décompresser des requêtes gzip.
+
+Et une sous-classe d'`APIRoute` pour utiliser cette classe de requête personnalisée.
+
+### Créer une classe `GzipRequest` personnalisée { #create-a-custom-gziprequest-class }
+
+/// tip | Astuce
+
+Il s'agit d'un exemple simplifié pour montrer le fonctionnement ; si vous avez besoin de la prise en charge de Gzip, vous pouvez utiliser le [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware){.internal-link target=_blank} fourni.
+
+///
+
+Commencez par créer une classe `GzipRequest`, qui va surcharger la méthode `Request.body()` pour décompresser le corps en présence d'un en-tête approprié.
+
+S'il n'y a pas `gzip` dans l'en-tête, elle n'essaiera pas de décompresser le corps.
+
+De cette manière, la même classe de route peut gérer des requêtes gzip compressées ou non compressées.
+
+{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[9:16] *}
+
+### Créer une classe `GzipRoute` personnalisée { #create-a-custom-gziproute-class }
+
+Ensuite, nous créons une sous-classe personnalisée de `fastapi.routing.APIRoute` qui utilisera `GzipRequest`.
+
+Cette fois, elle va surcharger la méthode `APIRoute.get_route_handler()`.
+
+Cette méthode renvoie une fonction. Et c'est cette fonction qui recevra une requête et retournera une réponse.
+
+Ici, nous l'utilisons pour créer une `GzipRequest` à partir de la requête originale.
+
+{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[19:27] *}
+
+/// note | Détails techniques
+
+Un `Request` possède un attribut `request.scope`, qui n'est qu'un `dict` Python contenant les métadonnées liées à la requête.
+
+Un `Request` a également un `request.receive`, qui est une fonction pour « recevoir » le corps de la requête.
+
+Le `dict` `scope` et la fonction `receive` font tous deux partie de la spécification ASGI.
+
+Et ces deux éléments, `scope` et `receive`, sont ce dont on a besoin pour créer une nouvelle instance de `Request`.
+
+Pour en savoir plus sur `Request`, consultez la documentation de Starlette sur les requêtes.
+
+///
+
+La seule chose que fait différemment la fonction renvoyée par `GzipRequest.get_route_handler`, c'est de convertir la `Request` en `GzipRequest`.
+
+Ce faisant, notre `GzipRequest` se chargera de décompresser les données (si nécessaire) avant de les transmettre à nos *chemins d'accès*.
+
+Après cela, toute la logique de traitement est identique.
+
+Mais grâce à nos modifications dans `GzipRequest.body`, le corps de la requête sera automatiquement décompressé lorsque **FastAPI** le chargera, si nécessaire.
+
+## Accéder au corps de la requête dans un gestionnaire d'exceptions { #accessing-the-request-body-in-an-exception-handler }
+
+/// tip | Astuce
+
+Pour résoudre ce même problème, il est probablement beaucoup plus simple d'utiliser `body` dans un gestionnaire personnalisé pour `RequestValidationError` ([Gérer les erreurs](../tutorial/handling-errors.md#use-the-requestvalidationerror-body){.internal-link target=_blank}).
+
+Mais cet exemple reste valable et montre comment interagir avec les composants internes.
+
+///
+
+Nous pouvons également utiliser cette même approche pour accéder au corps de la requête dans un gestionnaire d'exceptions.
+
+Il suffit de traiter la requête dans un bloc `try`/`except` :
+
+{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[14,16] *}
+
+Si une exception se produit, l'instance de `Request` sera toujours dans la portée, ce qui nous permet de lire et d'utiliser le corps de la requête lors du traitement de l'erreur :
+
+{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[17:19] *}
+
+## Utiliser une classe `APIRoute` personnalisée dans un routeur { #custom-apiroute-class-in-a-router }
+
+Vous pouvez également définir le paramètre `route_class` d'un `APIRouter` :
+
+{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[26] *}
+
+Dans cet exemple, les *chemins d'accès* sous le `router` utiliseront la classe personnalisée `TimedRoute`, et auront un en-tête supplémentaire `X-Response-Time` dans la réponse avec le temps nécessaire pour générer la réponse :
+
+{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[13:20] *}
diff --git a/docs/fr/docs/how-to/extending-openapi.md b/docs/fr/docs/how-to/extending-openapi.md
new file mode 100644
index 000000000..1c540ea6c
--- /dev/null
+++ b/docs/fr/docs/how-to/extending-openapi.md
@@ -0,0 +1,80 @@
+# Étendre OpenAPI { #extending-openapi }
+
+Il existe des cas où vous pouvez avoir besoin de modifier le schéma OpenAPI généré.
+
+Dans cette section, vous verrez comment faire.
+
+## Le processus normal { #the-normal-process }
+
+Le processus normal (par défaut) est le suivant.
+
+Une application (instance) `FastAPI` a une méthode `.openapi()` censée retourner le schéma OpenAPI.
+
+Lors de la création de l'objet application, un *chemin d'accès* pour `/openapi.json` (ou pour l'URL que vous avez définie dans votre `openapi_url`) est enregistré.
+
+Il renvoie simplement une réponse JSON avec le résultat de la méthode `.openapi()` de l'application.
+
+Par défaut, la méthode `.openapi()` vérifie la propriété `.openapi_schema` pour voir si elle contient des données et les renvoie.
+
+Sinon, elle les génère à l'aide de la fonction utilitaire `fastapi.openapi.utils.get_openapi`.
+
+Et cette fonction `get_openapi()` reçoit comme paramètres :
+
+* `title` : Le titre OpenAPI, affiché dans les documents.
+* `version` : La version de votre API, p. ex. `2.5.0`.
+* `openapi_version` : La version de la spécification OpenAPI utilisée. Par défaut, la plus récente : `3.1.0`.
+* `summary` : Un court résumé de l'API.
+* `description` : La description de votre API ; elle peut inclure du markdown et sera affichée dans la documentation.
+* `routes` : Une liste de routes ; chacune correspond à un *chemin d'accès* enregistré. Elles sont extraites de `app.routes`.
+
+/// info
+
+Le paramètre `summary` est disponible à partir d'OpenAPI 3.1.0, pris en charge par FastAPI 0.99.0 et versions ultérieures.
+
+///
+
+## Remplacer les valeurs par défaut { #overriding-the-defaults }
+
+En vous appuyant sur les informations ci-dessus, vous pouvez utiliser la même fonction utilitaire pour générer le schéma OpenAPI et remplacer chaque partie dont vous avez besoin.
+
+Par exemple, ajoutons l’extension OpenAPI de ReDoc pour inclure un logo personnalisé.
+
+### **FastAPI** normal { #normal-fastapi }
+
+Tout d’abord, écrivez votre application **FastAPI** comme d’habitude :
+
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[1,4,7:9] *}
+
+### Générer le schéma OpenAPI { #generate-the-openapi-schema }
+
+Ensuite, utilisez la même fonction utilitaire pour générer le schéma OpenAPI, dans une fonction `custom_openapi()` :
+
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[2,15:21] *}
+
+### Modifier le schéma OpenAPI { #modify-the-openapi-schema }
+
+Vous pouvez maintenant ajouter l’extension ReDoc, en ajoutant un `x-logo` personnalisé à l’« objet » `info` dans le schéma OpenAPI :
+
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[22:24] *}
+
+### Mettre en cache le schéma OpenAPI { #cache-the-openapi-schema }
+
+Vous pouvez utiliser la propriété `.openapi_schema` comme « cache » pour stocker votre schéma généré.
+
+Ainsi, votre application n’aura pas à générer le schéma à chaque fois qu’un utilisateur ouvre les documents de votre API.
+
+Il ne sera généré qu’une seule fois, puis le même schéma en cache sera utilisé pour les requêtes suivantes.
+
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[13:14,25:26] *}
+
+### Remplacer la méthode { #override-the-method }
+
+Vous pouvez maintenant remplacer la méthode `.openapi()` par votre nouvelle fonction.
+
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[29] *}
+
+### Vérifier { #check-it }
+
+Une fois que vous allez sur http://127.0.0.1:8000/redoc, vous verrez que vous utilisez votre logo personnalisé (dans cet exemple, le logo de **FastAPI**) :
+
+
diff --git a/docs/fr/docs/how-to/general.md b/docs/fr/docs/how-to/general.md
new file mode 100644
index 000000000..09d4498ac
--- /dev/null
+++ b/docs/fr/docs/how-to/general.md
@@ -0,0 +1,39 @@
+# Général - Guides pratiques - Recettes { #general-how-to-recipes }
+
+Voici plusieurs renvois vers d'autres endroits de la documentation, pour des questions générales ou fréquentes.
+
+## Filtrer des données - Sécurité { #filter-data-security }
+
+Pour vous assurer que vous ne renvoyez pas plus de données que nécessaire, lisez la documentation [Tutoriel - Modèle de réponse - Type de retour](../tutorial/response-model.md){.internal-link target=_blank}.
+
+## Étiquettes de documentation - OpenAPI { #documentation-tags-openapi }
+
+Pour ajouter des étiquettes à vos *chemins d'accès* et les regrouper dans l'interface utilisateur de la documentation, lisez la documentation [Tutoriel - Configurations de chemin d'accès - Tags](../tutorial/path-operation-configuration.md#tags){.internal-link target=_blank}.
+
+## Résumé et description de la documentation - OpenAPI { #documentation-summary-and-description-openapi }
+
+Pour ajouter un résumé et une description à vos *chemins d'accès* et les afficher dans l'interface utilisateur de la documentation, lisez la documentation [Tutoriel - Configurations de chemin d'accès - Résumé et description](../tutorial/path-operation-configuration.md#summary-and-description){.internal-link target=_blank}.
+
+## Description de la réponse dans la documentation - OpenAPI { #documentation-response-description-openapi }
+
+Pour définir la description de la réponse, affichée dans l'interface utilisateur de la documentation, lisez la documentation [Tutoriel - Configurations de chemin d'accès - Description de la réponse](../tutorial/path-operation-configuration.md#response-description){.internal-link target=_blank}.
+
+## Déprécier un *chemin d'accès* dans la documentation - OpenAPI { #documentation-deprecate-a-path-operation-openapi }
+
+Pour déprécier un *chemin d'accès* et l'indiquer dans l'interface utilisateur de la documentation, lisez la documentation [Tutoriel - Configurations de chemin d'accès - Déprécier un chemin d'accès](../tutorial/path-operation-configuration.md#deprecate-a-path-operation){.internal-link target=_blank}.
+
+## Convertir n'importe quelles données au format compatible JSON { #convert-any-data-to-json-compatible }
+
+Pour convertir des données vers un format compatible JSON, lisez la documentation [Tutoriel - Encodeur compatible JSON](../tutorial/encoder.md){.internal-link target=_blank}.
+
+## Métadonnées OpenAPI - Documentation { #openapi-metadata-docs }
+
+Pour ajouter des métadonnées à votre schéma OpenAPI, y compris une licence, une version, un contact, etc., lisez la documentation [Tutoriel - Métadonnées et URLs de la documentation](../tutorial/metadata.md){.internal-link target=_blank}.
+
+## URL OpenAPI personnalisée { #openapi-custom-url }
+
+Pour personnaliser l'URL OpenAPI (ou la supprimer), lisez la documentation [Tutoriel - Métadonnées et URLs de la documentation](../tutorial/metadata.md#openapi-url){.internal-link target=_blank}.
+
+## URL de la documentation OpenAPI { #openapi-docs-urls }
+
+Pour mettre à jour les URL utilisées pour les interfaces utilisateur de documentation générées automatiquement, lisez la documentation [Tutoriel - Métadonnées et URLs de la documentation](../tutorial/metadata.md#docs-urls){.internal-link target=_blank}.
diff --git a/docs/fr/docs/how-to/graphql.md b/docs/fr/docs/how-to/graphql.md
new file mode 100644
index 000000000..59cd1590f
--- /dev/null
+++ b/docs/fr/docs/how-to/graphql.md
@@ -0,0 +1,60 @@
+# GraphQL { #graphql }
+
+Comme **FastAPI** est basé sur la norme **ASGI**, il est très facile d'intégrer toute bibliothèque **GraphQL** également compatible avec ASGI.
+
+Vous pouvez combiner des *chemins d'accès* FastAPI classiques avec GraphQL dans la même application.
+
+/// tip | Astuce
+
+**GraphQL** résout des cas d'utilisation très spécifiques.
+
+Il présente des **avantages** et des **inconvénients** par rapport aux **API web** classiques.
+
+Assurez-vous d'évaluer si les **bénéfices** pour votre cas d'utilisation compensent les **inconvénients**. 🤓
+
+///
+
+## Bibliothèques GraphQL { #graphql-libraries }
+
+Voici quelques bibliothèques **GraphQL** qui prennent en charge **ASGI**. Vous pouvez les utiliser avec **FastAPI** :
+
+* Strawberry 🍓
+ * Avec la documentation pour FastAPI
+* Ariadne
+ * Avec la documentation pour FastAPI
+* Tartiflette
+ * Avec Tartiflette ASGI pour fournir l'intégration ASGI
+* Graphene
+ * Avec starlette-graphene3
+
+## GraphQL avec Strawberry { #graphql-with-strawberry }
+
+Si vous avez besoin ou souhaitez travailler avec **GraphQL**, **Strawberry** est la bibliothèque **recommandée** car sa conception est la plus proche de celle de **FastAPI**, tout est basé sur des **annotations de type**.
+
+Selon votre cas d'utilisation, vous pourriez préférer une autre bibliothèque, mais si vous me le demandiez, je vous suggérerais probablement d'essayer **Strawberry**.
+
+Voici un petit aperçu de la manière dont vous pouvez intégrer Strawberry avec FastAPI :
+
+{* ../../docs_src/graphql_/tutorial001_py310.py hl[3,22,25] *}
+
+Vous pouvez en apprendre davantage sur Strawberry dans la documentation de Strawberry.
+
+Et également la documentation sur Strawberry avec FastAPI.
+
+## Ancien `GraphQLApp` de Starlette { #older-graphqlapp-from-starlette }
+
+Les versions précédentes de Starlette incluaient une classe `GraphQLApp` pour s'intégrer à Graphene.
+
+Elle a été dépréciée dans Starlette, mais si vous avez du code qui l'utilisait, vous pouvez facilement **migrer** vers starlette-graphene3, qui couvre le même cas d'utilisation et propose une **interface presque identique**.
+
+/// tip | Astuce
+
+Si vous avez besoin de GraphQL, je vous recommande tout de même de regarder Strawberry, car il est basé sur des annotations de type plutôt que sur des classes et types personnalisés.
+
+///
+
+## En savoir plus { #learn-more }
+
+Vous pouvez en apprendre davantage sur **GraphQL** dans la documentation officielle de GraphQL.
+
+Vous pouvez également en lire davantage sur chacune des bibliothèques décrites ci-dessus via leurs liens.
diff --git a/docs/fr/docs/how-to/index.md b/docs/fr/docs/how-to/index.md
new file mode 100644
index 000000000..03736fa43
--- /dev/null
+++ b/docs/fr/docs/how-to/index.md
@@ -0,0 +1,13 @@
+# Comment faire - Recettes { #how-to-recipes }
+
+Vous trouverez ici différentes recettes ou des guides « comment faire » pour **plusieurs sujets**.
+
+La plupart de ces idées sont plus ou moins **indépendantes**, et dans la plupart des cas vous n'avez besoin de les étudier que si elles s'appliquent directement à **votre projet**.
+
+Si quelque chose vous paraît intéressant et utile pour votre projet, allez-y et consultez-le ; sinon, vous pouvez probablement simplement les ignorer.
+
+/// tip | Astuce
+
+Si vous voulez **apprendre FastAPI** de façon structurée (recommandé), allez lire le [Tutoriel - Guide utilisateur](../tutorial/index.md){.internal-link target=_blank} chapitre par chapitre à la place.
+
+///
diff --git a/docs/fr/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md b/docs/fr/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md
new file mode 100644
index 000000000..681cf697b
--- /dev/null
+++ b/docs/fr/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md
@@ -0,0 +1,135 @@
+# Migrer de Pydantic v1 à Pydantic v2 { #migrate-from-pydantic-v1-to-pydantic-v2 }
+
+Si vous avez une ancienne application FastAPI, vous utilisez peut-être Pydantic version 1.
+
+FastAPI version 0.100.0 prenait en charge soit Pydantic v1 soit v2. Il utilisait celle que vous aviez installée.
+
+FastAPI version 0.119.0 a introduit une prise en charge partielle de Pydantic v1 depuis l'intérieur de Pydantic v2 (comme `pydantic.v1`), pour faciliter la migration vers v2.
+
+FastAPI 0.126.0 a supprimé la prise en charge de Pydantic v1, tout en continuant à prendre en charge `pydantic.v1` pendant un certain temps.
+
+/// warning | Alertes
+
+L'équipe Pydantic a arrêté la prise en charge de Pydantic v1 pour les dernières versions de Python, à partir de Python 3.14.
+
+Cela inclut `pydantic.v1`, qui n'est plus pris en charge à partir de Python 3.14.
+
+Si vous souhaitez utiliser les dernières fonctionnalités de Python, vous devez vous assurer que vous utilisez Pydantic v2.
+
+///
+
+Si vous avez une ancienne application FastAPI avec Pydantic v1, je vais vous montrer comment la migrer vers Pydantic v2, et les fonctionnalités de FastAPI 0.119.0 pour vous aider à une migration progressive.
+
+## Guide officiel { #official-guide }
+
+Pydantic propose un Guide de migration officiel de la v1 à la v2.
+
+Il inclut aussi ce qui a changé, comment les validations sont désormais plus correctes et strictes, les pièges possibles, etc.
+
+Vous pouvez le lire pour mieux comprendre ce qui a changé.
+
+## Tests { #tests }
+
+Vous devez vous assurer d'avoir des [tests](../tutorial/testing.md){.internal-link target=_blank} pour votre application et de les exécuter en intégration continue (CI).
+
+De cette façon, vous pouvez effectuer la mise à niveau et vous assurer que tout fonctionne toujours comme prévu.
+
+## `bump-pydantic` { #bump-pydantic }
+
+Dans de nombreux cas, lorsque vous utilisez des modèles Pydantic classiques sans personnalisations, vous pourrez automatiser la majeure partie du processus de migration de Pydantic v1 à Pydantic v2.
+
+Vous pouvez utiliser `bump-pydantic` de la même équipe Pydantic.
+
+Cet outil vous aidera à modifier automatiquement la majeure partie du code à adapter.
+
+Après cela, vous pouvez exécuter les tests et vérifier que tout fonctionne. Si c'est le cas, vous avez terminé. 😎
+
+## Pydantic v1 dans v2 { #pydantic-v1-in-v2 }
+
+Pydantic v2 inclut tout Pydantic v1 sous la forme du sous-module `pydantic.v1`. Mais cela n'est plus pris en charge dans les versions au-delà de Python 3.13.
+
+Cela signifie que vous pouvez installer la dernière version de Pydantic v2 et importer/utiliser les anciens composants de Pydantic v1 depuis ce sous-module, comme si vous aviez l'ancien Pydantic v1 installé.
+
+{* ../../docs_src/pydantic_v1_in_v2/tutorial001_an_py310.py hl[1,4] *}
+
+### Prise en charge de FastAPI pour Pydantic v1 dans v2 { #fastapi-support-for-pydantic-v1-in-v2 }
+
+Depuis FastAPI 0.119.0, il existe également une prise en charge partielle de Pydantic v1 depuis l'intérieur de Pydantic v2, pour faciliter la migration vers v2.
+
+Vous pouvez donc mettre à niveau Pydantic vers la dernière version 2 et modifier les imports pour utiliser le sous-module `pydantic.v1`, et dans de nombreux cas cela fonctionnera tel quel.
+
+{* ../../docs_src/pydantic_v1_in_v2/tutorial002_an_py310.py hl[2,5,15] *}
+
+/// warning | Alertes
+
+Gardez à l'esprit que, puisque l'équipe Pydantic ne prend plus en charge Pydantic v1 dans les versions récentes de Python à partir de Python 3.14, l'utilisation de `pydantic.v1` n'est pas non plus prise en charge à partir de Python 3.14.
+
+///
+
+### Pydantic v1 et v2 dans la même application { #pydantic-v1-and-v2-on-the-same-app }
+
+Pydantic ne prend pas en charge le fait d'avoir un modèle Pydantic v2 contenant des champs eux-mêmes définis comme des modèles Pydantic v1, et inversement.
+
+```mermaid
+graph TB
+ subgraph "❌ Not Supported"
+ direction TB
+ subgraph V2["Pydantic v2 Model"]
+ V1Field["Pydantic v1 Model"]
+ end
+ subgraph V1["Pydantic v1 Model"]
+ V2Field["Pydantic v2 Model"]
+ end
+ end
+
+ style V2 fill:#f9fff3
+ style V1 fill:#fff6f0
+ style V1Field fill:#fff6f0
+ style V2Field fill:#f9fff3
+```
+
+... mais vous pouvez avoir des modèles séparés utilisant Pydantic v1 et v2 dans la même application.
+
+```mermaid
+graph TB
+ subgraph "✅ Supported"
+ direction TB
+ subgraph V2["Pydantic v2 Model"]
+ V2Field["Pydantic v2 Model"]
+ end
+ subgraph V1["Pydantic v1 Model"]
+ V1Field["Pydantic v1 Model"]
+ end
+ end
+
+ style V2 fill:#f9fff3
+ style V1 fill:#fff6f0
+ style V1Field fill:#fff6f0
+ style V2Field fill:#f9fff3
+```
+
+Dans certains cas, il est même possible d'avoir des modèles Pydantic v1 et v2 dans le même chemin d'accès de votre application FastAPI :
+
+{* ../../docs_src/pydantic_v1_in_v2/tutorial003_an_py310.py hl[2:3,6,12,21:22] *}
+
+Dans l'exemple ci-dessus, le modèle d'entrée est un modèle Pydantic v1 et le modèle de sortie (défini dans `response_model=ItemV2`) est un modèle Pydantic v2.
+
+### Paramètres Pydantic v1 { #pydantic-v1-parameters }
+
+Si vous devez utiliser certains des outils spécifiques à FastAPI pour les paramètres comme `Body`, `Query`, `Form`, etc., avec des modèles Pydantic v1, vous pouvez les importer depuis `fastapi.temp_pydantic_v1_params` le temps de terminer la migration vers Pydantic v2 :
+
+{* ../../docs_src/pydantic_v1_in_v2/tutorial004_an_py310.py hl[4,18] *}
+
+### Migrer par étapes { #migrate-in-steps }
+
+/// tip | Astuce
+
+Essayez d'abord avec `bump-pydantic` ; si vos tests passent et que cela fonctionne, vous avez tout terminé en une seule commande. ✨
+
+///
+
+Si `bump-pydantic` ne fonctionne pas pour votre cas d'usage, vous pouvez utiliser la prise en charge des modèles Pydantic v1 et v2 dans la même application pour effectuer la migration vers Pydantic v2 progressivement.
+
+Vous pouvez d'abord mettre à niveau Pydantic pour utiliser la dernière version 2 et modifier les imports pour utiliser `pydantic.v1` pour tous vos modèles.
+
+Ensuite, vous pouvez commencer à migrer vos modèles de Pydantic v1 vers v2 par groupes, par étapes progressives. 🚶
diff --git a/docs/fr/docs/how-to/separate-openapi-schemas.md b/docs/fr/docs/how-to/separate-openapi-schemas.md
new file mode 100644
index 000000000..fd767d738
--- /dev/null
+++ b/docs/fr/docs/how-to/separate-openapi-schemas.md
@@ -0,0 +1,102 @@
+# Séparer les schémas OpenAPI pour l'entrée et la sortie ou non { #separate-openapi-schemas-for-input-and-output-or-not }
+
+Depuis la sortie de **Pydantic v2**, l'OpenAPI généré est un peu plus précis et **correct** qu'avant. 😎
+
+En fait, dans certains cas, il y aura même **deux schémas JSON** dans OpenAPI pour le même modèle Pydantic, pour l'entrée et pour la sortie, selon s'ils ont des **valeurs par défaut**.
+
+Voyons comment cela fonctionne et comment le modifier si vous devez le faire.
+
+## Utiliser des modèles Pydantic pour l'entrée et la sortie { #pydantic-models-for-input-and-output }
+
+Supposons que vous ayez un modèle Pydantic avec des valeurs par défaut, comme celui‑ci :
+
+{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:7] hl[7] *}
+
+### Modèle pour l'entrée { #model-for-input }
+
+Si vous utilisez ce modèle en entrée comme ici :
+
+{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:15] hl[14] *}
+
+... alors, le champ `description` ne sera **pas requis**. Parce qu'il a une valeur par défaut de `None`.
+
+### Modèle d'entrée dans les documents { #input-model-in-docs }
+
+Vous pouvez le confirmer dans les documents, le champ `description` n'a pas d'**astérisque rouge**, il n'est pas indiqué comme requis :
+
+
+

+
+
+### Modèle pour la sortie { #model-for-output }
+
+Mais si vous utilisez le même modèle en sortie, comme ici :
+
+{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py hl[19] *}
+
+... alors, comme `description` a une valeur par défaut, si vous ne retournez rien pour ce champ, il aura tout de même cette **valeur par défaut**.
+
+### Modèle pour les données de réponse en sortie { #model-for-output-response-data }
+
+Si vous interagissez avec les documents et vérifiez la réponse, même si le code n'a rien ajouté dans l'un des champs `description`, la réponse JSON contient la valeur par défaut (`null`) :
+
+
+

+
+
+Cela signifie qu'il aura **toujours une valeur**, simplement, parfois la valeur pourra être `None` (ou `null` en JSON).
+
+Cela signifie que les clients utilisant votre API n'ont pas à vérifier si la valeur existe ou non, ils peuvent **supposer que le champ sera toujours présent**, mais que, dans certains cas, il aura la valeur par défaut `None`.
+
+La manière de décrire cela dans OpenAPI est de marquer ce champ comme **requis**, car il sera toujours présent.
+
+Pour cette raison, le schéma JSON d'un modèle peut être différent selon qu'il est utilisé pour **l'entrée ou la sortie** :
+
+- pour **l'entrée**, `description` ne sera **pas requis**
+- pour **la sortie**, il sera **requis** (et éventuellement `None`, ou en termes JSON, `null`)
+
+### Modèle de sortie dans les documents { #model-for-output-in-docs }
+
+Vous pouvez également vérifier le modèle de sortie dans les documents, **à la fois** `name` et `description` sont marqués comme **requis** avec un **astérisque rouge** :
+
+
+

+
+
+### Modèle pour l'entrée et la sortie dans les documents { #model-for-input-and-output-in-docs }
+
+Et si vous consultez tous les schémas disponibles (schémas JSON) dans OpenAPI, vous verrez qu'il y en a deux, un `Item-Input` et un `Item-Output`.
+
+Pour `Item-Input`, `description` n'est **pas requis**, il n'a pas d'astérisque rouge.
+
+Mais pour `Item-Output`, `description` est **requis**, il a un astérisque rouge.
+
+
+

+
+
+Avec cette fonctionnalité de **Pydantic v2**, la documentation de votre API est plus **précise**, et si vous avez des clients et SDKs générés automatiquement, ils seront eux aussi plus précis, avec une meilleure **expérience développeur** et davantage de cohérence. 🎉
+
+## Ne pas séparer les schémas { #do-not-separate-schemas }
+
+Il existe des cas où vous pourriez vouloir avoir le **même schéma pour l'entrée et la sortie**.
+
+Le cas d'usage principal est probablement que vous avez déjà du code client/SDKs générés automatiquement et que vous ne souhaitez pas encore mettre à jour tout ce code client/ces SDKs générés automatiquement ; vous le ferez sans doute à un moment donné, mais peut‑être pas tout de suite.
+
+Dans ce cas, vous pouvez désactiver cette fonctionnalité dans **FastAPI**, avec le paramètre `separate_input_output_schemas=False`.
+
+/// info | info
+
+La prise en charge de `separate_input_output_schemas` a été ajoutée dans FastAPI `0.102.0`. 🤓
+
+///
+
+{* ../../docs_src/separate_openapi_schemas/tutorial002_py310.py hl[10] *}
+
+### Utiliser le même schéma pour les modèles d'entrée et de sortie dans les documents { #same-schema-for-input-and-output-models-in-docs }
+
+Désormais, il n'y aura qu'un seul schéma pour l'entrée et la sortie du modèle, uniquement `Item`, et `description` ne sera pas requis :
+
+
+

+
diff --git a/docs/fr/docs/how-to/testing-database.md b/docs/fr/docs/how-to/testing-database.md
new file mode 100644
index 000000000..3179bc4c6
--- /dev/null
+++ b/docs/fr/docs/how-to/testing-database.md
@@ -0,0 +1,7 @@
+# Tester une base de données { #testing-a-database }
+
+Vous pouvez étudier les bases de données, SQL et SQLModel dans les documents SQLModel. 🤓
+
+Il existe un mini tutoriel sur l'utilisation de SQLModel avec FastAPI. ✨
+
+Ce tutoriel comprend une section sur les tests des bases de données SQL. 😎
diff --git a/docs/fr/docs/index.md b/docs/fr/docs/index.md
index 2aeaa1c69..bf4446b94 100644
--- a/docs/fr/docs/index.md
+++ b/docs/fr/docs/index.md
@@ -40,7 +40,7 @@ Les principales fonctionnalités sont :
* **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. Autocomplétion partout. Moins de temps passé à déboguer.
+* **Intuitif** : excellente compatibilité avec les éditeurs. Autocomplétion 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.
@@ -368,7 +368,7 @@ item: Item
* 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 JSON profondément imbriqués.
-* Conversion des données d'entrée : venant du réseau vers les données et types Python. Lecture depuis :
+* Conversion 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.
@@ -376,7 +376,7 @@ item: Item
* En-têtes.
* Formulaires.
* Fichiers.
-* Conversion des données de sortie : conversion des données et types Python en données réseau (au format JSON) :
+* Conversion 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`.
@@ -439,7 +439,7 @@ Pour un exemple plus complet comprenant plus de fonctionnalités, voir le d'injection de dépendances** très puissant et facile à utiliser.
+* Un système **d'injection de dépendances** 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 Strawberry et d'autres bibliothèques.
@@ -524,7 +524,7 @@ Utilisées par Starlette :
* httpx - Obligatoire si vous souhaitez utiliser le `TestClient`.
* jinja2 - Obligatoire si vous souhaitez utiliser la configuration de template par défaut.
-* python-multipart - Obligatoire si vous souhaitez prendre en charge l’« parsing » de formulaires avec `request.form()`.
+* python-multipart - Obligatoire si vous souhaitez prendre en charge l’« parsing » de formulaires avec `request.form()`.
Utilisées par FastAPI :
diff --git a/docs/fr/docs/learn/index.md b/docs/fr/docs/learn/index.md
index 552687703..e595ecf78 100644
--- a/docs/fr/docs/learn/index.md
+++ b/docs/fr/docs/learn/index.md
@@ -2,4 +2,4 @@
Voici les sections introductives et les tutoriels pour apprendre **FastAPI**.
-Vous pouvez considérer ceci comme un **livre**, un **cours**, la **méthode officielle** et recommandée pour apprendre FastAPI. 😎
+Vous pouvez considérer ceci comme un **livre**, un **cours**, la méthode **officielle** et recommandée pour apprendre FastAPI. 😎
diff --git a/docs/fr/docs/python-types.md b/docs/fr/docs/python-types.md
index f393b0f5c..770f1514a 100644
--- a/docs/fr/docs/python-types.md
+++ b/docs/fr/docs/python-types.md
@@ -1,8 +1,8 @@
# Introduction aux types Python { #python-types-intro }
-Python prend en charge des « type hints » (aussi appelées « annotations de type ») facultatives.
+Python prend en charge des « annotations de type » (aussi appelées « type hints ») facultatives.
-Ces « type hints » ou annotations sont une syntaxe spéciale qui permet de déclarer le type d'une variable.
+Ces **« annotations de type »** sont une syntaxe spéciale qui permet de déclarer le type d'une variable.
En déclarant les types de vos variables, les éditeurs et outils peuvent vous offrir un meilleur support.
@@ -22,7 +22,7 @@ Si vous êtes un expert Python, et que vous savez déjà tout sur les annotation
Commençons par un exemple simple :
-{* ../../docs_src/python_types/tutorial001_py39.py *}
+{* ../../docs_src/python_types/tutorial001_py310.py *}
Exécuter ce programme affiche :
@@ -34,9 +34,9 @@ La fonction fait ce qui suit :
* Prend un `first_name` et un `last_name`.
* Convertit la première lettre de chacun en majuscule avec `title()`.
-* Concatène ces deux valeurs avec un espace au milieu.
+* Concatène ces deux valeurs avec un espace au milieu.
-{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
+{* ../../docs_src/python_types/tutorial001_py310.py hl[2] *}
### Modifier le code { #edit-it }
@@ -78,7 +78,7 @@ C'est tout.
Ce sont les « annotations de type » :
-{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial002_py310.py hl[1] *}
Ce n'est pas la même chose que de déclarer des valeurs par défaut, ce qui serait :
@@ -106,7 +106,7 @@ Avec cela, vous pouvez faire défiler en voyant les options, jusqu'à trouver ce
Regardez cette fonction, elle a déjà des annotations de type :
-{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial003_py310.py hl[1] *}
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 :
@@ -114,7 +114,7 @@ Comme l'éditeur connaît les types des variables, vous n'obtenez pas seulement
Vous savez maintenant qu'il faut corriger, convertir `age` en chaîne avec `str(age)` :
-{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
+{* ../../docs_src/python_types/tutorial004_py310.py hl[2] *}
## Déclarer des types { #declaring-types }
@@ -133,29 +133,32 @@ Vous pouvez utiliser, par exemple :
* `bool`
* `bytes`
-{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial005_py310.py hl[1] *}
-### Types génériques avec paramètres de type { #generic-types-with-type-parameters }
+### Module `typing` { #typing-module }
-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 certains cas d'utilisation supplémentaires, vous pourriez avoir besoin d'importer certains éléments depuis le module standard `typing`, par exemple lorsque vous voulez déclarer que quelque chose a « n'importe quel type », vous pouvez utiliser `Any` depuis `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.
+```python
+from typing import Any
-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.
-#### Versions plus récentes de Python { #newer-versions-of-python }
+def some_function(data: Any):
+ print(data)
+```
-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.
+### Types génériques { #generic-types }
-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.
+Certains types peuvent prendre des « paramètres de type » entre crochets, pour définir leurs types internes, par exemple une « liste de chaînes » se déclarerait `list[str]`.
-Si vous pouvez choisir une version plus récente de Python pour votre projet, vous pourrez profiter de cette simplicité supplémentaire.
+Ces types qui peuvent prendre des paramètres de type sont appelés des **types génériques** ou **Generics**.
-Dans toute la documentation, il y a des exemples compatibles avec chaque version de Python (lorsqu'il y a une différence).
+Vous pouvez utiliser les mêmes types intégrés comme génériques (avec des crochets et des types à l'intérieur) :
-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).
-
-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+ ».
+* `list`
+* `tuple`
+* `set`
+* `dict`
#### Liste { #list }
@@ -167,9 +170,9 @@ 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] *}
+{* ../../docs_src/python_types/tutorial006_py310.py hl[1] *}
-/// info
+/// info | Info
Ces types internes entre crochets sont appelés « paramètres de type ».
@@ -193,7 +196,7 @@ Et pourtant, l'éditeur sait que c'est un `str` et fournit le support approprié
Vous feriez la même chose pour déclarer des `tuple` et des `set` :
-{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial007_py310.py hl[1] *}
Cela signifie :
@@ -208,7 +211,7 @@ 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] *}
+{* ../../docs_src/python_types/tutorial008_py310.py hl[1] *}
Cela signifie :
@@ -218,46 +221,22 @@ Cela signifie :
#### Union { #union }
-Vous pouvez déclarer qu'une variable peut être de plusieurs types, par exemple, un `int` ou un `str`.
+Vous pouvez déclarer qu'une variable peut être **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.
+Pour le définir, vous utilisez la barre verticale (`|`) pour séparer les deux types.
-Dans Python 3.10, il existe aussi une nouvelle syntaxe où vous pouvez mettre les types possibles séparés par une barre verticale (`|`).
-
-//// tab | Python 3.10+
+C'est ce qu'on appelle une « union », car la variable peut être n'importe quoi dans l'union de ces deux ensembles de types.
```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`.
+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"
@@ -266,96 +245,7 @@ Cela signifie aussi que dans Python 3.10, vous pouvez utiliser `Something | None
////
-//// 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.
-
-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.
-
-Par exemple, prenons cette fonction :
-
-{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *}
-
-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 :
-
-```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 🎉
-```
-
-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 :
-
-{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *}
-
-Et alors vous n'aurez plus à vous soucier de noms comme `Optional` et `Union`. 😎
-
-#### Types génériques { #generic-types }
-
-Ces types qui prennent des paramètres de type entre crochets sont appelés des **types génériques** ou **Generics**, par exemple :
-
-//// tab | Python 3.10+
-
-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.
-
-Dans Python 3.10, comme alternative à l'utilisation des génériques `Union` et `Optional`, vous pouvez utiliser la barre verticale (`|`) pour déclarer des unions de types, c'est bien mieux et plus simple.
-
-////
-
-//// 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.
-
-////
+Utiliser `str | None` 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`.
### Classes en tant que types { #classes-as-types }
@@ -363,19 +253,19 @@ Vous pouvez aussi déclarer une classe comme type d'une variable.
Disons que vous avez une classe `Person`, avec un nom :
-{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
+{* ../../docs_src/python_types/tutorial010_py310.py hl[1:3] *}
Vous pouvez ensuite déclarer une variable de type `Person` :
-{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
+{* ../../docs_src/python_types/tutorial010_py310.py hl[6] *}
Et là encore, vous obtenez tout le support de l'éditeur :
-Remarquez que cela signifie « `one_person` est une instance de la classe `Person` ».
+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` ».
+Cela ne signifie pas « `one_person` est la **classe** appelée `Person` ».
## Modèles Pydantic { #pydantic-models }
@@ -393,7 +283,7 @@ Un exemple tiré de la documentation officielle de Pydantic :
{* ../../docs_src/python_types/tutorial011_py310.py *}
-/// info
+/// info | Info
Pour en savoir plus à propos de Pydantic, consultez sa documentation.
@@ -403,33 +293,27 @@ Pour en savoir plus à propos de champs Optionals requis.
-
-///
-
## Annotations de type avec métadonnées { #type-hints-with-metadata-annotations }
-Python dispose également d'une fonctionnalité qui permet de mettre des **métadonnées supplémentaires** dans ces annotations de type en utilisant `Annotated`.
+Python dispose également d'une fonctionnalité qui permet de mettre des **métadonnées 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 pouvez importer `Annotated` depuis `typing`.
-{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *}
+{* ../../docs_src/python_types/tutorial013_py310.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.
+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.
+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. ✨
+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. 🚀
@@ -457,7 +341,7 @@ Tout cela peut sembler abstrait. Ne vous inquiétez pas. Vous verrez tout cela e
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
+/// info | Info
Si vous avez déjà parcouru tout le tutoriel et êtes revenu pour en voir plus sur les types, une bonne ressource est l'« aide-mémoire » de `mypy`.
diff --git a/docs/fr/docs/resources/index.md b/docs/fr/docs/resources/index.md
new file mode 100644
index 000000000..e62db346d
--- /dev/null
+++ b/docs/fr/docs/resources/index.md
@@ -0,0 +1,3 @@
+# Ressources { #resources }
+
+Ressources supplémentaires, liens externes et plus encore. ✈️
diff --git a/docs/fr/docs/translation-banner.md b/docs/fr/docs/translation-banner.md
new file mode 100644
index 000000000..9eaedf1b1
--- /dev/null
+++ b/docs/fr/docs/translation-banner.md
@@ -0,0 +1,11 @@
+/// details | 🌐 Traduction par IA et humains
+
+Cette traduction a été réalisée par une IA guidée par des humains. 🤝
+
+Elle peut contenir des erreurs d'interprétation du sens original, ou paraître peu naturelle, etc. 🤖
+
+Vous pouvez améliorer cette traduction en [nous aidant à mieux guider le LLM d'IA](https://fastapi.tiangolo.com/fr/contributing/#translations).
+
+[Version anglaise](ENGLISH_VERSION_URL)
+
+///
diff --git a/docs/fr/docs/tutorial/background-tasks.md b/docs/fr/docs/tutorial/background-tasks.md
index ed7494669..a8444ba27 100644
--- a/docs/fr/docs/tutorial/background-tasks.md
+++ b/docs/fr/docs/tutorial/background-tasks.md
@@ -15,12 +15,14 @@ Cela comprend, par exemple :
Pour commencer, importez `BackgroundTasks` et définissez un paramètre dans votre *fonction de chemin d'accès* avec `BackgroundTasks` comme type déclaré.
-{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *}
+{* ../../docs_src/background_tasks/tutorial001_py310.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 { #create-a-task-function }
+Créez une fonction à exécuter comme tâche d'arrière-plan.
+
Une fonction à exécuter comme tâche d'arrière-plan est juste une fonction standard qui peut recevoir des paramètres.
Elle peut être une fonction asynchrone (`async def`) ou une fonction normale (`def`), **FastAPI** saura la gérer correctement.
@@ -29,13 +31,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_py39.py hl[6:9] *}
+{* ../../docs_src/background_tasks/tutorial001_py310.py hl[6:9] *}
## 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_py39.py hl[14] *}
+{* ../../docs_src/background_tasks/tutorial001_py310.py hl[14] *}
`.add_task()` reçoit comme arguments :
diff --git a/docs/fr/docs/tutorial/bigger-applications.md b/docs/fr/docs/tutorial/bigger-applications.md
new file mode 100644
index 000000000..065962236
--- /dev/null
+++ b/docs/fr/docs/tutorial/bigger-applications.md
@@ -0,0 +1,504 @@
+# Créer des applications plus grandes - Plusieurs fichiers { #bigger-applications-multiple-files }
+
+Si vous créez une application ou une API web, il est rare que vous puissiez tout mettre dans un seul fichier.
+
+**FastAPI** fournit un outil pratique pour structurer votre application tout en conservant toute la flexibilité.
+
+/// info
+
+Si vous venez de Flask, cela équivaut aux Blueprints de Flask.
+
+///
+
+## Exemple de structure de fichiers { #an-example-file-structure }
+
+Supposons que vous ayez une structure de fichiers comme ceci :
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+│ ├── dependencies.py
+│ └── routers
+│ │ ├── __init__.py
+│ │ ├── items.py
+│ │ └── users.py
+│ └── internal
+│ ├── __init__.py
+│ └── admin.py
+```
+
+/// tip | Astuce
+
+Il y a plusieurs fichiers `__init__.py` : un dans chaque répertoire ou sous-répertoire.
+
+C'est cela qui permet d'importer du code d'un fichier dans un autre.
+
+Par exemple, dans `app/main.py` vous pourriez avoir une ligne comme :
+
+```
+from app.routers import items
+```
+
+///
+
+* Le répertoire `app` contient tout. Et il a un fichier vide `app/__init__.py`, c'est donc un « package Python » (une collection de « modules Python ») : `app`.
+* Il contient un fichier `app/main.py`. Comme il se trouve dans un package Python (un répertoire avec un fichier `__init__.py`), c'est un « module » de ce package : `app.main`.
+* Il y a aussi un fichier `app/dependencies.py`, tout comme `app/main.py`, c'est un « module » : `app.dependencies`.
+* Il y a un sous-répertoire `app/routers/` avec un autre fichier `__init__.py`, c'est donc un « sous-package Python » : `app.routers`.
+* Le fichier `app/routers/items.py` est dans un package, `app/routers/`, c'est donc un sous-module : `app.routers.items`.
+* De même pour `app/routers/users.py`, c'est un autre sous-module : `app.routers.users`.
+* Il y a aussi un sous-répertoire `app/internal/` avec un autre fichier `__init__.py`, c'est donc un autre « sous-package Python » : `app.internal`.
+* Et le fichier `app/internal/admin.py` est un autre sous-module : `app.internal.admin`.
+
+
+
+La même structure de fichiers avec des commentaires :
+
+```bash
+.
+├── app # "app" est un package Python
+│ ├── __init__.py # ce fichier fait de "app" un "package Python"
+│ ├── main.py # module "main", ex. import app.main
+│ ├── dependencies.py # module "dependencies", ex. import app.dependencies
+│ └── routers # "routers" est un "sous-package Python"
+│ │ ├── __init__.py # fait de "routers" un "sous-package Python"
+│ │ ├── items.py # sous-module "items", ex. import app.routers.items
+│ │ └── users.py # sous-module "users", ex. import app.routers.users
+│ └── internal # "internal" est un "sous-package Python"
+│ ├── __init__.py # fait de "internal" un "sous-package Python"
+│ └── admin.py # sous-module "admin", ex. import app.internal.admin
+```
+
+## `APIRouter` { #apirouter }
+
+Supposons que le fichier dédié à la gestion des utilisateurs soit le sous-module `/app/routers/users.py`.
+
+Vous voulez séparer les *chemins d'accès* liés à vos utilisateurs du reste du code pour le garder organisé.
+
+Mais cela fait toujours partie de la même application/API web **FastAPI** (cela fait partie du même « package Python »).
+
+Vous pouvez créer les *chemins d'accès* pour ce module à l'aide de `APIRouter`.
+
+### Importer `APIRouter` { #import-apirouter }
+
+Vous l'importez et créez une « instance » de la même manière que vous le feriez avec la classe `FastAPI` :
+
+{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[1,3] title["app/routers/users.py"] *}
+
+### Déclarer des *chemins d'accès* avec `APIRouter` { #path-operations-with-apirouter }
+
+Puis vous l'utilisez pour déclarer vos *chemins d'accès*.
+
+Utilisez-le de la même manière que vous utiliseriez la classe `FastAPI` :
+
+{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
+
+Vous pouvez considérer `APIRouter` comme une « mini `FastAPI` ».
+
+Toutes les mêmes options sont prises en charge.
+
+Tous les mêmes `parameters`, `responses`, `dependencies`, `tags`, etc.
+
+/// tip | Astuce
+
+Dans cet exemple, la variable s'appelle `router`, mais vous pouvez la nommer comme vous le souhaitez.
+
+///
+
+Nous allons inclure ce `APIRouter` dans l'application principale `FastAPI`, mais d'abord, examinons les dépendances et un autre `APIRouter`.
+
+## Gérer les dépendances { #dependencies }
+
+Nous voyons que nous allons avoir besoin de certaines dépendances utilisées à plusieurs endroits de l'application.
+
+Nous les mettons donc dans leur propre module `dependencies` (`app/dependencies.py`).
+
+Nous allons maintenant utiliser une dépendance simple pour lire un en-tête personnalisé `X-Token` :
+
+{* ../../docs_src/bigger_applications/app_an_py310/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
+
+/// tip | Astuce
+
+Nous utilisons un en-tête inventé pour simplifier cet exemple.
+
+Mais dans les cas réels, vous obtiendrez de meilleurs résultats en utilisant les [utilitaires de sécurité](security/index.md){.internal-link target=_blank} intégrés.
+
+///
+
+## Créer un autre module avec `APIRouter` { #another-module-with-apirouter }
+
+Supposons que vous ayez également les endpoints dédiés à la gestion des « items » de votre application dans le module `app/routers/items.py`.
+
+Vous avez des *chemins d'accès* pour :
+
+* `/items/`
+* `/items/{item_id}`
+
+C'est exactement la même structure que pour `app/routers/users.py`.
+
+Mais nous voulons être plus malins et simplifier un peu le code.
+
+Nous savons que tous les *chemins d'accès* de ce module ont les mêmes éléments :
+
+* Préfixe de chemin `prefix` : `/items`.
+* `tags` : (un seul tag : `items`).
+* `responses` supplémentaires.
+* `dependencies` : ils ont tous besoin de la dépendance `X-Token` que nous avons créée.
+
+Donc, au lieu d'ajouter tout cela à chaque *chemin d'accès*, nous pouvons l'ajouter au `APIRouter`.
+
+{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
+
+Comme le chemin de chaque *chemin d'accès* doit commencer par `/`, comme dans :
+
+```Python hl_lines="1"
+@router.get("/{item_id}")
+async def read_item(item_id: str):
+ ...
+```
+
+... le préfixe ne doit pas inclure un `/` final.
+
+Ainsi, le préfixe dans ce cas est `/items`.
+
+Nous pouvons également ajouter une liste de `tags` et des `responses` supplémentaires qui seront appliqués à tous les *chemins d'accès* inclus dans ce routeur.
+
+Et nous pouvons ajouter une liste de `dependencies` qui seront ajoutées à tous les *chemins d'accès* du routeur et seront exécutées/résolues pour chaque requête qui leur est faite.
+
+/// tip | Astuce
+
+Notez que, tout comme pour les [dépendances dans les décorateurs de *chemin d'accès*](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, aucune valeur ne sera transmise à votre *fonction de chemin d'accès*.
+
+///
+
+Le résultat final est que les chemins d'item sont désormais :
+
+* `/items/`
+* `/items/{item_id}`
+
+... comme prévu.
+
+* Ils seront marqués avec une liste de tags qui contient une seule chaîne « items ».
+ * Ces « tags » sont particulièrement utiles pour les systèmes de documentation interactive automatique (utilisant OpenAPI).
+* Ils incluront tous les `responses` prédéfinies.
+* Tous ces *chemins d'accès* auront la liste des `dependencies` évaluées/exécutées avant eux.
+ * Si vous déclarez également des dépendances dans un *chemin d'accès* spécifique, **elles seront aussi exécutées**.
+ * Les dépendances du routeur sont exécutées en premier, puis les [`dependencies` dans le décorateur](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, puis les dépendances des paramètres normaux.
+ * Vous pouvez également ajouter des [`Security` dependencies avec des `scopes`](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}.
+
+/// tip | Astuce
+
+Avoir des `dependencies` dans le `APIRouter` peut servir, par exemple, à exiger une authentification pour tout un groupe de *chemins d'accès*. Même si les dépendances ne sont pas ajoutées individuellement à chacun d'eux.
+
+///
+
+/// check | Vérifications
+
+Les paramètres `prefix`, `tags`, `responses` et `dependencies` sont (comme dans de nombreux autres cas) simplement une fonctionnalité de **FastAPI** pour vous aider à éviter la duplication de code.
+
+///
+
+### Importer les dépendances { #import-the-dependencies }
+
+Ce code se trouve dans le module `app.routers.items`, le fichier `app/routers/items.py`.
+
+Et nous devons récupérer la fonction de dépendance depuis le module `app.dependencies`, le fichier `app/dependencies.py`.
+
+Nous utilisons donc un import relatif avec `..` pour les dépendances :
+
+{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[3] title["app/routers/items.py"] *}
+
+#### Comprendre le fonctionnement des imports relatifs { #how-relative-imports-work }
+
+/// tip | Astuce
+
+Si vous savez parfaitement comment fonctionnent les imports, passez à la section suivante ci-dessous.
+
+///
+
+Un seul point `.`, comme dans :
+
+```Python
+from .dependencies import get_token_header
+```
+
+signifierait :
+
+* En partant du même package dans lequel vit ce module (le fichier `app/routers/items.py`) (le répertoire `app/routers/`)...
+* trouver le module `dependencies` (un fichier imaginaire `app/routers/dependencies.py`)...
+* et en importer la fonction `get_token_header`.
+
+Mais ce fichier n'existe pas, nos dépendances sont dans un fichier `app/dependencies.py`.
+
+Rappelez-vous à quoi ressemble la structure de notre app/fichiers :
+
+
+
+---
+
+Les deux points `..`, comme dans :
+
+```Python
+from ..dependencies import get_token_header
+```
+
+veulent dire :
+
+* En partant du même package dans lequel vit ce module (le fichier `app/routers/items.py`) (le répertoire `app/routers/`)...
+* aller au package parent (le répertoire `app/`)...
+* et là, trouver le module `dependencies` (le fichier `app/dependencies.py`)...
+* et en importer la fonction `get_token_header`.
+
+Cela fonctionne correctement ! 🎉
+
+---
+
+De la même manière, si nous avions utilisé trois points `...`, comme dans :
+
+```Python
+from ...dependencies import get_token_header
+```
+
+cela voudrait dire :
+
+* En partant du même package dans lequel vit ce module (le fichier `app/routers/items.py`) (le répertoire `app/routers/`)...
+* aller au package parent (le répertoire `app/`)...
+* puis aller au parent de ce package (il n'y a pas de package parent, `app` est le niveau supérieur 😱)...
+* et là, trouver le module `dependencies` (le fichier `app/dependencies.py`)...
+* et en importer la fonction `get_token_header`.
+
+Cela ferait référence à un package au-dessus de `app/`, avec son propre fichier `__init__.py`, etc. Mais nous n'avons pas cela. Donc, cela lèverait une erreur dans notre exemple. 🚨
+
+Mais maintenant vous savez comment cela fonctionne, vous pouvez donc utiliser des imports relatifs dans vos propres applications, aussi complexes soient-elles. 🤓
+
+### Ajouter des `tags`, `responses` et `dependencies` personnalisés { #add-some-custom-tags-responses-and-dependencies }
+
+Nous n'ajoutons pas le préfixe `/items` ni `tags=["items"]` à chaque *chemin d'accès* parce que nous les avons ajoutés au `APIRouter`.
+
+Mais nous pouvons toujours ajouter _davantage_ de `tags` qui seront appliqués à un *chemin d'accès* spécifique, ainsi que des `responses` supplémentaires propres à ce *chemin d'accès* :
+
+{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[30:31] title["app/routers/items.py"] *}
+
+/// tip | Astuce
+
+Ce dernier *chemin d'accès* aura la combinaison de tags : `["items", "custom"]`.
+
+Et il aura également les deux réponses dans la documentation, une pour `404` et une pour `403`.
+
+///
+
+## Créer l'application `FastAPI` principale { #the-main-fastapi }
+
+Voyons maintenant le module `app/main.py`.
+
+C'est ici que vous importez et utilisez la classe `FastAPI`.
+
+Ce sera le fichier principal de votre application qui reliera tout ensemble.
+
+Et comme la plupart de votre logique vivra désormais dans son propre module, le fichier principal sera assez simple.
+
+### Importer `FastAPI` { #import-fastapi }
+
+Vous importez et créez une classe `FastAPI` comme d'habitude.
+
+Et nous pouvons même déclarer des [dépendances globales](dependencies/global-dependencies.md){.internal-link target=_blank} qui seront combinées avec les dépendances de chaque `APIRouter` :
+
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[1,3,7] title["app/main.py"] *}
+
+### Importer les `APIRouter` { #import-the-apirouter }
+
+Nous importons maintenant les autres sous-modules qui ont des `APIRouter` :
+
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[4:5] title["app/main.py"] *}
+
+Comme les fichiers `app/routers/users.py` et `app/routers/items.py` sont des sous-modules qui font partie du même package Python `app`, nous pouvons utiliser un seul point `.` pour les importer en utilisant des « imports relatifs ».
+
+### Comprendre le fonctionnement de l'import { #how-the-importing-works }
+
+La section :
+
+```Python
+from .routers import items, users
+```
+
+signifie :
+
+* En partant du même package dans lequel vit ce module (le fichier `app/main.py`) (le répertoire `app/`)...
+* chercher le sous-package `routers` (le répertoire `app/routers/`)...
+* et en importer le sous-module `items` (le fichier `app/routers/items.py`) et `users` (le fichier `app/routers/users.py`)...
+
+Le module `items` aura une variable `router` (`items.router`). C'est celle que nous avons créée dans le fichier `app/routers/items.py`, c'est un objet `APIRouter`.
+
+Nous faisons ensuite la même chose pour le module `users`.
+
+Nous pourrions aussi les importer ainsi :
+
+```Python
+from app.routers import items, users
+```
+
+/// info
+
+La première version est un « import relatif » :
+
+```Python
+from .routers import items, users
+```
+
+La deuxième version est un « import absolu » :
+
+```Python
+from app.routers import items, users
+```
+
+Pour en savoir plus sur les Packages et Modules Python, lisez la documentation officielle de Python sur les modules.
+
+///
+
+### Éviter les collisions de noms { #avoid-name-collisions }
+
+Nous importons le sous-module `items` directement, au lieu d'importer uniquement sa variable `router`.
+
+C'est parce que nous avons également une autre variable nommée `router` dans le sous-module `users`.
+
+Si nous les avions importées l'une après l'autre, comme :
+
+```Python
+from .routers.items import router
+from .routers.users import router
+```
+
+le `router` de `users` écraserait celui de `items` et nous ne pourrions pas les utiliser en même temps.
+
+Donc, pour pouvoir utiliser les deux dans le même fichier, nous importons directement les sous-modules :
+
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[5] title["app/main.py"] *}
+
+### Inclure les `APIRouter` pour `users` et `items` { #include-the-apirouters-for-users-and-items }
+
+Incluons maintenant les `router` des sous-modules `users` et `items` :
+
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[10:11] title["app/main.py"] *}
+
+/// info
+
+`users.router` contient le `APIRouter` à l'intérieur du fichier `app/routers/users.py`.
+
+Et `items.router` contient le `APIRouter` à l'intérieur du fichier `app/routers/items.py`.
+
+///
+
+Avec `app.include_router()`, nous pouvons ajouter chaque `APIRouter` à l'application principale `FastAPI`.
+
+Cela inclura toutes les routes de ce routeur comme faisant partie de l'application.
+
+/// note | Détails techniques
+
+En interne, cela créera en fait un *chemin d'accès* pour chaque *chemin d'accès* qui a été déclaré dans le `APIRouter`.
+
+Donc, en coulisses, cela fonctionnera comme si tout faisait partie d'une seule et même application.
+
+///
+
+/// check | Vérifications
+
+Vous n'avez pas à vous soucier de la performance lors de l'inclusion de routeurs.
+
+Cela prendra des microsecondes et ne se produira qu'au démarrage.
+
+Donc cela n'affectera pas la performance. ⚡
+
+///
+
+### Inclure un `APIRouter` avec un `prefix`, des `tags`, des `responses` et des `dependencies` personnalisés { #include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies }
+
+Imaginons maintenant que votre organisation vous ait fourni le fichier `app/internal/admin.py`.
+
+Il contient un `APIRouter` avec quelques *chemins d'accès* d'administration que votre organisation partage entre plusieurs projets.
+
+Pour cet exemple, il sera très simple. Mais supposons que, parce qu'il est partagé avec d'autres projets de l'organisation, nous ne puissions pas le modifier et ajouter un `prefix`, des `dependencies`, des `tags`, etc. directement au `APIRouter` :
+
+{* ../../docs_src/bigger_applications/app_an_py310/internal/admin.py hl[3] title["app/internal/admin.py"] *}
+
+Mais nous voulons quand même définir un `prefix` personnalisé lors de l'inclusion du `APIRouter` afin que tous ses *chemins d'accès* commencent par `/admin`, nous voulons le sécuriser avec les `dependencies` que nous avons déjà pour ce projet, et nous voulons inclure des `tags` et des `responses`.
+
+Nous pouvons déclarer tout cela sans avoir à modifier le `APIRouter` d'origine en passant ces paramètres à `app.include_router()` :
+
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[14:17] title["app/main.py"] *}
+
+De cette façon, le `APIRouter` original restera inchangé, afin que nous puissions toujours partager ce même fichier `app/internal/admin.py` avec d'autres projets de l'organisation.
+
+Le résultat est que, dans notre application, chacun des *chemins d'accès* du module `admin` aura :
+
+* Le préfixe `/admin`.
+* Le tag `admin`.
+* La dépendance `get_token_header`.
+* La réponse `418`. 🍵
+
+Mais cela n'affectera que ce `APIRouter` dans notre application, pas dans tout autre code qui l'utilise.
+
+Ainsi, par exemple, d'autres projets pourraient utiliser le même `APIRouter` avec une méthode d'authentification différente.
+
+### Inclure un *chemin d'accès* { #include-a-path-operation }
+
+Nous pouvons également ajouter des *chemins d'accès* directement à l'application `FastAPI`.
+
+Ici, nous le faisons... juste pour montrer que nous le pouvons 🤷 :
+
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[21:23] title["app/main.py"] *}
+
+et cela fonctionnera correctement, avec tous les autres *chemins d'accès* ajoutés avec `app.include_router()`.
+
+/// info | Détails très techniques
+
+Note : c'est un détail très technique que vous pouvez probablement **simplement ignorer**.
+
+---
+
+Les `APIRouter` ne sont pas « montés », ils ne sont pas isolés du reste de l'application.
+
+C'est parce que nous voulons inclure leurs *chemins d'accès* dans le schéma OpenAPI et les interfaces utilisateur.
+
+Comme nous ne pouvons pas simplement les isoler et les « monter » indépendamment du reste, les *chemins d'accès* sont « clonés » (recréés), pas inclus directement.
+
+///
+
+## Consulter la documentation API automatique { #check-the-automatic-api-docs }
+
+Maintenant, exécutez votre application :
+
+
+
+```console
+$ fastapi dev app/main.py
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+Et ouvrez les documents à http://127.0.0.1:8000/docs.
+
+Vous verrez la documentation API automatique, incluant les chemins de tous les sous-modules, utilisant les bons chemins (et préfixes) et les bons tags :
+
+
+
+## Inclure le même routeur plusieurs fois avec des `prefix` différents { #include-the-same-router-multiple-times-with-different-prefix }
+
+Vous pouvez aussi utiliser `.include_router()` plusieurs fois avec le même routeur en utilisant des préfixes différents.
+
+Cela peut être utile, par exemple, pour exposer la même API sous des préfixes différents, p. ex. `/api/v1` et `/api/latest`.
+
+C'est un usage avancé dont vous n'aurez peut-être pas vraiment besoin, mais il est là au cas où.
+
+## Inclure un `APIRouter` dans un autre { #include-an-apirouter-in-another }
+
+De la même manière que vous pouvez inclure un `APIRouter` dans une application `FastAPI`, vous pouvez inclure un `APIRouter` dans un autre `APIRouter` en utilisant :
+
+```Python
+router.include_router(other_router)
+```
+
+Vous devez vous assurer de le faire avant d'inclure `router` dans l'application `FastAPI`, afin que les *chemins d'accès* de `other_router` soient également inclus.
diff --git a/docs/fr/docs/tutorial/body-fields.md b/docs/fr/docs/tutorial/body-fields.md
new file mode 100644
index 000000000..9830292c9
--- /dev/null
+++ b/docs/fr/docs/tutorial/body-fields.md
@@ -0,0 +1,61 @@
+# Corps - Champs { #body-fields }
+
+De la même manière que vous pouvez déclarer des validations supplémentaires et des métadonnées dans les paramètres d'une fonction de chemin d'accès avec `Query`, `Path` et `Body`, vous pouvez déclarer des validations et des métadonnées à l'intérieur des modèles Pydantic en utilisant `Field` de Pydantic.
+
+## Importer `Field` { #import-field }
+
+D'abord, vous devez l'importer :
+
+{* ../../docs_src/body_fields/tutorial001_an_py310.py hl[4] *}
+
+
+/// warning | Alertes
+
+Notez que `Field` est importé directement depuis `pydantic`, et non depuis `fastapi` comme le sont les autres (`Query`, `Path`, `Body`, etc.).
+
+///
+
+## Déclarer les attributs du modèle { #declare-model-attributes }
+
+Vous pouvez ensuite utiliser `Field` avec des attributs de modèle :
+
+{* ../../docs_src/body_fields/tutorial001_an_py310.py hl[11:14] *}
+
+`Field` fonctionne de la même manière que `Query`, `Path` et `Body`, il dispose des mêmes paramètres, etc.
+
+/// note | Détails techniques
+
+En réalité, `Query`, `Path` et d'autres que vous verrez ensuite créent des objets de sous-classes d'une classe commune `Param`, qui est elle-même une sous-classe de la classe `FieldInfo` de Pydantic.
+
+Et `Field` de Pydantic renvoie également une instance de `FieldInfo`.
+
+`Body` renvoie aussi directement des objets d'une sous-classe de `FieldInfo`. Et il y en a d'autres que vous verrez plus tard qui sont des sous-classes de la classe `Body`.
+
+Rappelez-vous que lorsque vous importez `Query`, `Path` et d'autres depuis `fastapi`, ce sont en réalité des fonctions qui renvoient des classes spéciales.
+
+///
+
+/// tip | Astuce
+
+Remarquez comment chaque attribut de modèle avec un type, une valeur par défaut et `Field` a la même structure qu'un paramètre de fonction de chemin d'accès, avec `Field` au lieu de `Path`, `Query` et `Body`.
+
+///
+
+## Ajouter des informations supplémentaires { #add-extra-information }
+
+Vous pouvez déclarer des informations supplémentaires dans `Field`, `Query`, `Body`, etc. Elles seront incluses dans le JSON Schema généré.
+
+Vous en apprendrez davantage sur l'ajout d'informations supplémentaires plus loin dans les documents, lorsque vous apprendrez à déclarer des exemples.
+
+/// warning | Alertes
+
+Les clés supplémentaires passées à `Field` seront également présentes dans le schéma OpenAPI résultant pour votre application.
+Comme ces clés ne font pas nécessairement partie de la spécification OpenAPI, certains outils OpenAPI, par exemple [le validateur OpenAPI](https://validator.swagger.io/), peuvent ne pas fonctionner avec votre schéma généré.
+
+///
+
+## Récapitulatif { #recap }
+
+Vous pouvez utiliser `Field` de Pydantic pour déclarer des validations supplémentaires et des métadonnées pour les attributs de modèle.
+
+Vous pouvez également utiliser des arguments nommés supplémentaires pour transmettre des métadonnées JSON Schema additionnelles.
diff --git a/docs/fr/docs/tutorial/body-multiple-params.md b/docs/fr/docs/tutorial/body-multiple-params.md
index 92ca2afc3..1c1ab0fca 100644
--- a/docs/fr/docs/tutorial/body-multiple-params.md
+++ b/docs/fr/docs/tutorial/body-multiple-params.md
@@ -104,12 +104,6 @@ Comme, par défaut, les valeurs singulières sont interprétées comme des param
q: str | None = None
```
-Ou en Python 3.9 :
-
-```Python
-q: Union[str, None] = None
-```
-
Par exemple :
{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *}
diff --git a/docs/fr/docs/tutorial/body-nested-models.md b/docs/fr/docs/tutorial/body-nested-models.md
new file mode 100644
index 000000000..dccfdb6c5
--- /dev/null
+++ b/docs/fr/docs/tutorial/body-nested-models.md
@@ -0,0 +1,220 @@
+# Corps - Modèles imbriqués { #body-nested-models }
+
+Avec FastAPI, vous pouvez définir, valider, documenter et utiliser des modèles imbriqués à n'importe quelle profondeur (grâce à Pydantic).
+
+## Déclarer des champs de liste { #list-fields }
+
+Vous pouvez définir un attribut comme étant un sous-type. Par exemple, une `list` Python :
+
+{* ../../docs_src/body_nested_models/tutorial001_py310.py hl[12] *}
+
+Cela fera de `tags` une liste, bien que le type des éléments de la liste ne soit pas déclaré.
+
+## Champs de liste avec paramètre de type { #list-fields-with-type-parameter }
+
+Mais Python a une manière spécifique de déclarer des listes avec des types internes, ou « paramètres de type » :
+
+### Déclarer une `list` avec un paramètre de type { #declare-a-list-with-a-type-parameter }
+
+Pour déclarer des types qui ont des paramètres de type (types internes), comme `list`, `dict`, `tuple`,
+passez le(s) type(s) interne(s) comme « paramètres de type » à l'aide de crochets : `[` et `]`
+
+```Python
+my_list: list[str]
+```
+
+C'est simplement la syntaxe Python standard pour les déclarations de type.
+
+Utilisez cette même syntaxe standard pour les attributs de modèles avec des types internes.
+
+Ainsi, dans notre exemple, nous pouvons faire de `tags` spécifiquement une « liste de chaînes » :
+
+{* ../../docs_src/body_nested_models/tutorial002_py310.py hl[12] *}
+
+## Types set { #set-types }
+
+Mais en y réfléchissant, nous réalisons que les tags ne devraient pas se répéter, ce seraient probablement des chaînes uniques.
+
+Et Python dispose d'un type de données spécial pour les ensembles d'éléments uniques, le `set`.
+
+Nous pouvons alors déclarer `tags` comme un set de chaînes :
+
+{* ../../docs_src/body_nested_models/tutorial003_py310.py hl[12] *}
+
+Avec cela, même si vous recevez une requête contenant des doublons, elle sera convertie en un set d'éléments uniques.
+
+Et chaque fois que vous renverrez ces données, même si la source contenait des doublons, elles seront renvoyées sous la forme d'un set d'éléments uniques.
+
+Elles seront également annotées / documentées en conséquence.
+
+## Modèles imbriqués { #nested-models }
+
+Chaque attribut d'un modèle Pydantic a un type.
+
+Mais ce type peut lui-même être un autre modèle Pydantic.
+
+Ainsi, vous pouvez déclarer des « objets » JSON profondément imbriqués avec des noms d'attributs, des types et des validations spécifiques.
+
+Tout cela, de manière arbitrairement imbriquée.
+
+### Définir un sous-modèle { #define-a-submodel }
+
+Par exemple, nous pouvons définir un modèle `Image` :
+
+{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[7:9] *}
+
+### Utiliser le sous-modèle comme type { #use-the-submodel-as-a-type }
+
+Nous pouvons ensuite l'utiliser comme type d'un attribut :
+
+{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[18] *}
+
+Cela signifie que FastAPI attendrait un corps similaire à :
+
+```JSON
+{
+ "name": "Foo",
+ "description": "The pretender",
+ "price": 42.0,
+ "tax": 3.2,
+ "tags": ["rock", "metal", "bar"],
+ "image": {
+ "url": "http://example.com/baz.jpg",
+ "name": "The Foo live"
+ }
+}
+```
+
+Là encore, avec cette simple déclaration, avec FastAPI vous obtenez :
+
+- Prise en charge par l'éditeur (autocomplétion, etc.), même pour les modèles imbriqués
+- Conversion des données
+- Validation des données
+- Documentation automatique
+
+## Types spéciaux et validation { #special-types-and-validation }
+
+Outre les types singuliers normaux comme `str`, `int`, `float`, etc. vous pouvez utiliser des types singuliers plus complexes qui héritent de `str`.
+
+Pour voir toutes les options dont vous disposez, consultez l’aperçu des types de Pydantic. Vous verrez quelques exemples au chapitre suivant.
+
+Par exemple, comme dans le modèle `Image` nous avons un champ `url`, nous pouvons le déclarer comme instance de `HttpUrl` de Pydantic au lieu de `str` :
+
+{* ../../docs_src/body_nested_models/tutorial005_py310.py hl[2,8] *}
+
+La chaîne sera vérifiée comme URL valide et documentée comme telle dans JSON Schema / OpenAPI.
+
+## Attributs avec des listes de sous-modèles { #attributes-with-lists-of-submodels }
+
+Vous pouvez également utiliser des modèles Pydantic comme sous-types de `list`, `set`, etc. :
+
+{* ../../docs_src/body_nested_models/tutorial006_py310.py hl[18] *}
+
+Cela attendra (convertira, validera, documentera, etc.) un corps JSON comme :
+
+```JSON hl_lines="11"
+{
+ "name": "Foo",
+ "description": "The pretender",
+ "price": 42.0,
+ "tax": 3.2,
+ "tags": [
+ "rock",
+ "metal",
+ "bar"
+ ],
+ "images": [
+ {
+ "url": "http://example.com/baz.jpg",
+ "name": "The Foo live"
+ },
+ {
+ "url": "http://example.com/dave.jpg",
+ "name": "The Baz"
+ }
+ ]
+}
+```
+/// info
+
+Remarquez que la clé `images` contient maintenant une liste d'objets image.
+
+///
+
+## Modèles profondément imbriqués { #deeply-nested-models }
+
+Vous pouvez définir des modèles imbriqués à une profondeur arbitraire :
+
+{* ../../docs_src/body_nested_models/tutorial007_py310.py hl[7,12,18,21,25] *}
+
+/// info
+
+Remarquez que `Offer` a une liste d’`Item`, qui à leur tour ont une liste optionnelle d’`Image`.
+
+///
+
+## Corps de listes pures { #bodies-of-pure-lists }
+
+Si la valeur de premier niveau du corps JSON attendu est un `array` JSON (une `list` Python), vous pouvez déclarer le type dans le paramètre de la fonction, de la même manière que dans les modèles Pydantic :
+
+```Python
+images: list[Image]
+```
+
+comme :
+
+{* ../../docs_src/body_nested_models/tutorial008_py310.py hl[13] *}
+
+## Bénéficier de la prise en charge de l'éditeur partout { #editor-support-everywhere }
+
+Et vous bénéficiez de la prise en charge de l'éditeur partout.
+
+Même pour les éléments à l'intérieur des listes :
+
+
+
+Vous ne pourriez pas obtenir ce type de prise en charge de l'éditeur si vous travailliez directement avec des `dict` au lieu de modèles Pydantic.
+
+Mais vous n'avez pas à vous en soucier non plus, les `dict` entrants sont convertis automatiquement et votre sortie est également convertie automatiquement en JSON.
+
+## Corps de `dict` arbitraires { #bodies-of-arbitrary-dicts }
+
+Vous pouvez également déclarer un corps comme un `dict` avec des clés d’un certain type et des valeurs d’un autre type.
+
+De cette façon, vous n'avez pas besoin de savoir à l'avance quels sont les noms de champs/attributs valides (comme ce serait le cas avec des modèles Pydantic).
+
+Cela serait utile si vous voulez recevoir des clés que vous ne connaissez pas à l'avance.
+
+---
+
+Un autre cas utile est lorsque vous souhaitez avoir des clés d'un autre type (par exemple `int`).
+
+C'est ce que nous allons voir ici.
+
+Dans ce cas, vous accepteriez n'importe quel `dict` tant qu'il a des clés `int` avec des valeurs `float` :
+
+{* ../../docs_src/body_nested_models/tutorial009_py310.py hl[7] *}
+
+/// tip | Astuce
+
+Gardez à l'esprit que JSON ne prend en charge que des `str` comme clés.
+
+Mais Pydantic dispose d'une conversion automatique des données.
+
+Cela signifie que, même si vos clients d'API ne peuvent envoyer que des chaînes comme clés, tant que ces chaînes contiennent des entiers purs, Pydantic les convertira et les validera.
+
+Et le `dict` que vous recevez dans `weights` aura en réalité des clés `int` et des valeurs `float`.
+
+///
+
+## Récapitulatif { #recap }
+
+Avec FastAPI, vous bénéficiez de la flexibilité maximale fournie par les modèles Pydantic, tout en gardant votre code simple, concis et élégant.
+
+Mais avec tous les avantages :
+
+- Prise en charge par l'éditeur (autocomplétion partout !)
+- Conversion des données (a.k.a. parsing / sérialisation)
+- Validation des données
+- Documentation des schémas
+- Documentation automatique
diff --git a/docs/fr/docs/tutorial/body-updates.md b/docs/fr/docs/tutorial/body-updates.md
new file mode 100644
index 000000000..36ad12681
--- /dev/null
+++ b/docs/fr/docs/tutorial/body-updates.md
@@ -0,0 +1,100 @@
+# Corps - Mises à jour { #body-updates }
+
+## Mettre à jour en remplaçant avec `PUT` { #update-replacing-with-put }
+
+Pour mettre à jour un élément, vous pouvez utiliser l’opération HTTP `PUT`.
+
+Vous pouvez utiliser le `jsonable_encoder` pour convertir les données d’entrée en données pouvant être stockées au format JSON (par exemple, avec une base de données NoSQL). Par exemple, convertir `datetime` en `str`.
+
+{* ../../docs_src/body_updates/tutorial001_py310.py hl[28:33] *}
+
+On utilise `PUT` pour recevoir des données qui doivent remplacer les données existantes.
+
+### Avertissement concernant le remplacement { #warning-about-replacing }
+
+Cela signifie que si vous souhaitez mettre à jour l’élément `bar` avec `PUT` et un corps contenant :
+
+```Python
+{
+ "name": "Barz",
+ "price": 3,
+ "description": None,
+}
+```
+
+comme il n’inclut pas l’attribut déjà enregistré « tax »: 20.2, le modèle d’entrée prendrait la valeur par défaut « tax »: 10.5.
+
+Et les données seraient enregistrées avec cette « nouvelle » `tax` de `10.5`.
+
+## Effectuer des mises à jour partielles avec `PATCH` { #partial-updates-with-patch }
+
+Vous pouvez également utiliser l’opération HTTP `PATCH` pour mettre à jour des données de manière partielle.
+
+Cela signifie que vous pouvez n’envoyer que les données que vous souhaitez mettre à jour, en laissant le reste intact.
+
+/// note | Remarque
+
+`PATCH` est moins utilisé et moins connu que `PUT`.
+
+Et de nombreuses équipes n’utilisent que `PUT`, même pour les mises à jour partielles.
+
+Vous êtes libre de les utiliser comme vous le souhaitez, **FastAPI** n’impose aucune restriction.
+
+Mais ce guide vous montre, plus ou moins, la façon dont ils sont censés être utilisés.
+
+///
+
+### Utiliser le paramètre `exclude_unset` de Pydantic { #using-pydantics-exclude-unset-parameter }
+
+Si vous souhaitez recevoir des mises à jour partielles, il est très utile d’utiliser le paramètre `exclude_unset` dans la méthode `.model_dump()` du modèle Pydantic.
+
+Comme `item.model_dump(exclude_unset=True)`.
+
+Cela génère un `dict` ne contenant que les données définies lors de la création du modèle `item`, en excluant les valeurs par défaut.
+
+Vous pouvez ensuite l’utiliser pour produire un `dict` avec uniquement les données définies (envoyées dans la requête), en omettant les valeurs par défaut :
+
+{* ../../docs_src/body_updates/tutorial002_py310.py hl[32] *}
+
+### Utiliser le paramètre `update` de Pydantic { #using-pydantics-update-parameter }
+
+Vous pouvez maintenant créer une copie du modèle existant avec `.model_copy()`, et passer le paramètre `update` avec un `dict` contenant les données à mettre à jour.
+
+Comme `stored_item_model.model_copy(update=update_data)` :
+
+{* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *}
+
+### Récapitulatif des mises à jour partielles { #partial-updates-recap }
+
+En résumé, pour appliquer des mises à jour partielles, vous procédez ainsi :
+
+* (Optionnel) utilisez `PATCH` au lieu de `PUT`.
+* Récupérez les données stockées.
+* Placez ces données dans un modèle Pydantic.
+* Générez un `dict` sans valeurs par défaut à partir du modèle d’entrée (en utilisant `exclude_unset`).
+ * De cette façon, vous mettez à jour uniquement les valeurs effectivement définies par l’utilisateur, au lieu d’écraser des valeurs déjà stockées par des valeurs par défaut de votre modèle.
+* Créez une copie du modèle stocké, en mettant à jour ses attributs avec les mises à jour partielles reçues (en utilisant le paramètre `update`).
+* Convertissez le modèle copié en quelque chose qui peut être stocké dans votre base de données (par exemple en utilisant le `jsonable_encoder`).
+ * Cela est comparable à l’utilisation à nouveau de la méthode `.model_dump()` du modèle, mais cela vérifie (et convertit) les valeurs vers des types pouvant être convertis en JSON, par exemple `datetime` en `str`.
+* Enregistrez les données dans votre base de données.
+* Retournez le modèle mis à jour.
+
+{* ../../docs_src/body_updates/tutorial002_py310.py hl[28:35] *}
+
+/// tip | Astuce
+
+Vous pouvez en réalité utiliser cette même technique avec une opération HTTP `PUT`.
+
+Mais l’exemple ici utilise `PATCH` car il a été créé pour ces cas d’usage.
+
+///
+
+/// note | Remarque
+
+Remarquez que le modèle d’entrée est toujours validé.
+
+Ainsi, si vous souhaitez recevoir des mises à jour partielles pouvant omettre tous les attributs, vous devez disposer d’un modèle avec tous les attributs marqués comme optionnels (avec des valeurs par défaut ou `None`).
+
+Pour distinguer les modèles avec toutes les valeurs optionnelles pour les mises à jour et les modèles avec des valeurs requises pour la création, vous pouvez utiliser les idées décrites dans [Modèles supplémentaires](extra-models.md){.internal-link target=_blank}.
+
+///
diff --git a/docs/fr/docs/tutorial/body.md b/docs/fr/docs/tutorial/body.md
index ca115fabc..a8703e030 100644
--- a/docs/fr/docs/tutorial/body.md
+++ b/docs/fr/docs/tutorial/body.md
@@ -10,7 +10,7 @@ Pour déclarer un corps de **requête**, on utilise les modèles de
-Et seront aussi utilisés dans chaque *opération de chemin* de la documentation utilisant ces modèles :
+Et seront aussi utilisés dans chaque *chemin d'accès* de la documentation utilisant ces modèles :
@@ -115,7 +115,7 @@ Ce qui améliore le support pour les modèles Pydantic avec :
* de l'autocomplétion
* des vérifications de type
-* du « refactoring » (ou remaniement de code)
+* du « refactoring »
* de la recherche
* des inspections
@@ -129,7 +129,7 @@ Dans la fonction, vous pouvez accéder à tous les attributs de l'objet du modè
## 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*.
+Vous pouvez déclarer des paramètres de chemin et un corps de requête pour la même *chemin d'accès*.
**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**.
@@ -137,7 +137,7 @@ Vous pouvez déclarer des paramètres de chemin et un corps de requête pour la
## 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*.
+Vous pouvez aussi déclarer un **corps**, et des paramètres de **chemin** et de **requête** dans la même *chemin d'accès*.
**FastAPI** saura reconnaître chacun d'entre eux et récupérer la bonne donnée au bon endroit.
@@ -153,7 +153,7 @@ Les paramètres de la fonction seront reconnus comme tel :
**FastAPI** saura que la valeur de `q` n'est pas requise grâce à la valeur par défaut `= None`.
-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`.
+L'annotation de type `str | None` 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.
diff --git a/docs/fr/docs/tutorial/cookie-param-models.md b/docs/fr/docs/tutorial/cookie-param-models.md
new file mode 100644
index 000000000..c6fc2f826
--- /dev/null
+++ b/docs/fr/docs/tutorial/cookie-param-models.md
@@ -0,0 +1,76 @@
+# Modèles de paramètres de cookies { #cookie-parameter-models }
+
+Si vous avez un groupe de **cookies** liés, vous pouvez créer un **modèle Pydantic** pour les déclarer. 🍪
+
+Cela vous permet de **réutiliser le modèle** à **plusieurs endroits** et aussi de déclarer des validations et des métadonnées pour tous les paramètres en une seule fois. 😎
+
+/// note | Remarque
+
+Ceci est pris en charge depuis la version `0.115.0` de FastAPI. 🤓
+
+///
+
+/// tip | Astuce
+
+Cette même technique s'applique à `Query`, `Cookie` et `Header`. 😎
+
+///
+
+## Déclarer des cookies avec un modèle Pydantic { #cookies-with-a-pydantic-model }
+
+Déclarez les paramètres de **cookie** dont vous avez besoin dans un **modèle Pydantic**, puis déclarez le paramètre comme `Cookie` :
+
+{* ../../docs_src/cookie_param_models/tutorial001_an_py310.py hl[9:12,16] *}
+
+**FastAPI** va **extraire** les données pour **chaque champ** à partir des **cookies** reçus dans la requête et vous fournir le modèle Pydantic que vous avez défini.
+
+## Consulter la documentation { #check-the-docs }
+
+Vous pouvez voir les cookies définis dans l'interface de la documentation à `/docs` :
+
+
+

+
+
+/// info
+
+Gardez à l'esprit que, comme les **navigateurs gèrent les cookies** de manière particulière et en arrière-plan, ils **n'autorisent pas** facilement **JavaScript** à y accéder.
+
+Si vous allez dans **l'interface de la documentation de l'API** à `/docs`, vous pourrez voir la **documentation** des cookies pour vos *chemins d'accès*.
+
+Mais même si vous **remplissez les données** et cliquez sur « Execute », comme l'interface de la documentation fonctionne avec **JavaScript**, les cookies ne seront pas envoyés et vous verrez un **message d'erreur** comme si vous n'aviez saisi aucune valeur.
+
+///
+
+## Interdire les cookies supplémentaires { #forbid-extra-cookies }
+
+Dans certains cas d'utilisation particuliers (probablement peu courants), vous pourriez vouloir **restreindre** les cookies que vous souhaitez recevoir.
+
+Votre API a désormais le pouvoir de contrôler son propre consentement aux cookies. 🤪🍪
+
+Vous pouvez utiliser la configuration du modèle de Pydantic pour `forbid` tout champ `extra` :
+
+{* ../../docs_src/cookie_param_models/tutorial002_an_py310.py hl[10] *}
+
+Si un client tente d'envoyer des **cookies supplémentaires**, il recevra une **réponse d'erreur**.
+
+Pauvres bannières de cookies, avec tous leurs efforts pour obtenir votre consentement pour que l'API pour le rejeter. 🍪
+
+Par exemple, si le client tente d'envoyer un cookie `santa_tracker` avec la valeur `good-list-please`, il recevra une **réponse d'erreur** lui indiquant que le `santa_tracker` le cookie n'est pas autorisé :
+
+```json
+{
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["cookie", "santa_tracker"],
+ "msg": "Extra inputs are not permitted",
+ "input": "good-list-please",
+ }
+ ]
+}
+```
+
+## Récapitulatif { #summary }
+
+Vous pouvez utiliser des **modèles Pydantic** pour déclarer des **cookies** dans **FastAPI**. 😎
diff --git a/docs/fr/docs/tutorial/cookie-params.md b/docs/fr/docs/tutorial/cookie-params.md
new file mode 100644
index 000000000..8f77d35dc
--- /dev/null
+++ b/docs/fr/docs/tutorial/cookie-params.md
@@ -0,0 +1,45 @@
+# Paramètres de cookie { #cookie-parameters }
+
+Vous pouvez définir des paramètres de cookie de la même manière que vous définissez les paramètres `Query` et `Path`.
+
+## Importer `Cookie` { #import-cookie }
+
+Commencez par importer `Cookie` :
+
+{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[3] *}
+
+## Déclarer des paramètres `Cookie` { #declare-cookie-parameters }
+
+Déclarez ensuite les paramètres de cookie en utilisant la même structure qu'avec `Path` et `Query`.
+
+Vous pouvez définir la valeur par défaut ainsi que tous les paramètres supplémentaires de validation ou d'annotation :
+
+{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[9] *}
+
+/// note | Détails techniques
+
+`Cookie` est une classe « sœur » de `Path` et `Query`. Elle hérite également de la même classe commune `Param`.
+
+Mais rappelez-vous que lorsque vous importez `Query`, `Path`, `Cookie` et d'autres depuis `fastapi`, il s'agit en réalité de fonctions qui renvoient des classes spéciales.
+
+///
+
+/// info
+
+Pour déclarer des cookies, vous devez utiliser `Cookie`, sinon les paramètres seraient interprétés comme des paramètres de requête.
+
+///
+
+/// info
+
+Gardez à l'esprit que, comme **les navigateurs gèrent les cookies** de manière particulière et en coulisses, ils **n'autorisent pas** facilement **JavaScript** à y accéder.
+
+Si vous allez dans l'**interface de la documentation de l'API** à `/docs`, vous pourrez voir la **documentation** des cookies pour vos *chemins d'accès*.
+
+Mais même si vous **renseignez les données** et cliquez sur « Execute », comme l'interface de documentation fonctionne avec **JavaScript**, les cookies ne seront pas envoyés et vous verrez un message **d'erreur** comme si vous n'aviez saisi aucune valeur.
+
+///
+
+## Récapitulatif { #recap }
+
+Déclarez les cookies avec `Cookie`, en utilisant le même schéma commun que `Query` et `Path`.
diff --git a/docs/fr/docs/tutorial/cors.md b/docs/fr/docs/tutorial/cors.md
new file mode 100644
index 000000000..3ae7de07c
--- /dev/null
+++ b/docs/fr/docs/tutorial/cors.md
@@ -0,0 +1,88 @@
+# CORS (Partage des ressources entre origines) { #cors-cross-origin-resource-sharing }
+
+CORS ou « Cross-Origin Resource Sharing » fait référence aux situations où un frontend exécuté dans un navigateur contient du code JavaScript qui communique avec un backend, et où le backend se trouve dans une « origine » différente de celle du frontend.
+
+## Origine { #origin }
+
+Une origine est la combinaison du protocole (`http`, `https`), du domaine (`myapp.com`, `localhost`, `localhost.tiangolo.com`) et du port (`80`, `443`, `8080`).
+
+Ainsi, toutes celles-ci sont des origines différentes :
+
+* `http://localhost`
+* `https://localhost`
+* `http://localhost:8080`
+
+Même si elles sont toutes sur `localhost`, elles utilisent des protocoles ou des ports différents, ce sont donc des « origines » différentes.
+
+## Étapes { #steps }
+
+Disons donc que vous avez un frontend exécuté dans votre navigateur à `http://localhost:8080`, et que son JavaScript essaie de communiquer avec un backend exécuté à `http://localhost` (comme nous ne spécifions pas de port, le navigateur supposera le port par défaut `80`).
+
+Le navigateur enverra alors une requête HTTP `OPTIONS` au backend `:80`, et si le backend envoie les en-têtes appropriés autorisant la communication depuis cette origine différente (`http://localhost:8080`), alors le navigateur `:8080` permettra au JavaScript du frontend d’envoyer sa requête au backend `:80`.
+
+Pour y parvenir, le backend `:80` doit disposer d’une liste « d’origines autorisées ».
+
+Dans ce cas, la liste devrait inclure `http://localhost:8080` pour que le frontend `:8080` fonctionne correctement.
+
+## Caractères génériques { #wildcards }
+
+Il est également possible de déclarer la liste comme « * » (un « wildcard ») pour indiquer que toutes sont autorisées.
+
+Mais cela n’autorisera que certains types de communication, en excluant tout ce qui implique des informations d’identification : cookies, en-têtes Authorization comme ceux utilisés avec les Bearer Tokens, etc.
+
+Ainsi, pour que tout fonctionne correctement, il est préférable d’indiquer explicitement les origines autorisées.
+
+## Utiliser `CORSMiddleware` { #use-corsmiddleware }
+
+Vous pouvez le configurer dans votre application **FastAPI** à l’aide de `CORSMiddleware`.
+
+* Importer `CORSMiddleware`.
+* Créer une liste d’origines autorisées (sous forme de chaînes).
+* L’ajouter comme « middleware » à votre application **FastAPI**.
+
+Vous pouvez également spécifier si votre backend autorise :
+
+* Les informations d’identification (en-têtes Authorization, cookies, etc.).
+* Des méthodes HTTP spécifiques (`POST`, `PUT`) ou toutes avec le caractère générique « * ».
+* Des en-têtes HTTP spécifiques ou tous avec le caractère générique « * ».
+
+{* ../../docs_src/cors/tutorial001_py310.py hl[2,6:11,13:19] *}
+
+Les paramètres utilisés par défaut par l’implémentation de `CORSMiddleware` sont restrictifs, vous devez donc activer explicitement des origines, méthodes ou en-têtes particuliers afin que les navigateurs soient autorisés à les utiliser dans un contexte inter‑domaine.
+
+Les arguments suivants sont pris en charge :
+
+* `allow_origins` - Une liste d’origines autorisées à effectuer des requêtes cross-origin. Par ex. `['https://example.org', 'https://www.example.org']`. Vous pouvez utiliser `['*']` pour autoriser n’importe quelle origine.
+* `allow_origin_regex` - Une chaîne regex pour faire correspondre les origines autorisées à effectuer des requêtes cross-origin. Par ex. `'https://.*\.example\.org'`.
+* `allow_methods` - Une liste de méthodes HTTP qui doivent être autorisées pour les requêtes cross-origin. Par défaut `['GET']`. Vous pouvez utiliser `['*']` pour autoriser toutes les méthodes standard.
+* `allow_headers` - Une liste d’en-têtes HTTP de requête qui doivent être pris en charge pour les requêtes cross-origin. Par défaut `[]`. Vous pouvez utiliser `['*']` pour autoriser tous les en-têtes. Les en-têtes `Accept`, `Accept-Language`, `Content-Language` et `Content-Type` sont toujours autorisés pour les requêtes CORS simples.
+* `allow_credentials` - Indique que les cookies doivent être pris en charge pour les requêtes cross-origin. Par défaut `False`.
+
+ Aucun de `allow_origins`, `allow_methods` et `allow_headers` ne peut être défini à `['*']` si `allow_credentials` est défini à `True`. Ils doivent tous être spécifiés explicitement.
+
+* `expose_headers` - Indique les en-têtes de réponse qui doivent être accessibles au navigateur. Par défaut `[]`.
+* `max_age` - Définit un temps maximum (en secondes) pendant lequel les navigateurs peuvent mettre en cache les réponses CORS. Par défaut `600`.
+
+Le middleware répond à deux types particuliers de requêtes HTTP ...
+
+### Requêtes CORS de pré‑vérification { #cors-preflight-requests }
+
+Il s’agit de toute requête `OPTIONS` avec les en-têtes `Origin` et `Access-Control-Request-Method`.
+
+Dans ce cas, le middleware interceptera la requête entrante et répondra avec les en-têtes CORS appropriés, et soit une réponse `200`, soit `400` à titre informatif.
+
+### Requêtes simples { #simple-requests }
+
+Toute requête avec un en-tête `Origin`. Dans ce cas, le middleware laissera passer la requête normalement, mais inclura les en-têtes CORS appropriés dans la réponse.
+
+## En savoir plus { #more-info }
+
+Pour plus d’informations sur CORS, consultez la documentation CORS de Mozilla.
+
+/// note | Détails techniques
+
+Vous pouvez également utiliser `from starlette.middleware.cors import CORSMiddleware`.
+
+**FastAPI** fournit plusieurs middlewares dans `fastapi.middleware` uniquement pour votre confort, en tant que développeur. Mais la plupart des middlewares disponibles proviennent directement de Starlette.
+
+///
diff --git a/docs/fr/docs/tutorial/debugging.md b/docs/fr/docs/tutorial/debugging.md
index a88fa2b23..d69e6a3ba 100644
--- a/docs/fr/docs/tutorial/debugging.md
+++ b/docs/fr/docs/tutorial/debugging.md
@@ -6,7 +6,7 @@ Vous pouvez connecter le débogueur da
Dans votre application FastAPI, importez et exécutez directement `uvicorn` :
-{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *}
+{* ../../docs_src/debugging/tutorial001_py310.py hl[1,15] *}
### À propos de `__name__ == "__main__"` { #about-name-main }
@@ -87,7 +87,7 @@ Parce que vous exécutez le serveur Uvicorn directement depuis votre code, vous
Par exemple, dans Visual Studio Code, vous pouvez :
- Allez dans le panneau « Debug ».
-- « Add configuration... ».
+- « Add configuration ... ».
- Sélectionnez « Python ».
- Lancez le débogueur avec l'option « Python: Current File (Integrated Terminal) ».
@@ -102,7 +102,7 @@ Voici à quoi cela pourrait ressembler :
Si vous utilisez Pycharm, vous pouvez :
- Ouvrez le menu « Run ».
-- Sélectionnez l'option « Debug... ».
+- Sélectionnez l'option « Debug ... ».
- Un menu contextuel s'affiche alors.
- Sélectionnez le fichier à déboguer (dans ce cas, `main.py`).
diff --git a/docs/fr/docs/tutorial/dependencies/classes-as-dependencies.md b/docs/fr/docs/tutorial/dependencies/classes-as-dependencies.md
new file mode 100644
index 000000000..69bc6008a
--- /dev/null
+++ b/docs/fr/docs/tutorial/dependencies/classes-as-dependencies.md
@@ -0,0 +1,288 @@
+# Utiliser des classes comme dépendances { #classes-as-dependencies }
+
+Avant d'aller plus loin dans le système d'**Injection de dépendances**, mettons à niveau l'exemple précédent.
+
+## Un `dict` de l'exemple précédent { #a-dict-from-the-previous-example }
+
+Dans l'exemple précédent, nous renvoyions un `dict` depuis notre dépendance (« dependable ») :
+
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[9] *}
+
+Mais nous recevons alors un `dict` dans le paramètre `commons` de la fonction de chemin d'accès.
+
+Et les éditeurs ne peuvent pas apporter beaucoup d'assistance (comme l'autocomplétion) pour les `dict`, car ils ne peuvent pas connaître leurs clés ni les types de valeurs.
+
+Nous pouvons faire mieux ...
+
+## Ce qui fait d'un objet une dépendance { #what-makes-a-dependency }
+
+Jusqu'à présent, vous avez vu des dépendances déclarées sous forme de fonctions.
+
+Mais ce n'est pas la seule manière de déclarer des dépendances (même si c'est probablement la plus courante).
+
+L'élément clé est qu'une dépendance doit être un « callable ».
+
+Un « callable » en Python est tout ce que Python peut « appeler » comme une fonction.
+
+Ainsi, si vous avez un objet `something` (qui n'est peut‑être pas une fonction) et que vous pouvez « l'appeler » (l'exécuter) comme :
+
+```Python
+something()
+```
+
+ou
+
+```Python
+something(some_argument, some_keyword_argument="foo")
+```
+
+alors c'est un « callable ».
+
+## Utiliser des classes comme dépendances { #classes-as-dependencies_1 }
+
+Vous remarquerez que pour créer une instance d'une classe Python, vous utilisez la même syntaxe.
+
+Par exemple :
+
+```Python
+class Cat:
+ def __init__(self, name: str):
+ self.name = name
+
+
+fluffy = Cat(name="Mr Fluffy")
+```
+
+Dans ce cas, `fluffy` est une instance de la classe `Cat`.
+
+Et pour créer `fluffy`, vous « appelez » `Cat`.
+
+Donc, une classe Python est aussi un « callable ».
+
+Ainsi, avec **FastAPI**, vous pouvez utiliser une classe Python comme dépendance.
+
+Ce que **FastAPI** vérifie réellement, c'est qu'il s'agit d'un « callable » (fonction, classe ou autre) et des paramètres qui y sont définis.
+
+Si vous passez un « callable » comme dépendance dans **FastAPI**, il en analysera les paramètres et les traitera de la même manière que les paramètres d'une fonction de chemin d'accès. Y compris les sous‑dépendances.
+
+Cela s'applique également aux callables sans aucun paramètre. Comme ce serait le cas pour des fonctions de chemin d'accès sans paramètres.
+
+Nous pouvons alors remplacer la dépendance « dependable » `common_parameters` ci‑dessus par la classe `CommonQueryParams` :
+
+{* ../../docs_src/dependencies/tutorial002_an_py310.py hl[11:15] *}
+
+Faites attention à la méthode `__init__` utilisée pour créer l'instance de la classe :
+
+{* ../../docs_src/dependencies/tutorial002_an_py310.py hl[12] *}
+
+... il a les mêmes paramètres que notre précédent `common_parameters` :
+
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[8] *}
+
+Ce sont ces paramètres que **FastAPI** utilisera pour « résoudre » la dépendance.
+
+Dans les deux cas, il y aura :
+
+- Un paramètre de requête optionnel `q` qui est un `str`.
+- Un paramètre de requête `skip` qui est un `int`, avec une valeur par défaut de `0`.
+- Un paramètre de requête `limit` qui est un `int`, avec une valeur par défaut de `100`.
+
+Dans les deux cas, les données seront converties, validées, documentées dans le schéma OpenAPI, etc.
+
+## Utiliser { #use-it }
+
+Vous pouvez maintenant déclarer votre dépendance en utilisant cette classe.
+
+{* ../../docs_src/dependencies/tutorial002_an_py310.py hl[19] *}
+
+**FastAPI** appelle la classe `CommonQueryParams`. Cela crée une « instance » de cette classe et l'instance sera passée comme paramètre `commons` à votre fonction.
+
+## Annotation de type vs `Depends` { #type-annotation-vs-depends }
+
+Remarquez que nous écrivons `CommonQueryParams` deux fois dans le code ci‑dessus :
+
+//// tab | Python 3.10+
+
+```Python
+commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
+```
+
+////
+
+//// tab | Python 3.10+ sans Annotated
+
+/// tip | Astuce
+
+Privilégiez la version avec `Annotated` si possible.
+
+///
+
+```Python
+commons: CommonQueryParams = Depends(CommonQueryParams)
+```
+
+////
+
+Le dernier `CommonQueryParams`, dans :
+
+```Python
+... Depends(CommonQueryParams)
+```
+
+... est ce que **FastAPI** utilisera réellement pour savoir quelle est la dépendance.
+
+C'est à partir de celui‑ci que FastAPI extraira les paramètres déclarés et c'est ce que FastAPI appellera effectivement.
+
+---
+
+Dans ce cas, le premier `CommonQueryParams`, dans :
+
+//// tab | Python 3.10+
+
+```Python
+commons: Annotated[CommonQueryParams, ...
+```
+
+////
+
+//// tab | Python 3.10+ sans Annotated
+
+/// tip | Astuce
+
+Privilégiez la version avec `Annotated` si possible.
+
+///
+
+```Python
+commons: CommonQueryParams ...
+```
+
+////
+
+... n'a aucune signification particulière pour **FastAPI**. FastAPI ne l'utilisera pas pour la conversion des données, la validation, etc. (car il utilise `Depends(CommonQueryParams)` pour cela).
+
+Vous pourriez en fait écrire simplement :
+
+//// tab | Python 3.10+
+
+```Python
+commons: Annotated[Any, Depends(CommonQueryParams)]
+```
+
+////
+
+//// tab | Python 3.10+ sans Annotated
+
+/// tip | Astuce
+
+Privilégiez la version avec `Annotated` si possible.
+
+///
+
+```Python
+commons = Depends(CommonQueryParams)
+```
+
+////
+
+... comme dans :
+
+{* ../../docs_src/dependencies/tutorial003_an_py310.py hl[19] *}
+
+Mais il est recommandé de déclarer le type ; ainsi, votre éditeur saura ce qui sera passé comme paramètre `commons`, et pourra vous aider avec l'autocomplétion, les vérifications de type, etc. :
+
+
+
+## Raccourci { #shortcut }
+
+Mais vous voyez qu'il y a ici de la duplication de code : nous écrivons `CommonQueryParams` deux fois :
+
+//// tab | Python 3.10+
+
+```Python
+commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
+```
+
+////
+
+//// tab | Python 3.10+ sans Annotated
+
+/// tip | Astuce
+
+Privilégiez la version avec `Annotated` si possible.
+
+///
+
+```Python
+commons: CommonQueryParams = Depends(CommonQueryParams)
+```
+
+////
+
+**FastAPI** fournit un raccourci pour ces cas, lorsque la dépendance est spécifiquement une classe que **FastAPI** va « appeler » pour créer une instance de la classe elle‑même.
+
+Pour ces cas précis, vous pouvez faire ce qui suit :
+
+Au lieu d'écrire :
+
+//// tab | Python 3.10+
+
+```Python
+commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
+```
+
+////
+
+//// tab | Python 3.10+ sans Annotated
+
+/// tip | Astuce
+
+Privilégiez la version avec `Annotated` si possible.
+
+///
+
+```Python
+commons: CommonQueryParams = Depends(CommonQueryParams)
+```
+
+////
+
+... vous écrivez :
+
+//// tab | Python 3.10+
+
+```Python
+commons: Annotated[CommonQueryParams, Depends()]
+```
+
+////
+
+//// tab | Python 3.10+ sans Annotated
+
+/// tip | Astuce
+
+Privilégiez la version avec `Annotated` si possible.
+
+///
+
+```Python
+commons: CommonQueryParams = Depends()
+```
+
+////
+
+Vous déclarez la dépendance comme type du paramètre et vous utilisez `Depends()` sans aucun paramètre, au lieu d'avoir à réécrire la classe entière à l'intérieur de `Depends(CommonQueryParams)`.
+
+Le même exemple ressemblerait alors à ceci :
+
+{* ../../docs_src/dependencies/tutorial004_an_py310.py hl[19] *}
+
+... et **FastAPI** saura quoi faire.
+
+/// tip | Astuce
+
+Si cela vous semble plus déroutant qu'utile, ignorez‑le, vous n'en avez pas besoin.
+
+Ce n'est qu'un raccourci. Parce que **FastAPI** tient à vous aider à minimiser la duplication de code.
+
+///
diff --git a/docs/fr/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md b/docs/fr/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
new file mode 100644
index 000000000..bf697fe8d
--- /dev/null
+++ b/docs/fr/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
@@ -0,0 +1,69 @@
+# Gérer les dépendances dans les décorateurs de chemins d'accès { #dependencies-in-path-operation-decorators }
+
+Dans certains cas, vous n'avez pas vraiment besoin de la valeur de retour d'une dépendance dans votre *fonction de chemin d'accès*.
+
+Ou la dépendance ne retourne aucune valeur.
+
+Mais vous avez quand même besoin qu'elle soit exécutée/résolue.
+
+Dans ces cas, au lieu de déclarer un paramètre de *fonction de chemin d'accès* avec `Depends`, vous pouvez ajouter une `list` de `dependencies` au *décorateur de chemin d'accès*.
+
+## Ajouter `dependencies` au *décorateur de chemin d'accès* { #add-dependencies-to-the-path-operation-decorator }
+
+Le *décorateur de chemin d'accès* accepte un argument optionnel `dependencies`.
+
+Il doit s'agir d'une `list` de `Depends()` :
+
+{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[19] *}
+
+Ces dépendances seront exécutées/résolues de la même manière que des dépendances normales. Mais leur valeur (si elles en retournent une) ne sera pas transmise à votre *fonction de chemin d'accès*.
+
+/// tip | Astuce
+
+Certains éditeurs vérifient les paramètres de fonction non utilisés et les signalent comme des erreurs.
+
+En utilisant ces `dependencies` dans le *décorateur de chemin d'accès*, vous pouvez vous assurer qu'elles sont exécutées tout en évitant des erreurs de l'éditeur/des outils.
+
+Cela peut également éviter toute confusion pour les nouveaux développeurs qui voient un paramètre inutilisé dans votre code et pourraient penser qu'il est superflu.
+
+///
+
+/// info | Info
+
+Dans cet exemple, nous utilisons des en-têtes personnalisés fictifs `X-Key` et `X-Token`.
+
+Mais dans des cas réels, lors de l'implémentation de la sécurité, vous tirerez davantage d'avantages en utilisant les [utilitaires de sécurité (chapitre suivant)](../security/index.md){.internal-link target=_blank} intégrés.
+
+///
+
+## Gérer les erreurs et les valeurs de retour des dépendances { #dependencies-errors-and-return-values }
+
+Vous pouvez utiliser les mêmes *fonctions* de dépendance que d'habitude.
+
+### Définir les exigences des dépendances { #dependency-requirements }
+
+Elles peuvent déclarer des exigences pour la requête (comme des en-têtes) ou d'autres sous-dépendances :
+
+{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[8,13] *}
+
+### Lever des exceptions { #raise-exceptions }
+
+Ces dépendances peuvent `raise` des exceptions, comme des dépendances normales :
+
+{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[10,15] *}
+
+### Gérer les valeurs de retour { #return-values }
+
+Elles peuvent retourner des valeurs ou non, ces valeurs ne seront pas utilisées.
+
+Vous pouvez donc réutiliser une dépendance normale (qui retourne une valeur) que vous utilisez déjà ailleurs ; même si la valeur n'est pas utilisée, la dépendance sera exécutée :
+
+{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[11,16] *}
+
+## Définir des dépendances pour un groupe de chemins d'accès { #dependencies-for-a-group-of-path-operations }
+
+Plus tard, en lisant comment structurer des applications plus grandes ([Applications plus grandes - Plusieurs fichiers](../../tutorial/bigger-applications.md){.internal-link target=_blank}), éventuellement avec plusieurs fichiers, vous apprendrez à déclarer un unique paramètre `dependencies` pour un groupe de *chemins d'accès*.
+
+## Définir des dépendances globales { #global-dependencies }
+
+Ensuite, nous verrons comment ajouter des dépendances à l'application `FastAPI` entière, afin qu'elles s'appliquent à chaque *chemin d'accès*.
diff --git a/docs/fr/docs/tutorial/dependencies/dependencies-with-yield.md b/docs/fr/docs/tutorial/dependencies/dependencies-with-yield.md
new file mode 100644
index 000000000..3f06df767
--- /dev/null
+++ b/docs/fr/docs/tutorial/dependencies/dependencies-with-yield.md
@@ -0,0 +1,289 @@
+# Utiliser des dépendances avec `yield` { #dependencies-with-yield }
+
+FastAPI prend en charge des dépendances qui effectuent des étapes supplémentaires après l'exécution.
+
+Pour cela, utilisez `yield` au lieu de `return`, et écrivez les étapes supplémentaires (code) après.
+
+/// tip | Astuce
+
+Vous devez vous assurer d'utiliser `yield` une seule fois par dépendance.
+
+///
+
+/// note | Détails techniques
+
+Toute fonction valide à utiliser avec :
+
+* `@contextlib.contextmanager` ou
+* `@contextlib.asynccontextmanager`
+
+sera valide comme dépendance **FastAPI**.
+
+En fait, FastAPI utilise ces deux décorateurs en interne.
+
+///
+
+## Créer une dépendance de base de données avec `yield` { #a-database-dependency-with-yield }
+
+Par exemple, vous pouvez l'utiliser pour créer une session de base de données et la fermer après la fin.
+
+Seul le code précédant et incluant l'instruction `yield` est exécuté avant la création de la réponse :
+
+{* ../../docs_src/dependencies/tutorial007_py310.py hl[2:4] *}
+
+La valeur transmise par `yield` est celle qui est injectée dans les *chemins d'accès* et autres dépendances :
+
+{* ../../docs_src/dependencies/tutorial007_py310.py hl[4] *}
+
+Le code suivant l'instruction `yield` est exécuté après la réponse :
+
+{* ../../docs_src/dependencies/tutorial007_py310.py hl[5:6] *}
+
+/// tip | Astuce
+
+Vous pouvez utiliser des fonctions `async` ou des fonctions classiques.
+
+**FastAPI** fera ce qu'il faut dans chaque cas, comme avec des dépendances normales.
+
+///
+
+## Créer une dépendance avec `yield` et `try` { #a-dependency-with-yield-and-try }
+
+Si vous utilisez un bloc `try` dans une dépendance avec `yield`, vous recevrez toute exception qui a été levée lors de l'utilisation de la dépendance.
+
+Par exemple, si à un moment donné, dans une autre dépendance ou dans un *chemin d'accès*, un code a effectué un « rollback » de transaction de base de données ou a créé une autre exception, vous recevrez l'exception dans votre dépendance.
+
+Vous pouvez donc rechercher cette exception spécifique dans la dépendance avec `except SomeException`.
+
+De la même manière, vous pouvez utiliser `finally` pour vous assurer que les étapes de sortie sont exécutées, qu'il y ait eu une exception ou non.
+
+{* ../../docs_src/dependencies/tutorial007_py310.py hl[3,5] *}
+
+## Utiliser des sous-dépendances avec `yield` { #sub-dependencies-with-yield }
+
+Vous pouvez avoir des sous-dépendances et des « arbres » de sous-dépendances de toute taille et forme, et certaines ou toutes peuvent utiliser `yield`.
+
+**FastAPI** s'assurera que le « code de sortie » dans chaque dépendance avec `yield` est exécuté dans le bon ordre.
+
+Par exemple, `dependency_c` peut dépendre de `dependency_b`, et `dependency_b` de `dependency_a` :
+
+{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[6,14,22] *}
+
+Et elles peuvent toutes utiliser `yield`.
+
+Dans ce cas, `dependency_c`, pour exécuter son code de sortie, a besoin que la valeur de `dependency_b` (appelée ici `dep_b`) soit toujours disponible.
+
+Et, à son tour, `dependency_b` a besoin que la valeur de `dependency_a` (appelée ici `dep_a`) soit disponible pour son code de sortie.
+
+{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[18:19,26:27] *}
+
+De la même manière, vous pouvez avoir certaines dépendances avec `yield` et d'autres avec `return`, et faire en sorte que certaines dépendent des autres.
+
+Et vous pouvez avoir une seule dépendance qui exige plusieurs autres dépendances avec `yield`, etc.
+
+Vous pouvez combiner les dépendances comme vous le souhaitez.
+
+**FastAPI** s'assurera que tout est exécuté dans le bon ordre.
+
+/// note | Détails techniques
+
+Cela fonctionne grâce aux gestionnaires de contexte de Python.
+
+**FastAPI** les utilise en interne pour y parvenir.
+
+///
+
+## Utiliser des dépendances avec `yield` et `HTTPException` { #dependencies-with-yield-and-httpexception }
+
+Vous avez vu que vous pouvez utiliser des dépendances avec `yield` et avoir des blocs `try` qui tentent d'exécuter du code puis exécutent du code de sortie après `finally`.
+
+Vous pouvez également utiliser `except` pour intercepter l'exception qui a été levée et faire quelque chose avec.
+
+Par exemple, vous pouvez lever une autre exception, comme `HTTPException`.
+
+/// tip | Astuce
+
+C'est une technique plutôt avancée, et dans la plupart des cas vous n'en aurez pas vraiment besoin, car vous pouvez lever des exceptions (y compris `HTTPException`) depuis le reste de votre code applicatif, par exemple, dans la *fonction de chemin d'accès*.
+
+Mais elle est à votre disposition si vous en avez besoin. 🤓
+
+///
+
+{* ../../docs_src/dependencies/tutorial008b_an_py310.py hl[18:22,31] *}
+
+Si vous souhaitez intercepter des exceptions et créer une réponse personnalisée en fonction de cela, créez un [Gestionnaire d'exceptions personnalisé](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
+
+## Utiliser des dépendances avec `yield` et `except` { #dependencies-with-yield-and-except }
+
+Si vous interceptez une exception avec `except` dans une dépendance avec `yield` et que vous ne la relancez pas (ou que vous ne levez pas une nouvelle exception), FastAPI ne pourra pas remarquer qu'il y a eu une exception, de la même manière que cela se produirait avec Python classique :
+
+{* ../../docs_src/dependencies/tutorial008c_an_py310.py hl[15:16] *}
+
+Dans ce cas, le client verra une réponse *HTTP 500 Internal Server Error* comme il se doit, étant donné que nous ne levons pas de `HTTPException` ou similaire, mais le serveur **n'aura aucun logs** ni aucune autre indication de l'erreur. 😱
+
+### Toujours `raise` dans les dépendances avec `yield` et `except` { #always-raise-in-dependencies-with-yield-and-except }
+
+Si vous interceptez une exception dans une dépendance avec `yield`, à moins de lever une autre `HTTPException` ou similaire, **vous devez relancer l'exception d'origine**.
+
+Vous pouvez relancer la même exception avec `raise` :
+
+{* ../../docs_src/dependencies/tutorial008d_an_py310.py hl[17] *}
+
+À présent, le client recevra la même réponse *HTTP 500 Internal Server Error*, mais le serveur aura notre `InternalError` personnalisé dans les logs. 😎
+
+## Comprendre l'exécution des dépendances avec `yield` { #execution-of-dependencies-with-yield }
+
+La séquence d'exécution ressemble plus ou moins à ce diagramme. Le temps s'écoule de haut en bas. Et chaque colonne représente une des parties qui interagit ou exécute du code.
+
+```mermaid
+sequenceDiagram
+
+participant client as Client
+participant handler as Exception handler
+participant dep as Dep with yield
+participant operation as Path Operation
+participant tasks as Background tasks
+
+ Note over client,operation: Can raise exceptions, including HTTPException
+ client ->> dep: Start request
+ Note over dep: Run code up to yield
+ opt raise Exception
+ dep -->> handler: Raise Exception
+ handler -->> client: HTTP error response
+ end
+ dep ->> operation: Run dependency, e.g. DB session
+ opt raise
+ operation -->> dep: Raise Exception (e.g. HTTPException)
+ opt handle
+ dep -->> dep: Can catch exception, raise a new HTTPException, raise other exception
+ end
+ handler -->> client: HTTP error response
+ end
+
+ operation ->> client: Return response to client
+ Note over client,operation: Response is already sent, can't change it anymore
+ opt Tasks
+ operation -->> tasks: Send background tasks
+ end
+ opt Raise other exception
+ tasks -->> tasks: Handle exceptions in the background task code
+ end
+```
+
+/// info
+
+Une **seule réponse** sera envoyée au client. Il peut s'agir d'une des réponses d'erreur ou de la réponse provenant du *chemin d'accès*.
+
+Après l'envoi de l'une de ces réponses, aucune autre réponse ne peut être envoyée.
+
+///
+
+/// tip | Astuce
+
+Si vous levez une exception dans le code de la *fonction de chemin d'accès*, elle sera transmise aux dépendances avec `yield`, y compris `HTTPException`. Dans la plupart des cas, vous voudrez relancer cette même exception ou en lever une nouvelle depuis la dépendance avec `yield` pour vous assurer qu'elle est correctement gérée.
+
+///
+
+## Utiliser la sortie anticipée et `scope` { #early-exit-and-scope }
+
+Normalement, le code de sortie des dépendances avec `yield` est exécuté **après la réponse** envoyée au client.
+
+Mais si vous savez que vous n'aurez pas besoin d'utiliser la dépendance après être revenu de la *fonction de chemin d'accès*, vous pouvez utiliser `Depends(scope="function")` pour indiquer à FastAPI qu'il doit fermer la dépendance après le retour de la *fonction de chemin d'accès*, mais **avant** que la **réponse ne soit envoyée**.
+
+{* ../../docs_src/dependencies/tutorial008e_an_py310.py hl[12,16] *}
+
+`Depends()` reçoit un paramètre `scope` qui peut être :
+
+* « function » : démarrer la dépendance avant la *fonction de chemin d'accès* qui gère la requête, terminer la dépendance après la fin de la *fonction de chemin d'accès*, mais **avant** que la réponse ne soit renvoyée au client. Ainsi, la fonction de dépendance sera exécutée **autour** de la *fonction de chemin d'accès*.
+* « request » : démarrer la dépendance avant la *fonction de chemin d'accès* qui gère la requête (similaire à l'utilisation de « function »), mais terminer **après** que la réponse a été renvoyée au client. Ainsi, la fonction de dépendance sera exécutée **autour** du cycle **requête** et réponse.
+
+S'il n'est pas spécifié et que la dépendance utilise `yield`, le `scope` sera par défaut « request ».
+
+### Définir `scope` pour les sous-dépendances { #scope-for-sub-dependencies }
+
+Lorsque vous déclarez une dépendance avec un `scope="request"` (par défaut), toute sous-dépendance doit également avoir un `scope` de « request ».
+
+Mais une dépendance avec un `scope` de « function » peut avoir des dépendances avec un `scope` de « function » et un `scope` de « request ».
+
+Cela vient du fait que toute dépendance doit pouvoir exécuter son code de sortie avant ses sous-dépendances, car elle pourrait encore avoir besoin de les utiliser pendant son code de sortie.
+
+```mermaid
+sequenceDiagram
+
+participant client as Client
+participant dep_req as Dep scope="request"
+participant dep_func as Dep scope="function"
+participant operation as Path Operation
+
+ client ->> dep_req: Start request
+ Note over dep_req: Run code up to yield
+ dep_req ->> dep_func: Pass dependency
+ Note over dep_func: Run code up to yield
+ dep_func ->> operation: Run path operation with dependency
+ operation ->> dep_func: Return from path operation
+ Note over dep_func: Run code after yield
+ Note over dep_func: ✅ Dependency closed
+ dep_func ->> client: Send response to client
+ Note over client: Response sent
+ Note over dep_req: Run code after yield
+ Note over dep_req: ✅ Dependency closed
+```
+
+## Utiliser des dépendances avec `yield`, `HTTPException`, `except` et Background Tasks { #dependencies-with-yield-httpexception-except-and-background-tasks }
+
+Les dépendances avec `yield` ont évolué au fil du temps pour couvrir différents cas d'utilisation et corriger certains problèmes.
+
+Si vous souhaitez voir ce qui a changé dans différentes versions de FastAPI, vous pouvez en savoir plus dans le guide avancé, dans [Dépendances avancées - Dépendances avec `yield`, `HTTPException`, `except` et Background Tasks](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks){.internal-link target=_blank}.
+## Gestionnaires de contexte { #context-managers }
+
+### Que sont les « Context Managers » { #what-are-context-managers }
+
+Les « Context Managers » sont des objets Python que vous pouvez utiliser dans une instruction `with`.
+
+Par exemple, vous pouvez utiliser `with` pour lire un fichier :
+
+```Python
+with open("./somefile.txt") as f:
+ contents = f.read()
+ print(contents)
+```
+
+En coulisse, `open("./somefile.txt")` crée un objet appelé « Context Manager ».
+
+Lorsque le bloc `with` se termine, il s'assure de fermer le fichier, même s'il y a eu des exceptions.
+
+Lorsque vous créez une dépendance avec `yield`, **FastAPI** créera en interne un gestionnaire de contexte pour celle-ci et le combinera avec d'autres outils associés.
+
+### Utiliser des gestionnaires de contexte dans des dépendances avec `yield` { #using-context-managers-in-dependencies-with-yield }
+
+/// warning | Alertes
+
+C'est, plus ou moins, une idée « avancée ».
+
+Si vous débutez avec **FastAPI**, vous voudrez peut-être l'ignorer pour le moment.
+
+///
+
+En Python, vous pouvez créer des gestionnaires de contexte en créant une classe avec deux méthodes : `__enter__()` et `__exit__()`.
+
+Vous pouvez également les utiliser dans des dépendances **FastAPI** avec `yield` en utilisant
+des instructions `with` ou `async with` à l'intérieur de la fonction de dépendance :
+
+{* ../../docs_src/dependencies/tutorial010_py310.py hl[1:9,13] *}
+
+/// tip | Astuce
+
+Une autre façon de créer un gestionnaire de contexte consiste à utiliser :
+
+* `@contextlib.contextmanager` ou
+* `@contextlib.asynccontextmanager`
+
+pour décorer une fonction avec un unique `yield`.
+
+C'est ce que **FastAPI** utilise en interne pour les dépendances avec `yield`.
+
+Mais vous n'avez pas à utiliser ces décorateurs pour les dépendances FastAPI (et vous ne devriez pas).
+
+FastAPI le fera pour vous en interne.
+
+///
diff --git a/docs/fr/docs/tutorial/dependencies/global-dependencies.md b/docs/fr/docs/tutorial/dependencies/global-dependencies.md
new file mode 100644
index 000000000..2c418ee4a
--- /dev/null
+++ b/docs/fr/docs/tutorial/dependencies/global-dependencies.md
@@ -0,0 +1,15 @@
+# Dépendances globales { #global-dependencies }
+
+Pour certains types d'applications, vous pourriez vouloir ajouter des dépendances à l'application entière.
+
+Comme vous pouvez [ajouter des `dependencies` aux *décorateurs de chemin d'accès*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, vous pouvez les ajouter à l'application `FastAPI`.
+
+Dans ce cas, elles seront appliquées à tous les *chemins d'accès* de l'application :
+
+{* ../../docs_src/dependencies/tutorial012_an_py310.py hl[17] *}
+
+Et toutes les idées de la section sur [l'ajout de `dependencies` aux *décorateurs de chemin d'accès*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} s'appliquent toujours, mais dans ce cas à tous les *chemins d'accès* de l'application.
+
+## Dépendances pour des groupes de *chemins d'accès* { #dependencies-for-groups-of-path-operations }
+
+Plus tard, en lisant comment structurer des applications plus grandes ([Applications plus grandes - Plusieurs fichiers](../../tutorial/bigger-applications.md){.internal-link target=_blank}), éventuellement avec plusieurs fichiers, vous apprendrez comment déclarer un unique paramètre `dependencies` pour un groupe de *chemins d'accès*.
diff --git a/docs/fr/docs/tutorial/dependencies/index.md b/docs/fr/docs/tutorial/dependencies/index.md
new file mode 100644
index 000000000..8fad77f62
--- /dev/null
+++ b/docs/fr/docs/tutorial/dependencies/index.md
@@ -0,0 +1,250 @@
+# Dépendances { #dependencies }
+
+**FastAPI** dispose d’un système d’**Injection de dépendances** très puissant mais intuitif.
+
+Il est conçu pour être très simple à utiliser, et pour faciliter l’intégration d’autres composants à **FastAPI** pour n’importe quel développeur.
+
+## Qu’est-ce que « l’injection de dépendances » { #what-is-dependency-injection }
+
+L’**« injection de dépendances »** signifie, en programmation, qu’il existe un moyen pour votre code (dans ce cas, vos fonctions de chemins d’accès) de déclarer ce dont il a besoin pour fonctionner et utiliser : « dépendances ».
+
+Ensuite, ce système (dans ce cas **FastAPI**) se charge de faire tout le nécessaire pour fournir à votre code ces dépendances requises (« injecter » les dépendances).
+
+C’est très utile lorsque vous avez besoin de :
+
+* Avoir de la logique partagée (la même logique de code encore et encore).
+* Partager des connexions à la base de données.
+* Imposer la sécurité, l’authentification, des exigences de rôles, etc.
+* Et bien d’autres choses ...
+
+Tout cela, en minimisant la répétition de code.
+
+## Premiers pas { #first-steps }
+
+Voyons un exemple très simple. Il sera tellement simple qu’il n’est pas très utile, pour l’instant.
+
+Mais de cette façon nous pouvons nous concentrer sur le fonctionnement du système d’**injection de dépendances**.
+
+### Créer une dépendance, ou « dependable » { #create-a-dependency-or-dependable }
+
+Concentrons-nous d’abord sur la dépendance.
+
+C’est simplement une fonction qui peut prendre tous les mêmes paramètres qu’une fonction de chemin d’accès peut prendre :
+
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[8:9] *}
+
+C’est tout.
+
+**2 lignes**.
+
+Et elle a la même forme et structure que toutes vos fonctions de chemins d’accès.
+
+Vous pouvez la considérer comme une fonction de chemin d’accès sans le « décorateur » (sans le `@app.get("/some-path")`).
+
+Et elle peut retourner tout ce que vous voulez.
+
+Dans ce cas, cette dépendance attend :
+
+* Un paramètre de requête optionnel `q` qui est une `str`.
+* Un paramètre de requête optionnel `skip` qui est un `int`, et vaut `0` par défaut.
+* Un paramètre de requête optionnel `limit` qui est un `int`, et vaut `100` par défaut.
+
+Puis elle retourne simplement un `dict` contenant ces valeurs.
+
+/// info | Info
+
+FastAPI a ajouté la prise en charge de `Annotated` (et a commencé à le recommander) dans la version 0.95.0.
+
+Si vous avez une version plus ancienne, vous obtiendrez des erreurs en essayant d’utiliser `Annotated`.
+
+Vous devez vous assurer de [mettre à niveau la version de FastAPI](../../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} vers au moins la 0.95.1 avant d’utiliser `Annotated`.
+
+///
+
+### Importer `Depends` { #import-depends }
+
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[3] *}
+
+### Déclarer la dépendance, dans le « dependant » { #declare-the-dependency-in-the-dependant }
+
+De la même manière que vous utilisez `Body`, `Query`, etc. avec les paramètres de votre fonction de chemin d’accès, utilisez `Depends` avec un nouveau paramètre :
+
+{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[13,18] *}
+
+Même si vous utilisez `Depends` dans les paramètres de votre fonction de la même façon que `Body`, `Query`, etc., `Depends` fonctionne un peu différemment.
+
+Vous ne donnez à `Depends` qu’un seul paramètre.
+
+Ce paramètre doit être quelque chose comme une fonction.
+
+Vous ne l’appelez pas directement (n’ajoutez pas de parenthèses à la fin), vous le passez simplement en paramètre à `Depends()`.
+
+Et cette fonction prend des paramètres de la même manière que les fonctions de chemins d’accès.
+
+/// tip | Astuce
+
+Vous verrez quelles autres « choses », en plus des fonctions, peuvent être utilisées comme dépendances dans le prochain chapitre.
+
+///
+
+Chaque fois qu’une nouvelle requête arrive, **FastAPI** se charge de :
+
+* Appeler votre fonction de dépendance (« dependable ») avec les bons paramètres.
+* Récupérer le résultat de votre fonction.
+* Affecter ce résultat au paramètre dans votre fonction de chemin d’accès.
+
+```mermaid
+graph TB
+
+common_parameters(["common_parameters"])
+read_items["/items/"]
+read_users["/users/"]
+
+common_parameters --> read_items
+common_parameters --> read_users
+```
+
+De cette façon vous écrivez le code partagé une seule fois et **FastAPI** se charge de l’appeler pour vos chemins d’accès.
+
+/// check | Vérifications
+
+Notez que vous n’avez pas à créer une classe spéciale et à la passer quelque part à **FastAPI** pour l’« enregistrer » ou quoi que ce soit de similaire.
+
+Vous la passez simplement à `Depends` et **FastAPI** sait faire le reste.
+
+///
+
+## Partager des dépendances `Annotated` { #share-annotated-dependencies }
+
+Dans les exemples ci-dessus, vous voyez qu’il y a un tout petit peu de **duplication de code**.
+
+Lorsque vous devez utiliser la dépendance `common_parameters()`, vous devez écrire tout le paramètre avec l’annotation de type et `Depends()` :
+
+```Python
+commons: Annotated[dict, Depends(common_parameters)]
+```
+
+Mais comme nous utilisons `Annotated`, nous pouvons stocker cette valeur `Annotated` dans une variable et l’utiliser à plusieurs endroits :
+
+{* ../../docs_src/dependencies/tutorial001_02_an_py310.py hl[12,16,21] *}
+
+/// tip | Astuce
+
+C’est simplement du Python standard, cela s’appelle un « alias de type », ce n’est en fait pas spécifique à **FastAPI**.
+
+Mais comme **FastAPI** est basé sur les standards Python, y compris `Annotated`, vous pouvez utiliser cette astuce dans votre code. 😎
+
+///
+
+Les dépendances continueront de fonctionner comme prévu, et la **meilleure partie** est que **l’information de type sera conservée**, ce qui signifie que votre éditeur pourra continuer à vous fournir **l’autocomplétion**, **des erreurs en ligne**, etc. Idem pour d’autres outils comme `mypy`.
+
+Cela sera particulièrement utile lorsque vous l’utiliserez dans une **grande base de code** où vous utilisez **les mêmes dépendances** encore et encore dans **de nombreux chemins d’accès**.
+
+## Utiliser `async` ou non { #to-async-or-not-to-async }
+
+Comme les dépendances seront aussi appelées par **FastAPI** (tout comme vos fonctions de chemins d’accès), les mêmes règles s’appliquent lors de la définition de vos fonctions.
+
+Vous pouvez utiliser `async def` ou un `def` normal.
+
+Et vous pouvez déclarer des dépendances avec `async def` à l’intérieur de fonctions de chemins d’accès `def` normales, ou des dépendances `def` à l’intérieur de fonctions de chemins d’accès `async def`, etc.
+
+Peu importe. **FastAPI** saura quoi faire.
+
+/// note | Remarque
+
+Si vous ne savez pas, consultez la section [Async : *« Pressé ? »*](../../async.md#in-a-hurry){.internal-link target=_blank} à propos de `async` et `await` dans la documentation.
+
+///
+
+## Intégrer à OpenAPI { #integrated-with-openapi }
+
+Toutes les déclarations de requête, validations et exigences de vos dépendances (et sous-dépendances) seront intégrées dans le même schéma OpenAPI.
+
+Ainsi, la documentation interactive contiendra aussi toutes les informations issues de ces dépendances :
+
+
+
+## Utilisation simple { #simple-usage }
+
+Si vous y regardez de près, les fonctions de chemins d’accès sont déclarées pour être utilisées chaque fois qu’un « chemin » et une « opération » correspondent, puis **FastAPI** se charge d’appeler la fonction avec les bons paramètres, en extrayant les données de la requête.
+
+En réalité, tous (ou la plupart) des frameworks web fonctionnent de cette manière.
+
+Vous n’appelez jamais ces fonctions directement. Elles sont appelées par votre framework (dans ce cas, **FastAPI**).
+
+Avec le système d’injection de dépendances, vous pouvez aussi indiquer à **FastAPI** que votre fonction de chemin d’accès « dépend » également d’autre chose qui doit être exécuté avant votre fonction de chemin d’accès, et **FastAPI** se chargera de l’exécuter et d’« injecter » les résultats.
+
+D’autres termes courants pour cette même idée « d’injection de dépendances » sont :
+
+* ressources
+* fournisseurs
+* services
+* injectables
+* composants
+
+## Plug-ins **FastAPI** { #fastapi-plug-ins }
+
+Les intégrations et « plug-ins » peuvent être construits en utilisant le système d’**injection de dépendances**. Mais en réalité, il n’y a **pas besoin de créer des « plug-ins »**, car en utilisant des dépendances il est possible de déclarer un nombre infini d’intégrations et d’interactions qui deviennent disponibles pour vos fonctions de chemins d’accès.
+
+Et les dépendances peuvent être créées de manière très simple et intuitive, ce qui vous permet d’importer juste les packages Python dont vous avez besoin, et de les intégrer à vos fonctions d’API en quelques lignes de code, *littéralement*.
+
+Vous verrez des exemples de cela dans les prochains chapitres, à propos des bases de données relationnelles et NoSQL, de la sécurité, etc.
+
+## Compatibilité **FastAPI** { #fastapi-compatibility }
+
+La simplicité du système d’injection de dépendances rend **FastAPI** compatible avec :
+
+* toutes les bases de données relationnelles
+* les bases de données NoSQL
+* les packages externes
+* les API externes
+* les systèmes d’authentification et d’autorisation
+* les systèmes de supervision d’usage d’API
+* les systèmes d’injection de données de réponse
+* etc.
+
+## Simple et puissant { #simple-and-powerful }
+
+Bien que le système hiérarchique d’injection de dépendances soit très simple à définir et à utiliser, il reste très puissant.
+
+Vous pouvez définir des dépendances qui, à leur tour, peuvent définir leurs propres dépendances.
+
+Au final, un arbre hiérarchique de dépendances est construit, et le système d’**injection de dépendances** se charge de résoudre toutes ces dépendances pour vous (et leurs sous-dépendances) et de fournir (injecter) les résultats à chaque étape.
+
+Par exemple, supposons que vous ayez 4 endpoints d’API (chemins d’accès) :
+
+* `/items/public/`
+* `/items/private/`
+* `/users/{user_id}/activate`
+* `/items/pro/`
+
+alors vous pourriez ajouter différentes exigences d’autorisations pour chacun d’eux uniquement avec des dépendances et des sous-dépendances :
+
+```mermaid
+graph TB
+
+current_user(["current_user"])
+active_user(["active_user"])
+admin_user(["admin_user"])
+paying_user(["paying_user"])
+
+public["/items/public/"]
+private["/items/private/"]
+activate_user["/users/{user_id}/activate"]
+pro_items["/items/pro/"]
+
+current_user --> active_user
+active_user --> admin_user
+active_user --> paying_user
+
+current_user --> public
+active_user --> private
+admin_user --> activate_user
+paying_user --> pro_items
+```
+
+## Intégrer à **OpenAPI** { #integrated-with-openapi_1 }
+
+Toutes ces dépendances, tout en déclarant leurs exigences, ajoutent également des paramètres, des validations, etc. à vos chemins d’accès.
+
+**FastAPI** se chargera d’ajouter le tout au schéma OpenAPI, afin que cela apparaisse dans les systèmes de documentation interactive.
diff --git a/docs/fr/docs/tutorial/dependencies/sub-dependencies.md b/docs/fr/docs/tutorial/dependencies/sub-dependencies.md
new file mode 100644
index 000000000..473ff02ba
--- /dev/null
+++ b/docs/fr/docs/tutorial/dependencies/sub-dependencies.md
@@ -0,0 +1,105 @@
+# Sous-dépendances { #sub-dependencies }
+
+Vous pouvez créer des dépendances qui ont des sous-dépendances.
+
+Elles peuvent être aussi profondes que nécessaire.
+
+**FastAPI** se chargera de les résoudre.
+
+## Créer une première dépendance « dependable » { #first-dependency-dependable }
+
+Vous pouvez créer une première dépendance (« dependable ») comme :
+
+{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[8:9] *}
+
+Elle déclare un paramètre de requête optionnel `q` de type `str`, puis le retourne simplement.
+
+C'est assez simple (pas très utile), mais cela nous aidera à nous concentrer sur le fonctionnement des sous-dépendances.
+
+## Créer une seconde dépendance, « dependable » et « dependant » { #second-dependency-dependable-and-dependant }
+
+Vous pouvez ensuite créer une autre fonction de dépendance (un « dependable ») qui, en même temps, déclare sa propre dépendance (elle est donc aussi un « dependant ») :
+
+{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[13] *}
+
+Concentrons-nous sur les paramètres déclarés :
+
+- Même si cette fonction est elle‑même une dépendance (« dependable »), elle déclare aussi une autre dépendance (elle « dépend » d'autre chose).
+ - Elle dépend de `query_extractor` et affecte la valeur renvoyée au paramètre `q`.
+- Elle déclare également un cookie `last_query` optionnel, de type `str`.
+ - Si l'utilisateur n'a fourni aucune requête `q`, nous utilisons la dernière requête utilisée, que nous avons enregistrée auparavant dans un cookie.
+
+## Utiliser la dépendance { #use-the-dependency }
+
+Nous pouvons ensuite utiliser la dépendance avec :
+
+{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[23] *}
+
+/// info
+
+Notez que nous ne déclarons qu'une seule dépendance dans la *fonction de chemin d'accès*, `query_or_cookie_extractor`.
+
+Mais **FastAPI** saura qu'il doit d'abord résoudre `query_extractor`, pour passer ses résultats à `query_or_cookie_extractor` lors de son appel.
+
+///
+
+```mermaid
+graph TB
+
+query_extractor(["query_extractor"])
+query_or_cookie_extractor(["query_or_cookie_extractor"])
+
+read_query["/items/"]
+
+query_extractor --> query_or_cookie_extractor --> read_query
+```
+
+## Utiliser la même dépendance plusieurs fois { #using-the-same-dependency-multiple-times }
+
+Si l'une de vos dépendances est déclarée plusieurs fois pour le même *chemin d'accès*, par exemple si plusieurs dépendances ont une sous-dépendance commune, **FastAPI** saura n'appeler cette sous-dépendance qu'une seule fois par requête.
+
+Et il enregistrera la valeur renvoyée dans un « cache » et la transmettra à tous les « dependants » qui en ont besoin dans cette requête spécifique, au lieu d'appeler la dépendance plusieurs fois pour la même requête.
+
+Dans un scénario avancé où vous savez que vous avez besoin que la dépendance soit appelée à chaque étape (éventuellement plusieurs fois) dans la même requête au lieu d'utiliser la valeur « mise en cache », vous pouvez définir le paramètre `use_cache=False` lors de l'utilisation de `Depends` :
+
+//// tab | Python 3.10+
+
+```Python hl_lines="1"
+async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
+ return {"fresh_value": fresh_value}
+```
+
+////
+
+//// tab | Python 3.10+ non annoté
+
+/// tip | Astuce
+
+Privilégiez la version `Annotated` si possible.
+
+///
+
+```Python hl_lines="1"
+async def needy_dependency(fresh_value: str = Depends(get_value, use_cache=False)):
+ return {"fresh_value": fresh_value}
+```
+
+////
+
+## Récapituler { #recap }
+
+En dehors de tout le jargon utilisé ici, le système d'**injection de dépendances** est assez simple.
+
+Ce ne sont que des fonctions qui ressemblent aux *fonctions de chemin d'accès*.
+
+Mais il est très puissant et vous permet de déclarer des « graphes » (arbres) de dépendances imbriquées aussi profondément que vous le souhaitez.
+
+/// tip | Astuce
+
+Tout cela peut ne pas sembler très utile avec ces exemples simples.
+
+Mais vous verrez à quel point c'est utile dans les chapitres sur la **sécurité**.
+
+Et vous verrez aussi la quantité de code que cela vous fera économiser.
+
+///
diff --git a/docs/fr/docs/tutorial/encoder.md b/docs/fr/docs/tutorial/encoder.md
new file mode 100644
index 000000000..f94be429c
--- /dev/null
+++ b/docs/fr/docs/tutorial/encoder.md
@@ -0,0 +1,35 @@
+# Encodeur compatible JSON { #json-compatible-encoder }
+
+Il existe des cas où vous pourriez avoir besoin de convertir un type de données (comme un modèle Pydantic) en quelque chose de compatible avec JSON (comme un `dict`, `list`, etc.).
+
+Par exemple, si vous devez le stocker dans une base de données.
+
+Pour cela, **FastAPI** fournit une fonction `jsonable_encoder()`.
+
+## Utiliser `jsonable_encoder` { #using-the-jsonable-encoder }
+
+Imaginons que vous ayez une base de données `fake_db` qui ne reçoit que des données compatibles JSON.
+
+Par exemple, elle ne reçoit pas d'objets `datetime`, car ceux-ci ne sont pas compatibles avec JSON.
+
+Ainsi, un objet `datetime` doit être converti en une `str` contenant les données au format ISO.
+
+De la même manière, cette base de données n'accepterait pas un modèle Pydantic (un objet avec des attributs), seulement un `dict`.
+
+Vous pouvez utiliser `jsonable_encoder` pour cela.
+
+Elle reçoit un objet, comme un modèle Pydantic, et renvoie une version compatible JSON :
+
+{* ../../docs_src/encoder/tutorial001_py310.py hl[4,21] *}
+
+Dans cet exemple, elle convertirait le modèle Pydantic en `dict`, et le `datetime` en `str`.
+
+Le résultat de son appel est quelque chose qui peut être encodé avec la fonction standard de Python `json.dumps()`.
+
+Elle ne renvoie pas une grande `str` contenant les données au format JSON (sous forme de chaîne). Elle renvoie une structure de données standard de Python (par ex. un `dict`) avec des valeurs et sous-valeurs toutes compatibles avec JSON.
+
+/// note | Remarque
+
+`jsonable_encoder` est en fait utilisée par **FastAPI** en interne pour convertir des données. Mais elle est utile dans de nombreux autres scénarios.
+
+///
diff --git a/docs/fr/docs/tutorial/extra-data-types.md b/docs/fr/docs/tutorial/extra-data-types.md
new file mode 100644
index 000000000..edaa7bd4c
--- /dev/null
+++ b/docs/fr/docs/tutorial/extra-data-types.md
@@ -0,0 +1,62 @@
+# Types de données supplémentaires { #extra-data-types }
+
+Jusqu'à présent, vous avez utilisé des types de données courants, comme :
+
+* `int`
+* `float`
+* `str`
+* `bool`
+
+Mais vous pouvez aussi utiliser des types de données plus complexes.
+
+Et vous bénéficierez toujours des mêmes fonctionnalités que jusqu'à présent :
+
+* Excellente prise en charge dans l'éditeur.
+* Conversion des données à partir des requêtes entrantes.
+* Conversion des données pour les données de réponse.
+* Validation des données.
+* Annotations et documentation automatiques.
+
+## Autres types de données { #other-data-types }
+
+Voici quelques types de données supplémentaires que vous pouvez utiliser :
+
+* `UUID` :
+ * Un « identifiant universel unique » standard, couramment utilisé comme ID dans de nombreuses bases de données et systèmes.
+ * Dans les requêtes et les réponses, il sera représenté sous forme de `str`.
+* `datetime.datetime` :
+ * Un `datetime.datetime` Python.
+ * Dans les requêtes et les réponses, il sera représenté sous forme de `str` au format ISO 8601, par exemple : `2008-09-15T15:53:00+05:00`.
+* `datetime.date` :
+ * `datetime.date` Python.
+ * Dans les requêtes et les réponses, il sera représenté sous forme de `str` au format ISO 8601, par exemple : `2008-09-15`.
+* `datetime.time` :
+ * Un `datetime.time` Python.
+ * Dans les requêtes et les réponses, il sera représenté sous forme de `str` au format ISO 8601, par exemple : `14:23:55.003`.
+* `datetime.timedelta` :
+ * Un `datetime.timedelta` Python.
+ * Dans les requêtes et les réponses, il sera représenté sous forme de `float` de secondes totales.
+ * Pydantic permet aussi de le représenter sous la forme d'un « encodage de différence de temps ISO 8601 », voir la documentation pour plus d'informations.
+* `frozenset` :
+ * Dans les requêtes et les réponses, traité de la même manière qu'un `set` :
+ * Dans les requêtes, une liste sera lue, les doublons éliminés, puis convertie en `set`.
+ * Dans les réponses, le `set` sera converti en `list`.
+ * Le schéma généré indiquera que les valeurs du `set` sont uniques (en utilisant `uniqueItems` de JSON Schema).
+* `bytes` :
+ * `bytes` Python standard.
+ * Dans les requêtes et les réponses, traité comme une `str`.
+ * Le schéma généré indiquera qu'il s'agit d'une `str` avec le « format » `binary`.
+* `Decimal` :
+ * `Decimal` Python standard.
+ * Dans les requêtes et les réponses, géré de la même manière qu'un `float`.
+* Vous pouvez consulter tous les types de données Pydantic valides ici : Types de données Pydantic.
+
+## Exemple { #example }
+
+Voici un exemple de *chemin d'accès* avec des paramètres utilisant certains des types ci-dessus.
+
+{* ../../docs_src/extra_data_types/tutorial001_an_py310.py hl[1,3,12:16] *}
+
+Notez que les paramètres à l'intérieur de la fonction ont leur type de données naturel et que vous pouvez, par exemple, effectuer des manipulations de dates normales, comme :
+
+{* ../../docs_src/extra_data_types/tutorial001_an_py310.py hl[18:19] *}
diff --git a/docs/fr/docs/tutorial/extra-models.md b/docs/fr/docs/tutorial/extra-models.md
new file mode 100644
index 000000000..1f9eb1561
--- /dev/null
+++ b/docs/fr/docs/tutorial/extra-models.md
@@ -0,0 +1,211 @@
+# Modèles supplémentaires { #extra-models }
+
+En poursuivant l'exemple précédent, il est courant d'avoir plusieurs modèles liés.
+
+C'est particulièrement vrai pour les modèles d'utilisateur, car :
+
+* Le modèle d'entrée doit pouvoir contenir un mot de passe.
+* Le modèle de sortie ne doit pas avoir de mot de passe.
+* Le modèle de base de données devra probablement avoir un mot de passe haché.
+
+/// danger | Danger
+
+Ne stockez jamais les mots de passe des utilisateurs en clair. Stockez toujours un « hachage sécurisé » que vous pourrez ensuite vérifier.
+
+Si vous ne savez pas ce que c'est, vous apprendrez ce qu'est un « hachage de mot de passe » dans les [chapitres sur la sécurité](security/simple-oauth2.md#password-hashing){.internal-link target=_blank}.
+
+///
+
+## Utiliser plusieurs modèles { #multiple-models }
+
+Voici une idée générale de l'apparence des modèles avec leurs champs de mot de passe et les endroits où ils sont utilisés :
+
+{* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *}
+
+### À propos de `**user_in.model_dump()` { #about-user-in-model-dump }
+
+#### La méthode `.model_dump()` de Pydantic { #pydantics-model-dump }
+
+`user_in` est un modèle Pydantic de classe `UserIn`.
+
+Les modèles Pydantic ont une méthode `.model_dump()` qui renvoie un `dict` avec les données du modèle.
+
+Ainsi, si nous créons un objet Pydantic `user_in` comme :
+
+```Python
+user_in = UserIn(username="john", password="secret", email="john.doe@example.com")
+```
+
+et que nous appelons ensuite :
+
+```Python
+user_dict = user_in.model_dump()
+```
+
+nous avons maintenant un `dict` avec les données dans la variable `user_dict` (c'est un `dict` au lieu d'un objet modèle Pydantic).
+
+Et si nous appelons :
+
+```Python
+print(user_dict)
+```
+
+nous obtiendrions un `dict` Python contenant :
+
+```Python
+{
+ 'username': 'john',
+ 'password': 'secret',
+ 'email': 'john.doe@example.com',
+ 'full_name': None,
+}
+```
+
+#### Déballer un `dict` { #unpacking-a-dict }
+
+Si nous prenons un `dict` comme `user_dict` et que nous le passons à une fonction (ou une classe) avec `**user_dict`, Python va « déballer » ce `dict`. Il passera les clés et valeurs de `user_dict` directement comme arguments nommés.
+
+Ainsi, en reprenant `user_dict` ci-dessus, écrire :
+
+```Python
+UserInDB(**user_dict)
+```
+
+aurait pour résultat quelque chose d'équivalent à :
+
+```Python
+UserInDB(
+ username="john",
+ password="secret",
+ email="john.doe@example.com",
+ full_name=None,
+)
+```
+
+Ou plus exactement, en utilisant `user_dict` directement, quels que soient ses contenus futurs :
+
+```Python
+UserInDB(
+ username = user_dict["username"],
+ password = user_dict["password"],
+ email = user_dict["email"],
+ full_name = user_dict["full_name"],
+)
+```
+
+#### Créer un modèle Pydantic à partir du contenu d'un autre { #a-pydantic-model-from-the-contents-of-another }
+
+Comme dans l'exemple ci-dessus nous avons obtenu `user_dict` depuis `user_in.model_dump()`, ce code :
+
+```Python
+user_dict = user_in.model_dump()
+UserInDB(**user_dict)
+```
+
+serait équivalent à :
+
+```Python
+UserInDB(**user_in.model_dump())
+```
+
+... parce que `user_in.model_dump()` est un `dict`, et nous demandons ensuite à Python de « déballer » ce `dict` en le passant à `UserInDB` précédé de `**`.
+
+Ainsi, nous obtenons un modèle Pydantic à partir des données d'un autre modèle Pydantic.
+
+#### Déballer un `dict` et ajouter des mots-clés supplémentaires { #unpacking-a-dict-and-extra-keywords }
+
+Et en ajoutant ensuite l'argument nommé supplémentaire `hashed_password=hashed_password`, comme ici :
+
+```Python
+UserInDB(**user_in.model_dump(), hashed_password=hashed_password)
+```
+
+... revient à :
+
+```Python
+UserInDB(
+ username = user_dict["username"],
+ password = user_dict["password"],
+ email = user_dict["email"],
+ full_name = user_dict["full_name"],
+ hashed_password = hashed_password,
+)
+```
+
+/// warning | Alertes
+
+Les fonctions auxiliaires `fake_password_hasher` et `fake_save_user` ne servent qu'à démontrer un flux de données possible, mais elles n'offrent évidemment aucune sécurité réelle.
+
+///
+
+## Réduire la duplication { #reduce-duplication }
+
+Réduire la duplication de code est l'une des idées centrales de **FastAPI**.
+
+La duplication de code augmente les risques de bogues, de problèmes de sécurité, de désynchronisation du code (lorsque vous mettez à jour un endroit mais pas les autres), etc.
+
+Et ces modèles partagent beaucoup de données et dupliquent des noms et types d'attributs.
+
+Nous pouvons faire mieux.
+
+Nous pouvons déclarer un modèle `UserBase` qui sert de base à nos autres modèles. Ensuite, nous pouvons créer des sous-classes de ce modèle qui héritent de ses attributs (déclarations de type, validation, etc.).
+
+Toutes les conversions de données, validations, documentation, etc., fonctionneront comme d'habitude.
+
+De cette façon, nous pouvons ne déclarer que les différences entre les modèles (avec `password` en clair, avec `hashed_password` et sans mot de passe) :
+
+{* ../../docs_src/extra_models/tutorial002_py310.py hl[7,13:14,17:18,21:22] *}
+
+## `Union` ou `anyOf` { #union-or-anyof }
+
+Vous pouvez déclarer qu'une réponse est l'`Union` de deux types ou plus, ce qui signifie que la réponse peut être n'importe lequel d'entre eux.
+
+Cela sera défini dans OpenAPI avec `anyOf`.
+
+Pour ce faire, utilisez l'annotation de type Python standard `typing.Union` :
+
+/// note | Remarque
+
+Lors de la définition d'une `Union`, incluez d'abord le type le plus spécifique, suivi du type le moins spécifique. Dans l'exemple ci-dessous, le type le plus spécifique `PlaneItem` précède `CarItem` dans `Union[PlaneItem, CarItem]`.
+
+///
+
+{* ../../docs_src/extra_models/tutorial003_py310.py hl[1,14:15,18:20,33] *}
+
+### `Union` en Python 3.10 { #union-in-python-3-10 }
+
+Dans cet exemple, nous passons `Union[PlaneItem, CarItem]` comme valeur de l'argument `response_model`.
+
+Comme nous le passons comme valeur d'un argument au lieu de l'utiliser dans une annotation de type, nous devons utiliser `Union` même en Python 3.10.
+
+S'il s'agissait d'une annotation de type, nous pourrions utiliser la barre verticale, comme :
+
+```Python
+some_variable: PlaneItem | CarItem
+```
+
+Mais si nous écrivons cela dans l'affectation `response_model=PlaneItem | CarItem`, nous obtiendrons une erreur, car Python essaierait d'effectuer une « opération invalide » entre `PlaneItem` et `CarItem` au lieu de l'interpréter comme une annotation de type.
+
+## Liste de modèles { #list-of-models }
+
+De la même manière, vous pouvez déclarer des réponses contenant des listes d'objets.
+
+Pour cela, utilisez le `list` Python standard :
+
+{* ../../docs_src/extra_models/tutorial004_py310.py hl[18] *}
+
+## Réponse avec un `dict` arbitraire { #response-with-arbitrary-dict }
+
+Vous pouvez également déclarer une réponse en utilisant un simple `dict` arbitraire, en déclarant uniquement le type des clés et des valeurs, sans utiliser de modèle Pydantic.
+
+C'est utile si vous ne connaissez pas à l'avance les noms de champs/attributs valides (qui seraient nécessaires pour un modèle Pydantic).
+
+Dans ce cas, vous pouvez utiliser `dict` :
+
+{* ../../docs_src/extra_models/tutorial005_py310.py hl[6] *}
+
+## Récapitulatif { #recap }
+
+Utilisez plusieurs modèles Pydantic et héritez librement selon chaque cas.
+
+Vous n'avez pas besoin d'avoir un seul modèle de données par entité si cette entité doit pouvoir avoir différents « états ». Comme pour l'« entité » utilisateur, avec un état incluant `password`, `password_hash` et sans mot de passe.
diff --git a/docs/fr/docs/tutorial/first-steps.md b/docs/fr/docs/tutorial/first-steps.md
index b2693b3e5..ae2358468 100644
--- a/docs/fr/docs/tutorial/first-steps.md
+++ b/docs/fr/docs/tutorial/first-steps.md
@@ -1,8 +1,8 @@
-# Démarrage { #first-steps }
+# Démarrer { #first-steps }
Le fichier **FastAPI** le plus simple possible pourrait ressembler à ceci :
-{* ../../docs_src/first_steps/tutorial001_py39.py *}
+{* ../../docs_src/first_steps/tutorial001_py310.py *}
Copiez cela dans un fichier `main.py`.
@@ -56,7 +56,7 @@ INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
Cette ligne montre l’URL où votre application est servie, sur votre machine locale.
-### Vérifiez { #check-it }
+### Vérifier { #check-it }
Ouvrez votre navigateur à l’adresse http://127.0.0.1:8000.
@@ -183,7 +183,7 @@ C’est tout ! Vous pouvez maintenant accéder à votre application à cette URL
### Étape 1 : importer `FastAPI` { #step-1-import-fastapi }
-{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *}
+{* ../../docs_src/first_steps/tutorial001_py310.py hl[1] *}
`FastAPI` est une classe Python qui fournit toutes les fonctionnalités nécessaires à votre API.
@@ -197,7 +197,7 @@ Vous pouvez donc aussi utiliser toutes les fonctionnalités de get opération
+* en utilisant une get opération
-/// info | `@décorateur` Info
+/// info | `@decorator` Info
Cette syntaxe `@something` en Python est appelée un « décorateur ».
@@ -320,7 +320,7 @@ Voici notre « fonction de chemin d’accès » :
* **opération** : `get`.
* **fonction** : la fonction sous le « décorateur » (sous `@app.get("/")`).
-{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial001_py310.py hl[7] *}
C’est une fonction Python.
@@ -332,9 +332,9 @@ Dans ce cas, c’est une fonction `async`.
Vous pouvez aussi la définir comme une fonction normale au lieu de `async def` :
-{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial003_py310.py hl[7] *}
-/// note
+/// note | Remarque
Si vous ne connaissez pas la différence, consultez [Asynchrone : « Pressé ? »](../async.md#in-a-hurry){.internal-link target=_blank}.
@@ -342,7 +342,7 @@ Si vous ne connaissez pas la différence, consultez [Asynchrone : « Pressé ?
### Étape 5 : retourner le contenu { #step-5-return-the-content }
-{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
+{* ../../docs_src/first_steps/tutorial001_py310.py hl[8] *}
Vous pouvez retourner un `dict`, une `list`, des valeurs uniques comme `str`, `int`, etc.
diff --git a/docs/fr/docs/tutorial/handling-errors.md b/docs/fr/docs/tutorial/handling-errors.md
new file mode 100644
index 000000000..38935c21c
--- /dev/null
+++ b/docs/fr/docs/tutorial/handling-errors.md
@@ -0,0 +1,244 @@
+# Gérer les erreurs { #handling-errors }
+
+Il existe de nombreuses situations où vous devez signaler une erreur à un client qui utilise votre API.
+
+Ce client peut être un navigateur avec un frontend, un code d'un tiers, un appareil IoT, etc.
+
+Vous pourriez avoir besoin d'indiquer au client que :
+
+* Le client n'a pas les privilèges suffisants pour cette opération.
+* Le client n'a pas accès à cette ressource.
+* L'élément auquel le client tentait d'accéder n'existe pas.
+* etc.
+
+Dans ces cas, vous retournez normalement un **code d'état HTTP** dans la plage de **400** (de 400 à 499).
+
+C'est similaire aux codes d'état HTTP 200 (de 200 à 299). Ces codes « 200 » signifient que, d'une certaine manière, la requête a été un « succès ».
+
+Les codes d'état dans la plage des 400 signifient qu'il y a eu une erreur côté client.
+
+Vous souvenez-vous de toutes ces erreurs **« 404 Not Found »** (et des blagues) ?
+
+## Utiliser `HTTPException` { #use-httpexception }
+
+Pour renvoyer au client des réponses HTTP avec des erreurs, vous utilisez `HTTPException`.
+
+### Importer `HTTPException` { #import-httpexception }
+
+{* ../../docs_src/handling_errors/tutorial001_py310.py hl[1] *}
+
+### Lever une `HTTPException` dans votre code { #raise-an-httpexception-in-your-code }
+
+`HTTPException` est une exception Python normale avec des données supplémentaires pertinentes pour les API.
+
+Comme il s'agit d'une exception Python, vous ne la `return` pas, vous la `raise`.
+
+Cela signifie aussi que si vous êtes dans une fonction utilitaire appelée depuis votre fonction de chemin d'accès, et que vous levez la `HTTPException` à l'intérieur de cette fonction utilitaire, le reste du code de la fonction de chemin d'accès ne s'exécutera pas : la requête sera immédiatement interrompue et l'erreur HTTP issue de la `HTTPException` sera envoyée au client.
+
+L'avantage de lever une exception plutôt que de retourner une valeur apparaîtra plus clairement dans la section sur les Dépendances et la Sécurité.
+
+Dans cet exemple, lorsque le client demande un élément par un ID qui n'existe pas, levez une exception avec un code d'état `404` :
+
+{* ../../docs_src/handling_errors/tutorial001_py310.py hl[11] *}
+
+### Réponse résultante { #the-resulting-response }
+
+Si le client demande `http://example.com/items/foo` (un `item_id` « foo »), il recevra un code d'état HTTP 200 et une réponse JSON :
+
+```JSON
+{
+ "item": "The Foo Wrestlers"
+}
+```
+
+Mais si le client demande `http://example.com/items/bar` (un `item_id` inexistant « bar »), il recevra un code d'état HTTP 404 (l'erreur « not found ») et une réponse JSON :
+
+```JSON
+{
+ "detail": "Item not found"
+}
+```
+
+/// tip | Astuce
+
+Lorsque vous levez une `HTTPException`, vous pouvez passer n'importe quelle valeur convertible en JSON comme paramètre `detail`, pas uniquement un `str`.
+
+Vous pouvez passer un `dict`, une `list`, etc.
+
+Elles sont gérées automatiquement par **FastAPI** et converties en JSON.
+
+///
+
+## Ajouter des en-têtes personnalisés { #add-custom-headers }
+
+Dans certaines situations, il est utile de pouvoir ajouter des en-têtes personnalisés à l'erreur HTTP. Par exemple, pour certains types de sécurité.
+
+Vous n'aurez probablement pas besoin de l'utiliser directement dans votre code.
+
+Mais si vous en aviez besoin pour un scénario avancé, vous pouvez ajouter des en-têtes personnalisés :
+
+{* ../../docs_src/handling_errors/tutorial002_py310.py hl[14] *}
+
+## Installer des gestionnaires d'exception personnalisés { #install-custom-exception-handlers }
+
+Vous pouvez ajouter des gestionnaires d'exception personnalisés avec les mêmes utilitaires d'exception de Starlette.
+
+Supposons que vous ayez une exception personnalisée `UnicornException` que vous (ou une bibliothèque que vous utilisez) pourriez `raise`.
+
+Et vous souhaitez gérer cette exception globalement avec FastAPI.
+
+Vous pouvez ajouter un gestionnaire d'exception personnalisé avec `@app.exception_handler()` :
+
+{* ../../docs_src/handling_errors/tutorial003_py310.py hl[5:7,13:18,24] *}
+
+Ici, si vous appelez `/unicorns/yolo`, le chemin d'accès va `raise` une `UnicornException`.
+
+Mais elle sera gérée par `unicorn_exception_handler`.
+
+Ainsi, vous recevrez une erreur propre, avec un code d'état HTTP `418` et un contenu JSON :
+
+```JSON
+{"message": "Oops! yolo did something. There goes a rainbow..."}
+```
+
+/// note | Détails techniques
+
+Vous pourriez aussi utiliser `from starlette.requests import Request` et `from starlette.responses import JSONResponse`.
+
+**FastAPI** fournit les mêmes `starlette.responses` sous `fastapi.responses` par simple commodité pour vous, développeur. Mais la plupart des réponses disponibles proviennent directement de Starlette. Il en va de même pour `Request`.
+
+///
+
+## Remplacer les gestionnaires d'exception par défaut { #override-the-default-exception-handlers }
+
+**FastAPI** fournit des gestionnaires d'exception par défaut.
+
+Ces gestionnaires se chargent de renvoyer les réponses JSON par défaut lorsque vous `raise` une `HTTPException` et lorsque la requête contient des données invalides.
+
+Vous pouvez remplacer ces gestionnaires d'exception par les vôtres.
+
+### Remplacer les exceptions de validation de la requête { #override-request-validation-exceptions }
+
+Lorsqu'une requête contient des données invalides, **FastAPI** lève en interne une `RequestValidationError`.
+
+Et il inclut également un gestionnaire d'exception par défaut pour cela.
+
+Pour la remplacer, importez `RequestValidationError` et utilisez-la avec `@app.exception_handler(RequestValidationError)` pour décorer le gestionnaire d'exception.
+
+Le gestionnaire d'exception recevra une `Request` et l'exception.
+
+{* ../../docs_src/handling_errors/tutorial004_py310.py hl[2,14:19] *}
+
+À présent, si vous allez sur `/items/foo`, au lieu d'obtenir l'erreur JSON par défaut suivante :
+
+```JSON
+{
+ "detail": [
+ {
+ "loc": [
+ "path",
+ "item_id"
+ ],
+ "msg": "value is not a valid integer",
+ "type": "type_error.integer"
+ }
+ ]
+}
+```
+
+vous obtiendrez une version texte, avec :
+
+```
+Validation errors:
+Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to parse string as an integer
+```
+
+### Remplacer le gestionnaire d'erreurs `HTTPException` { #override-the-httpexception-error-handler }
+
+De la même manière, vous pouvez remplacer le gestionnaire de `HTTPException`.
+
+Par exemple, vous pourriez vouloir renvoyer une réponse en texte brut au lieu de JSON pour ces erreurs :
+
+{* ../../docs_src/handling_errors/tutorial004_py310.py hl[3:4,9:11,25] *}
+
+/// note | Détails techniques
+
+Vous pourriez aussi utiliser `from starlette.responses import PlainTextResponse`.
+
+**FastAPI** fournit les mêmes `starlette.responses` sous `fastapi.responses` par simple commodité pour vous, le développeur. Mais la plupart des réponses disponibles proviennent directement de Starlette.
+
+///
+
+/// warning | Alertes
+
+Gardez à l'esprit que la `RequestValidationError` contient l'information du nom de fichier et de la ligne où l'erreur de validation se produit, afin que vous puissiez l'afficher dans vos journaux avec les informations pertinentes si vous le souhaitez.
+
+Mais cela signifie que si vous vous contentez de la convertir en chaîne et de renvoyer cette information directement, vous pourriez divulguer un peu d'information sur votre système. C'est pourquoi, ici, le code extrait et affiche chaque erreur indépendamment.
+
+///
+
+### Utiliser le corps de `RequestValidationError` { #use-the-requestvalidationerror-body }
+
+La `RequestValidationError` contient le `body` qu'elle a reçu avec des données invalides.
+
+Vous pouvez l'utiliser pendant le développement de votre application pour journaliser le corps et le déboguer, le renvoyer à l'utilisateur, etc.
+
+{* ../../docs_src/handling_errors/tutorial005_py310.py hl[14] *}
+
+Essayez maintenant d'envoyer un élément invalide comme :
+
+```JSON
+{
+ "title": "towel",
+ "size": "XL"
+}
+```
+
+Vous recevrez une réponse vous indiquant que les données sont invalides et contenant le corps reçu :
+
+```JSON hl_lines="12-15"
+{
+ "detail": [
+ {
+ "loc": [
+ "body",
+ "size"
+ ],
+ "msg": "value is not a valid integer",
+ "type": "type_error.integer"
+ }
+ ],
+ "body": {
+ "title": "towel",
+ "size": "XL"
+ }
+}
+```
+
+#### `HTTPException` de FastAPI vs `HTTPException` de Starlette { #fastapis-httpexception-vs-starlettes-httpexception }
+
+**FastAPI** a sa propre `HTTPException`.
+
+Et la classe d'erreur `HTTPException` de **FastAPI** hérite de la classe d'erreur `HTTPException` de Starlette.
+
+La seule différence est que la `HTTPException` de **FastAPI** accepte toute donnée sérialisable en JSON pour le champ `detail`, tandis que la `HTTPException` de Starlette n'accepte que des chaînes.
+
+Ainsi, vous pouvez continuer à lever la `HTTPException` de **FastAPI** normalement dans votre code.
+
+Mais lorsque vous enregistrez un gestionnaire d'exception, vous devez l'enregistrer pour la `HTTPException` de Starlette.
+
+De cette façon, si une partie du code interne de Starlette, ou une extension ou un plug-in Starlette, lève une `HTTPException` de Starlette, votre gestionnaire pourra l'intercepter et la traiter.
+
+Dans cet exemple, afin de pouvoir avoir les deux `HTTPException` dans le même code, les exceptions de Starlette sont renommées en `StarletteHTTPException` :
+
+```Python
+from starlette.exceptions import HTTPException as StarletteHTTPException
+```
+
+### Réutiliser les gestionnaires d'exception de **FastAPI** { #reuse-fastapis-exception-handlers }
+
+Si vous souhaitez utiliser l'exception avec les mêmes gestionnaires d'exception par défaut de **FastAPI**, vous pouvez importer et réutiliser les gestionnaires d'exception par défaut depuis `fastapi.exception_handlers` :
+
+{* ../../docs_src/handling_errors/tutorial006_py310.py hl[2:5,15,21] *}
+
+Dans cet exemple, vous vous contentez d'afficher l'erreur avec un message très expressif, mais vous voyez l'idée. Vous pouvez utiliser l'exception puis simplement réutiliser les gestionnaires d'exception par défaut.
diff --git a/docs/fr/docs/tutorial/header-param-models.md b/docs/fr/docs/tutorial/header-param-models.md
new file mode 100644
index 000000000..8fc1a3d36
--- /dev/null
+++ b/docs/fr/docs/tutorial/header-param-models.md
@@ -0,0 +1,72 @@
+# Modèles de paramètres d'en-tête { #header-parameter-models }
+
+Si vous avez un groupe de **paramètres d'en-tête** liés, vous pouvez créer un **modèle Pydantic** pour les déclarer.
+
+Cela vous permet de **réutiliser le modèle** à **plusieurs endroits** et aussi de déclarer des validations et des métadonnées pour tous les paramètres en une seule fois. 😎
+
+/// note | Remarque
+
+Cela est pris en charge depuis la version `0.115.0` de FastAPI. 🤓
+
+///
+
+## Paramètres d'en-tête avec un modèle Pydantic { #header-parameters-with-a-pydantic-model }
+
+Déclarez les **paramètres d'en-tête** dont vous avez besoin dans un **modèle Pydantic**, puis déclarez le paramètre comme `Header` :
+
+{* ../../docs_src/header_param_models/tutorial001_an_py310.py hl[9:14,18] *}
+
+**FastAPI** extrait les données de **chaque champ** depuis les **en-têtes** de la requête et vous fournit le modèle Pydantic que vous avez défini.
+
+## Consulter la documentation { #check-the-docs }
+
+Vous pouvez voir les en-têtes requis dans l'interface de la documentation à `/docs` :
+
+
+

+
+
+## Interdire les en-têtes supplémentaires { #forbid-extra-headers }
+
+Dans certains cas d'utilisation particuliers (probablement pas très courants), vous pourriez vouloir **restreindre** les en-têtes que vous souhaitez recevoir.
+
+Vous pouvez utiliser la configuration du modèle de Pydantic pour `forbid` tout champ `extra` :
+
+{* ../../docs_src/header_param_models/tutorial002_an_py310.py hl[10] *}
+
+Si un client essaie d'envoyer des **en-têtes supplémentaires**, il recevra une **réponse d'erreur**.
+
+Par exemple, si le client essaie d'envoyer un en-tête `tool` avec la valeur `plumbus`, il recevra une **réponse d'erreur** lui indiquant que le paramètre d'en-tête `tool` n'est pas autorisé :
+
+```json
+{
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["header", "tool"],
+ "msg": "Extra inputs are not permitted",
+ "input": "plumbus",
+ }
+ ]
+}
+```
+
+## Désactiver convert_underscores { #disable-convert-underscores }
+
+Comme pour les paramètres d'en-tête classiques, lorsque vous avez des caractères de soulignement dans les noms de paramètres, ils sont **automatiquement convertis en tirets**.
+
+Par exemple, si vous avez un paramètre d'en-tête `save_data` dans le code, l'en-tête HTTP attendu sera `save-data`, et il apparaîtra ainsi dans la documentation.
+
+Si, pour une raison quelconque, vous devez désactiver cette conversion automatique, vous pouvez aussi le faire pour les modèles Pydantic de paramètres d'en-tête.
+
+{* ../../docs_src/header_param_models/tutorial003_an_py310.py hl[19] *}
+
+/// warning | Alertes
+
+Avant de définir `convert_underscores` à `False`, gardez à l'esprit que certains proxys et serveurs HTTP interdisent l'utilisation d'en-têtes contenant des underscores.
+
+///
+
+## Résumé { #summary }
+
+Vous pouvez utiliser des **modèles Pydantic** pour déclarer des **en-têtes** dans **FastAPI**. 😎
diff --git a/docs/fr/docs/tutorial/header-params.md b/docs/fr/docs/tutorial/header-params.md
new file mode 100644
index 000000000..608559c85
--- /dev/null
+++ b/docs/fr/docs/tutorial/header-params.md
@@ -0,0 +1,91 @@
+# Paramètres d'en-tête { #header-parameters }
+
+Vous pouvez définir des paramètres `Header` de la même manière que vous définissez des paramètres `Query`, `Path` et `Cookie`.
+
+## Importer `Header` { #import-header }
+
+Commencez par importer `Header` :
+
+{* ../../docs_src/header_params/tutorial001_an_py310.py hl[3] *}
+
+## Déclarer des paramètres `Header` { #declare-header-parameters }
+
+Déclarez ensuite les paramètres d'en-tête en utilisant la même structure qu'avec `Path`, `Query` et `Cookie`.
+
+Vous pouvez définir la valeur par défaut ainsi que tous les paramètres supplémentaires de validation ou d'annotation :
+
+{* ../../docs_src/header_params/tutorial001_an_py310.py hl[9] *}
+
+/// note | Détails techniques
+
+`Header` est une classe « sœur » de `Path`, `Query` et `Cookie`. Elle hérite également de la même classe commune `Param`.
+
+Mais rappelez-vous que lorsque vous importez `Query`, `Path`, `Header` et d'autres depuis `fastapi`, ce sont en réalité des fonctions qui renvoient des classes spéciales.
+
+///
+
+/// info
+
+Pour déclarer des en-têtes, vous devez utiliser `Header`, sinon les paramètres seraient interprétés comme des paramètres de requête.
+
+///
+
+## Conversion automatique { #automatic-conversion }
+
+`Header` offre un peu de fonctionnalité supplémentaire par rapport à `Path`, `Query` et `Cookie`.
+
+La plupart des en-têtes standards sont séparés par un caractère « trait d'union », également appelé « signe moins » (`-`).
+
+Mais une variable comme `user-agent` est invalide en Python.
+
+Ainsi, par défaut, `Header` convertit les caractères des noms de paramètres du tiret bas (`_`) en trait d'union (`-`) pour extraire et documenter les en-têtes.
+
+De plus, les en-têtes HTTP ne sont pas sensibles à la casse, vous pouvez donc les déclarer avec le style Python standard (aussi appelé « snake_case »).
+
+Vous pouvez donc utiliser `user_agent` comme vous le feriez normalement dans du code Python, au lieu d'avoir à mettre des majuscules aux premières lettres comme `User_Agent` ou quelque chose de similaire.
+
+Si, pour une raison quelconque, vous devez désactiver la conversion automatique des traits bas en traits d'union, définissez le paramètre `convert_underscores` de `Header` sur `False` :
+
+{* ../../docs_src/header_params/tutorial002_an_py310.py hl[10] *}
+
+/// warning | Alertes
+
+Avant de définir `convert_underscores` sur `False`, gardez à l'esprit que certains proxies et serveurs HTTP interdisent l'utilisation d'en-têtes contenant des traits bas.
+
+///
+
+## Gérer les en-têtes dupliqués { #duplicate-headers }
+
+Il est possible de recevoir des en-têtes en double. Autrement dit, le même en-tête avec plusieurs valeurs.
+
+Vous pouvez définir ces cas à l'aide d'une liste dans la déclaration de type.
+
+Vous recevrez toutes les valeurs de l'en-tête dupliqué sous forme de `list` Python.
+
+Par exemple, pour déclarer un en-tête `X-Token` qui peut apparaître plusieurs fois, vous pouvez écrire :
+
+{* ../../docs_src/header_params/tutorial003_an_py310.py hl[9] *}
+
+Si vous communiquez avec ce *chemin d'accès* en envoyant deux en-têtes HTTP comme :
+
+```
+X-Token: foo
+X-Token: bar
+```
+
+La réponse ressemblerait à ceci :
+
+```JSON
+{
+ "X-Token values": [
+ "bar",
+ "foo"
+ ]
+}
+```
+
+## Récapitulatif { #recap }
+
+Déclarez les en-têtes avec `Header`, en suivant le même modèle que pour `Query`, `Path` et `Cookie`.
+
+Et ne vous souciez pas des traits bas dans vos variables, **FastAPI** s'occupe de les convertir.
diff --git a/docs/fr/docs/tutorial/metadata.md b/docs/fr/docs/tutorial/metadata.md
new file mode 100644
index 000000000..3ea3865ba
--- /dev/null
+++ b/docs/fr/docs/tutorial/metadata.md
@@ -0,0 +1,120 @@
+# Métadonnées et URL des documents { #metadata-and-docs-urls }
+
+Vous pouvez personnaliser plusieurs configurations de métadonnées dans votre application **FastAPI**.
+
+## Métadonnées pour l'API { #metadata-for-api }
+
+Vous pouvez définir les champs suivants qui sont utilisés dans la spécification OpenAPI et les interfaces utilisateur de documentation automatique de l’API :
+
+| Paramètre | Type | Description |
+|------------|------|-------------|
+| `title` | `str` | Le titre de l’API. |
+| `summary` | `str` | Un court résumé de l’API. Disponible depuis OpenAPI 3.1.0, FastAPI 0.99.0. |
+| `description` | `str` | Une brève description de l’API. Elle peut utiliser Markdown. |
+| `version` | `string` | La version de l’API. C’est la version de votre propre application, pas d’OpenAPI. Par exemple `2.5.0`. |
+| `terms_of_service` | `str` | Une URL vers les Conditions d’utilisation de l’API. Le cas échéant, il doit s’agir d’une URL. |
+| `contact` | `dict` | Les informations de contact pour l’API exposée. Cela peut contenir plusieurs champs. champs de contact
| Paramètre | Type | Description |
|---|
name | str | Le nom identifiant de la personne/organisation de contact. |
url | str | L’URL pointant vers les informations de contact. DOIT être au format d’une URL. |
email | str | L’adresse e-mail de la personne/organisation de contact. DOIT être au format d’une adresse e-mail. |
|
+| `license_info` | `dict` | Les informations de licence pour l’API exposée. Cela peut contenir plusieurs champs. champs de license_info
| Paramètre | Type | Description |
|---|
name | str | OBLIGATOIRE (si un license_info est défini). Le nom de la licence utilisée pour l’API. |
identifier | str | Une expression de licence SPDX pour l’API. Le champ identifier est mutuellement exclusif du champ url. Disponible depuis OpenAPI 3.1.0, FastAPI 0.99.0. |
url | str | Une URL vers la licence utilisée pour l’API. DOIT être au format d’une URL. |
|
+
+Vous pouvez les définir comme suit :
+
+{* ../../docs_src/metadata/tutorial001_py310.py hl[3:16, 19:32] *}
+
+/// tip | Astuce
+
+Vous pouvez écrire du Markdown dans le champ `description` et il sera rendu dans la sortie.
+
+///
+
+Avec cette configuration, les documents API automatiques ressembleraient à :
+
+
+
+## Identifiant de licence { #license-identifier }
+
+Depuis OpenAPI 3.1.0 et FastAPI 0.99.0, vous pouvez également définir `license_info` avec un `identifier` au lieu d’une `url`.
+
+Par exemple :
+
+{* ../../docs_src/metadata/tutorial001_1_py310.py hl[31] *}
+
+## Métadonnées pour les tags { #metadata-for-tags }
+
+Vous pouvez également ajouter des métadonnées supplémentaires pour les différents tags utilisés pour regrouper vos chemins d'accès avec le paramètre `openapi_tags`.
+
+Il prend une liste contenant un dictionnaire pour chaque tag.
+
+Chaque dictionnaire peut contenir :
+
+* `name` (**requis**) : un `str` avec le même nom de tag que vous utilisez dans le paramètre `tags` de vos *chemins d'accès* et `APIRouter`s.
+* `description` : un `str` avec une courte description pour le tag. Il peut contenir du Markdown et sera affiché dans l’interface utilisateur de la documentation.
+* `externalDocs` : un `dict` décrivant une documentation externe avec :
+ * `description` : un `str` avec une courte description pour la documentation externe.
+ * `url` (**requis**) : un `str` avec l’URL de la documentation externe.
+
+### Créer des métadonnées pour les tags { #create-metadata-for-tags }
+
+Essayons cela avec un exemple de tags pour `users` et `items`.
+
+Créez des métadonnées pour vos tags et transmettez-les au paramètre `openapi_tags` :
+
+{* ../../docs_src/metadata/tutorial004_py310.py hl[3:16,18] *}
+
+Notez que vous pouvez utiliser Markdown à l’intérieur des descriptions, par exemple « login » sera affiché en gras (**login**) et « fancy » sera affiché en italique (_fancy_).
+
+/// tip | Astuce
+
+Vous n’avez pas à ajouter des métadonnées pour tous les tags que vous utilisez.
+
+///
+
+### Utiliser vos tags { #use-your-tags }
+
+Utilisez le paramètre `tags` avec vos *chemins d'accès* (et `APIRouter`s) pour les affecter à différents tags :
+
+{* ../../docs_src/metadata/tutorial004_py310.py hl[21,26] *}
+
+/// info
+
+En savoir plus sur les tags dans [Configuration de chemins d'accès](path-operation-configuration.md#tags){.internal-link target=_blank}.
+
+///
+
+### Consultez les documents { #check-the-docs }
+
+Désormais, si vous consultez les documents, ils afficheront toutes les métadonnées supplémentaires :
+
+
+
+### Définir l’ordre des tags { #order-of-tags }
+
+L’ordre de chaque dictionnaire de métadonnées de tag définit également l’ordre affiché dans l’interface utilisateur de la documentation.
+
+Par exemple, même si `users` viendrait après `items` par ordre alphabétique, il est affiché avant, car nous avons ajouté ses métadonnées comme premier dictionnaire de la liste.
+
+## URL OpenAPI { #openapi-url }
+
+Par défaut, le schéma OpenAPI est servi à `/openapi.json`.
+
+Mais vous pouvez le configurer avec le paramètre `openapi_url`.
+
+Par exemple, pour qu’il soit servi à `/api/v1/openapi.json` :
+
+{* ../../docs_src/metadata/tutorial002_py310.py hl[3] *}
+
+Si vous souhaitez désactiver complètement le schéma OpenAPI, vous pouvez définir `openapi_url=None`, cela désactivera également les interfaces utilisateur de la documentation qui l’utilisent.
+
+## URL des documents { #docs-urls }
+
+Vous pouvez configurer les deux interfaces utilisateur de documentation incluses :
+
+* **Swagger UI** : servie à `/docs`.
+ * Vous pouvez définir son URL avec le paramètre `docs_url`.
+ * Vous pouvez la désactiver en définissant `docs_url=None`.
+* **ReDoc** : servie à `/redoc`.
+ * Vous pouvez définir son URL avec le paramètre `redoc_url`.
+ * Vous pouvez la désactiver en définissant `redoc_url=None`.
+
+Par exemple, pour que Swagger UI soit servi à `/documentation` et désactiver ReDoc :
+
+{* ../../docs_src/metadata/tutorial003_py310.py hl[3] *}
diff --git a/docs/fr/docs/tutorial/middleware.md b/docs/fr/docs/tutorial/middleware.md
new file mode 100644
index 000000000..6cbbc3e45
--- /dev/null
+++ b/docs/fr/docs/tutorial/middleware.md
@@ -0,0 +1,95 @@
+# Middleware { #middleware }
+
+Vous pouvez ajouter des middlewares aux applications **FastAPI**.
+
+Un « middleware » est une fonction qui agit sur chaque **requête** avant qu’elle ne soit traitée par un *chemin d'accès* spécifique. Et aussi sur chaque **réponse** avant son renvoi.
+
+* Il intercepte chaque **requête** qui parvient à votre application.
+* Il peut alors faire quelque chose avec cette **requête** ou exécuter tout code nécessaire.
+* Ensuite, il transmet la **requête** pour qu’elle soit traitée par le reste de l’application (par un *chemin d'accès*).
+* Puis il récupère la **réponse** générée par l’application (par un *chemin d'accès*).
+* Il peut faire quelque chose avec cette **réponse** ou exécuter tout code nécessaire.
+* Enfin, il renvoie la **réponse**.
+
+/// note | Détails techniques
+
+Si vous avez des dépendances avec `yield`, le code de sortie s’exécutera après le middleware.
+
+S’il y avait des tâches d’arrière-plan (présentées dans la section [Tâches d’arrière-plan](background-tasks.md){.internal-link target=_blank}, que vous verrez plus tard), elles s’exécuteront après tous les middlewares.
+
+///
+
+## Créer un middleware { #create-a-middleware }
+
+Pour créer un middleware, utilisez le décorateur `@app.middleware("http")` au-dessus d’une fonction.
+
+La fonction de middleware reçoit :
+
+* La `request`.
+* Une fonction `call_next` qui recevra la `request` en paramètre.
+ * Cette fonction transmettra la `request` au *chemin d'accès* correspondant.
+ * Puis elle renverra la `response` générée par le *chemin d'accès* correspondant.
+* Vous pouvez ensuite modifier la `response` avant de la renvoyer.
+
+{* ../../docs_src/middleware/tutorial001_py310.py hl[8:9,11,14] *}
+
+/// tip | Astuce
+
+Gardez à l’esprit que des en-têtes propriétaires personnalisés peuvent être ajoutés en utilisant le préfixe `X-`.
+
+Mais si vous avez des en-têtes personnalisés que vous voulez rendre visibles pour un client dans un navigateur, vous devez les ajouter à votre configuration CORS ([CORS (Partage des ressources entre origines)](cors.md){.internal-link target=_blank}) en utilisant le paramètre `expose_headers` documenté dans la documentation CORS de Starlette.
+
+///
+
+/// note | Détails techniques
+
+Vous pourriez aussi utiliser `from starlette.requests import Request`.
+
+**FastAPI** le fournit pour votre confort de développeur. Mais cela provient directement de Starlette.
+
+///
+
+### Avant et après la `response` { #before-and-after-the-response }
+
+Vous pouvez ajouter du code à exécuter avec la `request`, avant que tout *chemin d'accès* ne la reçoive.
+
+Et aussi après que la `response` a été générée, avant de la renvoyer.
+
+Par exemple, vous pourriez ajouter un en-tête personnalisé `X-Process-Time` contenant le temps en secondes nécessaire pour traiter la requête et générer une réponse :
+
+{* ../../docs_src/middleware/tutorial001_py310.py hl[10,12:13] *}
+
+/// tip | Astuce
+
+Ici, nous utilisons `time.perf_counter()` au lieu de `time.time()` car cela peut être plus précis pour ces cas d’usage. 🤓
+
+///
+
+## Ordre d’exécution de plusieurs middlewares { #multiple-middleware-execution-order }
+
+Quand vous ajoutez plusieurs middlewares en utilisant soit le décorateur `@app.middleware()`, soit la méthode `app.add_middleware()`, chaque nouveau middleware enveloppe l’application, formant une pile. Le dernier middleware ajouté est le plus externe, et le premier est le plus interne.
+
+Sur le chemin de la requête, le plus externe s’exécute en premier.
+
+Sur le chemin de la réponse, il s’exécute en dernier.
+
+Par exemple :
+
+```Python
+app.add_middleware(MiddlewareA)
+app.add_middleware(MiddlewareB)
+```
+
+Cela aboutit à l’ordre d’exécution suivant :
+
+* **Requête** : MiddlewareB → MiddlewareA → route
+
+* **Réponse** : route → MiddlewareA → MiddlewareB
+
+Ce comportement d’empilement garantit que les middlewares s’exécutent dans un ordre prévisible et contrôlable.
+
+## Autres middlewares { #other-middlewares }
+
+Vous pouvez en lire davantage sur d’autres middlewares dans le [Guide de l’utilisateur avancé : Middleware avancé](../advanced/middleware.md){.internal-link target=_blank}.
+
+Vous verrez comment gérer CORS avec un middleware dans la section suivante.
diff --git a/docs/fr/docs/tutorial/path-operation-configuration.md b/docs/fr/docs/tutorial/path-operation-configuration.md
new file mode 100644
index 000000000..f8041fa69
--- /dev/null
+++ b/docs/fr/docs/tutorial/path-operation-configuration.md
@@ -0,0 +1,107 @@
+# Configurer les chemins d'accès { #path-operation-configuration }
+
+Vous pouvez passer plusieurs paramètres à votre *décorateur de chemin d'accès* pour le configurer.
+
+/// warning | Alertes
+
+Notez que ces paramètres sont passés directement au *décorateur de chemin d'accès*, et non à votre *fonction de chemin d'accès*.
+
+///
+
+## Définir le code d'état de la réponse { #response-status-code }
+
+Vous pouvez définir le `status_code` (HTTP) à utiliser dans la réponse de votre *chemin d'accès*.
+
+Vous pouvez passer directement le code `int`, comme `404`.
+
+Mais si vous ne vous souvenez pas à quoi correspond chaque code numérique, vous pouvez utiliser les constantes abrégées dans `status` :
+
+{* ../../docs_src/path_operation_configuration/tutorial001_py310.py hl[1,15] *}
+
+Ce code d'état sera utilisé dans la réponse et ajouté au schéma OpenAPI.
+
+/// note | Détails techniques
+
+Vous pouvez également utiliser `from starlette import status`.
+
+**FastAPI** fournit le même `starlette.status` sous le nom `fastapi.status` pour votre commodité, en tant que développeur. Mais cela provient directement de Starlette.
+
+///
+
+## Ajouter des tags { #tags }
+
+Vous pouvez ajouter des tags à votre *chemin d'accès*, en passant le paramètre `tags` avec une `list` de `str` (généralement un seul `str`) :
+
+{* ../../docs_src/path_operation_configuration/tutorial002_py310.py hl[15,20,25] *}
+
+Ils seront ajoutés au schéma OpenAPI et utilisés par les interfaces de documentation automatiques :
+
+
+
+### Utiliser des tags avec Enum { #tags-with-enums }
+
+Si vous avez une grande application, vous pourriez finir par accumuler **plusieurs tags**, et vous voudrez vous assurer d'utiliser toujours le **même tag** pour les *chemins d'accès* associés.
+
+Dans ces cas, il peut être judicieux de stocker les tags dans un `Enum`.
+
+**FastAPI** le prend en charge de la même manière qu'avec des chaînes simples :
+
+{* ../../docs_src/path_operation_configuration/tutorial002b_py310.py hl[1,8:10,13,18] *}
+
+## Ajouter un résumé et une description { #summary-and-description }
+
+Vous pouvez ajouter un `summary` et une `description` :
+
+{* ../../docs_src/path_operation_configuration/tutorial003_py310.py hl[17:18] *}
+
+## Utiliser la description depuis la docstring { #description-from-docstring }
+
+Comme les descriptions ont tendance à être longues et à couvrir plusieurs lignes, vous pouvez déclarer la description du *chemin d'accès* dans la docstring de la fonction et **FastAPI** la lira à partir de là.
+
+Vous pouvez écrire Markdown dans la docstring, il sera interprété et affiché correctement (en tenant compte de l'indentation de la docstring).
+
+{* ../../docs_src/path_operation_configuration/tutorial004_py310.py hl[17:25] *}
+
+Elle sera utilisée dans les documents interactifs :
+
+
+
+## Définir la description de la réponse { #response-description }
+
+Vous pouvez spécifier la description de la réponse avec le paramètre `response_description` :
+
+{* ../../docs_src/path_operation_configuration/tutorial005_py310.py hl[18] *}
+
+/// info
+
+Notez que `response_description` se réfère spécifiquement à la réponse, tandis que `description` se réfère au *chemin d'accès* en général.
+
+///
+
+/// check | Vérifications
+
+OpenAPI spécifie que chaque *chemin d'accès* requiert une description de réponse.
+
+Donc, si vous n'en fournissez pas, **FastAPI** en générera automatiquement une « Réponse réussie ».
+
+///
+
+
+
+## Déprécier un *chemin d'accès* { #deprecate-a-path-operation }
+
+Si vous devez marquer un *chemin d'accès* comme déprécié, sans pour autant le supprimer, passez le paramètre `deprecated` :
+
+{* ../../docs_src/path_operation_configuration/tutorial006_py310.py hl[16] *}
+
+Il sera clairement marqué comme déprécié dans les documents interactifs :
+
+
+
+Voyez à quoi ressemblent les *chemins d'accès* dépréciés et non dépréciés :
+
+
+
+## Récapitulatif { #recap }
+
+Vous pouvez facilement configurer et ajouter des métadonnées à vos *chemins d'accès* en passant des paramètres aux *décorateurs de chemin d'accès*.
diff --git a/docs/fr/docs/tutorial/path-params-numeric-validations.md b/docs/fr/docs/tutorial/path-params-numeric-validations.md
index c80710777..2dbaaa8ca 100644
--- a/docs/fr/docs/tutorial/path-params-numeric-validations.md
+++ b/docs/fr/docs/tutorial/path-params-numeric-validations.md
@@ -54,11 +54,11 @@ 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_py39.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial002_py310.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 *}
+{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py310.py *}
## Ordonner les paramètres comme vous le souhaitez, astuces { #order-the-parameters-as-you-need-tricks }
@@ -81,15 +81,15 @@ Si vous voulez :
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 kwargs. Même s'ils n'ont pas de valeur par défaut.
+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 kwargs. Même s'ils n'ont pas de valeur par défaut.
-{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial003_py310.py hl[7] *}
### 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] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py310.py hl[10] *}
## Validations numériques : supérieur ou égal { #number-validations-greater-than-or-equal }
@@ -97,7 +97,7 @@ Avec `Query` et `Path` (et d'autres que vous verrez plus tard) vous pouvez décl
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] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py310.py hl[10] *}
## Validations numériques : supérieur et inférieur ou égal { #number-validations-greater-than-and-less-than-or-equal }
@@ -106,7 +106,7 @@ 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/tutorial005_an_py39.py hl[10] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py310.py hl[10] *}
## Validations numériques : flottants, supérieur et inférieur { #number-validations-floats-greater-than-and-less-than }
@@ -118,7 +118,7 @@ Ainsi, `0.5` serait une valeur valide. Mais `0.0` ou `0` ne le serait pas.
Et la même chose pour lt.
-{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py310.py hl[13] *}
## Pour résumer { #recap }
diff --git a/docs/fr/docs/tutorial/path-params.md b/docs/fr/docs/tutorial/path-params.md
index 3b2955a95..985eff635 100644
--- a/docs/fr/docs/tutorial/path-params.md
+++ b/docs/fr/docs/tutorial/path-params.md
@@ -2,7 +2,7 @@
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_py310.py hl[6:7] *}
La valeur du paramètre de chemin `item_id` sera transmise à votre fonction dans l'argument `item_id`.
@@ -16,7 +16,7 @@ Donc, si vous exécutez cet exemple et allez sur Conversion de données { #data-conversion }
+## Conversion de données { #data-conversion }
Si vous exécutez cet exemple et ouvrez votre navigateur sur http://127.0.0.1:8000/items/3, vous verrez comme réponse :
@@ -38,7 +38,7 @@ Si vous exécutez cet exemple et ouvrez votre navigateur sur « parsing » de la requête.
+Ainsi, avec cette déclaration de type, **FastAPI** vous fournit automatiquement le « parsing » de la requête.
///
@@ -118,19 +118,19 @@ Et vous pouvez aussi avoir un chemin `/users/{user_id}` pour récupérer des don
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}` :
-{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *}
+{* ../../docs_src/path_params/tutorial003_py310.py hl[6,11] *}
Sinon, le chemin `/users/{user_id}` correspondrait aussi à `/users/me`, « pensant » qu'il reçoit un paramètre `user_id` avec la valeur « me ».
De même, vous ne pouvez pas redéfinir un chemin d'accès :
-{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
+{* ../../docs_src/path_params/tutorial003b_py310.py hl[6,11] *}
Le premier sera toujours utilisé puisque le chemin correspond en premier.
## Valeurs prédéfinies { #predefined-values }
-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 `Enum` Python standard.
+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 `Enum` Python standard.
### Créer une classe `Enum` { #create-an-enum-class }
@@ -140,11 +140,11 @@ En héritant de `str`, la documentation de l'API saura que les valeurs doivent
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] *}
+{* ../../docs_src/path_params/tutorial005_py310.py hl[1,6:9] *}
/// tip | Astuce
-Si vous vous demandez, « AlexNet », « ResNet » et « LeNet » sont juste des noms de modèles de Machine Learning.
+Si vous vous demandez, « AlexNet », « ResNet » et « LeNet » sont juste des noms de modèles de Machine Learning.
///
@@ -152,7 +152,7 @@ Si vous vous demandez, « AlexNet », « ResNet » et « LeNet » sont juste des
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_py39.py hl[16] *}
+{* ../../docs_src/path_params/tutorial005_py310.py hl[16] *}
### Consulter la documentation { #check-the-docs }
@@ -168,13 +168,13 @@ La valeur du *paramètre de chemin* sera un *membre d'énumération*.
Vous pouvez le comparer avec le *membre d'énumération* dans votre enum `ModelName` :
-{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *}
+{* ../../docs_src/path_params/tutorial005_py310.py hl[17] *}
#### Obtenir la *valeur de l'énumération* { #get-the-enumeration-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_py39.py hl[20] *}
+{* ../../docs_src/path_params/tutorial005_py310.py hl[20] *}
/// tip | Astuce
@@ -188,7 +188,7 @@ Vous pouvez retourner des *membres d'énumération* depuis votre *chemin d'accè
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_py39.py hl[18,21,23] *}
+{* ../../docs_src/path_params/tutorial005_py310.py hl[18,21,23] *}
Dans votre client, vous recevrez une réponse JSON comme :
@@ -227,7 +227,7 @@ Dans ce cas, le nom du paramètre est `file_path`, et la dernière partie, `:pat
Vous pouvez donc l'utiliser ainsi :
-{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
+{* ../../docs_src/path_params/tutorial004_py310.py hl[6] *}
/// tip | Astuce
@@ -242,7 +242,7 @@ Dans ce cas, l'URL serait : `/files//home/johndoe/myfile.txt`, avec un double sl
Avec **FastAPI**, en utilisant des déclarations de type Python courtes, intuitives et standard, vous obtenez :
* Support de l'éditeur : vérifications d'erreurs, autocomplétion, etc.
-* Données « parsing »
+* Données « parsing »
* Validation de données
* Annotations d'API et documentation automatique
diff --git a/docs/fr/docs/tutorial/query-param-models.md b/docs/fr/docs/tutorial/query-param-models.md
new file mode 100644
index 000000000..b9bb1d137
--- /dev/null
+++ b/docs/fr/docs/tutorial/query-param-models.md
@@ -0,0 +1,68 @@
+# Modèles de paramètres de requête { #query-parameter-models }
+
+Si vous avez un groupe de paramètres de requête liés, vous pouvez créer un modèle Pydantic pour les déclarer.
+
+Cela vous permet de réutiliser le modèle à plusieurs endroits et aussi de déclarer des validations et des métadonnées pour tous les paramètres en une seule fois. 😎
+
+/// note | Remarque
+
+Pris en charge depuis FastAPI version `0.115.0`. 🤓
+
+///
+
+## Déclarer des paramètres de requête avec un modèle Pydantic { #query-parameters-with-a-pydantic-model }
+
+Déclarez les paramètres de requête dont vous avez besoin dans un modèle Pydantic, puis déclarez le paramètre en tant que `Query` :
+
+{* ../../docs_src/query_param_models/tutorial001_an_py310.py hl[9:13,17] *}
+
+FastAPI extrait les données pour chaque champ à partir des paramètres de requête de la requête et vous fournit le modèle Pydantic que vous avez défini.
+
+## Consulter les documents { #check-the-docs }
+
+Vous pouvez voir les paramètres de requête dans l'interface des documents à `/docs` :
+
+
+

+
+
+## Interdire des paramètres de requête supplémentaires { #forbid-extra-query-parameters }
+
+Dans certains cas d'utilisation particuliers (probablement peu courants), vous pouvez vouloir restreindre les paramètres de requête que vous souhaitez recevoir.
+
+Vous pouvez utiliser la configuration du modèle Pydantic pour `forbid` tout champ `extra` :
+
+{* ../../docs_src/query_param_models/tutorial002_an_py310.py hl[10] *}
+
+Si un client tente d'envoyer des données supplémentaires dans les paramètres de requête, il recevra une réponse d'erreur.
+
+Par exemple, si le client tente d'envoyer un paramètre de requête `tool` avec la valeur `plumbus`, comme :
+
+```http
+https://example.com/items/?limit=10&tool=plumbus
+```
+
+Il recevra une réponse d'erreur lui indiquant que le paramètre de requête `tool` n'est pas autorisé :
+
+```json
+{
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["query", "tool"],
+ "msg": "Extra inputs are not permitted",
+ "input": "plumbus"
+ }
+ ]
+}
+```
+
+## Résumé { #summary }
+
+Vous pouvez utiliser des modèles Pydantic pour déclarer des paramètres de requête dans FastAPI. 😎
+
+/// tip | Astuce
+
+Alerte spoiler : vous pouvez aussi utiliser des modèles Pydantic pour déclarer des cookies et des en-têtes, mais vous lirez cela plus tard dans le tutoriel. 🤫
+
+///
diff --git a/docs/fr/docs/tutorial/query-params-str-validations.md b/docs/fr/docs/tutorial/query-params-str-validations.md
index 544d10328..17b751f23 100644
--- a/docs/fr/docs/tutorial/query-params-str-validations.md
+++ b/docs/fr/docs/tutorial/query-params-str-validations.md
@@ -47,40 +47,16 @@ C’est le moment de l’utiliser avec FastAPI. 🚀
Nous avions cette annotation de type :
-//// tab | Python 3.10+
-
```Python
q: str | None = None
```
-////
-
-//// tab | Python 3.9+
-
-```Python
-q: Union[str, None] = None
-```
-
-////
-
Ce que nous allons faire, c’est l’englober avec `Annotated`, de sorte que cela devienne :
-//// tab | Python 3.10+
-
```Python
q: Annotated[str | None] = None
```
-////
-
-//// tab | Python 3.9+
-
-```Python
-q: Annotated[Union[str, None]] = None
-```
-
-////
-
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. 🎉
@@ -109,7 +85,7 @@ FastAPI va maintenant :
## Alternative (ancienne) : `Query` comme valeur par défaut { #alternative-old-query-as-the-default-value }
-Les versions précédentes de FastAPI (avant 0.95.0) 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.
+Les versions précédentes de FastAPI (avant 0.95.0) 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
@@ -191,7 +167,7 @@ Vous pouvez également ajouter un paramètre `min_length` :
## Ajouter des expressions régulières { #add-regular-expressions }
-Vous pouvez définir un `pattern` d’expression régulière auquel le paramètre doit correspondre :
+Vous pouvez définir un `pattern` d’expression régulière auquel le paramètre doit correspondre :
{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
@@ -211,7 +187,7 @@ Vous pouvez, bien sûr, utiliser des valeurs par défaut autres que `None`.
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] *}
+{* ../../docs_src/query_params_str_validations/tutorial005_an_py310.py hl[9] *}
/// note | Remarque
@@ -241,7 +217,7 @@ q: Annotated[str | None, Query(min_length=3)] = None
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_an_py39.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial006_an_py310.py hl[9] *}
### Requis, peut valoir `None` { #required-can-be-none }
@@ -292,7 +268,7 @@ L’interface de documentation interactive de l’API sera mise à jour en cons
Vous pouvez également définir une `list` de valeurs par défaut si aucune n’est fournie :
-{* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial012_an_py310.py hl[9] *}
Si vous allez à :
@@ -315,7 +291,7 @@ la valeur par défaut de `q` sera : `["foo", "bar"]` et votre réponse sera :
Vous pouvez aussi utiliser `list` directement au lieu de `list[str]` :
-{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial013_an_py310.py hl[9] *}
/// note | Remarque
@@ -371,7 +347,7 @@ Vous pouvez alors déclarer un `alias`, et cet alias sera utilisé pour trouver
Disons que vous n’aimez plus ce paramètre.
-Vous devez le laisser là quelque temps car des clients l’utilisent, mais vous voulez que les documents l’affichent clairement comme déprécié.
+Vous devez le laisser là quelque temps car des clients l’utilisent, mais vous voulez que les documents l’affichent clairement comme déprécié.
Passez alors le paramètre `deprecated=True` à `Query` :
@@ -401,7 +377,7 @@ Pydantic a aussi ISBN ou par `imdb-` pour un ID d’URL de film IMDB :
+Par exemple, ce validateur personnalisé vérifie que l’ID d’item commence par `isbn-` pour un numéro de livre ISBN ou par `imdb-` pour un ID d’URL de film IMDB :
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
@@ -435,7 +411,7 @@ Avez-vous remarqué ? Une chaîne utilisant `value.startswith()` peut prendre un
#### Un élément aléatoire { #a-random-item }
-Avec `data.items()` nous obtenons un objet itérable avec des tuples contenant la clé et la valeur pour chaque élément du dictionnaire.
+Avec `data.items()` nous obtenons un objet itérable 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())`.
diff --git a/docs/fr/docs/tutorial/query-params.md b/docs/fr/docs/tutorial/query-params.md
index 1a4880ced..01540ad17 100644
--- a/docs/fr/docs/tutorial/query-params.md
+++ b/docs/fr/docs/tutorial/query-params.md
@@ -2,7 +2,7 @@
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_py39.py hl[9] *}
+{* ../../docs_src/query_params/tutorial001_py310.py hl[9] *}
La query est l'ensemble des paires clé-valeur placées après le `?` dans une URL, séparées par des caractères `&`.
@@ -24,7 +24,7 @@ Mais lorsque vous les déclarez avec des types Python (dans l'exemple ci-dessus,
Tous les mêmes processus qui s'appliquaient aux paramètres de chemin s'appliquent aussi aux paramètres de requête :
* Prise en charge de l'éditeur (évidemment)
-* « parsing » des données
+* « parsing » des données
* Validation des données
* Documentation automatique
@@ -67,7 +67,7 @@ Dans ce cas, le paramètre de fonction `q` sera optionnel et vaudra `None` par d
/// check | Vérifications
-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.
+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.
///
@@ -127,7 +127,7 @@ Si vous ne voulez pas leur donner de valeur spécifique mais simplement les rend
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_py39.py hl[6:7] *}
+{* ../../docs_src/query_params/tutorial005_py310.py hl[6:7] *}
Ici, le paramètre de requête `needy` est un paramètre de requête requis de type `str`.
diff --git a/docs/fr/docs/tutorial/request-files.md b/docs/fr/docs/tutorial/request-files.md
new file mode 100644
index 000000000..01a0b72eb
--- /dev/null
+++ b/docs/fr/docs/tutorial/request-files.md
@@ -0,0 +1,176 @@
+# Envoyer des fichiers { #request-files }
+
+Vous pouvez définir des fichiers à téléverser par le client en utilisant `File`.
+
+/// info
+
+Pour recevoir des fichiers téléversés, installez d'abord `python-multipart`.
+
+Assurez-vous de créer un [environnement virtuel](../virtual-environments.md){.internal-link target=_blank}, de l'activer, puis d'installer le paquet, par exemple :
+
+```console
+$ pip install python-multipart
+```
+
+C'est parce que les fichiers téléversés sont envoyés en « données de formulaire ».
+
+///
+
+## Importer `File` { #import-file }
+
+Importez `File` et `UploadFile` depuis `fastapi` :
+
+{* ../../docs_src/request_files/tutorial001_an_py310.py hl[3] *}
+
+## Définir des paramètres `File` { #define-file-parameters }
+
+Créez des paramètres de fichier de la même manière que pour `Body` ou `Form` :
+
+{* ../../docs_src/request_files/tutorial001_an_py310.py hl[9] *}
+
+/// info
+
+`File` est une classe qui hérite directement de `Form`.
+
+Mais souvenez-vous que lorsque vous importez `Query`, `Path`, `File` et d'autres depuis `fastapi`, ce sont en réalité des fonctions qui renvoient des classes spéciales.
+
+///
+
+/// tip | Astuce
+
+Pour déclarer des fichiers dans le corps de la requête, vous devez utiliser `File`, sinon les paramètres seraient interprétés comme des paramètres de requête ou des paramètres de corps (JSON).
+
+///
+
+Les fichiers seront téléversés en « données de formulaire ».
+
+Si vous déclarez le type de votre paramètre de *fonction de chemin d'accès* comme `bytes`, **FastAPI** lira le fichier pour vous et vous recevrez le contenu sous forme de `bytes`.
+
+Gardez à l'esprit que cela signifie que tout le contenu sera stocké en mémoire. Cela fonctionnera bien pour de petits fichiers.
+
+Mais dans plusieurs cas, vous pourriez bénéficier de l'utilisation d'`UploadFile`.
+
+## Paramètres de fichier avec `UploadFile` { #file-parameters-with-uploadfile }
+
+Définissez un paramètre de fichier de type `UploadFile` :
+
+{* ../../docs_src/request_files/tutorial001_an_py310.py hl[14] *}
+
+Utiliser `UploadFile` présente plusieurs avantages par rapport à `bytes` :
+
+- Vous n'avez pas besoin d'utiliser `File()` comme valeur par défaut du paramètre.
+- Il utilise un fichier « spooled » :
+ - Un fichier stocké en mémoire jusqu'à une taille maximale, puis, au-delà de cette limite, stocké sur le disque.
+- Cela fonctionne donc bien pour des fichiers volumineux comme des images, des vidéos, de gros binaires, etc., sans consommer toute la mémoire.
+- Vous pouvez obtenir des métadonnées à partir du fichier téléversé.
+- Il offre une interface `async` de type file-like.
+- Il expose un véritable objet Python `SpooledTemporaryFile` que vous pouvez passer directement à d'autres bibliothèques qui attendent un objet « file-like ».
+
+### `UploadFile` { #uploadfile }
+
+`UploadFile` a les attributs suivants :
+
+- `filename` : une `str` contenant le nom de fichier original téléversé (par ex. `myimage.jpg`).
+- `content_type` : une `str` avec le type de contenu (type MIME / type média) (par ex. `image/jpeg`).
+- `file` : un `SpooledTemporaryFile` (un objet de type fichier). C'est l'objet fichier Python réel que vous pouvez passer directement à d'autres fonctions ou bibliothèques qui attendent un objet « file-like ».
+
+`UploadFile` a les méthodes `async` suivantes. Elles appellent toutes les méthodes correspondantes du fichier sous-jacent (en utilisant le `SpooledTemporaryFile` interne).
+
+- `write(data)` : écrit `data` (`str` ou `bytes`) dans le fichier.
+- `read(size)` : lit `size` (`int`) octets/caractères du fichier.
+- `seek(offset)` : se déplace à la position d'octet `offset` (`int`) dans le fichier.
+ - Par ex., `await myfile.seek(0)` irait au début du fichier.
+ - C'est particulièrement utile si vous exécutez `await myfile.read()` une fois puis devez relire le contenu.
+- `close()` : ferme le fichier.
+
+Comme toutes ces méthodes sont `async`, vous devez les « await ».
+
+Par exemple, à l'intérieur d'une *fonction de chemin d'accès* `async`, vous pouvez obtenir le contenu avec :
+
+```Python
+contents = await myfile.read()
+```
+
+Si vous êtes dans une *fonction de chemin d'accès* `def` normale, vous pouvez accéder directement à `UploadFile.file`, par exemple :
+
+```Python
+contents = myfile.file.read()
+```
+
+/// note | Détails techniques `async`
+
+Lorsque vous utilisez les méthodes `async`, **FastAPI** exécute les méthodes de fichier dans un pool de threads et les attend.
+
+///
+
+/// note | Détails techniques Starlette
+
+L'`UploadFile` de **FastAPI** hérite directement de l'`UploadFile` de **Starlette**, mais ajoute certaines parties nécessaires pour le rendre compatible avec **Pydantic** et les autres parties de FastAPI.
+
+///
+
+## Qu'est-ce que les « données de formulaire » { #what-is-form-data }
+
+La façon dont les formulaires HTML (``) envoient les données au serveur utilise normalement un encodage « spécial » pour ces données, différent de JSON.
+
+**FastAPI** s'assure de lire ces données au bon endroit plutôt que depuis JSON.
+
+/// note | Détails techniques
+
+Les données des formulaires sont normalement encodées avec le « type de média » `application/x-www-form-urlencoded` lorsqu'elles n'incluent pas de fichiers.
+
+Mais lorsque le formulaire inclut des fichiers, il est encodé en `multipart/form-data`. Si vous utilisez `File`, **FastAPI** saura qu'il doit récupérer les fichiers depuis la partie appropriée du corps.
+
+Si vous souhaitez en savoir plus sur ces encodages et les champs de formulaire, consultez la MDN Web Docs pour POST.
+
+///
+
+/// warning | Alertes
+
+Vous pouvez déclarer plusieurs paramètres `File` et `Form` dans un *chemin d'accès*, mais vous ne pouvez pas également déclarer des champs `Body` que vous vous attendez à recevoir en JSON, car la requête aura le corps encodé en `multipart/form-data` au lieu de `application/json`.
+
+Ce n'est pas une limitation de **FastAPI**, cela fait partie du protocole HTTP.
+
+///
+
+## Téléversement de fichier facultatif { #optional-file-upload }
+
+Vous pouvez rendre un fichier facultatif en utilisant des annotations de type standard et en définissant une valeur par défaut à `None` :
+
+{* ../../docs_src/request_files/tutorial001_02_an_py310.py hl[9,17] *}
+
+## `UploadFile` avec des métadonnées supplémentaires { #uploadfile-with-additional-metadata }
+
+Vous pouvez aussi utiliser `File()` avec `UploadFile`, par exemple pour définir des métadonnées supplémentaires :
+
+{* ../../docs_src/request_files/tutorial001_03_an_py310.py hl[9,15] *}
+
+## Téléverser plusieurs fichiers { #multiple-file-uploads }
+
+Il est possible de téléverser plusieurs fichiers en même temps.
+
+Ils seraient associés au même « champ de formulaire » envoyé en « données de formulaire ».
+
+Pour cela, déclarez une `list` de `bytes` ou d'`UploadFile` :
+
+{* ../../docs_src/request_files/tutorial002_an_py310.py hl[10,15] *}
+
+Vous recevrez, comme déclaré, une `list` de `bytes` ou d'`UploadFile`.
+
+/// note | Détails techniques
+
+Vous pourriez aussi utiliser `from starlette.responses import HTMLResponse`.
+
+**FastAPI** fournit les mêmes `starlette.responses` sous `fastapi.responses` simplement pour votre convenance en tant que développeur. Mais la plupart des réponses disponibles proviennent directement de Starlette.
+
+///
+
+### Téléversements multiples avec métadonnées supplémentaires { #multiple-file-uploads-with-additional-metadata }
+
+Et de la même manière que précédemment, vous pouvez utiliser `File()` pour définir des paramètres supplémentaires, même pour `UploadFile` :
+
+{* ../../docs_src/request_files/tutorial003_an_py310.py hl[11,18:20] *}
+
+## Récapitulatif { #recap }
+
+Utilisez `File`, `bytes` et `UploadFile` pour déclarer des fichiers à téléverser dans la requête, envoyés en « données de formulaire ».
diff --git a/docs/fr/docs/tutorial/request-form-models.md b/docs/fr/docs/tutorial/request-form-models.md
new file mode 100644
index 000000000..3fbac9c74
--- /dev/null
+++ b/docs/fr/docs/tutorial/request-form-models.md
@@ -0,0 +1,78 @@
+# Modèles de formulaire { #form-models }
+
+Vous pouvez utiliser des **modèles Pydantic** pour déclarer des **champs de formulaire** dans FastAPI.
+
+/// info
+
+Pour utiliser les formulaires, installez d'abord `python-multipart`.
+
+Assurez-vous de créer un [environnement virtuel](../virtual-environments.md){.internal-link target=_blank}, de l'activer, puis d'installer le paquet, par exemple :
+
+```console
+$ pip install python-multipart
+```
+
+///
+
+/// note | Remarque
+
+Ceci est pris en charge depuis la version `0.113.0` de FastAPI. 🤓
+
+///
+
+## Modèles Pydantic pour les formulaires { #pydantic-models-for-forms }
+
+Vous avez simplement besoin de déclarer un **modèle Pydantic** avec les champs que vous souhaitez recevoir comme **champs de formulaire**, puis de déclarer le paramètre comme `Form` :
+
+{* ../../docs_src/request_form_models/tutorial001_an_py310.py hl[9:11,15] *}
+
+**FastAPI** va **extraire** les données pour **chaque champ** à partir des **données de formulaire** de la requête et vous fournir le modèle Pydantic que vous avez défini.
+
+## Consulter les documents { #check-the-docs }
+
+Vous pouvez le vérifier dans l'interface des documents à `/docs` :
+
+
+

+
+
+## Interdire les champs de formulaire supplémentaires { #forbid-extra-form-fields }
+
+Dans certains cas d'utilisation particuliers (probablement peu courants), vous pourriez vouloir **restreindre** les champs de formulaire à ceux déclarés dans le modèle Pydantic, et **interdire** tout champ **supplémentaire**.
+
+/// note | Remarque
+
+Ceci est pris en charge depuis la version `0.114.0` de FastAPI. 🤓
+
+///
+
+Vous pouvez utiliser la configuration du modèle Pydantic pour `forbid` tout champ `extra` :
+
+{* ../../docs_src/request_form_models/tutorial002_an_py310.py hl[12] *}
+
+Si un client tente d'envoyer des données supplémentaires, il recevra une **réponse d'erreur**.
+
+Par exemple, si le client essaie d'envoyer les champs de formulaire :
+
+* `username`: `Rick`
+* `password`: `Portal Gun`
+* `extra`: `Mr. Poopybutthole`
+
+Il recevra une réponse d'erreur lui indiquant que le champ `extra` n'est pas autorisé :
+
+```json
+{
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["body", "extra"],
+ "msg": "Extra inputs are not permitted",
+ "input": "Mr. Poopybutthole"
+ }
+ ]
+}
+```
+
+## Résumer { #summary }
+
+Vous pouvez utiliser des modèles Pydantic pour déclarer des champs de formulaire dans FastAPI. 😎
diff --git a/docs/fr/docs/tutorial/request-forms-and-files.md b/docs/fr/docs/tutorial/request-forms-and-files.md
new file mode 100644
index 000000000..6774eec8e
--- /dev/null
+++ b/docs/fr/docs/tutorial/request-forms-and-files.md
@@ -0,0 +1,41 @@
+# Utiliser des formulaires et des fichiers de requête { #request-forms-and-files }
+
+Vous pouvez définir des fichiers et des champs de formulaire en même temps à l'aide de `File` et `Form`.
+
+/// info
+
+Pour recevoir des fichiers téléversés et/ou des données de formulaire, installez d'abord `python-multipart`.
+
+Vous devez créer un [environnement virtuel](../virtual-environments.md){.internal-link target=_blank}, l'activer, puis installer ce paquet, par exemple :
+
+```console
+$ pip install python-multipart
+```
+
+///
+
+## Importer `File` et `Form` { #import-file-and-form }
+
+{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[3] *}
+
+## Définir des paramètres `File` et `Form` { #define-file-and-form-parameters }
+
+Créez des paramètres de fichier et de formulaire de la même manière que pour `Body` ou `Query` :
+
+{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[10:12] *}
+
+Les fichiers et les champs de formulaire seront téléversés en tant que données de formulaire et vous les recevrez.
+
+Et vous pouvez déclarer certains fichiers comme `bytes` et d'autres comme `UploadFile`.
+
+/// warning | Alertes
+
+Vous pouvez déclarer plusieurs paramètres `File` et `Form` dans un *chemin d'accès*, mais vous ne pouvez pas aussi déclarer des champs `Body` que vous vous attendez à recevoir en JSON, car la requête aura le corps encodé en `multipart/form-data` au lieu de `application/json`.
+
+Ce n'est pas une limitation de **FastAPI**, cela fait partie du protocole HTTP.
+
+///
+
+## Récapitulatif { #recap }
+
+Utilisez `File` et `Form` ensemble lorsque vous devez recevoir des données et des fichiers dans la même requête.
diff --git a/docs/fr/docs/tutorial/request-forms.md b/docs/fr/docs/tutorial/request-forms.md
new file mode 100644
index 000000000..cea47c93e
--- /dev/null
+++ b/docs/fr/docs/tutorial/request-forms.md
@@ -0,0 +1,73 @@
+# Données de formulaire { #form-data }
+
+Lorsque vous devez recevoir des champs de formulaire au lieu de JSON, vous pouvez utiliser `Form`.
+
+/// info
+
+Pour utiliser les formulaires, installez d'abord `python-multipart`.
+
+Assurez-vous de créer un [environnement virtuel](../virtual-environments.md){.internal-link target=_blank}, de l'activer, puis d'installer ce paquet, par exemple :
+
+```console
+$ pip install python-multipart
+```
+
+///
+
+## Importer `Form` { #import-form }
+
+Importez `Form` depuis `fastapi` :
+
+{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[3] *}
+
+## Définir les paramètres `Form` { #define-form-parameters }
+
+Créez des paramètres de formulaire comme vous le feriez pour `Body` ou `Query` :
+
+{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[9] *}
+
+Par exemple, dans l'une des manières dont la spécification OAuth2 peut être utilisée (appelée « password flow »), il est requis d'envoyer un `username` et un `password` comme champs de formulaire.
+
+La spécification exige que les champs soient exactement nommés `username` et `password`, et qu'ils soient envoyés en tant que champs de formulaire, pas en JSON.
+
+Avec `Form`, vous pouvez déclarer les mêmes configurations que pour `Body` (ainsi que `Query`, `Path`, `Cookie`), y compris la validation, des exemples, un alias (p. ex. `user-name` au lieu de `username`), etc.
+
+/// info
+
+`Form` est une classe qui hérite directement de `Body`.
+
+///
+
+/// tip | Astuce
+
+Pour déclarer des corps de formulaire, vous devez utiliser `Form` explicitement, car sinon les paramètres seraient interprétés comme des paramètres de requête ou des paramètres de corps (JSON).
+
+///
+
+## À propos des « champs de formulaire » { #about-form-fields }
+
+La manière dont les formulaires HTML (``) envoient les données au serveur utilise normalement un encodage « spécial » pour ces données, différent de JSON.
+
+**FastAPI** s'assure de lire ces données au bon endroit au lieu de JSON.
+
+/// note | Détails techniques
+
+Les données issues des formulaires sont normalement encodées avec le « type de média » `application/x-www-form-urlencoded`.
+
+Mais lorsque le formulaire inclut des fichiers, il est encodé en `multipart/form-data`. Vous lirez la gestion des fichiers dans le chapitre suivant.
+
+Si vous voulez en savoir plus sur ces encodages et les champs de formulaire, consultez la MDN web docs pour POST.
+
+///
+
+/// warning | Alertes
+
+Vous pouvez déclarer plusieurs paramètres `Form` dans un chemin d'accès, mais vous ne pouvez pas aussi déclarer des champs `Body` que vous vous attendez à recevoir en JSON, car la requête aura le corps encodé en `application/x-www-form-urlencoded` au lieu de `application/json`.
+
+Ce n'est pas une limitation de **FastAPI**, cela fait partie du protocole HTTP.
+
+///
+
+## Récapitulatif { #recap }
+
+Utilisez `Form` pour déclarer les paramètres d'entrée des données de formulaire.
diff --git a/docs/fr/docs/tutorial/response-model.md b/docs/fr/docs/tutorial/response-model.md
new file mode 100644
index 000000000..337b1aa48
--- /dev/null
+++ b/docs/fr/docs/tutorial/response-model.md
@@ -0,0 +1,343 @@
+# Modèle de réponse - Type de retour { #response-model-return-type }
+
+Vous pouvez déclarer le type utilisé pour la réponse en annotant le **type de retour** de la *fonction de chemin d'accès*.
+
+Vous pouvez utiliser des **annotations de type** de la même manière que pour les données d'entrée dans les **paramètres** de fonction. Vous pouvez utiliser des modèles Pydantic, des listes, des dictionnaires, des valeurs scalaires comme des entiers, des booléens, etc.
+
+{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *}
+
+FastAPI utilisera ce type de retour pour :
+
+* **Valider** les données renvoyées.
+ * Si les données sont invalides (par exemple, il manque un champ), cela signifie que le code de *votre* application est défectueux, qu'il ne renvoie pas ce qu'il devrait, et un erreur serveur sera renvoyée au lieu de renvoyer des données incorrectes. De cette façon, vous et vos clients pouvez être certains de recevoir les données attendues et avec la structure attendue.
+* Ajouter un **JSON Schema** pour la réponse, dans l’OpenAPI du *chemin d'accès*.
+ * Ceci sera utilisé par la **documentation automatique**.
+ * Ceci sera également utilisé par les outils de génération automatique de code client.
+
+Mais surtout :
+
+* Il **limitera et filtrera** les données de sortie à ce qui est défini dans le type de retour.
+ * C'est particulièrement important pour la **sécurité**, nous verrons cela plus bas.
+
+## Paramètre `response_model` { #response-model-parameter }
+
+Il existe des cas où vous devez ou souhaitez renvoyer des données qui ne correspondent pas exactement à ce que déclare le type.
+
+Par exemple, vous pourriez vouloir **renvoyer un dictionnaire** ou un objet de base de données, mais **le déclarer comme un modèle Pydantic**. Ainsi, le modèle Pydantic ferait toute la documentation des données, la validation, etc. pour l'objet que vous avez renvoyé (par exemple un dictionnaire ou un objet de base de données).
+
+Si vous ajoutez l'annotation du type de retour, les outils et éditeurs se plaindront avec une (juste) erreur vous indiquant que votre fonction renvoie un type (par exemple un dict) différent de ce que vous avez déclaré (par exemple un modèle Pydantic).
+
+Dans ces cas, vous pouvez utiliser le paramètre `response_model` du *décorateur de chemin d'accès* au lieu du type de retour.
+
+Vous pouvez utiliser le paramètre `response_model` dans n'importe lequel des *chemins d'accès* :
+
+* `@app.get()`
+* `@app.post()`
+* `@app.put()`
+* `@app.delete()`
+* etc.
+
+{* ../../docs_src/response_model/tutorial001_py310.py hl[17,22,24:27] *}
+
+/// note | Remarque
+
+Notez que `response_model` est un paramètre de la méthode « decorator » (`get`, `post`, etc.). Pas de votre *fonction de chemin d'accès*, comme tous les paramètres et le corps.
+
+///
+
+`response_model` reçoit le même type que vous déclareriez pour un champ de modèle Pydantic, il peut donc s'agir d'un modèle Pydantic, mais il peut aussi être, par exemple, une `list` de modèles Pydantic, comme `List[Item]`.
+
+FastAPI utilisera ce `response_model` pour toute la documentation des données, la validation, etc. et aussi pour **convertir et filtrer les données de sortie** selon sa déclaration de type.
+
+/// tip | Astuce
+
+Si vous avez des vérifications de type strictes dans votre éditeur, mypy, etc., vous pouvez déclarer le type de retour de la fonction en `Any`.
+
+Ainsi, vous indiquez à l'éditeur que vous renvoyez intentionnellement n'importe quoi. Mais FastAPI effectuera quand même la documentation, la validation, le filtrage, etc. des données avec `response_model`.
+
+///
+
+### Priorité de `response_model` { #response-model-priority }
+
+Si vous déclarez à la fois un type de retour et un `response_model`, c'est `response_model` qui aura la priorité et sera utilisé par FastAPI.
+
+De cette manière, vous pouvez ajouter des annotations de type correctes à vos fonctions même si vous renvoyez un type différent du modèle de réponse, pour qu'il soit utilisé par l'éditeur et des outils comme mypy. Et vous pouvez toujours laisser FastAPI faire la validation des données, la documentation, etc. avec `response_model`.
+
+Vous pouvez également utiliser `response_model=None` pour désactiver la création d’un modèle de réponse pour ce *chemin d'accès* ; vous pourriez en avoir besoin si vous ajoutez des annotations de type pour des choses qui ne sont pas des champs valides Pydantic, vous verrez un exemple de cela dans une des sections ci-dessous.
+
+## Renvoyer les mêmes données d'entrée { #return-the-same-input-data }
+
+Ici, nous déclarons un modèle `UserIn`, il contiendra un mot de passe en clair :
+
+{* ../../docs_src/response_model/tutorial002_py310.py hl[7,9] *}
+
+/// info | Info
+
+Pour utiliser `EmailStr`, installez d'abord `email-validator`.
+
+Assurez-vous de créer un [environnement virtuel](../virtual-environments.md){.internal-link target=_blank}, de l'activer, puis de l'installer, par exemple :
+
+```console
+$ pip install email-validator
+```
+
+ou avec :
+
+```console
+$ pip install "pydantic[email]"
+```
+
+///
+
+Et nous utilisons ce modèle pour déclarer notre entrée et le même modèle pour déclarer notre sortie :
+
+{* ../../docs_src/response_model/tutorial002_py310.py hl[16] *}
+
+Désormais, chaque fois qu'un navigateur crée un utilisateur avec un mot de passe, l'API renverra le même mot de passe dans la réponse.
+
+Dans ce cas, cela peut ne pas poser de problème, car c'est le même utilisateur qui envoie le mot de passe.
+
+Mais si nous utilisons le même modèle pour un autre *chemin d'accès*, nous pourrions envoyer les mots de passe de nos utilisateurs à tous les clients.
+
+/// danger | Danger
+
+Ne stockez jamais le mot de passe en clair d'un utilisateur et ne l'envoyez pas dans une réponse de cette manière, à moins de connaître tous les écueils et de savoir exactement ce que vous faites.
+
+///
+
+## Ajouter un modèle de sortie { #add-an-output-model }
+
+Nous pouvons à la place créer un modèle d'entrée avec le mot de passe en clair et un modèle de sortie sans celui-ci :
+
+{* ../../docs_src/response_model/tutorial003_py310.py hl[9,11,16] *}
+
+Ici, même si notre *fonction de chemin d'accès* renvoie le même utilisateur d'entrée qui contient le mot de passe :
+
+{* ../../docs_src/response_model/tutorial003_py310.py hl[24] *}
+
+... nous avons déclaré `response_model` comme étant notre modèle `UserOut`, qui n'inclut pas le mot de passe :
+
+{* ../../docs_src/response_model/tutorial003_py310.py hl[22] *}
+
+Ainsi, **FastAPI** se chargera de filtrer toutes les données qui ne sont pas déclarées dans le modèle de sortie (en utilisant Pydantic).
+
+### `response_model` ou type de retour { #response-model-or-return-type }
+
+Dans ce cas, comme les deux modèles sont différents, si nous annotions le type de retour de la fonction en `UserOut`, l’éditeur et les outils se plaindraient que nous renvoyons un type invalide, car ce sont des classes différentes.
+
+C'est pourquoi, dans cet exemple, nous devons le déclarer dans le paramètre `response_model`.
+
+... mais continuez à lire ci-dessous pour voir comment contourner cela.
+
+## Type de retour et filtrage des données { #return-type-and-data-filtering }
+
+Continuons l'exemple précédent. Nous voulions **annoter la fonction avec un type**, mais nous voulions pouvoir renvoyer depuis la fonction quelque chose qui inclut **plus de données**.
+
+Nous voulons que FastAPI continue de **filtrer** les données à l’aide du modèle de réponse. Ainsi, même si la fonction renvoie plus de données, la réponse n’inclura que les champs déclarés dans le modèle de réponse.
+
+Dans l'exemple précédent, comme les classes étaient différentes, nous avons dû utiliser le paramètre `response_model`. Mais cela signifie aussi que nous ne bénéficions pas de la prise en charge de l'éditeur et des outils pour la vérification du type de retour de la fonction.
+
+Mais dans la plupart des cas où nous avons besoin de quelque chose comme cela, nous voulons que le modèle **filtre/supprime** simplement une partie des données comme dans cet exemple.
+
+Et dans ces cas, nous pouvons utiliser des classes et l'héritage pour tirer parti des **annotations de type** de fonction afin d'obtenir une meilleure prise en charge dans l'éditeur et les outils, tout en bénéficiant du **filtrage de données** de FastAPI.
+
+{* ../../docs_src/response_model/tutorial003_01_py310.py hl[7:10,13:14,18] *}
+
+Avec cela, nous obtenons la prise en charge des outils, des éditeurs et de mypy car ce code est correct en termes de types, et nous bénéficions également du filtrage des données par FastAPI.
+
+Comment cela fonctionne-t-il ? Voyons cela. 🤓
+
+### Annotations de type et outils { #type-annotations-and-tooling }
+
+Voyons d'abord comment les éditeurs, mypy et autres outils considèreraient cela.
+
+`BaseUser` a les champs de base. Puis `UserIn` hérite de `BaseUser` et ajoute le champ `password`, il inclura donc tous les champs des deux modèles.
+
+Nous annotons le type de retour de la fonction en `BaseUser`, mais nous renvoyons en réalité une instance de `UserIn`.
+
+L’éditeur, mypy et d'autres outils ne s’en plaindront pas car, en termes de typage, `UserIn` est une sous-classe de `BaseUser`, ce qui signifie que c’est un type *valide* lorsque ce qui est attendu est n'importe quoi de type `BaseUser`.
+
+### Filtrage des données par FastAPI { #fastapi-data-filtering }
+
+Maintenant, pour FastAPI, il verra le type de retour et s'assurera que ce que vous renvoyez inclut **uniquement** les champs qui sont déclarés dans le type.
+
+FastAPI fait plusieurs choses en interne avec Pydantic pour s'assurer que ces mêmes règles d'héritage de classes ne sont pas utilisées pour le filtrage des données renvoyées, sinon vous pourriez finir par renvoyer beaucoup plus de données que prévu.
+
+De cette façon, vous obtenez le meilleur des deux mondes : annotations de type avec **prise en charge par les outils** et **filtrage des données**.
+
+## Le voir dans la documentation { #see-it-in-the-docs }
+
+Dans la documentation automatique, vous pouvez vérifier que le modèle d'entrée et le modèle de sortie auront chacun leur propre JSON Schema :
+
+
+
+Et les deux modèles seront utilisés pour la documentation API interactive :
+
+
+
+## Autres annotations de type de retour { #other-return-type-annotations }
+
+Il peut y avoir des cas où vous renvoyez quelque chose qui n'est pas un champ Pydantic valide et vous l'annotez dans la fonction, uniquement pour obtenir la prise en charge fournie par les outils (l’éditeur, mypy, etc.).
+
+### Renvoyer directement une Response { #return-a-response-directly }
+
+Le cas le plus courant serait [de renvoyer directement une Response comme expliqué plus loin dans la documentation avancée](../advanced/response-directly.md){.internal-link target=_blank}.
+
+{* ../../docs_src/response_model/tutorial003_02_py310.py hl[8,10:11] *}
+
+Ce cas simple est géré automatiquement par FastAPI car l'annotation du type de retour est la classe (ou une sous-classe de) `Response`.
+
+Et les outils seront également satisfaits car `RedirectResponse` et `JSONResponse` sont des sous-classes de `Response`, donc l'annotation de type est correcte.
+
+### Annoter une sous-classe de Response { #annotate-a-response-subclass }
+
+Vous pouvez aussi utiliser une sous-classe de `Response` dans l'annotation de type :
+
+{* ../../docs_src/response_model/tutorial003_03_py310.py hl[8:9] *}
+
+Cela fonctionnera également car `RedirectResponse` est une sous-classe de `Response`, et FastAPI gérera automatiquement ce cas simple.
+
+### Annotations de type de retour invalides { #invalid-return-type-annotations }
+
+Mais lorsque vous renvoyez un autre objet arbitraire qui n'est pas un type Pydantic valide (par exemple un objet de base de données) et que vous l'annotez ainsi dans la fonction, FastAPI essaiera de créer un modèle de réponse Pydantic à partir de cette annotation de type, et échouera.
+
+Il en serait de même si vous aviez quelque chose comme une union entre différents types dont un ou plusieurs ne sont pas des types Pydantic valides, par exemple ceci échouerait 💥 :
+
+{* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}
+
+... cela échoue parce que l'annotation de type n'est pas un type Pydantic et n'est pas juste une unique classe `Response` ou une sous-classe, c'est une union (l'un des deux) entre une `Response` et un `dict`.
+
+### Désactiver le modèle de réponse { #disable-response-model }
+
+En reprenant l'exemple ci-dessus, vous pourriez ne pas vouloir avoir la validation par défaut des données, la documentation, le filtrage, etc. effectués par FastAPI.
+
+Mais vous pourriez vouloir tout de même conserver l’annotation du type de retour dans la fonction pour bénéficier de la prise en charge des outils comme les éditeurs et les vérificateurs de type (par exemple mypy).
+
+Dans ce cas, vous pouvez désactiver la génération du modèle de réponse en définissant `response_model=None` :
+
+{* ../../docs_src/response_model/tutorial003_05_py310.py hl[7] *}
+
+Cela fera en sorte que FastAPI ignore la génération du modèle de réponse et vous permettra ainsi d’avoir toutes les annotations de type de retour dont vous avez besoin sans que cela n’affecte votre application FastAPI. 🤓
+
+## Paramètres d'encodage du modèle de réponse { #response-model-encoding-parameters }
+
+Votre modèle de réponse peut avoir des valeurs par défaut, par exemple :
+
+{* ../../docs_src/response_model/tutorial004_py310.py hl[9,11:12] *}
+
+* `description: Union[str, None] = None` (ou `str | None = None` en Python 3.10) a une valeur par défaut `None`.
+* `tax: float = 10.5` a une valeur par défaut `10.5`.
+* `tags: List[str] = []` a une valeur par défaut de liste vide : `[]`.
+
+mais vous pourriez vouloir les omettre du résultat si elles n'ont pas été réellement stockées.
+
+Par exemple, si vous avez des modèles avec de nombreux attributs optionnels dans une base NoSQL, mais que vous ne voulez pas envoyer de très longues réponses JSON remplies de valeurs par défaut.
+
+### Utiliser le paramètre `response_model_exclude_unset` { #use-the-response-model-exclude-unset-parameter }
+
+Vous pouvez définir le paramètre du *décorateur de chemin d'accès* `response_model_exclude_unset=True` :
+
+{* ../../docs_src/response_model/tutorial004_py310.py hl[22] *}
+
+et ces valeurs par défaut ne seront pas incluses dans la réponse, uniquement les valeurs effectivement définies.
+
+Ainsi, si vous envoyez une requête à ce *chemin d'accès* pour l'article avec l'ID `foo`, la réponse (sans les valeurs par défaut) sera :
+
+```JSON
+{
+ "name": "Foo",
+ "price": 50.2
+}
+```
+
+/// info | Info
+
+Vous pouvez également utiliser :
+
+* `response_model_exclude_defaults=True`
+* `response_model_exclude_none=True`
+
+comme décrit dans la documentation Pydantic pour `exclude_defaults` et `exclude_none`.
+
+///
+
+#### Données avec des valeurs pour des champs avec des valeurs par défaut { #data-with-values-for-fields-with-defaults }
+
+Mais si vos données ont des valeurs pour les champs du modèle avec des valeurs par défaut, comme l'article avec l'ID `bar` :
+
+```Python hl_lines="3 5"
+{
+ "name": "Bar",
+ "description": "The bartenders",
+ "price": 62,
+ "tax": 20.2
+}
+```
+
+elles seront incluses dans la réponse.
+
+#### Données avec les mêmes valeurs que les valeurs par défaut { #data-with-the-same-values-as-the-defaults }
+
+Si les données ont les mêmes valeurs que les valeurs par défaut, comme l'article avec l'ID `baz` :
+
+```Python hl_lines="3 5-6"
+{
+ "name": "Baz",
+ "description": None,
+ "price": 50.2,
+ "tax": 10.5,
+ "tags": []
+}
+```
+
+FastAPI est suffisamment intelligent (en fait, Pydantic l’est) pour comprendre que, même si `description`, `tax` et `tags` ont les mêmes valeurs que les valeurs par défaut, elles ont été définies explicitement (au lieu d'être prises depuis les valeurs par défaut).
+
+Elles seront donc incluses dans la réponse JSON.
+
+/// tip | Astuce
+
+Notez que les valeurs par défaut peuvent être n'importe quoi, pas seulement `None`.
+
+Elles peuvent être une liste (`[]`), un `float` de `10.5`, etc.
+
+///
+
+### `response_model_include` et `response_model_exclude` { #response-model-include-and-response-model-exclude }
+
+Vous pouvez également utiliser les paramètres du *décorateur de chemin d'accès* `response_model_include` et `response_model_exclude`.
+
+Ils prennent un `set` de `str` avec les noms des attributs à inclure (en omettant le reste) ou à exclure (en incluant le reste).
+
+Cela peut être utilisé comme un raccourci rapide si vous n'avez qu'un seul modèle Pydantic et que vous souhaitez supprimer certaines données de la sortie.
+
+/// tip | Astuce
+
+Mais il est toujours recommandé d'utiliser les idées ci-dessus, en utilisant plusieurs classes, plutôt que ces paramètres.
+
+En effet, le JSON Schema généré dans l’OpenAPI de votre application (et la documentation) restera celui du modèle complet, même si vous utilisez `response_model_include` ou `response_model_exclude` pour omettre certains attributs.
+
+Cela s'applique également à `response_model_by_alias` qui fonctionne de manière similaire.
+
+///
+
+{* ../../docs_src/response_model/tutorial005_py310.py hl[29,35] *}
+
+/// tip | Astuce
+
+La syntaxe `{"name", "description"}` crée un `set` avec ces deux valeurs.
+
+Elle est équivalente à `set(["name", "description"])`.
+
+///
+
+#### Utiliser des `list` au lieu de `set` { #using-lists-instead-of-sets }
+
+Si vous oubliez d'utiliser un `set` et utilisez une `list` ou un `tuple` à la place, FastAPI le convertira quand même en `set` et cela fonctionnera correctement :
+
+{* ../../docs_src/response_model/tutorial006_py310.py hl[29,35] *}
+
+## Récapitulatif { #recap }
+
+Utilisez le paramètre du *décorateur de chemin d'accès* `response_model` pour définir les modèles de réponse et surtout pour garantir que les données privées sont filtrées.
+
+Utilisez `response_model_exclude_unset` pour ne renvoyer que les valeurs définies explicitement.
diff --git a/docs/fr/docs/tutorial/response-status-code.md b/docs/fr/docs/tutorial/response-status-code.md
new file mode 100644
index 000000000..388a53b3d
--- /dev/null
+++ b/docs/fr/docs/tutorial/response-status-code.md
@@ -0,0 +1,101 @@
+# Code d'état de la réponse { #response-status-code }
+
+De la même manière que vous pouvez spécifier un modèle de réponse, vous pouvez également déclarer le code d'état HTTP utilisé pour la réponse avec le paramètre `status_code` dans n'importe lequel des chemins d'accès :
+
+* `@app.get()`
+* `@app.post()`
+* `@app.put()`
+* `@app.delete()`
+* etc.
+
+{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *}
+
+/// note | Remarque
+
+Remarquez que `status_code` est un paramètre de la méthode « decorator » (`get`, `post`, etc.). Pas de votre fonction de chemin d'accès, comme tous les paramètres et le corps.
+
+///
+
+Le paramètre `status_code` reçoit un nombre correspondant au code d'état HTTP.
+
+/// info
+
+`status_code` peut aussi recevoir un `IntEnum`, comme le `http.HTTPStatus` de Python.
+
+///
+
+Il va :
+
+* Renvoyer ce code d'état dans la réponse.
+* Le documenter comme tel dans le schéma OpenAPI (et donc dans les interfaces utilisateur) :
+
+
+
+/// note | Remarque
+
+Certains codes de réponse (voir la section suivante) indiquent que la réponse n'a pas de corps.
+
+FastAPI le sait et produira une documentation OpenAPI indiquant qu'il n'y a pas de corps de réponse.
+
+///
+
+## À propos des codes d'état HTTP { #about-http-status-codes }
+
+/// note | Remarque
+
+Si vous savez déjà ce que sont les codes d'état HTTP, passez à la section suivante.
+
+///
+
+En HTTP, vous envoyez un code d'état numérique de 3 chiffres dans la réponse.
+
+Ces codes d'état ont un nom associé pour les reconnaître, mais la partie importante est le nombre.
+
+En bref :
+
+* `100 - 199` sont pour « Information ». Vous les utilisez rarement directement. Les réponses avec ces codes d'état ne peuvent pas avoir de corps.
+* **`200 - 299`** sont pour les réponses de « Succès ». Ce sont celles que vous utiliserez le plus.
+ * `200` est le code d'état par défaut, ce qui signifie que tout était « OK ».
+ * Un autre exemple est `201`, « Créé ». Il est couramment utilisé après la création d'un nouvel enregistrement dans la base de données.
+ * Un cas particulier est `204`, « Aucun contenu ». Cette réponse est utilisée lorsqu'il n'y a aucun contenu à renvoyer au client ; la réponse ne doit donc pas avoir de corps.
+* **`300 - 399`** sont pour la « Redirection ». Les réponses avec ces codes d'état peuvent avoir ou non un corps, sauf `304`, « Non modifié », qui ne doit pas en avoir.
+* **`400 - 499`** sont pour les réponses d'« Erreur côté client ». C'est probablement le deuxième type que vous utiliserez le plus.
+ * Un exemple est `404`, pour une réponse « Non trouvé ».
+ * Pour des erreurs génériques du client, vous pouvez simplement utiliser `400`.
+* `500 - 599` sont pour les erreurs côté serveur. Vous ne les utilisez presque jamais directement. Lorsqu'un problème survient quelque part dans le code de votre application ou sur le serveur, il renverra automatiquement l'un de ces codes d'état.
+
+/// tip | Astuce
+
+Pour en savoir plus sur chaque code d'état et à quoi il correspond, consultez la MDN documentation about HTTP status codes.
+
+///
+
+## Raccourci pour se souvenir des noms { #shortcut-to-remember-the-names }
+
+Reprenons l'exemple précédent :
+
+{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *}
+
+`201` est le code d'état pour « Créé ».
+
+Mais vous n'avez pas à mémoriser la signification de chacun de ces codes.
+
+Vous pouvez utiliser les variables pratiques de `fastapi.status`.
+
+{* ../../docs_src/response_status_code/tutorial002_py310.py hl[1,6] *}
+
+Elles ne sont qu'une commodité, elles contiennent le même nombre, mais de cette façon vous pouvez utiliser l'autocomplétion de l'éditeur pour les trouver :
+
+
+
+/// note | Détails techniques
+
+Vous pourriez aussi utiliser `from starlette import status`.
+
+FastAPI fournit le même `starlette.status` que `fastapi.status`, uniquement pour votre commodité de développeur. Mais cela vient directement de Starlette.
+
+///
+
+## Modifier la valeur par défaut { #changing-the-default }
+
+Plus tard, dans le [Guide utilisateur avancé](../advanced/response-change-status-code.md){.internal-link target=_blank}, vous verrez comment renvoyer un code d'état différent de celui par défaut que vous déclarez ici.
diff --git a/docs/fr/docs/tutorial/schema-extra-example.md b/docs/fr/docs/tutorial/schema-extra-example.md
new file mode 100644
index 000000000..d4403c779
--- /dev/null
+++ b/docs/fr/docs/tutorial/schema-extra-example.md
@@ -0,0 +1,202 @@
+# Déclarer des exemples de données de requête { #declare-request-example-data }
+
+Vous pouvez déclarer des exemples des données que votre application peut recevoir.
+
+Voici plusieurs façons de le faire.
+
+## Ajouter des données JSON Schema supplémentaires dans les modèles Pydantic { #extra-json-schema-data-in-pydantic-models }
+
+Vous pouvez déclarer `examples` pour un modèle Pydantic qui seront ajoutés au JSON Schema généré.
+
+{* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:24] *}
+
+Ces informations supplémentaires seront ajoutées telles quelles au **JSON Schema** de sortie pour ce modèle, et elles seront utilisées dans la documentation de l'API.
+
+Vous pouvez utiliser l'attribut `model_config` qui accepte un `dict` comme décrit dans Documentation de Pydantic : Configuration.
+
+Vous pouvez définir `"json_schema_extra"` avec un `dict` contenant toutes les données supplémentaires que vous souhaitez voir apparaître dans le JSON Schema généré, y compris `examples`.
+
+/// tip | Astuce
+
+Vous pouvez utiliser la même technique pour étendre le JSON Schema et ajouter vos propres informations supplémentaires personnalisées.
+
+Par exemple, vous pourriez l'utiliser pour ajouter des métadonnées pour une interface utilisateur frontend, etc.
+
+///
+
+/// info
+
+OpenAPI 3.1.0 (utilisé depuis FastAPI 0.99.0) a ajouté la prise en charge de `examples`, qui fait partie du standard **JSON Schema**.
+
+Avant cela, seule la clé `example` avec un exemple unique était prise en charge. Elle l'est toujours par OpenAPI 3.1.0, mais elle est dépréciée et ne fait pas partie du standard JSON Schema. Vous êtes donc encouragé à migrer de `example` vers `examples`. 🤓
+
+Vous pouvez en lire davantage à la fin de cette page.
+
+///
+
+## Arguments supplémentaires de `Field` { #field-additional-arguments }
+
+Lorsque vous utilisez `Field()` avec des modèles Pydantic, vous pouvez également déclarer des `examples` supplémentaires :
+
+{* ../../docs_src/schema_extra_example/tutorial002_py310.py hl[2,8:11] *}
+
+## `examples` dans JSON Schema - OpenAPI { #examples-in-json-schema-openapi }
+
+En utilisant l'un des éléments suivants :
+
+* `Path()`
+* `Query()`
+* `Header()`
+* `Cookie()`
+* `Body()`
+* `Form()`
+* `File()`
+
+vous pouvez également déclarer un groupe de `examples` avec des informations supplémentaires qui seront ajoutées à leurs **JSON Schemas** à l'intérieur d'**OpenAPI**.
+
+### `Body` avec `examples` { #body-with-examples }
+
+Ici, nous passons `examples` contenant un exemple des données attendues dans `Body()` :
+
+{* ../../docs_src/schema_extra_example/tutorial003_an_py310.py hl[22:29] *}
+
+### Exemple dans l'interface des documents { #example-in-the-docs-ui }
+
+Avec l'une des méthodes ci-dessus, cela ressemblerait à ceci dans le `/docs` :
+
+
+
+### `Body` avec plusieurs `examples` { #body-with-multiple-examples }
+
+Vous pouvez bien sûr aussi passer plusieurs `examples` :
+
+{* ../../docs_src/schema_extra_example/tutorial004_an_py310.py hl[23:38] *}
+
+Lorsque vous faites cela, les exemples feront partie du **JSON Schema** interne pour ces données de corps.
+
+Néanmoins, au moment de la rédaction, Swagger UI, l'outil chargé d'afficher l'interface des documents, ne prend pas en charge l'affichage de plusieurs exemples pour les données dans **JSON Schema**. Mais lisez ci-dessous pour un contournement.
+
+### `examples` spécifiques à OpenAPI { #openapi-specific-examples }
+
+Avant que **JSON Schema** ne prenne en charge `examples`, OpenAPI prenait déjà en charge un autre champ également appelé `examples`.
+
+Ce `examples` **spécifique à OpenAPI** se trouve dans une autre section de la spécification OpenAPI. Il se trouve dans les **détails de chaque *chemin d'accès***, et non à l'intérieur de chaque JSON Schema.
+
+Et Swagger UI prend en charge ce champ particulier `examples` depuis un certain temps. Vous pouvez donc l'utiliser pour **afficher** différents **exemples dans l'interface des documents**.
+
+La forme de ce champ `examples` spécifique à OpenAPI est un `dict` avec **plusieurs exemples** (au lieu d'une `list`), chacun avec des informations supplémentaires qui seront également ajoutées à **OpenAPI**.
+
+Cela ne va pas à l'intérieur de chaque JSON Schema contenu dans OpenAPI, cela se place à l'extérieur, directement dans le *chemin d'accès*.
+
+### Utiliser le paramètre `openapi_examples` { #using-the-openapi-examples-parameter }
+
+Vous pouvez déclarer le `examples` spécifique à OpenAPI dans FastAPI avec le paramètre `openapi_examples` pour :
+
+* `Path()`
+* `Query()`
+* `Header()`
+* `Cookie()`
+* `Body()`
+* `Form()`
+* `File()`
+
+Les clés du `dict` identifient chaque exemple, et chaque valeur est un autre `dict`.
+
+Chaque `dict` d'exemple spécifique dans `examples` peut contenir :
+
+* `summary` : une courte description de l'exemple.
+* `description` : une description longue qui peut contenir du texte Markdown.
+* `value` : c'est l'exemple réel affiché, par ex. un `dict`.
+* `externalValue` : alternative à `value`, une URL pointant vers l'exemple. Cependant, cela pourrait ne pas être pris en charge par autant d'outils que `value`.
+
+Vous pouvez l'utiliser ainsi :
+
+{* ../../docs_src/schema_extra_example/tutorial005_an_py310.py hl[23:49] *}
+
+### Exemples OpenAPI dans l'interface des documents { #openapi-examples-in-the-docs-ui }
+
+Avec `openapi_examples` ajouté à `Body()`, le `/docs` ressemblerait à :
+
+
+
+## Détails techniques { #technical-details }
+
+/// tip | Astuce
+
+Si vous utilisez déjà **FastAPI** en version **0.99.0 ou supérieure**, vous pouvez probablement **passer** ces détails.
+
+Ils sont plus pertinents pour les versions plus anciennes, avant que OpenAPI 3.1.0 ne soit disponible.
+
+Vous pouvez considérer ceci comme une courte leçon d'histoire d'OpenAPI et de JSON Schema. 🤓
+
+///
+
+/// warning | Alertes
+
+Ce sont des détails très techniques au sujet des standards **JSON Schema** et **OpenAPI**.
+
+Si les idées ci-dessus fonctionnent déjà pour vous, cela pourrait suffire, et vous n'avez probablement pas besoin de ces détails, n'hésitez pas à les ignorer.
+
+///
+
+Avant OpenAPI 3.1.0, OpenAPI utilisait une version plus ancienne et modifiée de **JSON Schema**.
+
+JSON Schema n'avait pas `examples`, donc OpenAPI a ajouté son propre champ `example` à sa version modifiée.
+
+OpenAPI a également ajouté les champs `example` et `examples` à d'autres parties de la spécification :
+
+* `Parameter Object` (dans la spécification) qui était utilisé par les éléments FastAPI :
+ * `Path()`
+ * `Query()`
+ * `Header()`
+ * `Cookie()`
+* `Request Body Object`, dans le champ `content`, sur le `Media Type Object` (dans la spécification) qui était utilisé par les éléments FastAPI :
+ * `Body()`
+ * `File()`
+ * `Form()`
+
+/// info
+
+Ce paramètre `examples` ancien et spécifique à OpenAPI est désormais `openapi_examples` depuis FastAPI `0.103.0`.
+
+///
+
+### Le champ `examples` de JSON Schema { #json-schemas-examples-field }
+
+Ensuite, JSON Schema a ajouté un champ `examples` dans une nouvelle version de la spécification.
+
+Puis le nouveau OpenAPI 3.1.0 s'est basé sur la dernière version (JSON Schema 2020-12) qui incluait ce nouveau champ `examples`.
+
+Et désormais, ce nouveau champ `examples` a priorité sur l'ancien champ unique (et personnalisé) `example`, qui est maintenant déprécié.
+
+Ce nouveau champ `examples` dans JSON Schema est **juste une `list`** d'exemples, et non pas un dict avec des métadonnées supplémentaires comme dans les autres endroits d'OpenAPI (décrits ci-dessus).
+
+/// info
+
+Même après la sortie d'OpenAPI 3.1.0 avec cette nouvelle intégration plus simple avec JSON Schema, pendant un temps, Swagger UI, l'outil qui fournit la documentation automatique, ne prenait pas en charge OpenAPI 3.1.0 (il le fait depuis la version 5.0.0 🎉).
+
+À cause de cela, les versions de FastAPI antérieures à 0.99.0 utilisaient encore des versions d'OpenAPI inférieures à 3.1.0.
+
+///
+
+### `examples` avec Pydantic et FastAPI { #pydantic-and-fastapi-examples }
+
+Lorsque vous ajoutez `examples` dans un modèle Pydantic, en utilisant `schema_extra` ou `Field(examples=["something"])`, cet exemple est ajouté au **JSON Schema** de ce modèle Pydantic.
+
+Et ce **JSON Schema** du modèle Pydantic est inclus dans l'**OpenAPI** de votre API, puis il est utilisé dans l'interface de la documentation.
+
+Dans les versions de FastAPI antérieures à 0.99.0 (0.99.0 et supérieures utilisent le nouveau OpenAPI 3.1.0), lorsque vous utilisiez `example` ou `examples` avec l'une des autres utilitaires (`Query()`, `Body()`, etc.), ces exemples n'étaient pas ajoutés au JSON Schema qui décrit ces données (pas même à la version de JSON Schema propre à OpenAPI), ils étaient ajoutés directement à la déclaration du *chemin d'accès* dans OpenAPI (en dehors des parties d'OpenAPI qui utilisent JSON Schema).
+
+Mais maintenant que FastAPI 0.99.0 et supérieures utilisent OpenAPI 3.1.0, qui utilise JSON Schema 2020-12, et Swagger UI 5.0.0 et supérieures, tout est plus cohérent et les exemples sont inclus dans JSON Schema.
+
+### Swagger UI et `examples` spécifiques à OpenAPI { #swagger-ui-and-openapi-specific-examples }
+
+Comme Swagger UI ne prenait pas en charge plusieurs exemples JSON Schema (au 2023-08-26), les utilisateurs n'avaient pas de moyen d'afficher plusieurs exemples dans les documents.
+
+Pour résoudre cela, FastAPI `0.103.0` a **ajouté la prise en charge** de la déclaration du même ancien champ `examples` **spécifique à OpenAPI** avec le nouveau paramètre `openapi_examples`. 🤓
+
+### Résumé { #summary }
+
+Je disais que je n'aimais pas trop l'histoire ... et me voilà maintenant à donner des leçons d'« tech history ». 😅
+
+En bref, **mettez à niveau vers FastAPI 0.99.0 ou supérieur**, et les choses sont bien plus **simples, cohérentes et intuitives**, et vous n'avez pas besoin de connaître tous ces détails historiques. 😎
diff --git a/docs/fr/docs/tutorial/security/first-steps.md b/docs/fr/docs/tutorial/security/first-steps.md
new file mode 100644
index 000000000..8c4eb50d7
--- /dev/null
+++ b/docs/fr/docs/tutorial/security/first-steps.md
@@ -0,0 +1,203 @@
+# Sécurité - Premiers pas { #security-first-steps }
+
+Imaginons que vous ayez votre API de **backend** sur un certain domaine.
+
+Et vous avez un **frontend** sur un autre domaine ou dans un chemin différent du même domaine (ou dans une application mobile).
+
+Et vous voulez que le **frontend** puisse s'authentifier auprès du **backend**, en utilisant un **username** et un **password**.
+
+Nous pouvons utiliser **OAuth2** pour construire cela avec **FastAPI**.
+
+Mais épargnons-vous le temps de lire toute la spécification complète juste pour trouver les petites informations dont vous avez besoin.
+
+Utilisons les outils fournis par **FastAPI** pour gérer la sécurité.
+
+## Voir à quoi cela ressemble { #how-it-looks }
+
+Commençons par utiliser le code et voir comment cela fonctionne, puis nous reviendrons pour comprendre ce qui se passe.
+
+## Créer `main.py` { #create-main-py }
+
+Copiez l'exemple dans un fichier `main.py` :
+
+{* ../../docs_src/security/tutorial001_an_py310.py *}
+
+## Exécuter { #run-it }
+
+/// info
+
+Le package `python-multipart` est installé automatiquement avec **FastAPI** lorsque vous exécutez la commande `pip install "fastapi[standard]"`.
+
+Cependant, si vous utilisez la commande `pip install fastapi`, le package `python-multipart` n'est pas inclus par défaut.
+
+Pour l'installer manuellement, vous devez vous assurer de créer un [environnement virtuel](../../virtual-environments.md){.internal-link target=_blank}, de l'activer, puis de l'installer avec :
+
+```console
+$ pip install python-multipart
+```
+
+Cela est dû au fait que **OAuth2** utilise des « form data » pour envoyer le `username` et le `password`.
+
+///
+
+Exécutez l'exemple avec :
+
+
+
+```console
+$ fastapi dev main.py
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+## Vérifier { #check-it }
+
+Allez à la documentation interactive à l'adresse : http://127.0.0.1:8000/docs.
+
+Vous verrez quelque chose comme ceci :
+
+
+
+/// check | Bouton « Authorize » !
+
+Vous avez déjà un tout nouveau bouton « Authorize ».
+
+Et votre *chemin d'accès* a un petit cadenas dans le coin supérieur droit sur lequel vous pouvez cliquer.
+
+///
+
+Et si vous cliquez dessus, vous obtenez un petit formulaire d'autorisation pour saisir un `username` et un `password` (et d'autres champs optionnels) :
+
+
+
+/// note | Remarque
+
+Peu importe ce que vous saisissez dans le formulaire, cela ne fonctionnera pas encore. Mais nous y viendrons.
+
+///
+
+Ce n'est bien sûr pas le frontend pour les utilisateurs finaux, mais c'est un excellent outil automatique pour documenter de manière interactive toute votre API.
+
+Il peut être utilisé par l'équipe frontend (qui peut aussi être vous-même).
+
+Il peut être utilisé par des applications et des systèmes tiers.
+
+Et il peut aussi être utilisé par vous-même, pour déboguer, vérifier et tester la même application.
+
+## Le flux `password` { #the-password-flow }
+
+Revenons un peu en arrière et comprenons de quoi il s'agit.
+
+Le « flux » `password` est l'une des manières (« flows ») définies dans OAuth2 pour gérer la sécurité et l'authentification.
+
+OAuth2 a été conçu pour que le backend ou l'API puisse être indépendant du serveur qui authentifie l'utilisateur.
+
+Mais dans ce cas, la même application **FastAPI** gérera l'API et l'authentification.
+
+Voyons cela selon ce point de vue simplifié :
+
+- L'utilisateur saisit le `username` et le `password` dans le frontend, puis appuie sur Entrée.
+- Le frontend (exécuté dans le navigateur de l'utilisateur) envoie ce `username` et ce `password` vers une URL spécifique de notre API (déclarée avec `tokenUrl="token"`).
+- L'API vérifie ce `username` et ce `password`, et répond avec un « token » (nous n'avons encore rien implémenté de tout cela).
+ - Un « token » n'est qu'une chaîne contenant des informations que nous pouvons utiliser plus tard pour vérifier cet utilisateur.
+ - Normalement, un token est configuré pour expirer après un certain temps.
+ - Ainsi, l'utilisateur devra se reconnecter à un moment donné.
+ - Et si le token est volé, le risque est moindre. Ce n'est pas une clé permanente qui fonctionnerait indéfiniment (dans la plupart des cas).
+- Le frontend stocke ce token temporairement quelque part.
+- L'utilisateur clique dans le frontend pour aller vers une autre section de l'application web frontend.
+- Le frontend doit récupérer d'autres données depuis l'API.
+ - Mais cela nécessite une authentification pour cet endpoint spécifique.
+ - Donc, pour s'authentifier auprès de notre API, il envoie un en-tête `Authorization` avec une valeur `Bearer ` suivie du token.
+ - Si le token contient `foobar`, le contenu de l'en-tête `Authorization` serait : `Bearer foobar`.
+
+## Le `OAuth2PasswordBearer` de **FastAPI** { #fastapis-oauth2passwordbearer }
+
+**FastAPI** fournit plusieurs outils, à différents niveaux d'abstraction, pour implémenter ces fonctionnalités de sécurité.
+
+Dans cet exemple, nous allons utiliser **OAuth2**, avec le flux **Password**, en utilisant un token **Bearer**. Nous le faisons avec la classe `OAuth2PasswordBearer`.
+
+/// info
+
+Un token « bearer » n'est pas la seule option.
+
+Mais c'est la meilleure pour notre cas d'utilisation.
+
+Et cela pourrait être la meilleure pour la plupart des cas, sauf si vous êtes expert en OAuth2 et savez exactement pourquoi une autre option convient mieux à vos besoins.
+
+Dans ce cas, **FastAPI** vous fournit aussi les outils pour la construire.
+
+///
+
+Lorsque nous créons une instance de la classe `OAuth2PasswordBearer`, nous passons le paramètre `tokenUrl`. Ce paramètre contient l'URL que le client (le frontend s'exécutant dans le navigateur de l'utilisateur) utilisera pour envoyer le `username` et le `password` afin d'obtenir un token.
+
+{* ../../docs_src/security/tutorial001_an_py310.py hl[8] *}
+
+/// tip | Astuce
+
+Ici `tokenUrl="token"` fait référence à une URL relative `token` que nous n'avons pas encore créée. Comme c'est une URL relative, elle est équivalente à `./token`.
+
+Parce que nous utilisons une URL relative, si votre API se trouvait à `https://example.com/`, alors elle ferait référence à `https://example.com/token`. Mais si votre API se trouvait à `https://example.com/api/v1/`, alors elle ferait référence à `https://example.com/api/v1/token`.
+
+Utiliser une URL relative est important pour vous assurer que votre application continue de fonctionner même dans un cas d'usage avancé comme [Derrière un proxy](../../advanced/behind-a-proxy.md){.internal-link target=_blank}.
+
+///
+
+Ce paramètre ne crée pas cet endpoint / *chemin d'accès*, mais déclare que l'URL `/token` sera celle que le client doit utiliser pour obtenir le token. Cette information est utilisée dans OpenAPI, puis dans les systèmes de documentation API interactifs.
+
+Nous créerons bientôt aussi le véritable chemin d'accès.
+
+/// info
+
+Si vous êtes un « Pythonista » très strict, vous pourriez ne pas apprécier le style du nom de paramètre `tokenUrl` au lieu de `token_url`.
+
+C'est parce qu'il utilise le même nom que dans la spécification OpenAPI. Ainsi, si vous devez approfondir l'un de ces schémas de sécurité, vous pouvez simplement copier-coller pour trouver plus d'informations à ce sujet.
+
+///
+
+La variable `oauth2_scheme` est une instance de `OAuth2PasswordBearer`, mais c'est aussi un « callable ».
+
+Elle pourrait être appelée ainsi :
+
+```Python
+oauth2_scheme(some, parameters)
+```
+
+Ainsi, elle peut être utilisée avec `Depends`.
+
+### Utiliser { #use-it }
+
+Vous pouvez maintenant passer ce `oauth2_scheme` en dépendance avec `Depends`.
+
+{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}
+
+Cette dépendance fournira une `str` qui est affectée au paramètre `token` de la fonction de *chemin d'accès*.
+
+**FastAPI** saura qu'il peut utiliser cette dépendance pour définir un « schéma de sécurité » dans le schéma OpenAPI (et la documentation API automatique).
+
+/// info | Détails techniques
+
+**FastAPI** saura qu'il peut utiliser la classe `OAuth2PasswordBearer` (déclarée dans une dépendance) pour définir le schéma de sécurité dans OpenAPI parce qu'elle hérite de `fastapi.security.oauth2.OAuth2`, qui hérite à son tour de `fastapi.security.base.SecurityBase`.
+
+Tous les utilitaires de sécurité qui s'intègrent à OpenAPI (et à la documentation API automatique) héritent de `SecurityBase`, c'est ainsi que **FastAPI** sait comment les intégrer dans OpenAPI.
+
+///
+
+## Ce que cela fait { #what-it-does }
+
+Il va chercher dans la requête cet en-tête `Authorization`, vérifier si la valeur est `Bearer ` plus un token, et renverra le token en tant que `str`.
+
+S'il ne voit pas d'en-tête `Authorization`, ou si la valeur n'a pas de token `Bearer `, il répondra directement avec une erreur de code d'état 401 (`UNAUTHORIZED`).
+
+Vous n'avez même pas à vérifier si le token existe pour renvoyer une erreur. Vous pouvez être sûr que si votre fonction est exécutée, elle aura une `str` dans ce token.
+
+Vous pouvez déjà l'essayer dans la documentation interactive :
+
+
+
+Nous ne vérifions pas encore la validité du token, mais c'est déjà un début.
+
+## Récapitulatif { #recap }
+
+Ainsi, en seulement 3 ou 4 lignes supplémentaires, vous disposez déjà d'une forme primitive de sécurité.
diff --git a/docs/fr/docs/tutorial/security/get-current-user.md b/docs/fr/docs/tutorial/security/get-current-user.md
new file mode 100644
index 000000000..5f73efea9
--- /dev/null
+++ b/docs/fr/docs/tutorial/security/get-current-user.md
@@ -0,0 +1,105 @@
+# Obtenir l'utilisateur actuel { #get-current-user }
+
+Dans le chapitre précédent, le système de sécurité (basé sur le système d'injection de dépendances) fournissait à la *fonction de chemin d'accès* un `token` en tant que `str` :
+
+{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}
+
+Mais ce n'est pas encore très utile.
+
+Faisons en sorte qu'il nous fournisse l'utilisateur actuel.
+
+## Créer un modèle d'utilisateur { #create-a-user-model }
+
+Commençons par créer un modèle d'utilisateur Pydantic.
+
+De la même manière que nous utilisons Pydantic pour déclarer des corps de requête, nous pouvons l'utiliser ailleurs :
+
+{* ../../docs_src/security/tutorial002_an_py310.py hl[5,12:6] *}
+
+## Créer une dépendance `get_current_user` { #create-a-get-current-user-dependency }
+
+Créons une dépendance `get_current_user`.
+
+Rappelez-vous que les dépendances peuvent avoir des sous-dépendances ?
+
+`get_current_user` aura une dépendance avec le même `oauth2_scheme` que nous avons créé précédemment.
+
+Comme nous le faisions auparavant directement dans le *chemin d'accès*, notre nouvelle dépendance `get_current_user` recevra un `token` en tant que `str` de la sous-dépendance `oauth2_scheme` :
+
+{* ../../docs_src/security/tutorial002_an_py310.py hl[25] *}
+
+## Récupérer l'utilisateur { #get-the-user }
+
+`get_current_user` utilisera une fonction utilitaire (factice) que nous avons créée, qui prend un token en `str` et retourne notre modèle Pydantic `User` :
+
+{* ../../docs_src/security/tutorial002_an_py310.py hl[19:22,26:27] *}
+
+## Injecter l'utilisateur actuel { #inject-the-current-user }
+
+Nous pouvons donc utiliser le même `Depends` avec notre `get_current_user` dans le *chemin d'accès* :
+
+{* ../../docs_src/security/tutorial002_an_py310.py hl[31] *}
+
+Remarquez que nous déclarons le type de `current_user` comme le modèle Pydantic `User`.
+
+Cela nous aidera dans la fonction avec toute l'autocomplétion et les vérifications de type.
+
+/// tip | Astuce
+
+Vous vous souvenez peut-être que les corps de requête sont également déclarés avec des modèles Pydantic.
+
+Ici, **FastAPI** ne s'y trompera pas car vous utilisez `Depends`.
+
+///
+
+/// check | Vérifications
+
+La manière dont ce système de dépendances est conçu nous permet d'avoir différentes dépendances (différents « dependables ») qui retournent toutes un modèle `User`.
+
+Nous ne sommes pas limités à une seule dépendance pouvant retourner ce type de données.
+
+///
+
+## Autres modèles { #other-models }
+
+Vous pouvez maintenant obtenir l'utilisateur actuel directement dans les *fonctions de chemin d'accès* et gérer les mécanismes de sécurité au niveau de l'**Injection de dépendances**, en utilisant `Depends`.
+
+Et vous pouvez utiliser n'importe quel modèle ou données pour les exigences de sécurité (dans ce cas, un modèle Pydantic `User`).
+
+Mais vous n'êtes pas limité à un modèle, une classe ou un type de données spécifique.
+
+Voulez-vous avoir un `id` et `email` et ne pas avoir de `username` dans votre modèle ? Bien sûr. Vous pouvez utiliser ces mêmes outils.
+
+Voulez-vous simplement avoir un `str` ? Ou juste un `dict` ? Ou directement une instance d'un modèle de classe de base de données ? Tout fonctionne de la même manière.
+
+Vous n'avez en fait pas d'utilisateurs qui se connectent à votre application, mais des robots, bots ou d'autres systèmes, qui n'ont qu'un jeton d'accès ? Là encore, tout fonctionne de la même façon.
+
+Utilisez simplement tout type de modèle, toute sorte de classe, tout type de base de données dont vous avez besoin pour votre application. **FastAPI** vous couvre avec le système d'injection de dépendances.
+
+## Taille du code { #code-size }
+
+Cet exemple peut sembler verbeux. Gardez à l'esprit que nous mélangeons sécurité, modèles de données, fonctions utilitaires et *chemins d'accès* dans le même fichier.
+
+Mais voici le point clé.
+
+La partie sécurité et injection de dépendances est écrite une seule fois.
+
+Et vous pouvez la rendre aussi complexe que vous le souhaitez. Et malgré tout, ne l'écrire qu'une seule fois, en un seul endroit. Avec toute la flexibilité.
+
+Mais vous pouvez avoir des milliers d'endpoints (*chemins d'accès*) utilisant le même système de sécurité.
+
+Et tous (ou seulement une partie d'entre eux, si vous le souhaitez) peuvent profiter de la réutilisation de ces dépendances ou de toute autre dépendance que vous créez.
+
+Et tous ces milliers de *chemins d'accès* peuvent tenir en seulement 3 lignes :
+
+{* ../../docs_src/security/tutorial002_an_py310.py hl[30:32] *}
+
+## Récapitulatif { #recap }
+
+Vous pouvez désormais obtenir l'utilisateur actuel directement dans votre *fonction de chemin d'accès*.
+
+Nous avons déjà fait la moitié du chemin.
+
+Il nous suffit d'ajouter un *chemin d'accès* pour que l'utilisateur/client envoie effectivement le `username` et le `password`.
+
+C'est pour la suite.
diff --git a/docs/fr/docs/tutorial/security/index.md b/docs/fr/docs/tutorial/security/index.md
new file mode 100644
index 000000000..6de75aed6
--- /dev/null
+++ b/docs/fr/docs/tutorial/security/index.md
@@ -0,0 +1,106 @@
+# Sécurité { #security }
+
+Il existe de nombreuses façons de gérer la sécurité, l'authentification et l'autorisation.
+
+Et c'est normalement un sujet complexe et « difficile ».
+
+Dans de nombreux frameworks et systèmes, le simple fait de gérer la sécurité et l'authentification demande beaucoup d'efforts et de code (dans de nombreux cas, cela peut représenter 50 % ou plus de tout le code écrit).
+
+**FastAPI** fournit plusieurs outils pour vous aider à gérer la **Sécurité** facilement, rapidement, de manière standard, sans avoir à étudier et apprendre toutes les spécifications de sécurité.
+
+Mais d'abord, voyons quelques notions.
+
+## Pressé ? { #in-a-hurry }
+
+Si ces termes ne vous intéressent pas et que vous avez simplement besoin d'ajouter une sécurité avec une authentification basée sur un nom d'utilisateur et un mot de passe immédiatement, passez aux chapitres suivants.
+
+## OAuth2 { #oauth2 }
+
+OAuth2 est une spécification qui définit plusieurs façons de gérer l'authentification et l'autorisation.
+
+C'est une spécification assez vaste qui couvre plusieurs cas d'utilisation complexes.
+
+Elle inclut des moyens de s'authentifier en utilisant un « tiers ».
+
+C'est ce que tous les systèmes avec « connexion avec Facebook, Google, X (Twitter), GitHub » utilisent en arrière-plan.
+
+### OAuth 1 { #oauth-1 }
+
+Il y a eu un OAuth 1, très différent d'OAuth2, et plus complexe, car il incluait des spécifications directes sur la manière de chiffrer la communication.
+
+Il n'est plus très populaire ni utilisé de nos jours.
+
+OAuth2 ne spécifie pas comment chiffrer la communication ; il suppose que votre application est servie en HTTPS.
+
+/// tip | Astuce
+
+Dans la section sur le déploiement, vous verrez comment configurer HTTPS gratuitement, en utilisant Traefik et Let's Encrypt.
+
+///
+
+## OpenID Connect { #openid-connect }
+
+OpenID Connect est une autre spécification, basée sur **OAuth2**.
+
+Elle étend simplement OAuth2 en précisant certains points relativement ambigus dans OAuth2, afin d'essayer de la rendre plus interopérable.
+
+Par exemple, la connexion Google utilise OpenID Connect (qui, en arrière-plan, utilise OAuth2).
+
+Mais la connexion Facebook ne prend pas en charge OpenID Connect. Elle a sa propre variante d'OAuth2.
+
+### OpenID (pas « OpenID Connect ») { #openid-not-openid-connect }
+
+Il y avait aussi une spécification « OpenID ». Elle essayait de résoudre la même chose qu'**OpenID Connect**, mais n'était pas basée sur OAuth2.
+
+C'était donc un système totalement distinct.
+
+Il n'est plus très populaire ni utilisé de nos jours.
+
+## OpenAPI { #openapi }
+
+OpenAPI (précédemment connu sous le nom de Swagger) est la spécification ouverte pour construire des API (désormais partie de la Linux Foundation).
+
+**FastAPI** est basé sur **OpenAPI**.
+
+C'est ce qui rend possibles plusieurs interfaces de documentation interactive automatiques, la génération de code, etc.
+
+OpenAPI propose une manière de définir plusieurs « schémas » de sécurité.
+
+En les utilisant, vous pouvez tirer parti de tous ces outils basés sur des standards, y compris ces systèmes de documentation interactive.
+
+OpenAPI définit les schémas de sécurité suivants :
+
+* `apiKey` : une clé spécifique à l'application qui peut provenir :
+ * D'un paramètre de requête.
+ * D'un en-tête.
+ * D'un cookie.
+* `http` : des systèmes d'authentification HTTP standards, notamment :
+ * `bearer` : un en-tête `Authorization` avec une valeur `Bearer ` plus un jeton. Hérité d'OAuth2.
+ * Authentification HTTP Basic.
+ * HTTP Digest, etc.
+* `oauth2` : toutes les méthodes OAuth2 pour gérer la sécurité (appelées « flows »).
+ * Plusieurs de ces flows conviennent pour construire un fournisseur d'authentification OAuth 2.0 (comme Google, Facebook, X (Twitter), GitHub, etc.) :
+ * `implicit`
+ * `clientCredentials`
+ * `authorizationCode`
+ * Mais il existe un « flow » spécifique qui peut parfaitement être utilisé pour gérer l'authentification directement dans la même application :
+ * `password` : certains des prochains chapitres couvriront des exemples à ce sujet.
+* `openIdConnect` : propose un moyen de définir comment découvrir automatiquement les données d'authentification OAuth2.
+ * Cette découverte automatique est ce qui est défini dans la spécification OpenID Connect.
+
+
+/// tip | Astuce
+
+Intégrer d'autres fournisseurs d'authentification/autorisation comme Google, Facebook, X (Twitter), GitHub, etc. est également possible et relativement facile.
+
+Le problème le plus complexe est de construire un fournisseur d'authentification/autorisation comme ceux-là, mais **FastAPI** vous donne les outils pour le faire facilement, tout en effectuant le gros du travail pour vous.
+
+///
+
+## Outils **FastAPI** { #fastapi-utilities }
+
+FastAPI propose plusieurs outils pour chacun de ces schémas de sécurité dans le module fastapi.security qui simplifient l'utilisation de ces mécanismes de sécurité.
+
+Dans les prochains chapitres, vous verrez comment ajouter de la sécurité à votre API en utilisant ces outils fournis par **FastAPI**.
+
+Et vous verrez aussi comment cela s'intègre automatiquement au système de documentation interactive.
diff --git a/docs/fr/docs/tutorial/security/oauth2-jwt.md b/docs/fr/docs/tutorial/security/oauth2-jwt.md
new file mode 100644
index 000000000..d35530fc9
--- /dev/null
+++ b/docs/fr/docs/tutorial/security/oauth2-jwt.md
@@ -0,0 +1,277 @@
+# OAuth2 avec mot de passe (et hachage), Bearer avec des jetons JWT { #oauth2-with-password-and-hashing-bearer-with-jwt-tokens }
+
+Maintenant que nous avons tout le flux de sécurité, rendons réellement l'application sécurisée, en utilisant des jetons JWT et un hachage de mot de passe sécurisé.
+
+Ce code est utilisable dans votre application, enregistrez les hachages de mots de passe dans votre base de données, etc.
+
+Nous allons repartir d'où nous nous sommes arrêtés dans le chapitre précédent et l'enrichir.
+
+## À propos de JWT { #about-jwt }
+
+JWT signifie « JSON Web Tokens ».
+
+C'est une norme pour coder un objet JSON dans une longue chaîne compacte sans espaces. Cela ressemble à ceci :
+
+```
+eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
+```
+
+Il n'est pas chiffré ; ainsi, n'importe qui peut récupérer les informations à partir de son contenu.
+
+Mais il est signé. Ainsi, quand vous recevez un jeton que vous avez émis, vous pouvez vérifier que vous l'avez bien émis.
+
+De cette façon, vous pouvez créer un jeton avec une expiration d'une semaine, par exemple. Et quand l'utilisateur revient le lendemain avec ce jeton, vous savez qu'il est toujours connecté à votre système.
+
+Après une semaine, le jeton aura expiré et l'utilisateur ne sera pas autorisé et devra se reconnecter pour obtenir un nouveau jeton. Et si l'utilisateur (ou un tiers) essayait de modifier le jeton pour changer l'expiration, vous pourriez le détecter, car les signatures ne correspondraient pas.
+
+Si vous voulez expérimenter avec des jetons JWT et voir comment ils fonctionnent, consultez https://jwt.io.
+
+## Installer `PyJWT` { #install-pyjwt }
+
+Nous devons installer `PyJWT` pour générer et vérifier les jetons JWT en Python.
+
+Assurez-vous de créer un [environnement virtuel](../../virtual-environments.md){.internal-link target=_blank}, de l'activer, puis d'installer `pyjwt` :
+
+
+
+```console
+$ pip install pyjwt
+
+---> 100%
+```
+
+
+
+/// info
+
+Si vous prévoyez d'utiliser des algorithmes de signature numérique comme RSA ou ECDSA, vous devez installer la dépendance de bibliothèque de cryptographie `pyjwt[crypto]`.
+
+Vous pouvez en lire davantage dans la documentation d'installation de PyJWT.
+
+///
+
+## Hachage de mot de passe { #password-hashing }
+
+« Hachage » signifie convertir un contenu (un mot de passe dans ce cas) en une séquence d'octets (juste une chaîne) qui ressemble à du charabia.
+
+Chaque fois que vous fournissez exactement le même contenu (exactement le même mot de passe), vous obtenez exactement le même charabia.
+
+Mais vous ne pouvez pas convertir le charabia en sens inverse vers le mot de passe.
+
+### Pourquoi utiliser le hachage de mot de passe { #why-use-password-hashing }
+
+Si votre base de données est volée, le voleur n'aura pas les mots de passe en clair de vos utilisateurs, seulement les hachages.
+
+Ainsi, le voleur ne pourra pas essayer d'utiliser ce mot de passe dans un autre système (comme beaucoup d'utilisateurs utilisent le même mot de passe partout, ce serait dangereux).
+
+## Installer `pwdlib` { #install-pwdlib }
+
+pwdlib est un excellent package Python pour gérer les hachages de mots de passe.
+
+Il prend en charge de nombreux algorithmes de hachage sécurisés et des utilitaires pour travailler avec eux.
+
+L'algorithme recommandé est « Argon2 ».
+
+Assurez-vous de créer un [environnement virtuel](../../virtual-environments.md){.internal-link target=_blank}, de l'activer, puis d'installer pwdlib avec Argon2 :
+
+
+
+```console
+$ pip install "pwdlib[argon2]"
+
+---> 100%
+```
+
+
+
+/// tip | Astuce
+
+Avec `pwdlib`, vous pouvez même le configurer pour pouvoir lire des mots de passe créés par **Django**, un plug-in de sécurité **Flask** ou bien d'autres.
+
+Ainsi, vous seriez par exemple en mesure de partager les mêmes données d'une application Django dans une base de données avec une application FastAPI. Ou de migrer progressivement une application Django en utilisant la même base de données.
+
+Et vos utilisateurs pourraient se connecter depuis votre application Django ou depuis votre application **FastAPI**, en même temps.
+
+///
+
+## Hacher et vérifier les mots de passe { #hash-and-verify-the-passwords }
+
+Importez les outils nécessaires depuis `pwdlib`.
+
+Créez une instance PasswordHash avec les réglages recommandés ; elle sera utilisée pour hacher et vérifier les mots de passe.
+
+/// tip | Astuce
+
+pwdlib prend également en charge l'algorithme de hachage bcrypt, mais n'inclut pas les algorithmes hérités. Pour travailler avec des hachages obsolètes, il est recommandé d'utiliser la bibliothèque passlib.
+
+Par exemple, vous pourriez l'utiliser pour lire et vérifier des mots de passe générés par un autre système (comme Django), mais hacher tous les nouveaux mots de passe avec un autre algorithme comme Argon2 ou Bcrypt.
+
+Et rester compatible avec tous en même temps.
+
+///
+
+Créez une fonction utilitaire pour hacher un mot de passe fourni par l'utilisateur.
+
+Et une autre pour vérifier si un mot de passe reçu correspond au hachage stocké.
+
+Et une autre pour authentifier et renvoyer un utilisateur.
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,51,58:59,62:63,72:79] *}
+
+Lorsque `authenticate_user` est appelée avec un nom d'utilisateur qui n'existe pas dans la base de données, nous exécutons tout de même `verify_password` contre un hachage factice.
+
+Cela garantit que le point de terminaison met approximativement le même temps à répondre que le nom d'utilisateur soit valide ou non, empêchant des **attaques temporelles** qui pourraient être utilisées pour énumérer les noms d'utilisateur existants.
+
+/// note | Remarque
+
+Si vous consultez la nouvelle (fausse) base de données `fake_users_db`, vous verrez à quoi ressemble maintenant le mot de passe haché : `"$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc"`.
+
+///
+
+## Gérer les jetons JWT { #handle-jwt-tokens }
+
+Importez les modules installés.
+
+Créez une clé secrète aléatoire qui sera utilisée pour signer les jetons JWT.
+
+Pour générer une clé secrète aléatoire sécurisée, utilisez la commande :
+
+
+
+```console
+$ openssl rand -hex 32
+
+09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7
+```
+
+
+
+Et copiez la sortie dans la variable `SECRET_KEY` (n'utilisez pas celle de l'exemple).
+
+Créez une variable `ALGORITHM` avec l'algorithme utilisé pour signer le jeton JWT, et définissez-la à `"HS256"`.
+
+Créez une variable pour l'expiration du jeton.
+
+Définissez un modèle Pydantic qui sera utilisé dans le point de terminaison du jeton pour la réponse.
+
+Créez une fonction utilitaire pour générer un nouveau jeton d'accès.
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,82:90] *}
+
+## Mettre à jour les dépendances { #update-the-dependencies }
+
+Mettez à jour `get_current_user` pour recevoir le même jeton qu'auparavant, mais cette fois en utilisant des jetons JWT.
+
+Décodez le jeton reçu, vérifiez-le, et renvoyez l'utilisateur courant.
+
+Si le jeton est invalide, renvoyez immédiatement une erreur HTTP.
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[93:110] *}
+
+## Mettre à jour le *chemin d'accès* `/token` { #update-the-token-path-operation }
+
+Créez un `timedelta` avec la durée d'expiration du jeton.
+
+Créez un véritable jeton d'accès JWT et renvoyez-le.
+
+{* ../../docs_src/security/tutorial004_an_py310.py hl[121:136] *}
+
+### Détails techniques au sujet du « subject » JWT `sub` { #technical-details-about-the-jwt-subject-sub }
+
+La spécification JWT indique qu'il existe une clé `sub`, contenant le sujet du jeton.
+
+Son utilisation est facultative, mais c'est là que vous placeriez l'identifiant de l'utilisateur ; nous l'utilisons donc ici.
+
+Les JWT peuvent être utilisés pour d'autres choses que l'identification d'un utilisateur et l'autorisation d'effectuer des opérations directement sur votre API.
+
+Par exemple, vous pourriez identifier une « voiture » ou un « article de blog ».
+
+Vous pourriez ensuite ajouter des permissions sur cette entité, comme « conduire » (pour la voiture) ou « modifier » (pour le blog).
+
+Vous pourriez alors donner ce jeton JWT à un utilisateur (ou un bot), et il pourrait l'utiliser pour effectuer ces actions (conduire la voiture, ou modifier l'article de blog) sans même avoir besoin d'avoir un compte, uniquement avec le jeton JWT que votre API a généré pour cela.
+
+En utilisant ces idées, les JWT peuvent servir à des scénarios bien plus sophistiqués.
+
+Dans ces cas, plusieurs de ces entités peuvent avoir le même identifiant, disons `foo` (un utilisateur `foo`, une voiture `foo`, et un article de blog `foo`).
+
+Donc, pour éviter les collisions d'identifiants, lors de la création du jeton JWT pour l'utilisateur, vous pouvez préfixer la valeur de la clé `sub`, par exemple avec `username:`. Ainsi, dans cet exemple, la valeur de `sub` aurait pu être : `username:johndoe`.
+
+L'important à garder à l'esprit est que la clé `sub` doit contenir un identifiant unique dans toute l'application, et ce doit être une chaîne de caractères.
+
+## Vérifier { #check-it }
+
+Lancez le serveur et allez à la documentation : http://127.0.0.1:8000/docs.
+
+Vous verrez l'interface utilisateur suivante :
+
+
+
+Autorisez l'application de la même manière qu'auparavant.
+
+En utilisant les identifiants :
+
+Nom d'utilisateur : `johndoe`
+Mot de passe : `secret`
+
+/// check | Vérifications
+
+Remarquez qu'à aucun endroit du code le mot de passe en clair « secret » n'apparaît, nous n'avons que la version hachée.
+
+///
+
+
+
+Appelez le point de terminaison `/users/me/`, vous obtiendrez la réponse suivante :
+
+```JSON
+{
+ "username": "johndoe",
+ "email": "johndoe@example.com",
+ "full_name": "John Doe",
+ "disabled": false
+}
+```
+
+
+
+Si vous ouvrez les outils de développement, vous pouvez voir que les données envoyées n'incluent que le jeton ; le mot de passe n'est envoyé que dans la première requête pour authentifier l'utilisateur et obtenir ce jeton d'accès, mais plus ensuite :
+
+
+
+/// note | Remarque
+
+Remarquez l'en-tête `Authorization`, avec une valeur qui commence par `Bearer `.
+
+///
+
+## Utilisation avancée avec `scopes` { #advanced-usage-with-scopes }
+
+OAuth2 comporte la notion de « scopes ».
+
+Vous pouvez les utiliser pour ajouter un ensemble spécifique d'autorisations à un jeton JWT.
+
+Vous pouvez ensuite donner ce jeton directement à un utilisateur ou à un tiers, pour interagir avec votre API avec un ensemble de restrictions.
+
+Vous pouvez apprendre à les utiliser et comment ils sont intégrés à **FastAPI** plus tard dans le **Guide de l'utilisateur avancé**.
+
+## Récapitulatif { #recap }
+
+Avec ce que vous avez vu jusqu'à présent, vous pouvez configurer une application **FastAPI** sécurisée en utilisant des standards comme OAuth2 et JWT.
+
+Dans presque n'importe quel framework, la gestion de la sécurité devient assez rapidement un sujet plutôt complexe.
+
+De nombreux packages qui la simplifient beaucoup doivent faire de nombreux compromis avec le modèle de données, la base de données et les fonctionnalités disponibles. Et certains de ces packages qui simplifient trop les choses comportent en fait des failles de sécurité sous-jacentes.
+
+---
+
+**FastAPI** ne fait aucun compromis avec une base de données, un modèle de données ni un outil.
+
+Il vous donne toute la flexibilité pour choisir ceux qui conviennent le mieux à votre projet.
+
+Et vous pouvez utiliser directement de nombreux packages bien maintenus et largement utilisés comme `pwdlib` et `PyJWT`, car **FastAPI** n'exige aucun mécanisme complexe pour intégrer des packages externes.
+
+Mais il vous fournit les outils pour simplifier le processus autant que possible sans compromettre la flexibilité, la robustesse ou la sécurité.
+
+Et vous pouvez utiliser et implémenter des protocoles sécurisés et standard, comme OAuth2, de manière relativement simple.
+
+Vous pouvez en apprendre davantage dans le **Guide de l'utilisateur avancé** sur la façon d'utiliser les « scopes » OAuth2, pour un système d'autorisations plus fin, en suivant ces mêmes standards. OAuth2 avec scopes est le mécanisme utilisé par de nombreux grands fournisseurs d'authentification, comme Facebook, Google, GitHub, Microsoft, X (Twitter), etc., pour autoriser des applications tierces à interagir avec leurs API au nom de leurs utilisateurs.
diff --git a/docs/fr/docs/tutorial/security/simple-oauth2.md b/docs/fr/docs/tutorial/security/simple-oauth2.md
new file mode 100644
index 000000000..662444753
--- /dev/null
+++ b/docs/fr/docs/tutorial/security/simple-oauth2.md
@@ -0,0 +1,289 @@
+# OAuth2 simple avec Password et Bearer { #simple-oauth2-with-password-and-bearer }
+
+Construisons maintenant à partir du chapitre précédent et ajoutons les éléments manquants pour avoir un flux de sécurité complet.
+
+## Obtenir `username` et `password` { #get-the-username-and-password }
+
+Nous allons utiliser les utilitaires de sécurité de **FastAPI** pour obtenir `username` et `password`.
+
+OAuth2 spécifie que lorsqu'on utilise le « password flow » (ce que nous utilisons), le client/utilisateur doit envoyer des champs `username` et `password` en tant que données de formulaire.
+
+Et la spécification indique que les champs doivent porter exactement ces noms. Ainsi, `user-name` ou `email` ne fonctionneraient pas.
+
+Mais ne vous inquiétez pas, vous pouvez l'afficher comme vous le souhaitez à vos utilisateurs finaux dans le frontend.
+
+Et vos modèles de base de données peuvent utiliser les noms que vous voulez.
+
+Mais pour le chemin d'accès de connexion, nous devons utiliser ces noms pour être compatibles avec la spécification (et pouvoir, par exemple, utiliser le système de documentation API intégré).
+
+La spécification précise également que `username` et `password` doivent être envoyés en données de formulaire (donc pas de JSON ici).
+
+### `scope` { #scope }
+
+La spécification indique aussi que le client peut envoyer un autre champ de formulaire « scope ».
+
+Le nom du champ de formulaire est `scope` (au singulier), mais il s'agit en fait d'une longue chaîne contenant des « scopes » séparés par des espaces.
+
+Chaque « scope » n'est qu'une chaîne (sans espaces).
+
+Ils sont normalement utilisés pour déclarer des permissions de sécurité spécifiques, par exemple :
+
+* `users:read` ou `users:write` sont des exemples courants.
+* `instagram_basic` est utilisé par Facebook / Instagram.
+* `https://www.googleapis.com/auth/drive` est utilisé par Google.
+
+/// info
+
+En OAuth2, un « scope » est simplement une chaîne qui déclare une permission spécifique requise.
+
+Peu importe s'il contient d'autres caractères comme `:` ou si c'est une URL.
+
+Ces détails dépendent de l'implémentation.
+
+Pour OAuth2, ce ne sont que des chaînes.
+
+///
+
+## Écrire le code pour obtenir `username` et `password` { #code-to-get-the-username-and-password }
+
+Utilisons maintenant les utilitaires fournis par **FastAPI** pour gérer cela.
+
+### `OAuth2PasswordRequestForm` { #oauth2passwordrequestform }
+
+Tout d'abord, importez `OAuth2PasswordRequestForm`, et utilisez-la en tant que dépendance avec `Depends` dans le chemin d'accès pour `/token` :
+
+{* ../../docs_src/security/tutorial003_an_py310.py hl[4,78] *}
+
+`OAuth2PasswordRequestForm` est une dépendance de classe qui déclare un corps de formulaire avec :
+
+* Le `username`.
+* Le `password`.
+* Un champ optionnel `scope` sous forme d'une grande chaîne, composée de chaînes séparées par des espaces.
+* Un `grant_type` optionnel.
+
+/// tip | Astuce
+
+La spécification OAuth2 exige en réalité un champ `grant_type` avec la valeur fixe `password`, mais `OAuth2PasswordRequestForm` ne l'impose pas.
+
+Si vous avez besoin de l'imposer, utilisez `OAuth2PasswordRequestFormStrict` au lieu de `OAuth2PasswordRequestForm`.
+
+///
+
+* Un `client_id` optionnel (nous n'en avons pas besoin pour notre exemple).
+* Un `client_secret` optionnel (nous n'en avons pas besoin pour notre exemple).
+
+/// info
+
+La classe `OAuth2PasswordRequestForm` n'est pas une classe spéciale pour **FastAPI** comme l'est `OAuth2PasswordBearer`.
+
+`OAuth2PasswordBearer` indique à **FastAPI** qu'il s'agit d'un schéma de sécurité. Il est donc ajouté de cette façon à OpenAPI.
+
+Mais `OAuth2PasswordRequestForm` est simplement une dépendance de classe que vous auriez pu écrire vous‑même, ou vous auriez pu déclarer des paramètres `Form` directement.
+
+Mais comme c'est un cas d'usage courant, elle est fournie directement par **FastAPI**, simplement pour vous faciliter la vie.
+
+///
+
+### Utiliser les données du formulaire { #use-the-form-data }
+
+/// tip | Astuce
+
+L'instance de la classe de dépendance `OAuth2PasswordRequestForm` n'aura pas d'attribut `scope` contenant la longue chaîne séparée par des espaces ; elle aura plutôt un attribut `scopes` avec la liste réelle des chaînes pour chaque scope envoyé.
+
+Nous n'utilisons pas `scopes` dans cet exemple, mais la fonctionnalité est disponible si vous en avez besoin.
+
+///
+
+Récupérez maintenant les données utilisateur depuis la (fausse) base de données, en utilisant le `username` du champ de formulaire.
+
+S'il n'existe pas d'utilisateur, nous renvoyons une erreur indiquant « Incorrect username or password ».
+
+Pour l'erreur, nous utilisons l'exception `HTTPException` :
+
+{* ../../docs_src/security/tutorial003_an_py310.py hl[3,79:81] *}
+
+### Vérifier le mot de passe { #check-the-password }
+
+À ce stade, nous avons les données utilisateur depuis notre base, mais nous n'avons pas encore vérifié le mot de passe.
+
+Mettons d'abord ces données dans le modèle Pydantic `UserInDB`.
+
+Vous ne devez jamais enregistrer des mots de passe en clair ; nous allons donc utiliser le système (factice) de hachage de mot de passe.
+
+Si les mots de passe ne correspondent pas, nous renvoyons la même erreur.
+
+#### Hachage de mot de passe { #password-hashing }
+
+Le « hachage » signifie : convertir un contenu (un mot de passe, dans ce cas) en une séquence d'octets (juste une chaîne) qui ressemble à du charabia.
+
+Chaque fois que vous fournissez exactement le même contenu (exactement le même mot de passe), vous obtenez exactement le même charabia.
+
+Mais vous ne pouvez pas convertir ce charabia pour retrouver le mot de passe.
+
+##### Pourquoi utiliser le hachage de mot de passe { #why-use-password-hashing }
+
+Si votre base de données est volée, le voleur n'aura pas les mots de passe en clair de vos utilisateurs, seulement les hachages.
+
+Ainsi, il ne pourra pas essayer d'utiliser ces mêmes mots de passe dans un autre système (comme beaucoup d'utilisateurs utilisent le même mot de passe partout, ce serait dangereux).
+
+{* ../../docs_src/security/tutorial003_an_py310.py hl[82:85] *}
+
+#### À propos de `**user_dict` { #about-user-dict }
+
+`UserInDB(**user_dict)` signifie :
+
+Passez les clés et valeurs de `user_dict` directement comme arguments clé‑valeur, équivalent à :
+
+```Python
+UserInDB(
+ username = user_dict["username"],
+ email = user_dict["email"],
+ full_name = user_dict["full_name"],
+ disabled = user_dict["disabled"],
+ hashed_password = user_dict["hashed_password"],
+)
+```
+
+/// info
+
+Pour une explication plus complète de `**user_dict`, consultez [la documentation pour **Modèles supplémentaires**](../extra-models.md#about-user-in-dict){.internal-link target=_blank}.
+
+///
+
+## Renvoyer le jeton { #return-the-token }
+
+La réponse de l'endpoint `token` doit être un objet JSON.
+
+Il doit contenir un `token_type`. Dans notre cas, comme nous utilisons des jetons « Bearer », le type de jeton doit être « bearer ».
+
+Et il doit contenir un `access_token`, avec une chaîne contenant notre jeton d'accès.
+
+Pour cet exemple simple, nous allons faire quelque chose de complètement non sécurisé et renvoyer le même `username` comme jeton.
+
+/// tip | Astuce
+
+Dans le prochain chapitre, vous verrez une véritable implémentation sécurisée, avec du hachage de mot de passe et des jetons JWT.
+
+Mais pour l'instant, concentrons‑nous sur les détails spécifiques dont nous avons besoin.
+
+///
+
+{* ../../docs_src/security/tutorial003_an_py310.py hl[87] *}
+
+/// tip | Astuce
+
+D'après la spécification, vous devez renvoyer un JSON avec un `access_token` et un `token_type`, comme dans cet exemple.
+
+C'est quelque chose que vous devez faire vous‑même dans votre code, et vous devez vous assurer d'utiliser ces clés JSON.
+
+C'est presque la seule chose que vous devez vous rappeler de faire correctement vous‑même pour être conforme aux spécifications.
+
+Pour le reste, **FastAPI** s'en charge pour vous.
+
+///
+
+## Mettre à jour les dépendances { #update-the-dependencies }
+
+Nous allons maintenant mettre à jour nos dépendances.
+
+Nous voulons obtenir `current_user` uniquement si cet utilisateur est actif.
+
+Nous créons donc une dépendance supplémentaire `get_current_active_user` qui utilise à son tour `get_current_user` comme dépendance.
+
+Ces deux dépendances renverront simplement une erreur HTTP si l'utilisateur n'existe pas, ou s'il est inactif.
+
+Ainsi, dans notre endpoint, nous n'obtiendrons un utilisateur que si l'utilisateur existe, a été correctement authentifié et est actif :
+
+{* ../../docs_src/security/tutorial003_an_py310.py hl[58:66,69:74,94] *}
+
+/// info
+
+L'en‑tête supplémentaire `WWW-Authenticate` avec la valeur `Bearer` que nous renvoyons ici fait également partie de la spécification.
+
+Il est prévu qu'un code d'état HTTP (d'erreur) 401 « UNAUTHORIZED » renvoie également un en‑tête `WWW-Authenticate`.
+
+Dans le cas des jetons bearer (notre cas), la valeur de cet en‑tête doit être `Bearer`.
+
+Vous pouvez en réalité omettre cet en‑tête supplémentaire et cela fonctionnerait quand même.
+
+Mais il est fourni ici pour être conforme aux spécifications.
+
+De plus, il peut exister des outils qui l'attendent et l'utilisent (maintenant ou à l'avenir) et cela pourrait vous être utile, à vous ou à vos utilisateurs, maintenant ou à l'avenir.
+
+C'est l'avantage des standards ...
+
+///
+
+## Voir en action { #see-it-in-action }
+
+Ouvrez la documentation interactive : http://127.0.0.1:8000/docs.
+
+### S'authentifier { #authenticate }
+
+Cliquez sur le bouton « Authorize ».
+
+Utilisez les identifiants :
+
+Utilisateur : `johndoe`
+
+Mot de passe : `secret`
+
+
+
+Après vous être authentifié dans le système, vous verrez ceci :
+
+
+
+### Obtenir vos propres données utilisateur { #get-your-own-user-data }
+
+Utilisez maintenant l'opération `GET` avec le chemin `/users/me`.
+
+Vous obtiendrez les données de votre utilisateur, par exemple :
+
+```JSON
+{
+ "username": "johndoe",
+ "email": "johndoe@example.com",
+ "full_name": "John Doe",
+ "disabled": false,
+ "hashed_password": "fakehashedsecret"
+}
+```
+
+
+
+Si vous cliquez sur l'icône de cadenas et vous vous déconnectez, puis réessayez la même opération, vous obtiendrez une erreur HTTP 401 :
+
+```JSON
+{
+ "detail": "Not authenticated"
+}
+```
+
+### Utilisateur inactif { #inactive-user }
+
+Essayez maintenant avec un utilisateur inactif, authentifiez‑vous avec :
+
+Utilisateur : `alice`
+
+Mot de passe : `secret2`
+
+Et essayez d'utiliser l'opération `GET` avec le chemin `/users/me`.
+
+Vous obtiendrez une erreur « Inactive user », par exemple :
+
+```JSON
+{
+ "detail": "Inactive user"
+}
+```
+
+## Récapitulatif { #recap }
+
+Vous avez maintenant les outils pour implémenter un système de sécurité complet basé sur `username` et `password` pour votre API.
+
+En utilisant ces outils, vous pouvez rendre le système de sécurité compatible avec n'importe quelle base de données et avec n'importe quel modèle d'utilisateur ou de données.
+
+Le seul détail manquant est qu'il n'est pas encore réellement « sécurisé ».
+
+Dans le prochain chapitre, vous verrez comment utiliser une bibliothèque de hachage de mot de passe sécurisée et des jetons JWT.
diff --git a/docs/fr/docs/tutorial/sql-databases.md b/docs/fr/docs/tutorial/sql-databases.md
new file mode 100644
index 000000000..75f9ae14f
--- /dev/null
+++ b/docs/fr/docs/tutorial/sql-databases.md
@@ -0,0 +1,357 @@
+# Bases de données SQL (relationnelles) { #sql-relational-databases }
+
+**FastAPI** ne vous oblige pas à utiliser une base de données SQL (relationnelle). Mais vous pouvez utiliser **n'importe quelle base de données** que vous voulez.
+
+Ici, nous allons voir un exemple utilisant SQLModel.
+
+**SQLModel** est construit au-dessus de SQLAlchemy et de Pydantic. Il a été créé par le même auteur que **FastAPI** pour être l'accord parfait pour les applications FastAPI qui ont besoin d'utiliser des **bases de données SQL**.
+
+/// tip | Astuce
+
+Vous pouvez utiliser toute autre bibliothèque SQL ou NoSQL que vous voulez (dans certains cas appelées « ORMs »), FastAPI ne vous impose rien. 😎
+
+///
+
+Comme SQLModel est basé sur SQLAlchemy, vous pouvez facilement utiliser **toute base prise en charge** par SQLAlchemy (ce qui les rend également prises en charge par SQLModel), comme :
+
+* PostgreSQL
+* MySQL
+* SQLite
+* Oracle
+* Microsoft SQL Server, etc.
+
+Dans cet exemple, nous utiliserons **SQLite**, car il utilise un seul fichier et Python a un support intégré. Ainsi, vous pouvez copier cet exemple et l'exécuter tel quel.
+
+Plus tard, pour votre application de production, vous voudrez peut-être utiliser un serveur de base de données comme **PostgreSQL**.
+
+/// tip | Astuce
+
+Il existe un générateur de projet officiel avec **FastAPI** et **PostgreSQL**, incluant un frontend et plus d'outils : https://github.com/fastapi/full-stack-fastapi-template
+
+///
+
+Il s'agit d'un tutoriel très simple et court ; si vous souhaitez apprendre sur les bases de données en général, sur SQL, ou des fonctionnalités plus avancées, allez voir la documentation SQLModel.
+
+## Installer `SQLModel` { #install-sqlmodel }
+
+D'abord, assurez-vous de créer votre [environnement virtuel](../virtual-environments.md){.internal-link target=_blank}, de l'activer, puis d'installer `sqlmodel` :
+
+
+
+```console
+$ pip install sqlmodel
+---> 100%
+```
+
+
+
+## Créer l'application avec un modèle unique { #create-the-app-with-a-single-model }
+
+Nous allons d'abord créer la première version la plus simple de l'application avec un seul modèle **SQLModel**.
+
+Ensuite, nous l'améliorerons en augmentant la sécurité et la polyvalence avec **plusieurs modèles** ci-dessous. 🤓
+
+### Créer les modèles { #create-models }
+
+Importez `SQLModel` et créez un modèle de base de données :
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:11] hl[7:11] *}
+
+La classe `Hero` est très similaire à un modèle Pydantic (en fait, en dessous, c'est réellement un modèle Pydantic).
+
+Il y a quelques différences :
+
+* `table=True` indique à SQLModel qu'il s'agit d'un *modèle de table*, il doit représenter une **table** dans la base SQL, ce n'est pas seulement un *modèle de données* (comme le serait n'importe quelle autre classe Pydantic classique).
+
+* `Field(primary_key=True)` indique à SQLModel que `id` est la **clé primaire** dans la base SQL (vous pouvez en savoir plus sur les clés primaires SQL dans la documentation SQLModel).
+
+ Remarque : nous utilisons `int | None` pour le champ clé primaire afin qu'en Python nous puissions *créer un objet sans `id`* (`id=None`), en supposant que la base *le génère à l'enregistrement*. SQLModel comprend que la base fournira l'`id` et *définit la colonne comme un `INTEGER` non nul* dans le schéma de base. Voir la documentation SQLModel sur les clés primaires pour plus de détails.
+
+* `Field(index=True)` indique à SQLModel qu'il doit créer un **index SQL** pour cette colonne, ce qui permettra des recherches plus rapides dans la base lors de la lecture de données filtrées par cette colonne.
+
+ SQLModel saura que quelque chose déclaré comme `str` sera une colonne SQL de type `TEXT` (ou `VARCHAR`, selon la base).
+
+### Créer un engine { #create-an-engine }
+
+Un `engine` SQLModel (en dessous c'est en fait un `engine` SQLAlchemy) est ce qui **détient les connexions** à la base de données.
+
+Vous devez avoir **un seul objet `engine`** pour tout votre code afin de se connecter à la même base.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[14:18] hl[14:15,17:18] *}
+
+L'utilisation de `check_same_thread=False` permet à FastAPI d'utiliser la même base SQLite dans différents threads. C'est nécessaire car **une seule requête** peut utiliser **plus d'un thread** (par exemple dans des dépendances).
+
+Ne vous inquiétez pas, avec la structure du code, nous nous assurerons d'utiliser **une seule *session* SQLModel par requête** plus loin, c'est en fait ce que `check_same_thread` essaie d'assurer.
+
+### Créer les tables { #create-the-tables }
+
+Nous ajoutons ensuite une fonction qui utilise `SQLModel.metadata.create_all(engine)` pour **créer les tables** pour tous les *modèles de table*.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[21:22] hl[21:22] *}
+
+### Créer une dépendance de session { #create-a-session-dependency }
+
+Une **`Session`** est ce qui stocke les **objets en mémoire** et suit les modifications nécessaires des données, puis **utilise l'`engine`** pour communiquer avec la base.
+
+Nous allons créer une **dépendance** FastAPI avec `yield` qui fournira une nouvelle `Session` pour chaque requête. C'est ce qui garantit que nous utilisons une seule session par requête. 🤓
+
+Puis nous créons une dépendance `Annotated` `SessionDep` pour simplifier le reste du code qui utilisera cette dépendance.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[25:30] hl[25:27,30] *}
+
+### Créer les tables de base au démarrage { #create-database-tables-on-startup }
+
+Nous allons créer les tables de base de données au démarrage de l'application.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[32:37] hl[35:37] *}
+
+Ici, nous créons les tables lors d'un événement de démarrage de l'application.
+
+En production, vous utiliseriez probablement un script de migration qui s'exécute avant de démarrer votre application. 🤓
+
+/// tip | Astuce
+
+SQLModel aura des utilitaires de migration enveloppant Alembic, mais pour l'instant, vous pouvez utiliser Alembic directement.
+
+///
+
+### Créer un héros { #create-a-hero }
+
+Comme chaque modèle SQLModel est aussi un modèle Pydantic, vous pouvez l'utiliser dans les mêmes **annotations de type** que vous utiliseriez pour des modèles Pydantic.
+
+Par exemple, si vous déclarez un paramètre de type `Hero`, il sera lu depuis le **corps JSON**.
+
+De la même manière, vous pouvez le déclarer comme **type de retour** de la fonction, et alors la forme des données apparaîtra dans l'UI automatique de documentation de l'API.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[40:45] hl[40:45] *}
+
+Ici, nous utilisons la dépendance `SessionDep` (une `Session`) pour ajouter le nouveau `Hero` à l'instance de `Session`, valider les changements dans la base, rafraîchir les données dans `hero`, puis le retourner.
+
+### Lire les héros { #read-heroes }
+
+Nous pouvons **lire** des `Hero` depuis la base en utilisant un `select()`. Nous pouvons inclure une `limit` et un `offset` pour paginer les résultats.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[48:55] hl[51:52,54] *}
+
+### Lire un héros { #read-one-hero }
+
+Nous pouvons **lire** un seul `Hero`.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[58:63] hl[60] *}
+
+### Supprimer un héros { #delete-a-hero }
+
+Nous pouvons aussi **supprimer** un `Hero`.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[66:73] hl[71] *}
+
+### Exécuter l'application { #run-the-app }
+
+Vous pouvez exécuter l'application :
+
+
+
+```console
+$ fastapi dev main.py
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+Ensuite, allez sur l'UI `/docs`, vous verrez que **FastAPI** utilise ces **modèles** pour **documenter** l'API, et les utilisera aussi pour **sérialiser** et **valider** les données.
+
+
+

+
+
+## Mettre à jour l'application avec plusieurs modèles { #update-the-app-with-multiple-models }
+
+Maintenant, **refactorisons** un peu cette application pour augmenter la **sécurité** et la **polyvalence**.
+
+Si vous vérifiez l'application précédente, dans l'UI vous pouvez voir que, jusqu'à présent, elle laisse le client décider de l'`id` du `Hero` à créer. 😱
+
+Nous ne devrions pas laisser cela se produire, ils pourraient écraser un `id` que nous avons déjà attribué dans la base. Décider de l'`id` doit être fait par le **backend** ou la **base**, **pas par le client**.
+
+De plus, nous créons un `secret_name` pour le héros, mais jusqu'ici, nous le renvoyons partout, ce n'est pas très « secret » ... 😅
+
+Nous allons corriger ces choses en ajoutant quelques **modèles supplémentaires**. C'est là que SQLModel brille. ✨
+
+### Créer plusieurs modèles { #create-multiple-models }
+
+Dans **SQLModel**, toute classe de modèle qui a `table=True` est un **modèle de table**.
+
+Et toute classe de modèle qui n'a pas `table=True` est un **modèle de données**, ceux-ci sont en réalité juste des modèles Pydantic (avec deux petites fonctionnalités en plus). 🤓
+
+Avec SQLModel, nous pouvons utiliser **l'héritage** pour **éviter de dupliquer** tous les champs dans tous les cas.
+
+#### `HeroBase` - la classe de base { #herobase-the-base-class }
+
+Commençons avec un modèle `HeroBase` qui a tous les **champs partagés** par tous les modèles :
+
+* `name`
+* `age`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:9] hl[7:9] *}
+
+#### `Hero` - le *modèle de table* { #hero-the-table-model }
+
+Créons ensuite `Hero`, le *modèle de table* proprement dit, avec les **champs supplémentaires** qui ne sont pas toujours dans les autres modèles :
+
+* `id`
+* `secret_name`
+
+Comme `Hero` hérite de `HeroBase`, il **a aussi** les **champs** déclarés dans `HeroBase`, donc tous les champs de `Hero` sont :
+
+* `id`
+* `name`
+* `age`
+* `secret_name`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:14] hl[12:14] *}
+
+#### `HeroPublic` - le *modèle de données* public { #heropublic-the-public-data-model }
+
+Ensuite, nous créons un modèle `HeroPublic`, c'est celui qui sera **retourné** aux clients de l'API.
+
+Il a les mêmes champs que `HeroBase`, il n'inclura donc pas `secret_name`.
+
+Enfin, l'identité de nos héros est protégée ! 🥷
+
+Il redéclare aussi `id: int`. Ce faisant, nous faisons un **contrat** avec les clients de l'API, afin qu'ils puissent toujours s'attendre à ce que `id` soit présent et soit un `int` (il ne sera jamais `None`).
+
+/// tip | Astuce
+
+Avoir le modèle de retour qui garantit qu'une valeur est toujours disponible et toujours `int` (pas `None`) est très utile pour les clients de l'API, ils peuvent écrire un code beaucoup plus simple avec cette certitude.
+
+De plus, les **clients générés automatiquement** auront des interfaces plus simples, afin que les développeurs qui communiquent avec votre API puissent travailler bien plus facilement avec votre API. 😎
+
+///
+
+Tous les champs de `HeroPublic` sont les mêmes que dans `HeroBase`, avec `id` déclaré comme `int` (pas `None`) :
+
+* `id`
+* `name`
+* `age`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:18] hl[17:18] *}
+
+#### `HeroCreate` - le *modèle de données* pour créer un héros { #herocreate-the-data-model-to-create-a-hero }
+
+Nous créons maintenant un modèle `HeroCreate`, c'est celui qui **validera** les données provenant des clients.
+
+Il a les mêmes champs que `HeroBase`, et il a aussi `secret_name`.
+
+Maintenant, lorsque les clients **créent un nouveau héros**, ils enverront `secret_name`, il sera stocké dans la base, mais ces noms secrets ne seront pas renvoyés dans l'API aux clients.
+
+/// tip | Astuce
+
+C'est ainsi que vous géreriez les **mots de passe**. Les recevoir, mais ne pas les renvoyer dans l'API.
+
+Vous **hacherez** aussi les valeurs des mots de passe avant de les stocker, **ne les stockez jamais en texte en clair**.
+
+///
+
+Les champs de `HeroCreate` sont :
+
+* `name`
+* `age`
+* `secret_name`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:22] hl[21:22] *}
+
+#### `HeroUpdate` - le *modèle de données* pour mettre à jour un héros { #heroupdate-the-data-model-to-update-a-hero }
+
+Nous n'avions pas de moyen de **mettre à jour un héros** dans la version précédente de l'application, mais maintenant avec **plusieurs modèles**, nous pouvons le faire. 🎉
+
+Le *modèle de données* `HeroUpdate` est un peu spécial, il a **tous les mêmes champs** qui seraient nécessaires pour créer un nouveau héros, mais tous les champs sont **optionnels** (ils ont tous une valeur par défaut). Ainsi, lorsque vous mettez à jour un héros, vous pouvez n'envoyer que les champs que vous souhaitez mettre à jour.
+
+Comme tous les **champs changent réellement** (le type inclut désormais `None` et ils ont maintenant une valeur par défaut de `None`), nous devons les **redéclarer**.
+
+Nous n'avons pas vraiment besoin d'hériter de `HeroBase` puisque nous redéclarons tous les champs. Je le laisse hériter juste pour la cohérence, mais ce n'est pas nécessaire. C'est plutôt une question de goût personnel. 🤷
+
+Les champs de `HeroUpdate` sont :
+
+* `name`
+* `age`
+* `secret_name`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:28] hl[25:28] *}
+
+### Créer avec `HeroCreate` et retourner un `HeroPublic` { #create-with-herocreate-and-return-a-heropublic }
+
+Maintenant que nous avons **plusieurs modèles**, nous pouvons mettre à jour les parties de l'application qui les utilisent.
+
+Nous recevons dans la requête un *modèle de données* `HeroCreate`, et à partir de celui-ci, nous créons un *modèle de table* `Hero`.
+
+Ce nouveau *modèle de table* `Hero` aura les champs envoyés par le client, et aura aussi un `id` généré par la base.
+
+Nous retournons ensuite le même *modèle de table* `Hero` tel quel depuis la fonction. Mais comme nous déclarons le `response_model` avec le *modèle de données* `HeroPublic`, **FastAPI** utilisera `HeroPublic` pour valider et sérialiser les données.
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[56:62] hl[56:58] *}
+
+/// tip | Astuce
+
+Nous utilisons maintenant `response_model=HeroPublic` au lieu de l'**annotation de type de retour** `-> HeroPublic` car la valeur que nous renvoyons n'est en réalité *pas* un `HeroPublic`.
+
+Si nous avions déclaré `-> HeroPublic`, votre éditeur et votre linter se plaindraient (à juste titre) que vous retournez un `Hero` au lieu d'un `HeroPublic`.
+
+En le déclarant dans `response_model`, nous disons à **FastAPI** de faire son travail, sans interférer avec les annotations de type et l'aide de votre éditeur et d'autres outils.
+
+///
+
+### Lire des héros avec `HeroPublic` { #read-heroes-with-heropublic }
+
+Nous pouvons faire la même chose qu'avant pour **lire** des `Hero`, à nouveau, nous utilisons `response_model=list[HeroPublic]` pour garantir que les données sont correctement validées et sérialisées.
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[65:72] hl[65] *}
+
+### Lire un héros avec `HeroPublic` { #read-one-hero-with-heropublic }
+
+Nous pouvons **lire** un héros unique :
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[75:80] hl[77] *}
+
+### Mettre à jour un héros avec `HeroUpdate` { #update-a-hero-with-heroupdate }
+
+Nous pouvons **mettre à jour un héros**. Pour cela, nous utilisons une opération HTTP `PATCH`.
+
+Et dans le code, nous obtenons un `dict` avec toutes les données envoyées par le client, **uniquement les données envoyées par le client**, en excluant toute valeur qui serait là simplement parce que c'est la valeur par défaut. Pour ce faire, nous utilisons `exclude_unset=True`. C'est l'astuce principale. 🪄
+
+Nous utilisons ensuite `hero_db.sqlmodel_update(hero_data)` pour mettre à jour `hero_db` avec les données de `hero_data`.
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[83:93] hl[83:84,88:89] *}
+
+### Supprimer un héros (bis) { #delete-a-hero-again }
+
+**Supprimer** un héros reste pratiquement identique.
+
+Nous n'allons pas céder à l'envie de tout refactoriser pour celui-ci. 😅
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[96:103] hl[101] *}
+
+### Exécuter l'application à nouveau { #run-the-app-again }
+
+Vous pouvez exécuter l'application à nouveau :
+
+
+
+```console
+$ fastapi dev main.py
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+Si vous allez sur l'UI `/docs` de l'API, vous verrez qu'elle est maintenant à jour, et qu'elle n'attendra plus de recevoir l'`id` du client lors de la création d'un héros, etc.
+
+
+

+
+
+## Récapitulatif { #recap }
+
+Vous pouvez utiliser **SQLModel** pour interagir avec une base SQL et simplifier le code avec des *modèles de données* et des *modèles de table*.
+
+Vous pouvez en apprendre beaucoup plus dans la documentation **SQLModel**, il y a un mini tutoriel plus long sur l'utilisation de SQLModel avec **FastAPI**. 🚀
diff --git a/docs/fr/docs/tutorial/static-files.md b/docs/fr/docs/tutorial/static-files.md
new file mode 100644
index 000000000..3928fed9b
--- /dev/null
+++ b/docs/fr/docs/tutorial/static-files.md
@@ -0,0 +1,40 @@
+# Fichiers statiques { #static-files }
+
+Vous pouvez servir des fichiers statiques automatiquement à partir d'un répertoire en utilisant `StaticFiles`.
+
+## Utiliser `StaticFiles` { #use-staticfiles }
+
+- Importer `StaticFiles`.
+- « Mount » une instance `StaticFiles()` sur un chemin spécifique.
+
+{* ../../docs_src/static_files/tutorial001_py310.py hl[2,6] *}
+
+/// note | Détails techniques
+
+Vous pouvez également utiliser `from starlette.staticfiles import StaticFiles`.
+
+**FastAPI** fournit le même `starlette.staticfiles` sous le nom `fastapi.staticfiles` uniquement pour votre commodité, en tant que développeur. Mais cela provient en réalité directement de Starlette.
+
+///
+
+### Qu'est-ce que « Mounting » { #what-is-mounting }
+
+« Mounting » signifie ajouter une application complète « indépendante » sur un chemin spécifique, qui se chargera ensuite de gérer tous les sous-chemins.
+
+Cela diffère de l'utilisation d'un `APIRouter`, car une application montée est complètement indépendante. L'OpenAPI et les documents de votre application principale n'incluront rien provenant de l'application montée, etc.
+
+Vous pouvez en lire davantage à ce sujet dans le [Guide utilisateur avancé](../advanced/index.md){.internal-link target=_blank}.
+
+## Détails { #details }
+
+Le premier `"/static"` fait référence au sous-chemin sur lequel cette « sous-application » sera « montée ». Ainsi, tout chemin qui commence par `"/static"` sera géré par elle.
+
+Le `directory="static"` fait référence au nom du répertoire qui contient vos fichiers statiques.
+
+Le `name="static"` lui donne un nom utilisable en interne par **FastAPI**.
+
+Tous ces paramètres peuvent être différents de « `static` », adaptez-les aux besoins et aux détails spécifiques de votre propre application.
+
+## Plus d'informations { #more-info }
+
+Pour plus de détails et d'options, consultez la documentation de Starlette sur les fichiers statiques.
diff --git a/docs/fr/docs/tutorial/testing.md b/docs/fr/docs/tutorial/testing.md
new file mode 100644
index 000000000..8a609b644
--- /dev/null
+++ b/docs/fr/docs/tutorial/testing.md
@@ -0,0 +1,193 @@
+# Tester { #testing }
+
+Grâce à Starlette, tester des applications **FastAPI** est simple et agréable.
+
+C’est basé sur HTTPX, dont la conception s’inspire de Requests, ce qui le rend très familier et intuitif.
+
+Avec cela, vous pouvez utiliser pytest directement avec **FastAPI**.
+
+## Utiliser `TestClient` { #using-testclient }
+
+/// info
+
+Pour utiliser `TestClient`, installez d’abord `httpx`.
+
+Vous devez créer un [environnement virtuel](../virtual-environments.md){.internal-link target=_blank}, l’activer, puis y installer le paquet, par exemple :
+
+```console
+$ pip install httpx
+```
+
+///
+
+Importez `TestClient`.
+
+Créez un `TestClient` en lui passant votre application **FastAPI**.
+
+Créez des fonctions dont le nom commence par `test_` (c’est la convention standard de `pytest`).
+
+Utilisez l’objet `TestClient` de la même manière que vous utilisez `httpx`.
+
+Écrivez de simples instructions `assert` avec les expressions Python standard que vous devez vérifier (là encore, standard `pytest`).
+
+{* ../../docs_src/app_testing/tutorial001_py310.py hl[2,12,15:18] *}
+
+/// tip | Astuce
+
+Remarquez que les fonctions de test sont des `def` normales, pas des `async def`.
+
+Et les appels au client sont aussi des appels normaux, sans utiliser `await`.
+
+Cela vous permet d’utiliser `pytest` directement sans complications.
+
+///
+
+/// note | Détails techniques
+
+Vous pouvez aussi utiliser `from starlette.testclient import TestClient`.
+
+**FastAPI** fournit le même `starlette.testclient` sous le nom `fastapi.testclient` uniquement pour votre commodité, en tant que développeur. Mais cela vient directement de Starlette.
+
+///
+
+/// tip | Astuce
+
+Si vous souhaitez appeler des fonctions `async` dans vos tests en dehors de l’envoi de requêtes à votre application FastAPI (par exemple des fonctions de base de données asynchrones), consultez les [Tests asynchrones](../advanced/async-tests.md){.internal-link target=_blank} dans le tutoriel avancé.
+
+///
+
+## Séparer les tests { #separating-tests }
+
+Dans une application réelle, vous auriez probablement vos tests dans un fichier différent.
+
+Et votre application **FastAPI** pourrait aussi être composée de plusieurs fichiers/modules, etc.
+
+### Fichier d’application **FastAPI** { #fastapi-app-file }
+
+Supposons que vous ayez une structure de fichiers comme décrit dans [Applications plus grandes](bigger-applications.md){.internal-link target=_blank} :
+
+```
+.
+├── app
+│ ├── __init__.py
+│ └── main.py
+```
+
+Dans le fichier `main.py`, vous avez votre application **FastAPI** :
+
+
+{* ../../docs_src/app_testing/app_a_py310/main.py *}
+
+### Fichier de test { #testing-file }
+
+Vous pourriez alors avoir un fichier `test_main.py` avec vos tests. Il pourrait vivre dans le même package Python (le même répertoire avec un fichier `__init__.py`) :
+
+``` hl_lines="5"
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+│ └── test_main.py
+```
+
+Comme ce fichier se trouve dans le même package, vous pouvez utiliser des imports relatifs pour importer l’objet `app` depuis le module `main` (`main.py`) :
+
+{* ../../docs_src/app_testing/app_a_py310/test_main.py hl[3] *}
+
+
+… et avoir le code des tests comme précédemment.
+
+## Tester : exemple étendu { #testing-extended-example }
+
+Étendons maintenant cet exemple et ajoutons plus de détails pour voir comment tester différentes parties.
+
+### Fichier d’application **FastAPI** étendu { #extended-fastapi-app-file }
+
+Continuons avec la même structure de fichiers qu’auparavant :
+
+```
+.
+├── app
+│ ├── __init__.py
+│ ├── main.py
+│ └── test_main.py
+```
+
+Supposons que désormais le fichier `main.py` avec votre application **FastAPI** contienne d’autres **chemins d’accès**.
+
+Il a une opération `GET` qui pourrait renvoyer une erreur.
+
+Il a une opération `POST` qui pourrait renvoyer plusieurs erreurs.
+
+Les deux chemins d’accès requièrent un en-tête `X-Token`.
+
+{* ../../docs_src/app_testing/app_b_an_py310/main.py *}
+
+### Fichier de test étendu { #extended-testing-file }
+
+Vous pourriez ensuite mettre à jour `test_main.py` avec les tests étendus :
+
+{* ../../docs_src/app_testing/app_b_an_py310/test_main.py *}
+
+
+Chaque fois que vous avez besoin que le client transmette des informations dans la requête et que vous ne savez pas comment faire, vous pouvez chercher (Google) comment le faire avec `httpx`, ou même comment le faire avec `requests`, puisque la conception de HTTPX est basée sur celle de Requests.
+
+Ensuite, vous faites simplement la même chose dans vos tests.
+
+Par exemple :
+
+* Pour passer un paramètre de chemin ou un paramètre de requête, ajoutez-le directement à l’URL.
+* Pour passer un corps JSON, passez un objet Python (par exemple un `dict`) au paramètre `json`.
+* Si vous devez envoyer des *Form Data* au lieu de JSON, utilisez le paramètre `data` à la place.
+* Pour passer des en-têtes, utilisez un `dict` dans le paramètre `headers`.
+* Pour les cookies, un `dict` dans le paramètre `cookies`.
+
+Pour plus d’informations sur la manière de transmettre des données au backend (en utilisant `httpx` ou le `TestClient`), consultez la documentation HTTPX.
+
+/// info
+
+Notez que le `TestClient` reçoit des données qui peuvent être converties en JSON, pas des modèles Pydantic.
+
+Si vous avez un modèle Pydantic dans votre test et que vous souhaitez envoyer ses données à l’application pendant les tests, vous pouvez utiliser le `jsonable_encoder` décrit dans [Encodeur compatible JSON](encoder.md){.internal-link target=_blank}.
+
+///
+
+## Exécuter { #run-it }
+
+Après cela, vous avez simplement besoin d’installer `pytest`.
+
+Vous devez créer un [environnement virtuel](../virtual-environments.md){.internal-link target=_blank}, l’activer, puis y installer le paquet, par exemple :
+
+
+
+```console
+$ pip install pytest
+
+---> 100%
+```
+
+
+
+Il détectera automatiquement les fichiers et les tests, les exécutera et vous communiquera les résultats.
+
+Exécutez les tests avec :
+
+
+
+```console
+$ pytest
+
+================ test session starts ================
+platform linux -- Python 3.6.9, pytest-5.3.5, py-1.8.1, pluggy-0.13.1
+rootdir: /home/user/code/superawesome-cli/app
+plugins: forked-1.1.3, xdist-1.31.0, cov-2.8.1
+collected 6 items
+
+---> 100%
+
+test_main.py ...... [100%]
+
+================= 1 passed in 0.03s =================
+```
+
+
diff --git a/docs/fr/docs/virtual-environments.md b/docs/fr/docs/virtual-environments.md
new file mode 100644
index 000000000..86b5faadc
--- /dev/null
+++ b/docs/fr/docs/virtual-environments.md
@@ -0,0 +1,864 @@
+# Environnements virtuels { #virtual-environments }
+
+Lorsque vous travaillez sur des projets Python, vous devriez probablement utiliser un environnement virtuel (ou un mécanisme similaire) pour isoler les packages que vous installez pour chaque projet.
+
+/// info
+
+Si vous connaissez déjà les environnements virtuels, comment les créer et les utiliser, vous pouvez passer cette section. 🤓
+
+///
+
+/// tip | Astuce
+
+Un environnement virtuel est différent d’une variable d’environnement.
+
+Une variable d’environnement est une variable du système qui peut être utilisée par des programmes.
+
+Un environnement virtuel est un répertoire contenant certains fichiers.
+
+///
+
+/// info
+
+Cette page vous apprendra à utiliser les environnements virtuels et à comprendre leur fonctionnement.
+
+Si vous êtes prêt à adopter un outil qui gère tout pour vous (y compris l’installation de Python), essayez uv.
+
+///
+
+## Créer un projet { #create-a-project }
+
+Commencez par créer un répertoire pour votre projet.
+
+Ce que je fais généralement, c’est créer un répertoire nommé `code` dans mon répertoire personnel/utilisateur.
+
+Et à l’intérieur, je crée un répertoire par projet.
+
+
+
+```console
+// Aller au répertoire personnel
+$ cd
+// Créer un répertoire pour tous vos projets de code
+$ mkdir code
+// Entrer dans ce répertoire code
+$ cd code
+// Créer un répertoire pour ce projet
+$ mkdir awesome-project
+// Entrer dans ce répertoire de projet
+$ cd awesome-project
+```
+
+
+
+## Créer un environnement virtuel { #create-a-virtual-environment }
+
+Lorsque vous commencez à travailler sur un projet Python pour la première fois, créez un environnement virtuel dans votre projet.
+
+/// tip | Astuce
+
+Vous n’avez besoin de faire cela qu’une seule fois par projet, pas à chaque fois que vous travaillez.
+
+///
+
+//// tab | `venv`
+
+Pour créer un environnement virtuel, vous pouvez utiliser le module `venv` fourni avec Python.
+
+
+
+```console
+$ python -m venv .venv
+```
+
+
+
+/// details | Que signifie cette commande
+
+* `python` : utiliser le programme nommé `python`
+* `-m` : appeler un module comme un script, nous préciserons ensuite quel module
+* `venv` : utiliser le module nommé `venv` qui est normalement installé avec Python
+* `.venv` : créer l’environnement virtuel dans le nouveau répertoire `.venv`
+
+///
+
+////
+
+//// tab | `uv`
+
+Si vous avez installé `uv`, vous pouvez l’utiliser pour créer un environnement virtuel.
+
+
+
+```console
+$ uv venv
+```
+
+
+
+/// tip | Astuce
+
+Par défaut, `uv` créera un environnement virtuel dans un répertoire appelé `.venv`.
+
+Mais vous pouvez le personnaliser en passant un argument supplémentaire avec le nom du répertoire.
+
+///
+
+////
+
+Cette commande crée un nouvel environnement virtuel dans un répertoire appelé `.venv`.
+
+/// details | `.venv` ou autre nom
+
+Vous pourriez créer l’environnement virtuel dans un autre répertoire, mais il est d’usage de l’appeler `.venv`.
+
+///
+
+## Activer l’environnement virtuel { #activate-the-virtual-environment }
+
+Activez le nouvel environnement virtuel afin que toute commande Python que vous exécutez ou tout package que vous installez l’utilise.
+
+/// tip | Astuce
+
+Faites cela à chaque fois que vous démarrez une nouvelle session de terminal pour travailler sur le projet.
+
+///
+
+//// tab | Linux, macOS
+
+
+
+```console
+$ source .venv/bin/activate
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ .venv\Scripts\Activate.ps1
+```
+
+
+
+////
+
+//// tab | Windows Bash
+
+Ou si vous utilisez Bash pour Windows (par exemple Git Bash) :
+
+
+
+```console
+$ source .venv/Scripts/activate
+```
+
+
+
+////
+
+/// tip | Astuce
+
+Chaque fois que vous installez un nouveau package dans cet environnement, activez de nouveau l’environnement.
+
+Vous vous assurez ainsi que si vous utilisez un programme de terminal (CLI) installé par ce package, vous utilisez celui de votre environnement virtuel et non un autre qui pourrait être installé globalement, probablement avec une version différente de celle dont vous avez besoin.
+
+///
+
+## Vérifier que l’environnement virtuel est actif { #check-the-virtual-environment-is-active }
+
+Vérifiez que l’environnement virtuel est actif (la commande précédente a fonctionné).
+
+/// tip | Astuce
+
+C’est facultatif, mais c’est une bonne manière de vérifier que tout fonctionne comme prévu et que vous utilisez l’environnement virtuel voulu.
+
+///
+
+//// tab | Linux, macOS, Windows Bash
+
+
+
+```console
+$ which python
+
+/home/user/code/awesome-project/.venv/bin/python
+```
+
+
+
+S’il affiche le binaire `python` à `.venv/bin/python`, dans votre projet (dans cet exemple `awesome-project`), alors cela a fonctionné. 🎉
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ Get-Command python
+
+C:\Users\user\code\awesome-project\.venv\Scripts\python
+```
+
+
+
+S’il affiche le binaire `python` à `.venv\Scripts\python`, dans votre projet (dans cet exemple `awesome-project`), alors cela a fonctionné. 🎉
+
+////
+
+## Mettre à niveau `pip` { #upgrade-pip }
+
+/// tip | Astuce
+
+Si vous utilisez `uv`, vous l’utiliserez pour installer des éléments à la place de `pip`, vous n’avez donc pas besoin de mettre `pip` à niveau. 😎
+
+///
+
+Si vous utilisez `pip` pour installer des packages (il est fourni par défaut avec Python), vous devez le mettre à niveau vers la dernière version.
+
+Beaucoup d’erreurs exotiques lors de l’installation d’un package se résolvent simplement en mettant d’abord `pip` à niveau.
+
+/// tip | Astuce
+
+Vous feriez normalement cela une seule fois, juste après avoir créé l’environnement virtuel.
+
+///
+
+Vous devez vous assurer que l’environnement virtuel est actif (avec la commande ci-dessus), puis exécuter :
+
+
+
+```console
+$ python -m pip install --upgrade pip
+
+---> 100%
+```
+
+
+
+/// tip | Astuce
+
+Parfois, vous pourriez obtenir une erreur **`No module named pip`** en essayant de mettre à niveau pip.
+
+Si cela arrive, installez et mettez à niveau pip avec la commande ci-dessous :
+
+
+
+```console
+$ python -m ensurepip --upgrade
+
+---> 100%
+```
+
+
+
+Cette commande installera pip s’il n’est pas déjà installé et garantit aussi que la version de pip installée est au moins aussi récente que celle disponible dans `ensurepip`.
+
+///
+
+## Ajouter `.gitignore` { #add-gitignore }
+
+Si vous utilisez Git (vous devriez), ajoutez un fichier `.gitignore` pour exclure tout ce qui se trouve dans votre `.venv` de Git.
+
+/// tip | Astuce
+
+Si vous avez utilisé `uv` pour créer l’environnement virtuel, il l’a déjà fait pour vous, vous pouvez passer cette étape. 😎
+
+///
+
+/// tip | Astuce
+
+Faites cela une seule fois, juste après avoir créé l’environnement virtuel.
+
+///
+
+
+
+```console
+$ echo "*" > .venv/.gitignore
+```
+
+
+
+/// details | Que signifie cette commande
+
+* `echo "*"` : va « afficher » le texte `*` dans le terminal (la partie suivante change un peu cela)
+* `>` : tout ce qui est affiché dans le terminal par la commande à gauche de `>` ne doit pas être affiché mais écrit dans le fichier à droite de `>`
+* `.gitignore` : le nom du fichier dans lequel le texte doit être écrit
+
+Et `*` signifie pour Git « tout ». Ainsi, il ignorera tout dans le répertoire `.venv`.
+
+Cette commande créera un fichier `.gitignore` avec le contenu :
+
+```gitignore
+*
+```
+
+///
+
+## Installer des packages { #install-packages }
+
+Après avoir activé l’environnement, vous pouvez y installer des packages.
+
+/// tip | Astuce
+
+Faites cela une seule fois lorsque vous installez ou mettez à niveau les packages nécessaires à votre projet.
+
+Si vous devez mettre à niveau une version ou ajouter un nouveau package, vous le referez.
+
+///
+
+### Installer des packages directement { #install-packages-directly }
+
+Si vous êtes pressé et ne souhaitez pas utiliser un fichier pour déclarer les dépendances de votre projet, vous pouvez les installer directement.
+
+/// tip | Astuce
+
+C’est une très bonne idée de placer les packages et leurs versions nécessaires à votre programme dans un fichier (par exemple `requirements.txt` ou `pyproject.toml`).
+
+///
+
+//// tab | `pip`
+
+
+
+```console
+$ pip install "fastapi[standard]"
+
+---> 100%
+```
+
+
+
+////
+
+//// tab | `uv`
+
+Si vous avez `uv` :
+
+
+
+```console
+$ uv pip install "fastapi[standard]"
+---> 100%
+```
+
+
+
+////
+
+### Installer depuis `requirements.txt` { #install-from-requirements-txt }
+
+Si vous avez un `requirements.txt`, vous pouvez maintenant l’utiliser pour installer ses packages.
+
+//// tab | `pip`
+
+
+
+```console
+$ pip install -r requirements.txt
+---> 100%
+```
+
+
+
+////
+
+//// tab | `uv`
+
+Si vous avez `uv` :
+
+
+
+```console
+$ uv pip install -r requirements.txt
+---> 100%
+```
+
+
+
+////
+
+/// details | `requirements.txt`
+
+Un `requirements.txt` avec quelques packages pourrait ressembler à :
+
+```requirements.txt
+fastapi[standard]==0.113.0
+pydantic==2.8.0
+```
+
+///
+
+## Exécuter votre programme { #run-your-program }
+
+Après avoir activé l’environnement virtuel, vous pouvez exécuter votre programme, et il utilisera le Python de votre environnement virtuel avec les packages que vous y avez installés.
+
+
+
+```console
+$ python main.py
+
+Hello World
+```
+
+
+
+## Configurer votre éditeur { #configure-your-editor }
+
+Vous utiliserez probablement un éditeur, assurez-vous de le configurer pour utiliser le même environnement virtuel que vous avez créé (il le détectera probablement automatiquement) afin d’avoir l’autocomplétion et les erreurs inline.
+
+Par exemple :
+
+* VS Code
+* PyCharm
+
+/// tip | Astuce
+
+Vous devez normalement faire cela une seule fois, lorsque vous créez l’environnement virtuel.
+
+///
+
+## Désactiver l’environnement virtuel { #deactivate-the-virtual-environment }
+
+Une fois que vous avez fini de travailler sur votre projet, vous pouvez désactiver l’environnement virtuel.
+
+
+
+```console
+$ deactivate
+```
+
+
+
+Ainsi, lorsque vous exécutez `python`, il n’essaiera pas de l’exécuter depuis cet environnement virtuel avec les packages qui y sont installés.
+
+## Prêt à travailler { #ready-to-work }
+
+Vous êtes maintenant prêt à commencer à travailler sur votre projet.
+
+
+
+/// tip | Astuce
+
+Voulez-vous comprendre tout ce qui précède ?
+
+Continuez la lecture. 👇🤓
+
+///
+
+## Pourquoi des environnements virtuels { #why-virtual-environments }
+
+Pour travailler avec FastAPI, vous devez installer Python.
+
+Ensuite, vous devrez installer FastAPI et tout autre package que vous souhaitez utiliser.
+
+Pour installer des packages, vous utiliseriez normalement la commande `pip` fournie avec Python (ou des alternatives similaires).
+
+Néanmoins, si vous utilisez simplement `pip` directement, les packages seraient installés dans votre environnement Python global (l’installation globale de Python).
+
+### Le problème { #the-problem }
+
+Alors, quel est le problème d’installer des packages dans l’environnement Python global ?
+
+À un moment donné, vous finirez probablement par écrire de nombreux programmes différents qui dépendent de packages différents. Et certains de ces projets sur lesquels vous travaillez dépendront de versions différentes du même package. 😱
+
+Par exemple, vous pourriez créer un projet appelé `philosophers-stone`, ce programme dépend d’un autre package appelé **`harry`, en version `1`**. Vous devez donc installer `harry`.
+
+```mermaid
+flowchart LR
+ stone(philosophers-stone) -->|requires| harry-1[harry v1]
+```
+
+Puis, plus tard, vous créez un autre projet appelé `prisoner-of-azkaban`, et ce projet dépend aussi de `harry`, mais il a besoin de **`harry` en version `3`**.
+
+```mermaid
+flowchart LR
+ azkaban(prisoner-of-azkaban) --> |requires| harry-3[harry v3]
+```
+
+Mais maintenant, le problème est que, si vous installez les packages globalement (dans l’environnement global) au lieu de dans un environnement virtuel local, vous devrez choisir quelle version de `harry` installer.
+
+Si vous voulez exécuter `philosophers-stone`, vous devrez d’abord installer `harry` en version `1`, par exemple avec :
+
+
+
+```console
+$ pip install "harry==1"
+```
+
+
+
+Et vous vous retrouverez avec `harry` en version `1` installé dans votre environnement Python global.
+
+```mermaid
+flowchart LR
+ subgraph global[global env]
+ harry-1[harry v1]
+ end
+ subgraph stone-project[philosophers-stone project]
+ stone(philosophers-stone) -->|requires| harry-1
+ end
+```
+
+Mais si vous voulez ensuite exécuter `prisoner-of-azkaban`, vous devrez désinstaller `harry` version `1` et installer `harry` version `3` (ou bien installer la version `3` désinstallerait automatiquement la version `1`).
+
+
+
+```console
+$ pip install "harry==3"
+```
+
+
+
+Et vous vous retrouverez alors avec `harry` version `3` installé dans votre environnement Python global.
+
+Et si vous essayez d’exécuter à nouveau `philosophers-stone`, il y a une chance que cela ne fonctionne pas car il a besoin de `harry` version `1`.
+
+```mermaid
+flowchart LR
+ subgraph global[global env]
+ harry-1[harry v1]
+ style harry-1 fill:#ccc,stroke-dasharray: 5 5
+ harry-3[harry v3]
+ end
+ subgraph stone-project[philosophers-stone project]
+ stone(philosophers-stone) -.-x|⛔️| harry-1
+ end
+ subgraph azkaban-project[prisoner-of-azkaban project]
+ azkaban(prisoner-of-azkaban) --> |requires| harry-3
+ end
+```
+
+/// tip | Astuce
+
+Il est très courant que les packages Python fassent de leur mieux pour éviter les changements cassants dans les nouvelles versions, mais il vaut mieux jouer la sécurité et installer de nouvelles versions intentionnellement et lorsque vous pouvez exécuter les tests pour vérifier que tout fonctionne correctement.
+
+///
+
+Maintenant, imaginez cela avec beaucoup d’autres packages dont tous vos projets dépendent. C’est très difficile à gérer. Et vous finiriez probablement par exécuter certains projets avec des versions incompatibles des packages, sans savoir pourquoi quelque chose ne fonctionne pas.
+
+De plus, selon votre système d’exploitation (par exemple Linux, Windows, macOS), il se peut qu’il soit livré avec Python déjà installé. Et dans ce cas, il avait probablement des packages préinstallés avec des versions spécifiques nécessaires à votre système. Si vous installez des packages dans l’environnement Python global, vous pourriez finir par casser certains des programmes fournis avec votre système d’exploitation.
+
+## Où les packages sont-ils installés { #where-are-packages-installed }
+
+Lorsque vous installez Python, il crée des répertoires avec des fichiers sur votre ordinateur.
+
+Certains de ces répertoires sont chargés de contenir tous les packages que vous installez.
+
+Lorsque vous exécutez :
+
+
+
+```console
+// Ne l’exécutez pas maintenant, c’est juste un exemple 🤓
+$ pip install "fastapi[standard]"
+---> 100%
+```
+
+
+
+Cela téléchargera un fichier compressé avec le code de FastAPI, normalement depuis PyPI.
+
+Il téléchargera également des fichiers pour d’autres packages dont FastAPI dépend.
+
+Ensuite, il extraira tous ces fichiers et les placera dans un répertoire de votre ordinateur.
+
+Par défaut, il placera ces fichiers téléchargés et extraits dans le répertoire fourni avec votre installation de Python, c’est l’environnement global.
+
+## Qu’est-ce qu’un environnement virtuel { #what-are-virtual-environments }
+
+La solution aux problèmes posés par le fait d’avoir tous les packages dans l’environnement global est d’utiliser un environnement virtuel pour chaque projet sur lequel vous travaillez.
+
+Un environnement virtuel est un répertoire, très similaire à celui global, où vous pouvez installer les packages pour un projet.
+
+De cette manière, chaque projet aura son propre environnement virtuel (répertoire `.venv`) avec ses propres packages.
+
+```mermaid
+flowchart TB
+ subgraph stone-project[philosophers-stone project]
+ stone(philosophers-stone) --->|requires| harry-1
+ subgraph venv1[.venv]
+ harry-1[harry v1]
+ end
+ end
+ subgraph azkaban-project[prisoner-of-azkaban project]
+ azkaban(prisoner-of-azkaban) --->|requires| harry-3
+ subgraph venv2[.venv]
+ harry-3[harry v3]
+ end
+ end
+ stone-project ~~~ azkaban-project
+```
+
+## Que signifie activer un environnement virtuel { #what-does-activating-a-virtual-environment-mean }
+
+Lorsque vous activez un environnement virtuel, par exemple avec :
+
+//// tab | Linux, macOS
+
+
+
+```console
+$ source .venv/bin/activate
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ .venv\Scripts\Activate.ps1
+```
+
+
+
+////
+
+//// tab | Windows Bash
+
+Ou si vous utilisez Bash pour Windows (par exemple Git Bash) :
+
+
+
+```console
+$ source .venv/Scripts/activate
+```
+
+
+
+////
+
+Cette commande créera ou modifiera certaines [variables d’environnement](environment-variables.md){.internal-link target=_blank} qui seront disponibles pour les prochaines commandes.
+
+L’une de ces variables est la variable `PATH`.
+
+/// tip | Astuce
+
+Vous pouvez en savoir plus sur la variable d’environnement `PATH` dans la section [Variables d’environnement](environment-variables.md#path-environment-variable){.internal-link target=_blank}.
+
+///
+
+Activer un environnement virtuel ajoute son chemin `.venv/bin` (sur Linux et macOS) ou `.venv\Scripts` (sur Windows) à la variable d’environnement `PATH`.
+
+Disons qu’avant d’activer l’environnement, la variable `PATH` ressemblait à ceci :
+
+//// tab | Linux, macOS
+
+```plaintext
+/usr/bin:/bin:/usr/sbin:/sbin
+```
+
+Cela signifie que le système chercherait des programmes dans :
+
+* `/usr/bin`
+* `/bin`
+* `/usr/sbin`
+* `/sbin`
+
+////
+
+//// tab | Windows
+
+```plaintext
+C:\Windows\System32
+```
+
+Cela signifie que le système chercherait des programmes dans :
+
+* `C:\Windows\System32`
+
+////
+
+Après avoir activé l’environnement virtuel, la variable `PATH` ressemblerait à quelque chose comme ceci :
+
+//// tab | Linux, macOS
+
+```plaintext
+/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin
+```
+
+Cela signifie que le système commencera maintenant par chercher des programmes dans :
+
+```plaintext
+/home/user/code/awesome-project/.venv/bin
+```
+
+avant de chercher dans les autres répertoires.
+
+Ainsi, lorsque vous tapez `python` dans le terminal, le système trouvera le programme Python dans
+
+```plaintext
+/home/user/code/awesome-project/.venv/bin/python
+```
+
+et utilisera celui-ci.
+
+////
+
+//// tab | Windows
+
+```plaintext
+C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32
+```
+
+Cela signifie que le système commencera maintenant par chercher des programmes dans :
+
+```plaintext
+C:\Users\user\code\awesome-project\.venv\Scripts
+```
+
+avant de chercher dans les autres répertoires.
+
+Ainsi, lorsque vous tapez `python` dans le terminal, le système trouvera le programme Python dans
+
+```plaintext
+C:\Users\user\code\awesome-project\.venv\Scripts\python
+```
+
+et utilisera celui-ci.
+
+////
+
+Un détail important est qu’il placera le chemin de l’environnement virtuel au début de la variable `PATH`. Le système le trouvera avant de trouver tout autre Python disponible. Ainsi, lorsque vous exécutez `python`, il utilisera le Python de l’environnement virtuel au lieu de tout autre `python` (par exemple, un `python` d’un environnement global).
+
+Activer un environnement virtuel change aussi deux ou trois autres choses, mais c’est l’un des points les plus importants.
+
+## Vérifier un environnement virtuel { #checking-a-virtual-environment }
+
+Lorsque vous vérifiez si un environnement virtuel est actif, par exemple avec :
+
+//// tab | Linux, macOS, Windows Bash
+
+
+
+```console
+$ which python
+
+/home/user/code/awesome-project/.venv/bin/python
+```
+
+
+
+////
+
+//// tab | Windows PowerShell
+
+
+
+```console
+$ Get-Command python
+
+C:\Users\user\code\awesome-project\.venv\Scripts\python
+```
+
+
+
+////
+
+Cela signifie que le programme `python` qui sera utilisé est celui dans l’environnement virtuel.
+
+Vous utilisez `which` sous Linux et macOS et `Get-Command` sous Windows PowerShell.
+
+La façon dont cette commande fonctionne est qu’elle va vérifier la variable d’environnement `PATH`, en parcourant chaque chemin dans l’ordre, à la recherche du programme nommé `python`. Une fois trouvé, elle vous affichera le chemin vers ce programme.
+
+La partie la plus importante est que lorsque vous appelez `python`, c’est exactement « `python` » qui sera exécuté.
+
+Ainsi, vous pouvez confirmer si vous êtes dans le bon environnement virtuel.
+
+/// tip | Astuce
+
+Il est facile d’activer un environnement virtuel, d’obtenir un Python, puis d’aller vers un autre projet.
+
+Et le second projet ne fonctionnerait pas parce que vous utilisez le Python incorrect, provenant d’un environnement virtuel d’un autre projet.
+
+Il est utile de pouvoir vérifier quel `python` est utilisé. 🤓
+
+///
+
+## Pourquoi désactiver un environnement virtuel { #why-deactivate-a-virtual-environment }
+
+Par exemple, vous pourriez travailler sur un projet `philosophers-stone`, activer cet environnement virtuel, installer des packages et travailler avec cet environnement.
+
+Puis vous souhaitez travailler sur un autre projet `prisoner-of-azkaban`.
+
+Vous allez vers ce projet :
+
+
+
+```console
+$ cd ~/code/prisoner-of-azkaban
+```
+
+
+
+Si vous ne désactivez pas l’environnement virtuel de `philosophers-stone`, lorsque vous exécutez `python` dans le terminal, il essaiera d’utiliser le Python de `philosophers-stone`.
+
+
+
+```console
+$ cd ~/code/prisoner-of-azkaban
+
+$ python main.py
+
+// Erreur lors de l'import de sirius, il n'est pas installé 😱
+Traceback (most recent call last):
+ File "main.py", line 1, in
+ import sirius
+```
+
+
+
+Mais si vous désactivez l’environnement virtuel et activez le nouveau pour `prisoner-of-askaban`, alors lorsque vous exécuterez `python`, il utilisera le Python de l’environnement virtuel de `prisoner-of-azkaban`.
+
+
+
+```console
+$ cd ~/code/prisoner-of-azkaban
+
+// Vous n’avez pas besoin d’être dans l’ancien répertoire pour désactiver, vous pouvez le faire où que vous soyez, même après être allé dans l’autre projet 😎
+$ deactivate
+
+// Activer l’environnement virtuel dans prisoner-of-azkaban/.venv 🚀
+$ source .venv/bin/activate
+
+// Maintenant, lorsque vous exécutez python, il trouvera le package sirius installé dans cet environnement virtuel ✨
+$ python main.py
+
+I solemnly swear 🐺
+```
+
+
+
+## Alternatives { #alternatives }
+
+Ceci est un guide simple pour vous lancer et vous montrer comment tout fonctionne en dessous.
+
+Il existe de nombreuses alternatives pour gérer les environnements virtuels, les dépendances de packages (requirements), les projets.
+
+Lorsque vous êtes prêt et souhaitez utiliser un outil pour gérer l’ensemble du projet, les dépendances, les environnements virtuels, etc., je vous suggère d’essayer uv.
+
+`uv` peut faire beaucoup de choses, il peut :
+
+* Installer Python pour vous, y compris différentes versions
+* Gérer l’environnement virtuel pour vos projets
+* Installer des packages
+* Gérer les dépendances de packages et leurs versions pour votre projet
+* Vous assurer d’avoir un ensemble exact de packages et de versions à installer, y compris leurs dépendances, afin que vous puissiez être certain d’exécuter votre projet en production exactement comme sur votre ordinateur pendant le développement, cela s’appelle le locking
+* Et bien d’autres choses
+
+## Conclusion { #conclusion }
+
+Si vous avez lu et compris tout cela, vous en savez maintenant bien plus sur les environnements virtuels que beaucoup de développeurs. 🤓
+
+Connaître ces détails vous sera très probablement utile à l’avenir lorsque vous déboguerez quelque chose qui semble complexe, mais vous saurez comment tout fonctionne en dessous. 😎