diff --git a/docs/fr/docs/advanced/additional-responses.md b/docs/fr/docs/advanced/additional-responses.md
index 38527aad3..4e16227e8 100644
--- a/docs/fr/docs/advanced/additional-responses.md
+++ b/docs/fr/docs/advanced/additional-responses.md
@@ -1,6 +1,6 @@
-# Réponses supplémentaires dans OpenAPI
+# Réponses supplémentaires dans OpenAPI { #additional-responses-in-openapi }
-/// warning | Attention
+/// warning | Alertes
Ceci concerne un sujet plutôt avancé.
@@ -8,29 +8,29 @@ 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 de statut 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.
-Mais pour ces réponses supplémentaires, vous devez vous assurer de renvoyer directement une `Response` comme `JSONResponse`, avec votre code HTTP et votre contenu.
+Mais pour ces réponses supplémentaires, vous devez vous assurer de renvoyer directement une `Response` comme `JSONResponse`, avec votre code de statut et votre contenu.
-## Réponse supplémentaire avec `model`
+## Réponse supplémentaire avec `model` { #additional-response-with-model }
-Vous pouvez ajouter à votre décorateur de *paramètre de chemin* un paramètre `responses`.
+Vous pouvez passer à vos *décorateurs de chemin d'accès* un paramètre `responses`.
-Il prend comme valeur un `dict` dont les clés sont des codes HTTP pour chaque réponse, comme `200`, et la valeur de ces clés sont d'autres `dict` avec des informations pour chacun d'eux.
+Il reçoit un `dict` : les clés sont des codes de statut pour chaque réponse (comme `200`), et les valeurs sont d'autres `dict` avec les informations pour chacune d'elles.
Chacun de ces `dict` de réponse peut avoir une clé `model`, contenant un modèle Pydantic, tout comme `response_model`.
-**FastAPI** prendra ce modèle, générera son schéma JSON et l'inclura au bon endroit dans OpenAPI.
+**FastAPI** prendra ce modèle, générera son JSON Schema et l'inclura au bon endroit dans OpenAPI.
-Par exemple, pour déclarer une autre réponse avec un code HTTP `404` et un modèle Pydantic `Message`, vous pouvez écrire :
+Par exemple, pour déclarer une autre réponse avec un code de statut `404` et un modèle Pydantic `Message`, vous pouvez écrire :
-{* ../../docs_src/additional_responses/tutorial001.py hl[18,22] *}
+{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *}
/// note | Remarque
-Gardez à l'esprit que vous devez renvoyer directement `JSONResponse`.
+Gardez à l'esprit que vous devez renvoyer directement le `JSONResponse`.
///
@@ -38,18 +38,18 @@ Gardez à l'esprit que vous devez renvoyer directement `JSONResponse`.
La clé `model` ne fait pas partie d'OpenAPI.
-**FastAPI** prendra le modèle Pydantic à partir de là, générera le `JSON Schema` et le placera au bon endroit.
+**FastAPI** prendra le modèle Pydantic à partir de là, générera le JSON Schema et le placera au bon endroit.
Le bon endroit est :
-* Dans la clé `content`, qui a pour valeur un autre objet JSON (`dict`) qui contient :
- * Une clé avec le type de support, par ex. `application/json`, qui contient comme valeur un autre objet JSON, qui contient :
- * Une clé `schema`, qui a pour valeur le schéma JSON du modèle, voici le bon endroit.
- * **FastAPI** ajoute ici une référence aux schémas JSON globaux à un autre endroit de votre OpenAPI au lieu de l'inclure directement. De cette façon, d'autres applications et clients peuvent utiliser ces schémas JSON directement, fournir de meilleurs outils de génération de code, etc.
+* Dans la clé `content`, qui a pour valeur un autre objet JSON (`dict`) qui contient :
+ * Une clé avec le type de média, par ex. `application/json`, qui contient comme valeur un autre objet JSON, qui contient :
+ * Une clé `schema`, qui a pour valeur le JSON Schema du modèle, voici le bon endroit.
+ * **FastAPI** ajoute ici une référence aux JSON Schemas globaux à un autre endroit de votre OpenAPI au lieu de l'inclure directement. De cette façon, d'autres applications et clients peuvent utiliser ces JSON Schemas directement, fournir de meilleurs outils de génération de code, etc.
///
-Les réponses générées au format OpenAPI pour cette *opération de chemin* seront :
+Les réponses générées dans OpenAPI pour cette *opération de chemin d'accès* seront :
```JSON hl_lines="3-12"
{
@@ -88,7 +88,7 @@ Les réponses générées au format OpenAPI pour cette *opération de chemin* se
}
```
-Les schémas sont référencés à un autre endroit du modèle OpenAPI :
+Les schémas sont référencés à un autre endroit dans le schéma OpenAPI :
```JSON hl_lines="4-16"
{
@@ -169,13 +169,13 @@ Les schémas sont référencés à un autre endroit du modèle OpenAPI :
}
```
-## Types de médias supplémentaires pour la réponse principale
+## Types de médias supplémentaires pour la réponse principale { #additional-media-types-for-the-main-response }
Vous pouvez utiliser ce même paramètre `responses` pour ajouter différents types de médias pour la même réponse principale.
-Par exemple, vous pouvez ajouter un type de média supplémentaire `image/png`, en déclarant que votre *opération de chemin* peut renvoyer un objet JSON (avec le type de média `application/json`) ou une image PNG :
+Par exemple, vous pouvez ajouter un type de média supplémentaire `image/png`, en déclarant que votre *opération de chemin d'accès* peut renvoyer un objet JSON (avec le type de média `application/json`) ou une image PNG :
-{* ../../docs_src/additional_responses/tutorial002.py hl[19:24,28] *}
+{* ../../docs_src/additional_responses/tutorial002_py310.py hl[17:22,26] *}
/// note | Remarque
@@ -191,29 +191,29 @@ Mais si vous avez spécifié une classe de réponse personnalisée avec `None` c
///
-## Combinaison d'informations
+## Combinaison d'informations { #combining-information }
Vous pouvez également combiner des informations de réponse provenant de plusieurs endroits, y compris les paramètres `response_model`, `status_code` et `responses`.
-Vous pouvez déclarer un `response_model`, en utilisant le code HTTP par défaut `200` (ou un code personnalisé si vous en avez besoin), puis déclarer des informations supplémentaires pour cette même réponse dans `responses`, directement dans le schéma OpenAPI.
+Vous pouvez déclarer un `response_model`, en utilisant le code de statut par défaut `200` (ou un code personnalisé si vous en avez besoin), puis déclarer des informations supplémentaires pour cette même réponse dans `responses`, directement dans le schéma OpenAPI.
-**FastAPI** conservera les informations supplémentaires des `responses` et les combinera avec le schéma JSON de votre modèle.
+**FastAPI** conservera les informations supplémentaires des `responses` et les combinera avec le JSON Schema de votre modèle.
-Par exemple, vous pouvez déclarer une réponse avec un code HTTP `404` qui utilise un modèle Pydantic et a une `description` personnalisée.
+Par exemple, vous pouvez déclarer une réponse avec un code de statut `404` qui utilise un modèle Pydantic et a une `description` personnalisée.
-Et une réponse avec un code HTTP `200` qui utilise votre `response_model`, mais inclut un `example` personnalisé :
+Et une réponse avec un code de statut `200` qui utilise votre `response_model`, mais inclut un `example` personnalisé :
-{* ../../docs_src/additional_responses/tutorial003.py hl[20:31] *}
+{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *}
-Tout sera combiné et inclus dans votre OpenAPI, et affiché dans la documentation de l'API :
+Tout sera combiné et inclus dans votre OpenAPI, et affiché dans la documentation de l'API :
-## Combinez les réponses prédéfinies et les réponses personnalisées
+## Combiner des réponses prédéfinies et des réponses personnalisées { #combine-predefined-responses-and-custom-ones }
-Vous voulez peut-être avoir des réponses prédéfinies qui s'appliquent à de nombreux *paramètre de chemin*, mais vous souhaitez les combiner avec des réponses personnalisées nécessaires à chaque *opération de chemin*.
+Vous voulez peut-être avoir des réponses prédéfinies qui s'appliquent à de nombreuses *opérations de chemin d'accès*, mais vous souhaitez les combiner avec des réponses personnalisées nécessaires à chaque *opération de chemin d'accès*.
-Dans ces cas, vous pouvez utiliser la technique Python "d'affection par décomposition" (appelé _unpacking_ en anglais) d'un `dict` avec `**dict_to_unpack` :
+Dans ces cas, vous pouvez utiliser la technique Python de « unpacking » d'un `dict` avec `**dict_to_unpack` :
```Python
old_dict = {
@@ -223,7 +223,7 @@ old_dict = {
new_dict = {**old_dict, "new key": "new value"}
```
-Ici, `new_dict` contiendra toutes les paires clé-valeur de `old_dict` plus la nouvelle paire clé-valeur :
+Ici, `new_dict` contiendra toutes les paires clé-valeur de `old_dict` plus la nouvelle paire clé-valeur :
```Python
{
@@ -233,15 +233,15 @@ Ici, `new_dict` contiendra toutes les paires clé-valeur de `old_dict` plus la n
}
```
-Vous pouvez utiliser cette technique pour réutiliser certaines réponses prédéfinies dans vos *paramètres de chemin* et les combiner avec des réponses personnalisées supplémentaires.
+Vous pouvez utiliser cette technique pour réutiliser certaines réponses prédéfinies dans vos *opérations de chemin d'accès* et les combiner avec des réponses personnalisées supplémentaires.
-Par exemple:
+Par exemple :
-{* ../../docs_src/additional_responses/tutorial004.py hl[13:17,26] *}
+{* ../../docs_src/additional_responses/tutorial004_py310.py hl[11:15,24] *}
-## Plus d'informations sur les réponses OpenAPI
+## Plus d'informations sur les réponses OpenAPI { #more-information-about-openapi-responses }
-Pour voir exactement ce que vous pouvez inclure dans les réponses, vous pouvez consulter ces sections dans la spécification OpenAPI :
+Pour voir exactement ce que vous pouvez inclure dans les réponses, vous pouvez consulter ces sections dans la spécification OpenAPI :
-* Objet Responses de OpenAPI , il inclut le `Response Object`.
-* Objet Response de OpenAPI , vous pouvez inclure n'importe quoi directement dans chaque réponse à l'intérieur de votre paramètre `responses`. Y compris `description`, `headers`, `content` (à l'intérieur de cela, vous déclarez différents types de médias et schémas JSON) et `links`.
+* Objet Responses d'OpenAPI, il inclut le `Response Object`.
+* Objet Response d'OpenAPI, vous pouvez inclure n'importe quoi à partir de celui-ci directement dans chaque réponse à l'intérieur de votre paramètre `responses`. Y compris `description`, `headers`, `content` (à l'intérieur de cela, vous déclarez différents types de médias et JSON Schemas), et `links`.
diff --git a/docs/fr/docs/advanced/additional-status-codes.md b/docs/fr/docs/advanced/additional-status-codes.md
index dde6b9a63..c89e9375d 100644
--- a/docs/fr/docs/advanced/additional-status-codes.md
+++ b/docs/fr/docs/advanced/additional-status-codes.md
@@ -1,28 +1,28 @@
-# Codes HTTP supplémentaires
+# Codes de statut supplémentaires { #additional-status-codes }
-Par défaut, **FastAPI** renverra les réponses à l'aide d'une structure de données `JSONResponse`, en plaçant la réponse de votre *chemin d'accès* à l'intérieur de cette `JSONResponse`.
+Par défaut, **FastAPI** renverra les réponses en utilisant une `JSONResponse`, en plaçant le contenu que vous renvoyez depuis votre *chemin d'accès* à l'intérieur de cette `JSONResponse`.
-Il utilisera le code HTTP par défaut ou celui que vous avez défini dans votre *chemin d'accès*.
+Il utilisera le code de statut par défaut ou celui que vous définissez dans votre *chemin d'accès*.
-## Codes HTTP supplémentaires
+## Codes de statut supplémentaires { #additional-status-codes_1 }
-Si vous souhaitez renvoyer des codes HTTP supplémentaires en plus du code principal, vous pouvez le faire en renvoyant directement une `Response`, comme une `JSONResponse`, et en définissant directement le code HTTP supplémentaire.
+Si vous souhaitez renvoyer des codes de statut supplémentaires en plus du code principal, vous pouvez le faire en renvoyant directement une `Response`, comme une `JSONResponse`, et en définissant directement le code de statut supplémentaire.
-Par exemple, disons que vous voulez avoir un *chemin d'accès* qui permet de mettre à jour les éléments et renvoie les codes HTTP 200 "OK" en cas de succès.
+Par exemple, disons que vous voulez avoir un *chemin d'accès* qui permet de mettre à jour des éléments et renvoie des codes de statut HTTP 200 « OK » en cas de succès.
-Mais vous voulez aussi qu'il accepte de nouveaux éléments. Et lorsque les éléments n'existaient pas auparavant, il les crée et renvoie un code HTTP de 201 "Créé".
+Mais vous voulez aussi qu'il accepte de nouveaux éléments. Et lorsque les éléments n'existaient pas auparavant, il les crée et renvoie un code de statut HTTP de 201 « Created ».
-Pour y parvenir, importez `JSONResponse` et renvoyez-y directement votre contenu, en définissant le `status_code` que vous souhaitez :
+Pour y parvenir, importez `JSONResponse` et renvoyez-y directement votre contenu, en définissant le `status_code` que vous voulez :
-{* ../../docs_src/additional_status_codes/tutorial001.py hl[4,25] *}
+{* ../../docs_src/additional_status_codes/tutorial001_an_py310.py hl[4,25] *}
-/// warning | Attention
+/// warning | Alertes
Lorsque vous renvoyez une `Response` directement, comme dans l'exemple ci-dessus, elle sera renvoyée directement.
-Elle ne sera pas sérialisée avec un modèle.
+Elle ne sera pas sérialisée avec un modèle, etc.
-Assurez-vous qu'il contient les données souhaitées et que les valeurs soient dans un format JSON valides (si vous utilisez une `JSONResponse`).
+Vous devez vous assurer qu'elle contient les données que vous voulez qu'elle contienne, et que les valeurs sont du JSON valide (si vous utilisez `JSONResponse`).
///
@@ -30,12 +30,12 @@ Assurez-vous qu'il contient les données souhaitées et que les valeurs soient d
Vous pouvez également utiliser `from starlette.responses import JSONResponse`.
-Pour plus de commodités, **FastAPI** fournit les objets `starlette.responses` sous forme d'un alias accessible par `fastapi.responses`. Mais la plupart des réponses disponibles proviennent directement de Starlette. Il en est de même avec l'objet `statut`.
+**FastAPI** fournit les mêmes `starlette.responses` que `fastapi.responses` uniquement par commodité pour vous, le développeur. Mais la plupart des réponses disponibles proviennent directement de Starlette. De même pour `status`.
///
-## Documents OpenAPI et API
+## Documents OpenAPI et API { #openapi-and-api-docs }
-Si vous renvoyez directement des codes HTTP et des réponses supplémentaires, ils ne seront pas inclus dans le schéma OpenAPI (la documentation de l'API), car FastAPI n'a aucun moyen de savoir à l'avance ce que vous allez renvoyer.
+Si vous renvoyez directement des codes de statut 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 dans OpenAPI](additional-responses.md){.internal-link target=_blank}.
+Mais vous pouvez documenter cela dans votre code, en utilisant : [Réponses supplémentaires](additional-responses.md){.internal-link target=_blank}.
diff --git a/docs/fr/docs/advanced/index.md b/docs/fr/docs/advanced/index.md
index d9d8ad8e6..6b43a35f2 100644
--- a/docs/fr/docs/advanced/index.md
+++ b/docs/fr/docs/advanced/index.md
@@ -1,27 +1,21 @@
-# Guide de l'utilisateur avancé
+# Guide de l'utilisateur avancé { #advanced-user-guide }
-## Caractéristiques supplémentaires
+## Caractéristiques supplémentaires { #additional-features }
Le [Tutoriel - Guide de l'utilisateur](../tutorial/index.md){.internal-link target=_blank} devrait suffire à vous faire découvrir toutes les fonctionnalités principales de **FastAPI**.
Dans les sections suivantes, vous verrez des options, configurations et fonctionnalités supplémentaires.
-/// note | Remarque
+/// tip | Astuce
-Les sections de ce chapitre ne sont **pas nécessairement "avancées"**.
+Les sections suivantes ne sont **pas nécessairement « avancées »**.
-Et il est possible que pour votre cas d'utilisation, la solution se trouve dans l'un d'entre eux.
+Et il est possible que, pour votre cas d'utilisation, la solution se trouve dans l'une d'entre elles.
///
-## Lisez d'abord le didacticiel
+## Lisez d'abord le didacticiel { #read-the-tutorial-first }
-Vous pouvez utiliser la plupart des fonctionnalités de **FastAPI** grâce aux connaissances du [Tutoriel - Guide de l'utilisateur](../tutorial/index.md){.internal-link target=_blank}.
+Vous pouvez toujours utiliser la plupart des fonctionnalités de **FastAPI** avec les connaissances du [Tutoriel - Guide de l'utilisateur](../tutorial/index.md){.internal-link target=_blank}.
-Et les sections suivantes supposent que vous l'avez lu et que vous en connaissez les idées principales.
-
-## Cours TestDriven.io
-
-Si vous souhaitez suivre un cours pour débutants avancés pour compléter cette section de la documentation, vous pouvez consulter : Développement piloté par les tests avec FastAPI et Docker par **TestDriven.io**.
-
-10 % de tous les bénéfices de ce cours sont reversés au développement de **FastAPI**. 🎉 😄
+Et les sections suivantes supposent que vous l'avez déjà lu, et supposent que vous connaissez ces idées principales.
diff --git a/docs/fr/docs/advanced/path-operation-advanced-configuration.md b/docs/fr/docs/advanced/path-operation-advanced-configuration.md
index 7daf0fc65..f143b35b6 100644
--- a/docs/fr/docs/advanced/path-operation-advanced-configuration.md
+++ b/docs/fr/docs/advanced/path-operation-advanced-configuration.md
@@ -1,26 +1,26 @@
-# Configuration avancée des paramètres de chemin
+# Configuration avancée des chemins d'accès { #path-operation-advanced-configuration }
-## ID d'opération OpenAPI
+## operationId OpenAPI { #openapi-operationid }
-/// warning | Attention
+/// warning | Alertes
-Si vous n'êtes pas un "expert" en OpenAPI, vous n'en avez probablement pas besoin.
+Si vous n’êtes pas un « expert » en OpenAPI, vous n’en avez probablement pas besoin.
///
-Dans OpenAPI, les chemins sont des ressources, tels que /users/ ou /items/, exposées par votre API, et les opérations sont les méthodes HTTP utilisées pour manipuler ces chemins, telles que GET, POST ou DELETE. Les operationId sont des chaînes uniques facultatives utilisées pour identifier une opération d'un chemin. Vous pouvez définir l'OpenAPI `operationId` à utiliser dans votre *opération de chemin* avec le paramètre `operation_id`.
+Vous pouvez définir l’OpenAPI `operationId` à utiliser dans votre *chemin d'accès* avec le paramètre `operation_id`.
-Vous devez vous assurer qu'il est unique pour chaque opération.
+Vous devez vous assurer qu’il est unique pour chaque opération.
-{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
-### Utilisation du nom *path operation function* comme operationId
+### Utiliser le nom de la *fonction de chemin d'accès* comme operationId { #using-the-path-operation-function-name-as-the-operationid }
-Si vous souhaitez utiliser les noms de fonction de vos API comme `operationId`, vous pouvez les parcourir tous et remplacer chaque `operation_id` de l'*opération de chemin* en utilisant leur `APIRoute.name`.
+Si vous souhaitez utiliser les noms de fonction de vos API comme `operationId`, vous pouvez les parcourir tous et remplacer chaque `operation_id` des *chemins d'accès* en utilisant leur `APIRoute.name`.
-Vous devriez le faire après avoir ajouté toutes vos *paramètres de chemin*.
+Vous devez le faire après avoir ajouté tous vos *chemins d'accès*.
-{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2,12:21,24] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
/// tip | Astuce
@@ -28,79 +28,81 @@ Si vous appelez manuellement `app.openapi()`, vous devez mettre à jour les `ope
///
-/// warning | Attention
+/// warning | Alertes
-Pour faire cela, vous devez vous assurer que chacun de vos *chemin* ait un nom unique.
+Si vous faites cela, vous devez vous assurer que chacune de vos *fonctions de chemin d'accès* a un nom unique.
-Même s'ils se trouvent dans des modules différents (fichiers Python).
+Même si elles sont dans des modules différents (fichiers Python).
///
-## Exclusion d'OpenAPI
+## Exclusion d'OpenAPI { #exclude-from-openapi }
-Pour exclure un *chemin* du schéma OpenAPI généré (et donc des systèmes de documentation automatiques), utilisez le paramètre `include_in_schema` et assignez-lui la valeur `False` :
+Pour exclure un *chemin d'accès* du schéma OpenAPI généré (et donc des systèmes de documentation automatiques), utilisez le paramètre `include_in_schema` et définissez-le à `False` :
-{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
-## Description avancée de docstring
+## Description avancée depuis la docstring { #advanced-description-from-docstring }
-Vous pouvez limiter le texte utilisé de la docstring d'une *fonction de chemin* qui sera affiché sur OpenAPI.
+Vous pouvez limiter les lignes utilisées depuis la docstring d’une *fonction de chemin d'accès* pour OpenAPI.
-L'ajout d'un `\f` (un caractère d'échappement "form feed") va permettre à **FastAPI** de tronquer la sortie utilisée pour OpenAPI à ce stade.
+Ajouter un `\f` (un caractère « form feed » échappé) amène **FastAPI** à tronquer la sortie utilisée pour OpenAPI à cet endroit.
-Il n'apparaîtra pas dans la documentation, mais d'autres outils (tel que Sphinx) pourront utiliser le reste.
+Il n’apparaîtra pas dans la documentation, mais d’autres outils (tels que Sphinx) pourront utiliser le reste.
-{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *}
-## Réponses supplémentaires
+## Réponses supplémentaires { #additional-responses }
-Vous avez probablement vu comment déclarer le `response_model` et le `status_code` pour une *opération de chemin*.
+Vous avez probablement vu comment déclarer le `response_model` et le `status_code` pour un *chemin d'accès*.
-Cela définit les métadonnées sur la réponse principale d'une *opération de chemin*.
+Cela définit les métadonnées concernant la réponse principale d’un *chemin d'accès*.
Vous pouvez également déclarer des réponses supplémentaires avec leurs modèles, codes de statut, etc.
-Il y a un chapitre entier ici dans la documentation à ce sujet, vous pouvez le lire sur [Réponses supplémentaires dans OpenAPI](additional-responses.md){.internal-link target=_blank}.
+Il y a un chapitre entier dans la documentation à ce sujet, vous pouvez le lire dans [Réponses supplémentaires dans OpenAPI](additional-responses.md){.internal-link target=_blank}.
-## OpenAPI supplémentaire
+## OpenAPI Extra { #openapi-extra }
-Lorsque vous déclarez un *chemin* dans votre application, **FastAPI** génère automatiquement les métadonnées concernant ce *chemin* à inclure dans le schéma OpenAPI.
+Lorsque vous déclarez un *chemin d'accès* dans votre application, **FastAPI** génère automatiquement les métadonnées pertinentes concernant ce *chemin d'accès* à inclure dans le schéma OpenAPI.
/// note | Détails techniques
-La spécification OpenAPI appelle ces métadonnées des Objets d'opération.
+Dans la spécification OpenAPI, cela s’appelle l’Operation Object.
///
-Il contient toutes les informations sur le *chemin* et est utilisé pour générer automatiquement la documentation.
+Il contient toutes les informations sur le *chemin d'accès* et est utilisé pour générer la documentation automatique.
Il inclut les `tags`, `parameters`, `requestBody`, `responses`, etc.
-Ce schéma OpenAPI spécifique aux *operations* est normalement généré automatiquement par **FastAPI**, mais vous pouvez également l'étendre.
+Ce schéma OpenAPI spécifique au *chemin d'accès* est normalement généré automatiquement par **FastAPI**, mais vous pouvez aussi l’étendre.
/// tip | Astuce
-Si vous avez seulement besoin de déclarer des réponses supplémentaires, un moyen plus pratique de le faire est d'utiliser les [réponses supplémentaires dans OpenAPI](additional-responses.md){.internal-link target=_blank}.
+C’est un point d’extension de bas niveau.
+
+Si vous avez uniquement besoin de déclarer des réponses supplémentaires, une manière plus pratique de le faire est avec [Réponses supplémentaires dans OpenAPI](additional-responses.md){.internal-link target=_blank}.
///
-Vous pouvez étendre le schéma OpenAPI pour une *opération de chemin* en utilisant le paramètre `openapi_extra`.
+Vous pouvez étendre le schéma OpenAPI pour un *chemin d'accès* en utilisant le paramètre `openapi_extra`.
-### Extensions OpenAPI
+### Extensions OpenAPI { #openapi-extensions }
-Cet `openapi_extra` peut être utile, par exemple, pour déclarer [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions) :
+Cet `openapi_extra` peut être utile, par exemple, pour déclarer des [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions) :
-{* ../../docs_src/path_operation_advanced_configuration/tutorial005.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *}
-Si vous ouvrez la documentation automatique de l'API, votre extension apparaîtra au bas du *chemin* spécifique.
+Si vous ouvrez les documents automatiques de l’API, votre extension apparaîtra au bas du *chemin d'accès* spécifique.
-Et dans le fichier openapi généré (`/openapi.json`), vous verrez également votre extension dans le cadre du *chemin* spécifique :
+Et si vous regardez l’OpenAPI résultant (dans `/openapi.json` de votre API), vous verrez aussi votre extension comme faisant partie du *chemin d'accès* spécifique :
```JSON hl_lines="22"
{
- "openapi": "3.0.2",
+ "openapi": "3.1.0",
"info": {
"title": "FastAPI",
"version": "0.1.0"
@@ -127,44 +129,44 @@ Et dans le fichier openapi généré (`/openapi.json`), vous verrez également v
}
```
-### Personnalisation du Schéma OpenAPI pour un chemin
+### Schéma OpenAPI personnalisé pour un *chemin d'accès* { #custom-openapi-path-operation-schema }
-Le dictionnaire contenu dans la variable `openapi_extra` sera fusionné avec le schéma OpenAPI généré automatiquement pour l'*opération de chemin*.
+Le dictionnaire dans `openapi_extra` sera fusionné en profondeur avec le schéma OpenAPI généré automatiquement pour le *chemin d'accès*.
-Ainsi, vous pouvez ajouter des données supplémentaires au schéma généré automatiquement.
+Ainsi, vous pourriez ajouter des données supplémentaires au schéma généré automatiquement.
-Par exemple, vous pouvez décider de lire et de valider la requête avec votre propre code, sans utiliser les fonctionnalités automatiques de validation proposée par Pydantic, mais vous pouvez toujours définir la requête dans le schéma OpenAPI.
+Par exemple, vous pourriez décider de lire et de valider la requête avec votre propre code, sans utiliser les fonctionnalités automatiques de FastAPI avec Pydantic, mais vous pourriez tout de même vouloir définir la requête dans le schéma OpenAPI.
-Vous pouvez le faire avec `openapi_extra` :
+Vous pourriez faire cela avec `openapi_extra` :
-{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[20:37,39:40] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
-Dans cet exemple, nous n'avons déclaré aucun modèle Pydantic. En fait, le corps de la requête n'est même pas parsé en tant que JSON, il est lu directement en tant que `bytes`, et la fonction `magic_data_reader()` serait chargé de l'analyser d'une manière ou d'une autre.
+Dans cet exemple, nous n’avons déclaré aucun modèle Pydantic. En fait, le corps de la requête n’est même pas parsed en tant que JSON, il est lu directement en tant que `bytes`, et la fonction `magic_data_reader()` serait chargée de l’analyser d’une manière ou d’une autre.
Néanmoins, nous pouvons déclarer le schéma attendu pour le corps de la requête.
-### Type de contenu OpenAPI personnalisé
+### Type de contenu OpenAPI personnalisé { #custom-openapi-content-type }
-En utilisant cette même astuce, vous pouvez utiliser un modèle Pydantic pour définir le schéma JSON qui est ensuite inclus dans la section de schéma OpenAPI personnalisée pour le *chemin* concerné.
+En utilisant cette même astuce, vous pourriez utiliser un modèle Pydantic pour définir le JSON Schema qui est ensuite inclus dans la section de schéma OpenAPI personnalisée pour le *chemin d'accès*.
-Et vous pouvez le faire même si le type de données dans la requête n'est pas au format JSON.
+Et vous pourriez faire cela même si le type de données dans la requête n’est pas du JSON.
-Dans cet exemple, nous n'utilisons pas les fonctionnalités de FastAPI pour extraire le schéma JSON des modèles Pydantic ni la validation automatique pour JSON. En fait, nous déclarons le type de contenu de la requête en tant que YAML, et non JSON :
+Par exemple, dans cette application, nous n’utilisons pas la fonctionnalité intégrée de FastAPI pour extraire le JSON Schema depuis les modèles Pydantic ni la validation automatique pour le JSON. En fait, nous déclarons le type de contenu de la requête comme étant du YAML, pas du JSON :
-{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[17:22,24] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
-Néanmoins, bien que nous n'utilisions pas la fonctionnalité par défaut, nous utilisons toujours un modèle Pydantic pour générer manuellement le schéma JSON pour les données que nous souhaitons recevoir en YAML.
+Néanmoins, bien que nous n’utilisions pas la fonctionnalité intégrée par défaut, nous utilisons tout de même un modèle Pydantic pour générer manuellement le JSON Schema pour les données que nous voulons recevoir en YAML.
-Ensuite, nous utilisons directement la requête et extrayons son contenu en tant qu'octets. Cela signifie que FastAPI n'essaiera même pas d'analyser le payload de la requête en tant que JSON.
+Ensuite, nous utilisons la requête directement et extrayons le corps en tant que `bytes`. Cela signifie que FastAPI n’essaiera même pas d’analyser le payload de la requête comme du JSON.
-Et nous analysons directement ce contenu YAML, puis nous utilisons à nouveau le même modèle Pydantic pour valider le contenu YAML :
+Et ensuite, dans notre code, nous analysons directement ce contenu YAML, et puis nous utilisons à nouveau le même modèle Pydantic pour valider le contenu YAML :
-{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[26:33] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
/// tip | Astuce
Ici, nous réutilisons le même modèle Pydantic.
-Mais nous aurions pu tout aussi bien pu le valider d'une autre manière.
+Mais, de la même manière, nous aurions pu le valider d’une autre façon.
///
diff --git a/docs/fr/docs/advanced/response-directly.md b/docs/fr/docs/advanced/response-directly.md
index 4ff883c77..c347eeff9 100644
--- a/docs/fr/docs/advanced/response-directly.md
+++ b/docs/fr/docs/advanced/response-directly.md
@@ -1,20 +1,20 @@
-# Renvoyer directement une réponse
+# Renvoyer directement une réponse { #return-a-response-directly }
-Lorsque vous créez une *opération de chemins* **FastAPI**, vous pouvez normalement retourner n'importe quelle donnée : un `dict`, une `list`, un modèle Pydantic, un modèle de base de données, etc.
+Lorsque vous créez un *chemin d'accès* **FastAPI**, vous pouvez normalement en retourner n'importe quelle donnée : un `dict`, une `list`, un modèle Pydantic, un modèle de base de données, etc.
-Par défaut, **FastAPI** convertirait automatiquement cette valeur de retour en JSON en utilisant le `jsonable_encoder` expliqué dans [JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank}.
+Par défaut, **FastAPI** convertirait automatiquement cette valeur de retour en JSON en utilisant le `jsonable_encoder` expliqué dans [Encodeur compatible JSON](../tutorial/encoder.md){.internal-link target=_blank}.
-Ensuite, en arrière-plan, il mettra ces données JSON-compatible (par exemple un `dict`) à l'intérieur d'un `JSONResponse` qui sera utilisé pour envoyer la réponse au client.
+Ensuite, en arrière-plan, il mettrait ces données compatibles JSON (par exemple un `dict`) à l'intérieur d'une `JSONResponse` qui serait utilisée pour envoyer la réponse au client.
-Mais vous pouvez retourner une `JSONResponse` directement à partir de vos *opérations de chemin*.
+Mais vous pouvez retourner une `JSONResponse` directement à partir de vos *chemins d'accès*.
Cela peut être utile, par exemple, pour retourner des en-têtes personnalisés ou des cookies.
-## Renvoyer une `Response`
+## Renvoyer une `Response` { #return-a-response }
En fait, vous pouvez retourner n'importe quelle `Response` ou n'importe quelle sous-classe de celle-ci.
-/// note | Remarque
+/// tip | Astuce
`JSONResponse` est elle-même une sous-classe de `Response`.
@@ -22,29 +22,29 @@ 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.
+Cela vous donne beaucoup de flexibilité. Vous pouvez retourner n'importe quel type de données, surcharger n'importe quelle déclaration ou validation de données, etc.
-## Utiliser le `jsonable_encoder` dans une `Response`
+## Utiliser le `jsonable_encoder` dans une `Response` { #using-the-jsonable-encoder-in-a-response }
-Parce que **FastAPI** n'apporte aucune modification à une `Response` que vous retournez, vous devez vous assurer que son contenu est prêt à être utilisé (sérialisable).
+Parce que **FastAPI** n'apporte aucune modification à une `Response` que vous retournez, vous devez vous assurer que son contenu est prêt.
-Par exemple, vous ne pouvez pas mettre un modèle Pydantic dans une `JSONResponse` sans d'abord le convertir en un `dict` avec tous les types de données (comme `datetime`, `UUID`, etc.) convertis en types compatibles avec JSON.
+Par exemple, vous ne pouvez pas mettre un modèle Pydantic dans une `JSONResponse` sans d'abord le convertir en un `dict` avec tous les types de données (comme `datetime`, `UUID`, etc) convertis en types compatibles avec JSON.
-Pour ces cas, vous pouvez spécifier un appel à `jsonable_encoder` pour convertir vos données avant de les passer à une réponse :
+Pour ces cas, vous pouvez utiliser le `jsonable_encoder` pour convertir vos données avant de les passer à une réponse :
-{* ../../docs_src/response_directly/tutorial001.py hl[6:7,21:22] *}
+{* ../../docs_src/response_directly/tutorial001_py310.py hl[5:6,20:21] *}
/// note | Détails techniques
Vous pouvez aussi utiliser `from starlette.responses import JSONResponse`.
-**FastAPI** fournit le même objet `starlette.responses` que `fastapi.responses` juste par commodité pour le développeur. Mais la plupart des réponses disponibles proviennent directement de Starlette.
+**FastAPI** fournit le même objet `starlette.responses` que `fastapi.responses` juste par commodité pour vous, le développeur. Mais la plupart des réponses disponibles proviennent directement de Starlette.
///
-## Renvoyer une `Response` personnalisée
+## Renvoyer une `Response` personnalisée { #returning-a-custom-response }
L'exemple ci-dessus montre toutes les parties dont vous avez besoin, mais il n'est pas encore très utile, car vous auriez pu retourner l'`item` directement, et **FastAPI** l'aurait mis dans une `JSONResponse` pour vous, en le convertissant en `dict`, etc. Tout cela par défaut.
@@ -54,12 +54,12 @@ Disons que vous voulez retourner une réponse étant l'un des frameworks Python les plus rapides disponibles, seulement inférieur à Starlette et Uvicorn (tous deux utilisés au cœur de FastAPI). (*)
+Les benchmarks indépendants de TechEmpower montrent que les applications **FastAPI** exécutées avec Uvicorn sont l’un des frameworks Python les plus rapides disponibles, juste en dessous de Starlette et Uvicorn eux-mêmes (utilisés en interne par FastAPI).
-Mais en prêtant attention aux tests de performance et aux comparaisons, il faut tenir compte de ce qu'il suit.
+Mais lorsque vous consultez des benchmarks et des comparaisons, vous devez garder ce qui suit à l’esprit.
-## Tests de performance et rapidité
+## Benchmarks et vitesse { #benchmarks-and-speed }
-Lorsque vous vérifiez les tests de performance, il est commun de voir plusieurs outils de différents types comparés comme équivalents.
+Lorsque vous consultez les benchmarks, il est courant de voir plusieurs outils de types différents comparés comme s’ils étaient équivalents.
-En particulier, on voit Uvicorn, Starlette et FastAPI comparés (parmi de nombreux autres outils).
+En particulier, de voir Uvicorn, Starlette et FastAPI comparés ensemble (parmi de nombreux autres outils).
-Plus le problème résolu par un outil est simple, mieux seront les performances obtenues. Et la plupart des tests de performance ne prennent pas en compte les fonctionnalités additionnelles fournies par les outils.
+Plus le problème résolu par l’outil est simple, meilleures seront les performances qu’il obtiendra. Et la plupart des benchmarks ne testent pas les fonctionnalités supplémentaires fournies par l’outil.
La hiérarchie est la suivante :
* **Uvicorn** : un serveur ASGI
- * **Starlette** : (utilise Uvicorn) un micro-framework web
- * **FastAPI**: (utilise Starlette) un micro-framework pour API disposant de fonctionnalités additionnelles pour la création d'API, avec la validation des données, etc.
+ * **Starlette** : (utilise Uvicorn) un microframework web
+ * **FastAPI** : (utilise Starlette) un microframework d’API avec plusieurs fonctionnalités supplémentaires pour construire des API, avec la validation des données, etc.
* **Uvicorn** :
- * A les meilleures performances, étant donné qu'il n'a pas beaucoup de code mis-à-part le serveur en lui-même.
- * On n'écrit pas une application avec uniquement Uvicorn. Cela signifie que le code devrait inclure plus ou moins, au minimum, tout le code offert par Starlette (ou **FastAPI**). Et si on fait cela, l'application finale apportera les mêmes complications que si on avait utilisé un framework et que l'on avait minimisé la quantité de code et de bugs.
- * Si on compare Uvicorn, il faut le comparer à d'autre applications de serveurs comme Daphne, Hypercorn, uWSGI, etc.
+ * Aura les meilleures performances, car il n’a pas beaucoup de code supplémentaire en dehors du serveur lui-même.
+ * Vous n’écririez pas une application directement en Uvicorn. Cela signifierait que votre code devrait inclure plus ou moins, au minimum, tout le code fourni par Starlette (ou **FastAPI**). Et si vous faisiez cela, votre application finale aurait la même surcharge que si vous aviez utilisé un framework, tout en minimisant le code de votre application et les bugs.
+ * Si vous comparez Uvicorn, comparez-le à Daphne, Hypercorn, uWSGI, etc. Des serveurs d’applications.
* **Starlette** :
- * A les seconde meilleures performances après Uvicorn. Starlette utilise en réalité Uvicorn. De ce fait, il ne peut qu’être plus "lent" qu'Uvicorn car il requiert l'exécution de plus de code.
- * Cependant il nous apporte les outils pour construire une application web simple, avec un routage basé sur des chemins, etc.
- * Si on compare Starlette, il faut le comparer à d'autres frameworks web (ou micorframework) comme Sanic, Flask, Django, etc.
+ * Aura les performances suivantes, après Uvicorn. En fait, Starlette utilise Uvicorn pour s’exécuter. Donc, il ne peut probablement que devenir « plus lent » qu’Uvicorn, en devant exécuter plus de code.
+ * Mais il vous fournit les outils pour construire des applications web simples, avec du routage basé sur des chemins, etc.
+ * Si vous comparez Starlette, comparez-le à Sanic, Flask, Django, etc. Des frameworks web (ou microframeworks).
* **FastAPI** :
- * Comme Starlette, FastAPI utilise Uvicorn et ne peut donc pas être plus rapide que ce dernier.
- * FastAPI apporte des fonctionnalités supplémentaires à Starlette. Des fonctionnalités qui sont nécessaires presque systématiquement lors de la création d'une API, comme la validation des données, la sérialisation. En utilisant FastAPI, on obtient une documentation automatiquement (qui ne requiert aucune manipulation pour être mise en place).
- * Si on n'utilisait pas FastAPI mais directement Starlette (ou un outil équivalent comme Sanic, Flask, Responder, etc) il faudrait implémenter la validation des données et la sérialisation par nous-même. Le résultat serait donc le même dans les deux cas mais du travail supplémentaire serait à réaliser avec Starlette, surtout en considérant que la validation des données et la sérialisation représentent la plus grande quantité de code à écrire dans une application.
- * De ce fait, en utilisant FastAPI on minimise le temps de développement, les bugs, le nombre de lignes de code, et on obtient les mêmes performances (si ce n'est de meilleurs performances) que l'on aurait pu avoir sans ce framework (en ayant à implémenter de nombreuses fonctionnalités importantes par nous-mêmes).
- * Si on compare FastAPI, il faut le comparer à d'autres frameworks web (ou ensemble d'outils) qui fournissent la validation des données, la sérialisation et la documentation, comme Flask-apispec, NestJS, Molten, etc.
+ * De la même manière que Starlette utilise Uvicorn et ne peut pas être plus rapide que lui, **FastAPI** utilise Starlette, donc il ne peut pas être plus rapide que lui.
+ * FastAPI fournit plus de fonctionnalités par-dessus Starlette. Des fonctionnalités dont vous avez presque toujours besoin lorsque vous construisez des API, comme la validation des données et la sérialisation. Et en l’utilisant, vous obtenez de la documentation automatique gratuitement (la documentation automatique n’ajoute même pas de surcharge à l’exécution des applications, elle est générée au démarrage).
+ * Si vous n’utilisiez pas FastAPI et utilisiez Starlette directement (ou un autre outil, comme Sanic, Flask, Responder, etc.), vous devriez implémenter vous-même toute la validation des données et la sérialisation. Ainsi, votre application finale aurait toujours la même surcharge que si elle avait été construite en utilisant FastAPI. Et dans de nombreux cas, cette validation des données et cette sérialisation représentent la plus grande quantité de code écrite dans les applications.
+ * Ainsi, en utilisant FastAPI, vous économisez du temps de développement, des bugs, des lignes de code, et vous obtiendriez probablement les mêmes performances (ou de meilleures) que si vous ne l’utilisiez pas (puisque vous devriez tout implémenter dans votre code).
+ * Si vous comparez FastAPI, comparez-le à un framework d’application web (ou à un ensemble d’outils) qui fournit la validation des données, la sérialisation et la documentation, comme Flask-apispec, NestJS, Molten, etc. Des frameworks avec validation automatique intégrée des données, sérialisation et documentation.
diff --git a/docs/fr/docs/deployment/docker.md b/docs/fr/docs/deployment/docker.md
index 05b597a2d..8e9d89667 100644
--- a/docs/fr/docs/deployment/docker.md
+++ b/docs/fr/docs/deployment/docker.md
@@ -1,74 +1,151 @@
-# Déployer avec Docker
+# FastAPI dans des conteneurs - Docker { #fastapi-in-containers-docker }
-Dans cette section, vous verrez des instructions et des liens vers des guides pour savoir comment :
+Lors du déploiement d’applications FastAPI, une approche courante consiste à construire une **image de conteneur Linux**. Cela se fait généralement avec **Docker**. Vous pouvez ensuite déployer cette image de conteneur de l’une de plusieurs manières possibles.
-* Faire de votre application **FastAPI** une image/conteneur Docker avec une performance maximale. En environ **5 min**.
-* (Optionnellement) comprendre ce que vous, en tant que développeur, devez savoir sur HTTPS.
-* Configurer un cluster en mode Docker Swarm avec HTTPS automatique, même sur un simple serveur à 5 dollars US/mois. En environ **20 min**.
-* Générer et déployer une application **FastAPI** complète, en utilisant votre cluster Docker Swarm, avec HTTPS, etc. En environ **10 min**.
+L’utilisation de conteneurs Linux présente plusieurs avantages, notamment la **sécurité**, la **réplicabilité**, la **simplicité**, et d’autres.
-Vous pouvez utiliser **Docker** pour le déploiement. Il présente plusieurs avantages comme la sécurité, la réplicabilité, la simplicité de développement, etc.
-
-Si vous utilisez Docker, vous pouvez utiliser l'image Docker officielle :
+/// tip | Astuce
-## tiangolo/uvicorn-gunicorn-fastapi
+Vous êtes pressé(e) et vous connaissez déjà tout ça ? Allez directement au [`Dockerfile` ci-dessous 👇](#build-a-docker-image-for-fastapi).
-Cette image est dotée d'un mécanisme d'"auto-tuning", de sorte qu'il vous suffit d'ajouter votre code pour obtenir automatiquement des performances très élevées. Et sans faire de sacrifices.
+///
-Mais vous pouvez toujours changer et mettre à jour toutes les configurations avec des variables d'environnement ou des fichiers de configuration.
+
+Aperçu du Dockerfile 👀
-/// tip | Astuce
+```Dockerfile
+FROM python:3.9
-Pour voir toutes les configurations et options, rendez-vous sur la page de l'image Docker : tiangolo/uvicorn-gunicorn-fastapi.
+WORKDIR /code
-///
+COPY ./requirements.txt /code/requirements.txt
-## Créer un `Dockerfile`
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
-* Allez dans le répertoire de votre projet.
-* Créez un `Dockerfile` avec :
+COPY ./app /code/app
-```Dockerfile
-FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
+CMD ["fastapi", "run", "app/main.py", "--port", "80"]
-COPY ./app /app
+# If running behind a proxy like Nginx or Traefik add --proxy-headers
+# CMD ["fastapi", "run", "app/main.py", "--port", "80", "--proxy-headers"]
```
-### Applications plus larges
+
-Si vous avez suivi la section sur la création d' [Applications avec plusieurs fichiers](../tutorial/bigger-applications.md){.internal-link target=_blank}, votre `Dockerfile` pourrait ressembler à ceci :
+## Qu’est-ce qu’un conteneur { #what-is-a-container }
-```Dockerfile
-FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
+Les conteneurs (principalement les conteneurs Linux) sont une manière très **légère** d’empaqueter des applications, y compris toutes leurs dépendances et les fichiers nécessaires, tout en les gardant isolées des autres conteneurs (d’autres applications ou composants) sur le même système.
-COPY ./app /app/app
-```
+Les conteneurs Linux s’exécutent en utilisant le même kernel Linux que l’hôte (machine, machine virtuelle, serveur cloud, etc.). Cela signifie simplement qu’ils sont très légers (comparés à des machines virtuelles complètes émulant un système d’exploitation entier).
-### Raspberry Pi et autres architectures
+Ainsi, les conteneurs consomment **peu de ressources**, une quantité comparable à l’exécution directe des processus (une machine virtuelle consommerait bien plus).
-Si vous utilisez Docker sur un Raspberry Pi (qui a un processeur ARM) ou toute autre architecture, vous pouvez créer un `Dockerfile` à partir de zéro, basé sur une image de base Python (qui est multi-architecture) et utiliser Uvicorn seul.
+Les conteneurs ont aussi leurs propres processus en cours d’exécution **isolés** (généralement un seul processus), leur système de fichiers et leur réseau, ce qui simplifie le déploiement, la sécurité, le développement, etc.
-Dans ce cas, votre `Dockerfile` pourrait ressembler à ceci :
+## Qu’est-ce qu’une image de conteneur { #what-is-a-container-image }
-```Dockerfile
-FROM python:3.7
+Un **conteneur** s’exécute à partir d’une **image de conteneur**.
+
+Une image de conteneur est une version **statique** de tous les fichiers, des variables d’environnement, et de la commande/du programme par défaut qui doivent être présents dans un conteneur. **Statique** signifie ici que l’**image** de conteneur ne s’exécute pas, elle n’est pas lancée, ce sont uniquement les fichiers empaquetés et les métadonnées.
+
+Contrairement à une « image de conteneur » qui correspond au contenu statique stocké, un « conteneur » désigne généralement l’instance en cours d’exécution, la chose qui est **exécutée**.
+
+Quand le **conteneur** est démarré et s’exécute (démarré depuis une **image de conteneur**), il peut créer ou modifier des fichiers, des variables d’environnement, etc. Ces changements n’existeront que dans ce conteneur, et ne persisteront pas dans l’image de conteneur sous-jacente (ils ne seront pas enregistrés sur disque).
+
+Une image de conteneur est comparable au fichier et au contenu d’un **programme**, par exemple `python` et un fichier `main.py`.
+
+Et le **conteneur** lui-même (par opposition à l’**image de conteneur**) est l’instance réellement exécutée de l’image, comparable à un **processus**. En fait, un conteneur ne s’exécute que lorsqu’il a un **processus en cours d’exécution** (et normalement c’est un seul processus). Le conteneur s’arrête lorsqu’il n’y a plus de processus en cours d’exécution à l’intérieur.
+
+## Images de conteneur { #container-images }
+
+Docker a été l’un des principaux outils pour créer et gérer les **images de conteneur** et les **conteneurs**.
+
+Et il existe un Docker Hub public avec des **images de conteneur officielles** préfabriquées pour de nombreux outils, environnements, bases de données, et applications.
+
+Par exemple, il existe une image Python officielle.
+
+Et il existe beaucoup d’autres images pour différentes choses comme des bases de données, par exemple pour :
+
+* PostgreSQL
+* MySQL
+* MongoDB
+* Redis, etc.
+
+En utilisant une image de conteneur préfabriquée, il est très facile de **combiner** et d’utiliser différents outils. Par exemple, pour tester une nouvelle base de données. Dans la plupart des cas, vous pouvez utiliser les **images officielles** et simplement les configurer via des variables d’environnement.
+
+De cette façon, dans de nombreux cas, vous pouvez apprendre les conteneurs et Docker et réutiliser ces connaissances avec beaucoup d’outils et de composants différents.
+
+Ainsi, vous exécuteriez **plusieurs conteneurs** avec différentes choses, comme une base de données, une application Python, un serveur web avec une application frontend React, et vous les connecteriez entre eux via leur réseau interne.
+
+Tous les systèmes de gestion de conteneurs (comme Docker ou Kubernetes) intègrent ces fonctionnalités réseau.
+
+## Conteneurs et processus { #containers-and-processes }
+
+Une **image de conteneur** inclut normalement dans ses métadonnées le programme ou la commande par défaut à exécuter lorsque le **conteneur** est démarré, ainsi que les paramètres à passer à ce programme. Très similaire à ce que ce serait en ligne de commande.
+
+Quand un **conteneur** est démarré, il exécutera cette commande/ce programme (bien que vous puissiez l’outrepasser et lui faire exécuter une commande/un programme différent).
+
+Un conteneur s’exécute tant que le **processus principal** (commande ou programme) s’exécute.
+
+Un conteneur a normalement un **seul processus**, mais il est aussi possible de démarrer des sous-processus depuis le processus principal, et ainsi vous aurez **plusieurs processus** dans le même conteneur.
-RUN pip install fastapi uvicorn
+Mais il n’est pas possible d’avoir un conteneur en cours d’exécution sans **au moins un processus en cours d’exécution**. Si le processus principal s’arrête, le conteneur s’arrête.
-EXPOSE 80
+## Construire une image Docker pour FastAPI { #build-a-docker-image-for-fastapi }
-COPY ./app /app
+Ok, construisons quelque chose maintenant ! 🚀
-CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
+Je vais vous montrer comment construire une **image Docker** pour FastAPI **à partir de zéro**, sur la base de l’**image Python officielle**.
+
+C’est ce que vous voudrez faire dans **la plupart des cas**, par exemple :
+
+* Utiliser **Kubernetes** ou des outils similaires
+* Exécuter sur un **Raspberry Pi**
+* Utiliser un service cloud qui exécute une image de conteneur pour vous, etc.
+
+### Exigences de packages { #package-requirements }
+
+Vous aurez normalement les **exigences de packages** de votre application dans un fichier.
+
+Cela dépendra principalement de l’outil que vous utilisez pour **installer** ces exigences.
+
+La manière la plus courante de le faire est d’avoir un fichier `requirements.txt` avec les noms de packages et leurs versions, un par ligne.
+
+Vous utiliseriez bien sûr les mêmes idées que celles présentées dans [À propos des versions de FastAPI](versions.md){.internal-link target=_blank} pour définir les plages de versions.
+
+Par exemple, votre `requirements.txt` pourrait ressembler à :
+
+```
+fastapi[standard]>=0.113.0,<0.114.0
+pydantic>=2.7.0,<3.0.0
+```
+
+Et vous installeriez normalement ces dépendances de packages avec `pip`, par exemple :
+
+
+
+```console
+$ pip install -r requirements.txt
+---> 100%
+Successfully installed fastapi pydantic
```
-## Créer le code **FastAPI**.
+
+
+/// info
+
+Il existe d’autres formats et outils pour définir et installer des dépendances de packages.
+
+///
+
+### Créer le code **FastAPI** { #create-the-fastapi-code }
-* Créer un répertoire `app` et y entrer.
-* Créez un fichier `main.py` avec :
+* Créez un répertoire `app` et entrez dedans.
+* Créez un fichier vide `__init__.py`.
+* Créez un fichier `main.py` avec :
```Python
-from typing import Optional
+from typing import Union
from fastapi import FastAPI
@@ -81,20 +158,166 @@ def read_root():
@app.get("/items/{item_id}")
-def read_item(item_id: int, q: Optional[str] = None):
+def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
```
-* Vous devriez maintenant avoir une structure de répertoire telle que :
+### Dockerfile { #dockerfile }
+
+Maintenant, dans le même répertoire de projet, créez un fichier `Dockerfile` avec :
+
+```{ .dockerfile .annotate }
+# (1)!
+FROM python:3.9
+
+# (2)!
+WORKDIR /code
+
+# (3)!
+COPY ./requirements.txt /code/requirements.txt
+
+# (4)!
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+
+# (5)!
+COPY ./app /code/app
+
+# (6)!
+CMD ["fastapi", "run", "app/main.py", "--port", "80"]
+```
+
+1. Partir de l’image de base Python officielle.
+
+2. Définir le répertoire de travail courant sur `/code`.
+
+ C’est là que nous mettrons le fichier `requirements.txt` et le répertoire `app`.
+
+3. Copier le fichier contenant les exigences dans le répertoire `/code`.
+
+ Copier **uniquement** le fichier contenant les exigences d’abord, pas le reste du code.
+
+ Comme ce fichier **ne change pas souvent**, Docker le détectera et utilisera le **cache** pour cette étape, permettant d’utiliser le cache pour l’étape suivante aussi.
+
+4. Installer les dépendances de packages du fichier d’exigences.
+
+ L’option `--no-cache-dir` indique à `pip` de ne pas enregistrer localement les packages téléchargés, car cela ne sert que si `pip` devait être relancé pour installer les mêmes packages, mais ce n’est pas le cas lorsqu’on travaille avec des conteneurs.
+
+ /// note | Remarque
+
+ `--no-cache-dir` est uniquement lié à `pip`, il n’a rien à voir avec Docker ou les conteneurs.
+
+ ///
+
+ L’option `--upgrade` indique à `pip` de mettre à niveau les packages s’ils sont déjà installés.
+
+ Comme l’étape précédente de copie du fichier pourrait être détectée par le **cache Docker**, cette étape va aussi **utiliser le cache Docker** lorsqu’il est disponible.
+
+ Utiliser le cache à cette étape va vous **faire gagner** beaucoup de **temps** lorsque vous reconstruisez l’image encore et encore pendant le développement, au lieu de **télécharger et installer** toutes les dépendances **à chaque fois**.
+
+5. Copier le répertoire `./app` dans le répertoire `/code`.
+
+ Comme cela contient tout le code, qui est ce qui **change le plus fréquemment**, le **cache** Docker ne sera pas facilement utilisé pour cette étape ou pour les **étapes suivantes**.
+
+ Il est donc important de placer cela **près de la fin** du `Dockerfile`, pour optimiser les temps de build de l’image de conteneur.
+
+6. Définir la **commande** pour utiliser `fastapi run`, qui utilise Uvicorn en dessous.
+
+ `CMD` prend une liste de chaînes de caractères, chacune de ces chaînes correspond à ce que vous taperiez en ligne de commande, séparé par des espaces.
+
+ Cette commande sera exécutée depuis le **répertoire de travail courant**, le même répertoire `/code` que vous avez défini plus haut avec `WORKDIR /code`.
+
+/// tip | Astuce
+
+Passez en revue ce que fait chaque ligne en cliquant sur chaque bulle numérotée dans le code. 👆
+
+///
+
+/// warning | Alertes
+
+Vous devez vous assurer d’utiliser **toujours** la **forme exec** de l’instruction `CMD`, comme expliqué ci-dessous.
+
+///
+
+#### Utiliser `CMD` - forme exec { #use-cmd-exec-form }
+
+L’instruction Docker `CMD` peut s’écrire sous deux formes :
+
+✅ Forme **exec** :
+
+```Dockerfile
+# ✅ Do this
+CMD ["fastapi", "run", "app/main.py", "--port", "80"]
+```
+
+⛔️ Forme **shell** :
+
+```Dockerfile
+# ⛔️ Don't do this
+CMD fastapi run app/main.py --port 80
+```
+
+Vous devez vous assurer de toujours utiliser la forme **exec** pour garantir que FastAPI puisse s’arrêter proprement et que les [événements de lifespan](../advanced/events.md){.internal-link target=_blank} soient déclenchés.
+
+Vous pouvez en lire plus à ce sujet dans la documentation Docker sur les formes shell et exec.
+
+Cela peut être assez visible lors de l’utilisation de `docker compose`. Consultez cette section de la FAQ Docker Compose pour plus de détails techniques : Why do my services take 10 seconds to recreate or stop?.
+
+#### Structure de répertoires { #directory-structure }
+
+Vous devriez maintenant avoir une structure de répertoires comme :
```
.
├── app
+│ ├── __init__.py
│ └── main.py
-└── Dockerfile
+├── Dockerfile
+└── requirements.txt
```
-## Construire l'image Docker
+#### Derrière un proxy de terminaison TLS { #behind-a-tls-termination-proxy }
+
+Si vous exécutez votre conteneur derrière un proxy de terminaison TLS (load balancer) comme Nginx ou Traefik, ajoutez l’option `--proxy-headers` ; cela indiquera à Uvicorn (via la CLI FastAPI) de faire confiance aux en-têtes envoyés par ce proxy lui indiquant que l’application s’exécute derrière HTTPS, etc.
+
+```Dockerfile
+CMD ["fastapi", "run", "app/main.py", "--proxy-headers", "--port", "80"]
+```
+
+#### Cache Docker { #docker-cache }
+
+Il y a une astuce importante dans ce `Dockerfile` : nous copions d’abord **le fichier des dépendances seul**, pas le reste du code. Je vais vous expliquer pourquoi.
+
+```Dockerfile
+COPY ./requirements.txt /code/requirements.txt
+```
+
+Docker et d’autres outils **construisent** ces images de conteneur **de manière incrémentale**, en ajoutant **une couche par-dessus l’autre**, en commençant par le haut du `Dockerfile` et en ajoutant tous les fichiers créés par chacune des instructions du `Dockerfile`.
+
+Docker et des outils similaires utilisent aussi un **cache interne** lors de la construction de l’image : si un fichier n’a pas changé depuis la dernière construction de l’image de conteneur, alors il va **réutiliser la même couche** créée la dernière fois, au lieu de copier le fichier à nouveau et de créer une nouvelle couche à partir de zéro.
+
+Le simple fait d’éviter la copie de fichiers n’améliore pas forcément beaucoup les choses, mais comme le cache a été utilisé pour cette étape, il peut **être utilisé pour l’étape suivante**. Par exemple, il pourrait être utilisé pour l’instruction qui installe les dépendances avec :
+
+```Dockerfile
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+```
+
+Le fichier des exigences de packages **ne changera pas fréquemment**. Donc, en ne copiant que ce fichier, Docker pourra **utiliser le cache** pour cette étape.
+
+Et ensuite, Docker pourra **utiliser le cache pour l’étape suivante** qui télécharge et installe ces dépendances. Et c’est là que nous **gagnons beaucoup de temps**. ✨ ... et évitons l’ennui d’attendre. 😪😆
+
+Le téléchargement et l’installation des dépendances de packages **peuvent prendre des minutes**, mais utiliser le **cache** **prendrait au maximum quelques secondes**.
+
+Et comme vous reconstruiriez l’image de conteneur encore et encore pendant le développement pour vérifier que vos modifications de code fonctionnent, cela vous ferait gagner beaucoup de temps cumulé.
+
+Ensuite, près de la fin du `Dockerfile`, nous copions tout le code. Comme c’est ce qui **change le plus fréquemment**, nous le mettons près de la fin, car presque toujours, tout ce qui vient après cette étape ne pourra pas utiliser le cache.
+
+```Dockerfile
+COPY ./app /code/app
+```
+
+### Construire l’image Docker { #build-the-docker-image }
+
+Maintenant que tous les fichiers sont en place, construisons l’image de conteneur.
* Allez dans le répertoire du projet (dans lequel se trouve votre `Dockerfile`, contenant votre répertoire `app`).
* Construisez votre image FastAPI :
@@ -109,9 +332,17 @@ $ docker build -t myimage .
-## Démarrer le conteneur Docker
+/// tip | Astuce
+
+Remarquez le `.` à la fin, il est équivalent à `./` : il indique à Docker le répertoire à utiliser pour construire l’image de conteneur.
+
+Dans ce cas, c’est le même répertoire courant (`.`).
+
+///
+
+### Démarrer le conteneur Docker { #start-the-docker-container }
-* Exécutez un conteneur basé sur votre image :
+* Exécutez un conteneur basé sur votre image :
@@ -121,65 +352,269 @@ $ docker run -d --name mycontainer -p 80:80 myimage
-Vous disposez maintenant d'un serveur FastAPI optimisé dans un conteneur Docker. Configuré automatiquement pour votre
-serveur actuel (et le nombre de cœurs du CPU).
+## Vérifier { #check-it }
-## Vérifier
+Vous devriez pouvoir le vérifier via l’URL de votre conteneur Docker, par exemple : http://192.168.99.100/items/5?q=somequery ou http://127.0.0.1/items/5?q=somequery (ou équivalent, en utilisant votre hôte Docker).
-Vous devriez pouvoir accéder à votre application via l'URL de votre conteneur Docker, par exemple : http://192.168.99.100/items/5?q=somequery ou http://127.0.0.1/items/5?q=somequery (ou équivalent, en utilisant votre hôte Docker).
-
-Vous verrez quelque chose comme :
+Vous verrez quelque chose comme :
```JSON
{"item_id": 5, "q": "somequery"}
```
-## Documentation interactive de l'API
+## Documentation interactive de l’API { #interactive-api-docs }
-Vous pouvez maintenant visiter http://192.168.99.100/docs ou http://127.0.0.1/docs (ou équivalent, en utilisant votre hôte Docker).
+Vous pouvez maintenant aller sur http://192.168.99.100/docs ou http://127.0.0.1/docs (ou équivalent, en utilisant votre hôte Docker).
-Vous verrez la documentation interactive automatique de l'API (fournie par Swagger UI) :
+Vous verrez la documentation interactive automatique de l’API (fournie par Swagger UI) :

-## Documentation de l'API alternative
+## Documentation de l’API alternative { #alternative-api-docs }
Et vous pouvez également aller sur http://192.168.99.100/redoc ou http://127.0.0.1/redoc (ou équivalent, en utilisant votre hôte Docker).
-Vous verrez la documentation automatique alternative (fournie par ReDoc) :
+Vous verrez la documentation automatique alternative (fournie par ReDoc) :

-## Traefik
+## Construire une image Docker avec un FastAPI dans un seul fichier { #build-a-docker-image-with-a-single-file-fastapi }
+
+Si votre FastAPI est un seul fichier, par exemple `main.py` sans répertoire `./app`, votre structure de fichiers pourrait ressembler à ceci :
+
+```
+.
+├── Dockerfile
+├── main.py
+└── requirements.txt
+```
+
+Ensuite, vous n’auriez qu’à modifier les chemins correspondants pour copier le fichier dans le `Dockerfile` :
+
+```{ .dockerfile .annotate hl_lines="10 13" }
+FROM python:3.9
+
+WORKDIR /code
+
+COPY ./requirements.txt /code/requirements.txt
+
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+
+# (1)!
+COPY ./main.py /code/
+
+# (2)!
+CMD ["fastapi", "run", "main.py", "--port", "80"]
+```
+
+1. Copier le fichier `main.py` directement dans le répertoire `/code` (sans aucun répertoire `./app`).
+
+2. Utiliser `fastapi run` pour servir votre application dans le fichier unique `main.py`.
+
+Quand vous passez le fichier à `fastapi run`, il détectera automatiquement qu’il s’agit d’un fichier unique et non d’une partie d’un package, et saura comment l’importer et servir votre application FastAPI. 😎
+
+## Concepts de déploiement { #deployment-concepts }
+
+Parlons à nouveau de certains des mêmes [concepts de déploiement](concepts.md){.internal-link target=_blank} en termes de conteneurs.
+
+Les conteneurs sont principalement un outil pour simplifier le processus de **construction et de déploiement** d’une application, mais ils n’imposent pas une approche particulière pour gérer ces **concepts de déploiement**, et il existe plusieurs stratégies possibles.
+
+La **bonne nouvelle**, c’est qu’avec chaque stratégie différente il existe un moyen de couvrir tous les concepts de déploiement. 🎉
+
+Passons en revue ces **concepts de déploiement** en termes de conteneurs :
+
+* HTTPS
+* Exécution au démarrage
+* Redémarrages
+* Réplication (le nombre de processus en cours d’exécution)
+* Mémoire
+* Étapes préalables avant de démarrer
+
+## HTTPS { #https }
+
+Si nous nous concentrons uniquement sur l’**image de conteneur** d’une application FastAPI (et plus tard sur le **conteneur** en cours d’exécution), HTTPS serait normalement géré **en externe** par un autre outil.
+
+Cela pourrait être un autre conteneur, par exemple avec Traefik, gérant **HTTPS** et l’acquisition **automatique** de **certificats**.
+
+/// tip | Astuce
+
+Traefik dispose d’intégrations avec Docker, Kubernetes et d’autres, il est donc très simple à mettre en place et à configurer pour HTTPS avec vos conteneurs.
+
+///
+
+Alternativement, HTTPS pourrait être géré par un fournisseur cloud comme l’un de ses services (tout en exécutant l’application dans un conteneur).
+
+## Exécution au démarrage et redémarrages { #running-on-startup-and-restarts }
+
+Il y a normalement un autre outil chargé de **démarrer et exécuter** votre conteneur.
+
+Cela pourrait être **Docker** directement, **Docker Compose**, **Kubernetes**, un **service cloud**, etc.
+
+Dans la plupart (ou tous) les cas, il existe une option simple pour activer l’exécution du conteneur au démarrage et activer les redémarrages en cas d’échec. Par exemple, dans Docker, c’est l’option en ligne de commande `--restart`.
+
+Sans utiliser de conteneurs, faire exécuter des applications au démarrage et avec redémarrages peut être contraignant et difficile. Mais en **travaillant avec des conteneurs**, dans la plupart des cas cette fonctionnalité est incluse par défaut. ✨
+
+## Réplication - Nombre de processus { #replication-number-of-processes }
+
+Si vous avez un 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** au lieu d’utiliser un **gestionnaire de processus** (comme Uvicorn avec des workers) dans chaque conteneur.
+
+Un de ces systèmes de gestion de conteneurs distribués comme Kubernetes dispose normalement d’un moyen intégré de gérer la **réplication des conteneurs** tout en prenant en charge l’**équilibrage de charge** pour les requêtes entrantes. Le tout au **niveau du cluster**.
+
+Dans ces cas, vous voudrez probablement construire une **image Docker à partir de zéro** comme [expliqué ci-dessus](#dockerfile), installer vos dépendances, et exécuter **un seul processus Uvicorn** au lieu d’utiliser plusieurs workers Uvicorn.
+
+### Load Balancer { #load-balancer }
-Traefik est un reverse proxy/load balancer
-haute performance. Il peut faire office de "Proxy de terminaison TLS" (entre autres fonctionnalités).
+Lors de l’utilisation de conteneurs, vous aurez normalement un composant **à l’écoute sur le port principal**. Cela pourrait éventuellement être un autre conteneur qui est aussi un **proxy de terminaison TLS** pour gérer **HTTPS** ou un outil similaire.
-Il est intégré à Let's Encrypt. Ainsi, il peut gérer toutes les parties HTTPS, y compris l'acquisition et le renouvellement des certificats.
+Comme ce composant prendrait la **charge** des requêtes et la distribuerait entre les workers d’une manière (espérons-le) **équilibrée**, on l’appelle aussi communément un **Load Balancer**.
-Il est également intégré à Docker. Ainsi, vous pouvez déclarer vos domaines dans les configurations de chaque application et faire en sorte qu'elles lisent ces configurations, génèrent les certificats HTTPS et servent via HTTPS à votre application automatiquement, sans nécessiter aucune modification de leurs configurations.
+/// tip | Astuce
+
+Le même composant de **proxy de terminaison TLS** utilisé pour HTTPS serait probablement aussi un **Load Balancer**.
+
+///
+
+Et en travaillant avec des conteneurs, le même système que vous utilisez pour les démarrer et les gérer aura déjà des outils internes pour transmettre la **communication réseau** (par exemple les requêtes HTTP) depuis ce **load balancer** (qui pourrait aussi être un **proxy de terminaison TLS**) vers le(s) conteneur(s) avec votre application.
+
+### Un load balancer - Plusieurs conteneurs workers { #one-load-balancer-multiple-worker-containers }
+
+En travaillant avec **Kubernetes** ou des systèmes distribués de gestion de conteneurs similaires, utiliser leurs mécanismes réseau internes permettrait au **load balancer** unique qui écoute sur le **port** principal de transmettre la communication (les requêtes) à potentiellement **plusieurs conteneurs** exécutant votre application.
+
+Chacun de ces conteneurs exécutant votre application aurait normalement **un seul processus** (par exemple un processus Uvicorn exécutant votre application FastAPI). Ce seraient tous des **conteneurs identiques**, exécutant la même chose, mais chacun avec son propre processus, sa mémoire, etc. Ainsi, vous profiteriez de la **parallélisation** sur **différents cœurs** du CPU, ou même sur **différentes machines**.
+
+Et le système de conteneurs distribués avec le **load balancer** **distribuerait les requêtes** à chacun des conteneurs avec votre application **à tour de rôle**. Ainsi, chaque requête pourrait être traitée par l’un des multiples **conteneurs répliqués** exécutant votre application.
+
+Et normalement ce **load balancer** serait capable de gérer des requêtes allant vers *d’autres* applications dans votre cluster (par exemple vers un domaine différent, ou sous un préfixe de chemin d’URL différent), et transmettrait cette communication aux bons conteneurs pour *cette autre* application s’exécutant dans votre cluster.
+
+### Un processus par conteneur { #one-process-per-container }
+
+Dans ce type de scénario, vous voudrez probablement avoir **un seul processus (Uvicorn) par conteneur**, puisque vous gérez déjà la réplication au niveau du cluster.
+
+Donc, dans ce cas, vous **ne** voudrez **pas** avoir plusieurs workers dans le conteneur, par exemple avec l’option en ligne de commande `--workers`. Vous voudrez avoir un **seul processus Uvicorn** par conteneur (mais probablement plusieurs conteneurs).
+
+Avoir un autre gestionnaire de processus à l’intérieur du conteneur (comme ce serait le cas avec plusieurs workers) ne ferait qu’ajouter une **complexité inutile** que vous gérez très probablement déjà avec votre système de cluster.
+
+### Conteneurs avec plusieurs processus et cas particuliers { #containers-with-multiple-processes-and-special-cases }
+
+Bien sûr, il existe des **cas particuliers** où vous pourriez vouloir avoir **un conteneur** avec plusieurs **processus workers Uvicorn** à l’intérieur.
+
+Dans ces cas, vous pouvez utiliser l’option en ligne de commande `--workers` pour définir le nombre de workers que vous souhaitez exécuter :
+
+```{ .dockerfile .annotate }
+FROM python:3.9
+
+WORKDIR /code
+
+COPY ./requirements.txt /code/requirements.txt
+
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+
+COPY ./app /code/app
+
+# (1)!
+CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
+```
+
+1. Ici, nous utilisons l’option en ligne de commande `--workers` pour définir le nombre de workers à 4.
+
+Voici quelques exemples où cela pourrait avoir du sens :
+
+#### Une application simple { #a-simple-app }
+
+Vous pourriez vouloir un gestionnaire de processus dans le conteneur si votre application est **suffisamment simple** pour pouvoir s’exécuter sur un **seul serveur**, pas un cluster.
+
+#### Docker Compose { #docker-compose }
+
+Vous pourriez déployer sur un **seul serveur** (pas un cluster) avec **Docker Compose**, et vous n’auriez donc pas un moyen simple de gérer la réplication des conteneurs (avec Docker Compose) tout en préservant le réseau partagé et l’**équilibrage de charge**.
+
+Vous pourriez alors vouloir avoir **un seul conteneur** avec un **gestionnaire de processus** démarrant **plusieurs processus worker** à l’intérieur.
---
-Avec ces informations et ces outils, passez à la section suivante pour tout combiner.
+Le point principal est que **rien** de tout cela n’est une **règle gravée dans le marbre** que vous devez suivre aveuglément. Vous pouvez utiliser ces idées pour **évaluer votre propre cas d’usage** et décider quelle est la meilleure approche pour votre système, en examinant comment gérer les concepts de :
+
+* 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 de démarrer
+
+## Mémoire { #memory }
+
+Si vous exécutez **un seul processus par conteneur**, vous aurez une quantité de mémoire plus ou moins bien définie, stable, et limitée consommée par chacun de ces conteneurs (plus d’un si vous les répliquez).
+
+Et ensuite, vous pouvez définir ces mêmes limites et exigences de mémoire dans vos configurations pour votre système de gestion de conteneurs (par exemple dans **Kubernetes**). Ainsi, il pourra **répliquer les conteneurs** sur les **machines disponibles** en tenant compte de la quantité de mémoire nécessaire et de la quantité disponible sur les machines du cluster.
+
+Si votre application est **simple**, ce ne sera probablement **pas un problème**, et vous pourriez ne pas avoir besoin de spécifier des limites strictes de mémoire. Mais si vous **utilisez beaucoup de mémoire** (par exemple avec des modèles de **machine learning**), vous devriez vérifier la quantité de mémoire consommée et ajuster le **nombre de conteneurs** qui s’exécutent sur **chaque machine** (et peut-être ajouter plus de machines à votre cluster).
+
+Si vous exécutez **plusieurs processus par conteneur**, vous devez vous assurer que le nombre de processus démarrés ne **consomme pas plus de mémoire** que ce qui est disponible.
+
+## Étapes préalables avant de démarrer et conteneurs { #previous-steps-before-starting-and-containers }
+
+Si vous utilisez des conteneurs (par exemple Docker, Kubernetes), alors il existe deux approches principales que vous pouvez utiliser.
+
+### Plusieurs conteneurs { #multiple-containers }
+
+Si vous avez **plusieurs conteneurs**, probablement chacun exécutant un **seul processus** (par exemple, dans un cluster **Kubernetes**), vous voudrez probablement avoir un **conteneur séparé** pour effectuer le travail des **étapes préalables** dans un conteneur unique, exécutant un seul processus, **avant** d’exécuter les conteneurs workers répliqués.
+
+/// info
+
+Si vous utilisez Kubernetes, ce serait probablement un Init Container.
+
+///
+
+Si, dans votre cas d’usage, il n’y a pas de problème à exécuter ces étapes préalables **plusieurs fois en parallèle** (par exemple si vous n’exécutez pas des migrations de base de données, mais vérifiez simplement si la base de données est prête), alors vous pourriez aussi les placer dans chaque conteneur juste avant de démarrer le processus principal.
+
+### Conteneur unique { #single-container }
+
+Si vous avez une configuration simple, avec un **conteneur unique** qui démarre ensuite plusieurs **processus worker** (ou aussi juste un processus), alors vous pourriez exécuter ces étapes préalables dans le même conteneur, juste avant de démarrer le processus avec l’application.
+
+### Image Docker de base { #base-docker-image }
+
+Il existait une image Docker FastAPI officielle : tiangolo/uvicorn-gunicorn-fastapi. Mais elle est maintenant dépréciée. ⛔️
+
+Vous ne devriez probablement **pas** utiliser cette image Docker de base (ni une autre similaire).
+
+Si vous utilisez **Kubernetes** (ou d’autres) et que vous définissez déjà la **réplication** au niveau du cluster, avec plusieurs **conteneurs**. Dans ces cas, il vaut mieux **construire une image à partir de zéro** comme décrit ci-dessus : [Construire une image Docker pour FastAPI](#build-a-docker-image-for-fastapi).
+
+Et si vous devez avoir plusieurs workers, vous pouvez simplement utiliser l’option en ligne de commande `--workers`.
+
+/// note | Détails techniques
+
+L’image Docker a été créée à une époque où Uvicorn ne prenait pas en charge la gestion et le redémarrage des workers morts, il était donc nécessaire d’utiliser Gunicorn avec Uvicorn, ce qui ajoutait pas mal de complexité, simplement pour que Gunicorn gère et redémarre les processus workers Uvicorn.
+
+Mais maintenant qu’Uvicorn (et la commande `fastapi`) prennent en charge l’utilisation de `--workers`, il n’y a aucune raison d’utiliser une image Docker de base au lieu de construire la vôtre (c’est à peu près la même quantité de code 😅).
+
+///
+
+## Déployer l’image de conteneur { #deploy-the-container-image }
-## Cluster en mode Docker Swarm avec Traefik et HTTPS
+Après avoir une image de conteneur (Docker), il existe plusieurs façons de la déployer.
-Vous pouvez avoir un cluster en mode Docker Swarm configuré en quelques minutes (environ 20 min) avec un processus Traefik principal gérant HTTPS (y compris l'acquisition et le renouvellement des certificats).
+Par exemple :
-En utilisant le mode Docker Swarm, vous pouvez commencer par un "cluster" d'une seule machine (il peut même s'agir
-d'un serveur à 5 USD/mois) et ensuite vous pouvez vous développer autant que vous le souhaitez en ajoutant d'autres serveurs.
+* Avec **Docker Compose** sur un seul serveur
+* Avec un cluster **Kubernetes**
+* Avec un cluster en mode Docker Swarm
+* Avec un autre outil comme Nomad
+* Avec un service cloud qui prend votre image de conteneur et la déploie
-Pour configurer un cluster en mode Docker Swarm avec Traefik et la gestion de HTTPS, suivez ce guide :
+## Image Docker avec `uv` { #docker-image-with-uv }
-### Docker Swarm Mode et Traefik pour un cluster HTTPS
+Si vous utilisez uv pour installer et gérer votre projet, vous pouvez suivre leur guide Docker uv.
-### Déployer une application FastAPI
+## Récapitulatif { #recap }
-La façon la plus simple de tout mettre en place, serait d'utiliser les [**Générateurs de projet FastAPI**](../project-generation.md){.internal-link target=_blank}.
+En utilisant des systèmes de conteneurs (par ex. avec **Docker** et **Kubernetes**), il devient assez simple de gérer tous les **concepts de déploiement** :
-Le génerateur de projet adéquat est conçu pour être intégré à ce cluster Docker Swarm avec Traefik et HTTPS décrit ci-dessus.
+* HTTPS
+* Exécution au démarrage
+* Redémarrages
+* Réplication (le nombre de processus en cours d’exécution)
+* Mémoire
+* Étapes préalables avant de démarrer
-Vous pouvez générer un projet en 2 min environ.
+Dans la plupart des cas, vous ne voudrez probablement pas utiliser une image de base, et vous voudrez plutôt **construire une image de conteneur à partir de zéro** basée sur l’image Docker Python officielle.
-Le projet généré a des instructions pour le déployer et le faire prend 2 min de plus.
+En prenant soin de l’**ordre** des instructions dans le `Dockerfile` et du **cache Docker**, vous pouvez **minimiser les temps de build**, afin de maximiser votre productivité (et d’éviter l’ennui). 😎
diff --git a/docs/fr/docs/deployment/https.md b/docs/fr/docs/deployment/https.md
index 3f7068ff0..7afa08c0c 100644
--- a/docs/fr/docs/deployment/https.md
+++ b/docs/fr/docs/deployment/https.md
@@ -1,56 +1,231 @@
-# À propos de HTTPS
+# À propos de HTTPS { #about-https }
-Il est facile de penser que HTTPS peut simplement être "activé" ou non.
+Il est facile de supposer que HTTPS est quelque chose qui est simplement « activé » ou non.
-Mais c'est beaucoup plus complexe que cela.
+Mais c'est bien plus complexe que cela.
-/// tip
+/// tip | Astuce
-Si vous êtes pressé ou si cela ne vous intéresse pas, passez aux sections suivantes pour obtenir des instructions étape par étape afin de tout configurer avec différentes techniques.
+Si vous êtes pressé ou si cela ne vous intéresse pas, continuez avec les sections suivantes pour obtenir des instructions étape par étape afin de tout configurer avec différentes techniques.
///
-Pour apprendre les bases du HTTPS, du point de vue d'un utilisateur, consultez https://howhttps.works/.
-
-Maintenant, du point de vue d'un développeur, voici plusieurs choses à avoir en tête en pensant au HTTPS :
-
-* Pour le HTTPS, le serveur a besoin de "certificats" générés par une tierce partie.
- * Ces certificats sont en fait acquis auprès de la tierce partie, et non "générés".
-* Les certificats ont une durée de vie.
- * Ils expirent.
- * Puis ils doivent être renouvelés et acquis à nouveau auprès de la tierce partie.
-* Le cryptage de la connexion se fait au niveau du protocole TCP.
- * C'est une couche en dessous de HTTP.
- * Donc, le certificat et le traitement du cryptage sont faits avant HTTP.
-* TCP ne connaît pas les "domaines", seulement les adresses IP.
- * L'information sur le domaine spécifique demandé se trouve dans les données HTTP.
-* Les certificats HTTPS "certifient" un certain domaine, mais le protocole et le cryptage se font au niveau TCP, avant de savoir quel domaine est traité.
-* Par défaut, cela signifie que vous ne pouvez avoir qu'un seul certificat HTTPS par adresse IP.
- * Quelle que soit la taille de votre serveur ou la taille de chacune des applications qu'il contient.
- * Il existe cependant une solution à ce problème.
-* Il existe une extension du protocole TLS (celui qui gère le cryptage au niveau TCP, avant HTTP) appelée SNI (indication du nom du serveur).
- * Cette extension SNI permet à un seul serveur (avec une seule adresse IP) d'avoir plusieurs certificats HTTPS et de servir plusieurs domaines/applications HTTPS.
- * Pour que cela fonctionne, un seul composant (programme) fonctionnant sur le serveur, écoutant sur l'adresse IP publique, doit avoir tous les certificats HTTPS du serveur.
-* Après avoir obtenu une connexion sécurisée, le protocole de communication est toujours HTTP.
- * Le contenu est crypté, même s'il est envoyé avec le protocole HTTP.
-
-Il est courant d'avoir un seul programme/serveur HTTP fonctionnant sur le serveur (la machine, l'hôte, etc.) et
-gérant toutes les parties HTTPS : envoyer les requêtes HTTP décryptées à l'application HTTP réelle fonctionnant sur
-le même serveur (dans ce cas, l'application **FastAPI**), prendre la réponse HTTP de l'application, la crypter en utilisant le certificat approprié et la renvoyer au client en utilisant HTTPS. Ce serveur est souvent appelé un Proxy de terminaison TLS.
-
-## Let's Encrypt
-
-Avant Let's Encrypt, ces certificats HTTPS étaient vendus par des tiers de confiance.
+Pour **apprendre les bases de HTTPS**, du point de vue d'un utilisateur, consultez https://howhttps.works/.
+
+Maintenant, du point de vue d'un développeur, voici plusieurs choses à garder à l'esprit en pensant à HTTPS :
+
+* Pour HTTPS, **le serveur** doit **avoir des « certificats »** générés par une **tierce partie**.
+ * Ces certificats sont en fait **acquis** auprès de la tierce partie, et non « générés ».
+* Les certificats ont une **durée de vie**.
+ * Ils **expirent**.
+ * Et ensuite ils doivent être **renouvelés**, **acquis à nouveau** auprès de la tierce partie.
+* Le chiffrement de la connexion se fait au **niveau TCP**.
+ * C'est une couche **en dessous de HTTP**.
+ * Donc, la gestion du **certificat et du chiffrement** est faite **avant HTTP**.
+* **TCP ne connaît pas les « domaines »**. Seulement les adresses IP.
+ * L'information sur le **domaine spécifique** demandé se trouve dans les **données HTTP**.
+* Les **certificats HTTPS** « certifient » un **certain domaine**, mais le protocole et le chiffrement se font au niveau TCP, **avant de savoir** quel domaine est traité.
+* **Par défaut**, cela signifierait que vous ne pouvez avoir qu'**un seul certificat HTTPS par adresse IP**.
+ * Peu importe la taille de votre serveur ou à quel point chaque application que vous avez dessus peut être petite.
+ * Il existe cependant une **solution** à ce problème.
+* Il existe une **extension** du protocole **TLS** (celui qui gère le chiffrement au niveau TCP, avant HTTP) appelée **SNI**.
+ * Cette extension SNI permet à un seul serveur (avec une **seule adresse IP**) d'avoir **plusieurs certificats HTTPS** et de servir **plusieurs domaines/applications HTTPS**.
+ * Pour que cela fonctionne, un **seul** composant (programme) fonctionnant sur le serveur, écoutant sur l'**adresse IP publique**, doit avoir **tous les certificats HTTPS** du serveur.
+* **Après** avoir obtenu une connexion sécurisée, le protocole de communication est **toujours HTTP**.
+ * Le contenu est **chiffré**, même s'il est envoyé avec le **protocole HTTP**.
+
+Il est courant d'avoir **un seul programme/serveur HTTP** fonctionnant sur le serveur (la machine, l'hôte, etc.) et **gérant toutes les parties HTTPS** : recevoir les **requêtes HTTPS chiffrées**, envoyer les **requêtes HTTP déchiffrées** à l'application HTTP réelle fonctionnant sur le même serveur (l'application **FastAPI**, dans ce cas), prendre la **réponse HTTP** de l'application, la **chiffrer** en utilisant le **certificat HTTPS** approprié et la renvoyer au client en utilisant **HTTPS**. Ce serveur est souvent appelé un **Proxy de terminaison TLS**.
+
+Certaines des options que vous pouvez utiliser comme Proxy de terminaison TLS sont :
+
+* Traefik (qui peut aussi gérer les renouvellements de certificats)
+* Caddy (qui peut aussi gérer les renouvellements de certificats)
+* Nginx
+* HAProxy
+
+## Let's Encrypt { #lets-encrypt }
+
+Avant Let's Encrypt, ces **certificats HTTPS** étaient vendus par des tiers de confiance.
Le processus d'acquisition d'un de ces certificats était auparavant lourd, nécessitait pas mal de paperasses et les certificats étaient assez chers.
-Mais ensuite, Let's Encrypt a été créé.
+Mais ensuite **Let's Encrypt** a été créé.
-Il s'agit d'un projet de la Fondation Linux. Il fournit des certificats HTTPS gratuitement. De manière automatisée. Ces certificats utilisent toutes les sécurités cryptographiques standard et ont une durée de vie courte (environ 3 mois), de sorte que la sécurité est en fait meilleure en raison de leur durée de vie réduite.
+Il s'agit d'un projet de la Linux Foundation. Il fournit des **certificats HTTPS gratuitement**, de manière automatisée. Ces certificats utilisent toutes les sécurités cryptographiques standard, et ont une durée de vie courte (environ 3 mois), de sorte que la **sécurité est en fait meilleure** en raison de leur durée de vie réduite.
Les domaines sont vérifiés de manière sécurisée et les certificats sont générés automatiquement. Cela permet également d'automatiser le renouvellement de ces certificats.
-L'idée est d'automatiser l'acquisition et le renouvellement de ces certificats, afin que vous puissiez disposer d'un HTTPS sécurisé, gratuitement et pour toujours.
+L'idée est d'automatiser l'acquisition et le renouvellement de ces certificats, afin que vous puissiez disposer d'un **HTTPS sécurisé, gratuitement, pour toujours**.
+
+## HTTPS pour les développeurs { #https-for-developers }
+
+Voici un exemple de ce à quoi une API HTTPS pourrait ressembler, étape par étape, en faisant attention principalement aux idées importantes pour les développeurs.
+
+### Nom de domaine { #domain-name }
+
+Cela commencerait probablement par le fait que vous **acquérez** un **nom de domaine**. Ensuite, vous le configureriez dans un serveur DNS (éventuellement votre même fournisseur cloud).
+
+Vous obtiendriez probablement un serveur cloud (une machine virtuelle) ou quelque chose de similaire, et il aurait une adresse IP publique fixed.
+
+Dans le(s) serveur(s) DNS vous configureriez un enregistrement (un « `A record` ») pour faire pointer **votre domaine** vers l'**adresse IP publique de votre serveur**.
+
+Vous feriez probablement cela une seule fois, la première fois, lorsque vous mettez tout en place.
+
+/// tip | Astuce
+
+Cette partie « nom de domaine » se situe bien avant HTTPS, mais comme tout dépend du domaine et de l'adresse IP, cela vaut la peine de le mentionner ici.
+
+///
+
+### DNS { #dns }
+
+Maintenant, concentrons-nous sur toutes les parties réellement liées à HTTPS.
+
+D'abord, le navigateur vérifierait auprès des **serveurs DNS** quelle est l'**IP du domaine**, dans ce cas, `someapp.example.com`.
+
+Les serveurs DNS diraient au navigateur d'utiliser une **adresse IP** spécifique. Ce serait l'adresse IP publique utilisée par votre serveur, que vous avez configurée dans les serveurs DNS.
+
+
+
+### Début du handshake TLS { #tls-handshake-start }
+
+Le navigateur communiquerait ensuite avec cette adresse IP sur le **port 443** (le port HTTPS).
+
+La première partie de la communication consiste simplement à établir la connexion entre le client et le serveur et à décider des clés cryptographiques qu'ils utiliseront, etc.
+
+
+
+Cette interaction entre le client et le serveur pour établir la connexion TLS s'appelle le **handshake TLS**.
+
+### TLS avec l'extension SNI { #tls-with-sni-extension }
+
+**Un seul process** sur le serveur peut écouter sur un **port** spécifique sur une **adresse IP** spécifique. Il peut y avoir d'autres process écoutant sur d'autres ports sur la même adresse IP, mais un seul pour chaque combinaison d'adresse IP et de port.
+
+TLS (HTTPS) utilise par défaut le port spécifique `443`. Donc c'est ce port dont nous avons besoin.
+
+Comme un seul process peut écouter sur ce port, le process qui le ferait serait le **Proxy de terminaison TLS**.
+
+Le Proxy de terminaison TLS aurait accès à un ou plusieurs **certificats TLS** (certificats HTTPS).
+
+En utilisant l'**extension SNI** mentionnée ci-dessus, le Proxy de terminaison TLS vérifierait lequel des certificats TLS (HTTPS) disponibles il doit utiliser pour cette connexion, en utilisant celui qui correspond au domaine attendu par le client.
+
+Dans ce cas, il utiliserait le certificat pour `someapp.example.com`.
+
+
+
+Le client **fait déjà confiance** à l'entité qui a généré ce certificat TLS (dans ce cas Let's Encrypt, mais nous verrons cela plus tard), il peut donc **vérifier** que le certificat est valide.
+
+Ensuite, en utilisant le certificat, le client et le Proxy de terminaison TLS **décident comment chiffrer** le reste de la **communication TCP**. Cela complète la partie **Handshake TLS**.
+
+Après cela, le client et le serveur ont une **connexion TCP chiffrée**, c'est ce que fournit TLS. Et ensuite ils peuvent utiliser cette connexion pour démarrer la véritable **communication HTTP**.
+
+Et c'est ce qu'est **HTTPS**, c'est simplement du **HTTP** à l'intérieur d'une **connexion TLS sécurisée** au lieu d'une connexion TCP pure (non chiffrée).
+
+/// tip | Astuce
+
+Notez que le chiffrement de la communication se produit au **niveau TCP**, pas au niveau HTTP.
+
+///
+
+### Requête HTTPS { #https-request }
+
+Maintenant que le client et le serveur (spécifiquement le navigateur et le Proxy de terminaison TLS) ont une **connexion TCP chiffrée**, ils peuvent démarrer la **communication HTTP**.
+
+Ainsi, le client envoie une **requête HTTPS**. Il s'agit simplement d'une requête HTTP via une connexion TLS chiffrée.
+
+
+
+### Déchiffrer la requête { #decrypt-the-request }
+
+Le Proxy de terminaison TLS utiliserait le chiffrement convenu pour **déchiffrer la requête**, et transmettrait la **requête HTTP en clair (déchiffrée)** au process exécutant l'application (par exemple un process avec Uvicorn exécutant l'application FastAPI).
+
+
+
+### Réponse HTTP { #http-response }
+
+L'application traiterait la requête et enverrait une **réponse HTTP en clair (non chiffrée)** au Proxy de terminaison TLS.
+
+
+
+### Réponse HTTPS { #https-response }
+
+Le Proxy de terminaison TLS **chiffrerait ensuite la réponse** en utilisant la cryptographie convenue auparavant (qui a commencé avec le certificat pour `someapp.example.com`), et la renverrait au navigateur.
+
+Ensuite, le navigateur vérifierait que la réponse est valide et chiffrée avec la bonne clé cryptographique, etc. Il **déchiffrerait ensuite la réponse** et la traiterait.
+
+
+
+Le client (navigateur) saura que la réponse provient du bon serveur parce qu'il utilise la cryptographie qu'ils ont convenue en utilisant le **certificat HTTPS** auparavant.
+
+### Applications multiples { #multiple-applications }
+
+Sur le même serveur (ou les mêmes serveurs), il pourrait y avoir **plusieurs applications**, par exemple d'autres programmes d'API ou une base de données.
+
+Un seul process peut gérer la combinaison spécifique d'IP et de port (le Proxy de terminaison TLS dans notre exemple) mais les autres applications/process peuvent également s'exécuter sur le(s) serveur(s), tant qu'ils n'essaient pas d'utiliser la même **combinaison d'IP publique et de port**.
+
+
+
+De cette façon, le Proxy de terminaison TLS pourrait gérer HTTPS et les certificats pour **plusieurs domaines**, pour plusieurs applications, puis transmettre les requêtes à la bonne application dans chaque cas.
+
+### Renouvellement des certificats { #certificate-renewal }
+
+À un moment donné dans le futur, chaque certificat **expirerait** (environ 3 mois après son acquisition).
+
+Et ensuite, il y aurait un autre programme (dans certains cas c'est un autre programme, dans certains cas cela pourrait être le même Proxy de terminaison TLS) qui parlerait à Let's Encrypt, et renouvellerait le(s) certificat(s).
+
+
+
+Les **certificats TLS** sont **associés à un nom de domaine**, pas à une adresse IP.
+
+Ainsi, pour renouveler les certificats, le programme de renouvellement doit **prouver** à l'autorité (Let's Encrypt) qu'il **« possède » et contrôle effectivement ce domaine**.
+
+Pour ce faire, et pour répondre à différents besoins applicatifs, il existe plusieurs façons de procéder. Voici quelques méthodes populaires :
+
+* **Modifier certains enregistrements DNS**.
+ * Pour cela, le programme de renouvellement doit prendre en charge les API du fournisseur DNS, donc, selon le fournisseur DNS que vous utilisez, cela peut ou non être une option.
+* **S'exécuter comme un serveur** (au moins pendant le processus d'acquisition du certificat) sur l'adresse IP publique associée au domaine.
+ * Comme nous l'avons dit ci-dessus, un seul process peut écouter sur une IP et un port spécifiques.
+ * C'est l'une des raisons pour lesquelles il est très utile que le même Proxy de terminaison TLS s'occupe aussi du processus de renouvellement des certificats.
+ * Sinon, vous devrez peut-être arrêter momentanément le Proxy de terminaison TLS, démarrer le programme de renouvellement pour acquérir les certificats, puis les configurer avec le Proxy de terminaison TLS, et ensuite redémarrer le Proxy de terminaison TLS. Ce n'est pas idéal, car votre/vos app(s) ne seront pas disponibles pendant le temps où le Proxy de terminaison TLS est arrêté.
+
+Tout ce processus de renouvellement, tout en continuant de servir l'app, est l'une des principales raisons pour lesquelles vous voulez avoir un **système séparé pour gérer HTTPS** avec un Proxy de terminaison TLS au lieu de simplement utiliser les certificats TLS directement avec le serveur d'application (par ex. Uvicorn).
+
+## En-têtes de proxy transférés { #proxy-forwarded-headers }
+
+Lorsque vous utilisez un proxy pour gérer HTTPS, votre **serveur d'application** (par exemple Uvicorn via la FastAPI CLI) ne sait rien du processus HTTPS, il communique en HTTP en clair avec le **Proxy de terminaison TLS**.
+
+Ce **proxy** définirait normalement certains en-têtes HTTP à la volée avant de transmettre la requête au **serveur d'application**, pour indiquer au serveur d'application que la requête est **transférée** par le proxy.
+
+/// note | Détails techniques
+
+Les en-têtes du proxy sont :
+
+* X-Forwarded-For
+* X-Forwarded-Proto
+* X-Forwarded-Host
+
+///
+
+Néanmoins, comme le **serveur d'application** ne sait pas qu'il est derrière un **proxy** de confiance, par défaut, il ne ferait pas confiance à ces en-têtes.
+
+Mais vous pouvez configurer le **serveur d'application** pour faire confiance aux en-têtes *forwarded* envoyés par le **proxy**. Si vous utilisez la FastAPI CLI, vous pouvez utiliser l'*option CLI* `--forwarded-allow-ips` pour lui indiquer depuis quelles IP il doit faire confiance à ces en-têtes *forwarded*.
+
+Par exemple, si le **serveur d'application** ne reçoit la communication que du **proxy** de confiance, vous pouvez le définir sur `--forwarded-allow-ips="*"` pour lui faire confiance pour toutes les IP entrantes, car il ne recevra des requêtes que depuis l'adresse IP utilisée par le **proxy**.
+
+De cette façon, l'application serait capable de connaître sa propre URL publique, si elle utilise HTTPS, le domaine, etc.
+
+Ce serait utile par exemple pour gérer correctement les redirections.
+
+/// tip | Astuce
+
+Vous pouvez en apprendre davantage à ce sujet dans la documentation pour [Derrière un proxy - Activer les en-têtes Proxy Forwarded](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers){.internal-link target=_blank}
+
+///
+
+## Récapitulatif { #recap }
+
+Avoir **HTTPS** est très important, et assez **critique** dans la plupart des cas. La plupart des efforts que vous, en tant que développeur, devez fournir autour de HTTPS consistent simplement à **comprendre ces concepts** et comment ils fonctionnent.
+
+Mais une fois que vous connaissez les informations de base sur **HTTPS pour les développeurs** vous pouvez facilement combiner et configurer différents outils pour vous aider à tout gérer de manière simple.
+
+Dans certains des prochains chapitres, je vais vous montrer plusieurs exemples concrets de configuration de **HTTPS** pour des applications **FastAPI**. 🔒
diff --git a/docs/fr/docs/deployment/index.md b/docs/fr/docs/deployment/index.md
index e2014afe9..7038f4a8c 100644
--- a/docs/fr/docs/deployment/index.md
+++ b/docs/fr/docs/deployment/index.md
@@ -1,28 +1,23 @@
-# Déploiement
+# Déploiement { #deployment }
Le déploiement d'une application **FastAPI** est relativement simple.
-## Que signifie le déploiement
+## Que signifie le déploiement { #what-does-deployment-mean }
-**Déployer** une application signifie effectuer les étapes nécessaires pour la rendre **disponible pour les
-utilisateurs**.
+**Déployer** une application signifie effectuer les étapes nécessaires pour la rendre **disponible pour les utilisateurs**.
-Pour une **API Web**, cela implique normalement de la placer sur une **machine distante**, avec un **programme serveur**
-qui offre de bonnes performances, une bonne stabilité, _etc._, afin que vos **utilisateurs** puissent **accéder** à
-l'application efficacement et sans interruption ni problème.
+Pour une **API Web**, cela implique normalement de la placer sur une **machine distante**, avec un **programme serveur** qui offre de bonnes performances, une bonne stabilité, etc, afin que vos **utilisateurs** puissent **accéder** à l'application efficacement et sans interruption ni problème.
-Ceci contraste avec les étapes de **développement**, où vous êtes constamment en train de modifier le code, de le casser
-et de le réparer, d'arrêter et de redémarrer le serveur de développement, _etc._
+Ceci contraste avec les étapes de **développement**, où vous êtes constamment en train de modifier le code, de le casser et de le réparer, d'arrêter et de redémarrer le serveur de développement, etc.
-## Stratégies de déploiement
+## Stratégies de déploiement { #deployment-strategies }
-Il existe plusieurs façons de procéder, en fonction de votre cas d'utilisation spécifique et des outils que vous
-utilisez.
+Il existe plusieurs façons de procéder, en fonction de votre cas d'utilisation spécifique et des outils que vous utilisez.
-Vous pouvez **déployer un serveur** vous-même en utilisant une combinaison d'outils, vous pouvez utiliser un **service
-cloud** qui fait une partie du travail pour vous, ou encore d'autres options possibles.
+Vous pouvez **déployer un serveur** vous-même en utilisant une combinaison d'outils, vous pouvez utiliser un **service cloud** qui fait une partie du travail pour vous, ou encore d'autres options possibles.
-Je vais vous montrer certains des principaux concepts que vous devriez probablement avoir à l'esprit lors du déploiement
-d'une application **FastAPI** (bien que la plupart de ces concepts s'appliquent à tout autre type d'application web).
+Par exemple, nous, l'équipe derrière FastAPI, avons créé **FastAPI Cloud**, afin de rendre le déploiement d'apps FastAPI sur le cloud aussi rationalisé que possible, avec la même expérience développeur que celle du travail avec FastAPI.
+
+Je vais vous montrer certains des principaux concepts que vous devriez probablement avoir à l'esprit lors du déploiement d'une application **FastAPI** (bien que la plupart de ces concepts s'appliquent à tout autre type d'application web).
Vous verrez plus de détails à avoir en tête et certaines des techniques pour le faire dans les sections suivantes. ✨
diff --git a/docs/fr/docs/deployment/versions.md b/docs/fr/docs/deployment/versions.md
index 9d84274e2..60bdc5978 100644
--- a/docs/fr/docs/deployment/versions.md
+++ b/docs/fr/docs/deployment/versions.md
@@ -1,85 +1,78 @@
-# À propos des versions de FastAPI
+# À propos des versions de FastAPI { #about-fastapi-versions }
-**FastAPI** est déjà utilisé en production dans de nombreuses applications et systèmes. Et la couverture de test est maintenue à 100 %. Mais son développement est toujours aussi rapide.
+**FastAPI** est déjà utilisé en production dans de nombreuses applications et systèmes. Et la couverture de test est maintenue à 100 %. Mais son développement avance toujours rapidement.
-De nouvelles fonctionnalités sont ajoutées fréquemment, des bogues sont corrigés régulièrement et le code est
-amélioré continuellement.
+De nouvelles fonctionnalités sont ajoutées fréquemment, des bogues sont corrigés régulièrement, et le code continue de s’améliorer en continu.
-C'est pourquoi les versions actuelles sont toujours `0.x.x`, cela reflète que chaque version peut potentiellement
-recevoir des changements non rétrocompatibles. Cela suit les conventions de versionnage sémantique.
+C’est pourquoi les versions actuelles sont toujours `0.x.x`, cela reflète que chaque version peut potentiellement introduire des changements incompatibles. Cela suit les conventions du Semantic Versioning.
-Vous pouvez créer des applications de production avec **FastAPI** dès maintenant (et vous le faites probablement depuis un certain temps), vous devez juste vous assurer que vous utilisez une version qui fonctionne correctement avec le reste de votre code.
+Vous pouvez créer des applications de production avec **FastAPI** dès maintenant (et vous le faites probablement depuis un certain temps), vous devez simplement vous assurer que vous utilisez une version qui fonctionne correctement avec le reste de votre code.
-## Épinglez votre version de `fastapi`
+## Épinglez votre version de `fastapi` { #pin-your-fastapi-version }
-Tout d'abord il faut "épingler" la version de **FastAPI** que vous utilisez à la dernière version dont vous savez
-qu'elle fonctionne correctement pour votre application.
+La première chose que vous devez faire est d’« épingler » la version de **FastAPI** que vous utilisez à la version spécifique la plus récente dont vous savez qu’elle fonctionne correctement pour votre application.
-Par exemple, disons que vous utilisez la version `0.45.0` dans votre application.
+Par exemple, disons que vous utilisez la version `0.112.0` dans votre app.
-Si vous utilisez un fichier `requirements.txt`, vous pouvez spécifier la version avec :
+Si vous utilisez un fichier `requirements.txt`, vous pouvez spécifier la version avec :
```txt
-fastapi==0.45.0
+fastapi[standard]==0.112.0
```
-ce qui signifierait que vous utiliseriez exactement la version `0.45.0`.
+cela signifierait que vous utiliseriez exactement la version `0.112.0`.
-Ou vous pourriez aussi l'épingler avec :
+Ou vous pourriez aussi l’épingler avec :
```txt
-fastapi>=0.45.0,<0.46.0
+fastapi[standard]>=0.112.0,<0.113.0
```
-cela signifierait que vous utiliseriez les versions `0.45.0` ou supérieures, mais inférieures à `0.46.0`, par exemple, une version `0.45.2` serait toujours acceptée.
+cela signifierait que vous utiliseriez les versions `0.112.0` ou supérieures, mais inférieures à `0.113.0`, par exemple, une version `0.112.2` serait toujours acceptée.
-Si vous utilisez un autre outil pour gérer vos installations, comme Poetry, Pipenv, ou autres, ils ont tous un moyen que vous pouvez utiliser pour définir des versions spécifiques pour vos paquets.
+Si vous utilisez un autre outil pour gérer vos installations, comme `uv`, Poetry, Pipenv, ou autres, ils ont tous un moyen que vous pouvez utiliser pour définir des versions spécifiques pour vos paquets.
-## Versions disponibles
+## Versions disponibles { #available-versions }
-Vous pouvez consulter les versions disponibles (par exemple, pour vérifier quelle est la dernière version en date) dans les [Notes de version](../release-notes.md){.internal-link target=_blank}.
+Vous pouvez consulter les versions disponibles (p. ex. pour vérifier quelle est la dernière version actuelle) dans les [Notes de version](../release-notes.md){.internal-link target=_blank}.
-## À propos des versions
+## À propos des versions { #about-versions }
-Suivant les conventions de versionnage sémantique, toute version inférieure à `1.0.0` peut potentiellement ajouter
-des changements non rétrocompatibles.
+En suivant les conventions du Semantic Versioning, toute version inférieure à `1.0.0` peut potentiellement ajouter des changements incompatibles.
-FastAPI suit également la convention que tout changement de version "PATCH" est pour des corrections de bogues et
-des changements rétrocompatibles.
+FastAPI suit également la convention selon laquelle tout changement de version « PATCH » concerne des corrections de bogues et des changements compatibles.
/// tip | Astuce
-Le "PATCH" est le dernier chiffre, par exemple, dans `0.2.3`, la version PATCH est `3`.
+Le « PATCH » est le dernier chiffre, par exemple, dans `0.2.3`, la version PATCH est `3`.
///
-Donc, vous devriez être capable d'épingler une version comme suit :
+Ainsi, vous devriez pouvoir épingler une version comme suit :
```txt
fastapi>=0.45.0,<0.46.0
```
-Les changements non rétrocompatibles et les nouvelles fonctionnalités sont ajoutés dans les versions "MINOR".
+Les changements incompatibles et les nouvelles fonctionnalités sont ajoutés dans les versions « MINOR ».
/// tip | Astuce
-Le "MINOR" est le numéro au milieu, par exemple, dans `0.2.3`, la version MINOR est `2`.
+Le « MINOR » est le numéro au milieu, par exemple, dans `0.2.3`, la version MINOR est `2`.
///
-## Mise à jour des versions FastAPI
+## Mettre à niveau les versions de FastAPI { #upgrading-the-fastapi-versions }
-Vous devriez tester votre application.
+Vous devez ajouter des tests pour votre app.
-Avec **FastAPI** c'est très facile (merci à Starlette), consultez la documentation : [Testing](../tutorial/testing.md){.internal-link target=_blank}
+Avec **FastAPI**, c’est très facile (grâce à Starlette), consultez la documentation : [Testing](../tutorial/testing.md){.internal-link target=_blank}
-Après avoir effectué des tests, vous pouvez mettre à jour la version **FastAPI** vers une version plus récente, et vous assurer que tout votre code fonctionne correctement en exécutant vos tests.
+Après avoir des tests, vous pouvez alors mettre à niveau la version de **FastAPI** vers une version plus récente, et vous assurer que tout votre code fonctionne correctement en exécutant vos tests.
-Si tout fonctionne, ou après avoir fait les changements nécessaires, et que tous vos tests passent, vous pouvez
-épingler votre version de `fastapi` à cette nouvelle version récente.
+Si tout fonctionne, ou après avoir effectué les changements nécessaires, et que tous vos tests passent, vous pouvez alors épingler votre `fastapi` à cette nouvelle version récente.
-## À propos de Starlette
+## À propos de Starlette { #about-starlette }
Vous ne devriez pas épingler la version de `starlette`.
@@ -87,15 +80,14 @@ Différentes versions de **FastAPI** utiliseront une version spécifique plus r
Ainsi, vous pouvez simplement laisser **FastAPI** utiliser la bonne version de Starlette.
-## À propos de Pydantic
+## À propos de Pydantic { #about-pydantic }
-Pydantic inclut des tests pour **FastAPI** avec ses propres tests, ainsi les nouvelles versions de Pydantic (au-dessus
-de `1.0.0`) sont toujours compatibles avec **FastAPI**.
+Pydantic inclut les tests pour **FastAPI** avec ses propres tests, ainsi les nouvelles versions de Pydantic (au-dessus de `1.0.0`) sont toujours compatibles avec FastAPI.
-Vous pouvez épingler Pydantic à toute version supérieure à `1.0.0` qui fonctionne pour vous et inférieure à `2.0.0`.
+Vous pouvez épingler Pydantic à toute version supérieure à `1.0.0` qui fonctionne pour vous.
-Par exemple :
+Par exemple :
```txt
-pydantic>=1.2.0,<2.0.0
+pydantic>=2.7.0,<3.0.0
```
diff --git a/docs/fr/docs/index.md b/docs/fr/docs/index.md
index 99ea8dda1..53b73bbc2 100644
--- a/docs/fr/docs/index.md
+++ b/docs/fr/docs/index.md
@@ -1,4 +1,4 @@
-# FastAPI
+# FastAPI { #fastapi }