fastapi/docs/fr/docs/tutorial/query-params-str-validation...

474 lines
19 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Paramètres de requête et validations de chaînes de caractères { #query-parameters-and-string-validations }
**FastAPI** vous permet de déclarer des informations et des validations supplémentaires pour vos paramètres.
Prenons cette application comme exemple :
{* ../../docs_src/query_params_str_validations/tutorial001_py310.py hl[7] *}
Le paramètre de requête `q` est de type `str | None`, cela signifie quil est de type `str` mais peut aussi être `None`, et en effet, la valeur par défaut est `None`, donc FastAPI saura quil nest pas requis.
/// note | Remarque
FastAPI saura que la valeur de `q` nest pas requise grâce à la valeur par défaut `= None`.
Avoir `str | None` permettra à votre éditeur de vous offrir un meilleur support et de détecter les erreurs.
///
## Validation additionnelle { #additional-validation }
Nous allons imposer que, même si `q` est optionnel, dès quil est fourni, **sa longueur nexcède pas 50 caractères**.
### Importer `Query` et `Annotated` { #import-query-and-annotated }
Pour ce faire, importez dabord :
- `Query` depuis `fastapi`
- `Annotated` depuis `typing`
{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[1,3] *}
/// info
FastAPI a ajouté la prise en charge de `Annotated` (et a commencé à le recommander) dans la version 0.95.0.
Si vous avez une version plus ancienne, vous obtiendrez des erreurs en essayant dutiliser `Annotated`.
Assurez-vous de [mettre à niveau la version de FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} vers au moins 0.95.1 avant dutiliser `Annotated`.
///
## Utiliser `Annotated` dans le type pour le paramètre `q` { #use-annotated-in-the-type-for-the-q-parameter }
Vous vous souvenez que je vous ai dit plus tôt que `Annotated` peut être utilisé pour ajouter des métadonnées à vos paramètres dans l[Introduction aux types Python](../python-types.md#type-hints-with-metadata-annotations){.internal-link target=_blank} ?
Cest le moment de lutiliser avec FastAPI. 🚀
Nous avions cette annotation de type :
//// tab | Python 3.10+
```Python
q: str | None = None
```
////
//// tab | Python 3.9+
```Python
q: Union[str, None] = None
```
////
Ce que nous allons faire, cest lenglober avec `Annotated`, de sorte que cela devienne :
//// tab | Python 3.10+
```Python
q: Annotated[str | None] = None
```
////
//// tab | Python 3.9+
```Python
q: Annotated[Union[str, None]] = None
```
////
Les deux versions signifient la même chose, `q` est un paramètre qui peut être une `str` ou `None`, et par défaut, cest `None`.
Passons maintenant aux choses amusantes. 🎉
## Ajouter `Query` à `Annotated` dans le paramètre `q` { #add-query-to-annotated-in-the-q-parameter }
Maintenant que nous avons cet `Annotated` dans lequel nous pouvons mettre plus dinformations (dans ce cas une validation supplémentaire), ajoutez `Query` à lintérieur de `Annotated`, et définissez le paramètre `max_length` à `50` :
{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[9] *}
Remarquez que la valeur par défaut est toujours `None`, donc le paramètre est toujours optionnel.
Mais maintenant, avec `Query(max_length=50)` à lintérieur de `Annotated`, nous indiquons à FastAPI que nous voulons **une validation supplémentaire** pour cette valeur, nous voulons quelle ait au maximum 50 caractères. 😎
/// tip | Astuce
Ici nous utilisons `Query()` parce quil sagit dun **paramètre de requête**. Plus tard nous verrons dautres comme `Path()`, `Body()`, `Header()` et `Cookie()`, qui acceptent également les mêmes arguments que `Query()`.
///
FastAPI va maintenant :
- **Valider** les données en sassurant que la longueur maximale est de 50 caractères
- Afficher une **erreur claire** au client quand les données ne sont pas valides
- **Documenter** le paramètre dans la *chemin d'accès* du schéma OpenAPI (il apparaîtra donc dans l**interface de documentation automatique**)
## Alternative (ancienne) : `Query` comme valeur par défaut { #alternative-old-query-as-the-default-value }
Les versions précédentes de FastAPI (avant <abbr title="avant 2023-03">0.95.0</abbr>) exigeaient dutiliser `Query` comme valeur par défaut de votre paramètre, au lieu de le mettre dans `Annotated`. Il y a de fortes chances que vous voyiez du code qui lutilise encore, je vais donc vous lexpliquer.
/// tip | Astuce
Pour du nouveau code et dès que possible, utilisez `Annotated` comme expliqué ci-dessus. Il y a de multiples avantages (expliqués ci-dessous) et aucun inconvénient. 🍰
///
Voici comment vous utiliseriez `Query()` comme valeur par défaut du paramètre de votre fonction, en définissant le paramètre `max_length` à 50 :
{* ../../docs_src/query_params_str_validations/tutorial002_py310.py hl[7] *}
Comme, dans ce cas (sans utiliser `Annotated`), nous devons remplacer la valeur par défaut `None` dans la fonction par `Query()`, nous devons maintenant définir la valeur par défaut avec le paramètre `Query(default=None)`, cela sert le même objectif de définir cette valeur par défaut (au moins pour FastAPI).
Donc :
```Python
q: str | None = Query(default=None)
```
... rend le paramètre optionnel, avec une valeur par défaut de `None`, comme :
```Python
q: str | None = None
```
Mais la version avec `Query` le déclare explicitement comme étant un paramètre de requête.
Ensuite, nous pouvons passer plus de paramètres à `Query`. Dans ce cas, le paramètre `max_length` qui sapplique aux chaînes de caractères :
```Python
q: str | None = Query(default=None, max_length=50)
```
Cela validera les données, affichera une erreur claire lorsque les données ne sont pas valides et documentera le paramètre dans la *chemin d'accès* du schéma OpenAPI.
### `Query` comme valeur par défaut ou dans `Annotated` { #query-as-the-default-value-or-in-annotated }
Gardez à lesprit quen utilisant `Query` à lintérieur de `Annotated`, vous ne pouvez pas utiliser le paramètre `default` de `Query`.
Utilisez à la place la valeur par défaut réelle du paramètre de fonction. Sinon, ce serait incohérent.
Par exemple, ceci nest pas autorisé :
```Python
q: Annotated[str, Query(default="rick")] = "morty"
```
... parce quil nest pas clair si la valeur par défaut doit être « rick » ou « morty ».
Donc, vous utiliseriez (de préférence) :
```Python
q: Annotated[str, Query()] = "rick"
```
... ou dans des bases de code plus anciennes, vous trouverez :
```Python
q: str = Query(default="rick")
```
### Avantages de `Annotated` { #advantages-of-annotated }
**Lutilisation de `Annotated` est recommandée** plutôt que la valeur par défaut dans les paramètres de fonction, cest **mieux** pour plusieurs raisons. 🤓
La valeur **par défaut** du **paramètre de fonction** est la **vraie valeur par défaut**, cest plus intuitif en Python en général. 😌
Vous pouvez **appeler** cette même fonction dans **dautres endroits** sans FastAPI, et elle **fonctionnera comme prévu**. Sil y a un paramètre **requis** (sans valeur par défaut), votre **éditeur** vous le signalera avec une erreur, **Python** se plaindra aussi si vous lexécutez sans passer le paramètre requis.
Quand vous nutilisez pas `Annotated` et utilisez à la place l**ancienne** méthode avec la **valeur par défaut**, si vous appelez cette fonction sans FastAPI dans **dautres endroits**, vous devez **penser** à passer les arguments à la fonction pour quelle fonctionne correctement, sinon les valeurs seront différentes de ce que vous attendez (par ex. `QueryInfo` ou quelque chose de similaire au lieu dune `str`). Et votre éditeur ne se plaindra pas, et Python ne se plaindra pas en exécutant cette fonction, seulement quand les opérations internes échoueront.
Comme `Annotated` peut avoir plus dune annotation de métadonnées, vous pouvez maintenant même utiliser la même fonction avec dautres outils, comme <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">Typer</a>. 🚀
## Ajouter plus de validations { #add-more-validations }
Vous pouvez également ajouter un paramètre `min_length` :
{* ../../docs_src/query_params_str_validations/tutorial003_an_py310.py hl[10] *}
## Ajouter des expressions régulières { #add-regular-expressions }
Vous pouvez définir un `pattern` d<abbr title="Une expression régulière, regex ou regexp, est une suite de caractères qui définit un motif de recherche pour les chaînes de caractères.">expression régulière</abbr> auquel le paramètre doit correspondre :
{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
Ce pattern dexpression régulière spécifique vérifie que la valeur reçue pour le paramètre :
- `^` : commence avec les caractères qui suivent, na pas de caractères avant.
- `fixedquery` : a exactement la valeur `fixedquery`.
- `$` : se termine là, na pas dautres caractères après `fixedquery`.
Si vous vous sentez perdu avec toutes ces idées d**« expression régulière »**, pas dinquiétude. Cest un sujet difficile pour beaucoup. Vous pouvez déjà faire beaucoup de choses sans avoir besoin dexpressions régulières.
Désormais, vous savez que, lorsque vous en aurez besoin, vous pourrez les utiliser dans **FastAPI**.
## Valeurs par défaut { #default-values }
Vous pouvez, bien sûr, utiliser des valeurs par défaut autres que `None`.
Disons que vous voulez déclarer le paramètre de requête `q` avec un `min_length` de `3`, et avec une valeur par défaut de « fixedquery » :
{* ../../docs_src/query_params_str_validations/tutorial005_an_py39.py hl[9] *}
/// note | Remarque
Avoir une valeur par défaut de nimporte quel type, y compris `None`, rend le paramètre optionnel (non requis).
///
## Paramètres requis { #required-parameters }
Quand nous navons pas besoin de déclarer plus de validations ou de métadonnées, nous pouvons rendre le paramètre de requête `q` requis en nindiquant simplement pas de valeur par défaut, comme :
```Python
q: str
```
au lieu de :
```Python
q: str | None = None
```
Mais maintenant nous le déclarons avec `Query`, par exemple ainsi :
```Python
q: Annotated[str | None, Query(min_length=3)] = None
```
Donc, lorsque vous avez besoin de déclarer une valeur comme requise tout en utilisant `Query`, vous pouvez simplement ne pas déclarer de valeur par défaut :
{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
### Requis, peut valoir `None` { #required-can-be-none }
Vous pouvez déclarer quun paramètre accepte `None`, mais quil est tout de même requis. Cela obligerait les clients à envoyer une valeur, même si la valeur est `None`.
Pour ce faire, vous pouvez déclarer que `None` est un type valide tout en ne déclarant pas de valeur par défaut :
{* ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py hl[9] *}
## Liste de paramètres de requête / valeurs multiples { #query-parameter-list-multiple-values }
Quand vous définissez un paramètre de requête explicitement avec `Query`, vous pouvez aussi déclarer quil reçoit une liste de valeurs, autrement dit, quil reçoit des valeurs multiples.
Par exemple, pour déclarer un paramètre de requête `q` qui peut apparaître plusieurs fois dans lURL, vous pouvez écrire :
{* ../../docs_src/query_params_str_validations/tutorial011_an_py310.py hl[9] *}
Ensuite, avec une URL comme :
```
http://localhost:8000/items/?q=foo&q=bar
```
vous recevriez les valeurs des multiples paramètres de requête `q` (`foo` et `bar`) dans une `list` Python à lintérieur de votre fonction de *chemin d'accès*, dans le *paramètre de fonction* `q`.
Donc, la réponse pour cette URL serait :
```JSON
{
"q": [
"foo",
"bar"
]
}
```
/// tip | Astuce
Pour déclarer un paramètre de requête avec un type `list`, comme dans lexemple ci-dessus, vous devez explicitement utiliser `Query`, sinon il serait interprété comme faisant partie du corps de la requête.
///
Linterface de documentation interactive de lAPI sera mise à jour en conséquence, pour autoriser plusieurs valeurs :
<img src="/img/tutorial/query-params-str-validations/image02.png">
### Liste de paramètres de requête / valeurs multiples avec valeurs par défaut { #query-parameter-list-multiple-values-with-defaults }
Vous pouvez également définir une `list` de valeurs par défaut si aucune nest fournie :
{* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *}
Si vous allez à :
```
http://localhost:8000/items/
```
la valeur par défaut de `q` sera : `["foo", "bar"]` et votre réponse sera :
```JSON
{
"q": [
"foo",
"bar"
]
}
```
#### Utiliser simplement `list` { #using-just-list }
Vous pouvez aussi utiliser `list` directement au lieu de `list[str]` :
{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
/// note | Remarque
Gardez à lesprit que dans ce cas, FastAPI ne vérifiera pas le contenu de la liste.
Par exemple, `list[int]` vérifierait (et documenterait) que le contenu de la liste est composé dentiers. Mais un simple `list` ne le ferait pas.
///
## Déclarer plus de métadonnées { #declare-more-metadata }
Vous pouvez ajouter plus dinformations à propos du paramètre.
Ces informations seront incluses dans lOpenAPI généré et utilisées par les interfaces de documentation et les outils externes.
/// note | Remarque
Gardez à lesprit que différents outils peuvent avoir des niveaux de prise en charge dOpenAPI différents.
Certains dentre eux pourraient ne pas encore afficher toutes les informations supplémentaires déclarées, bien que, dans la plupart des cas, la fonctionnalité manquante soit déjà prévue au développement.
///
Vous pouvez ajouter un `title` :
{* ../../docs_src/query_params_str_validations/tutorial007_an_py310.py hl[10] *}
Et une `description` :
{* ../../docs_src/query_params_str_validations/tutorial008_an_py310.py hl[14] *}
## Paramètres avec alias { #alias-parameters }
Imaginez que vous vouliez que le paramètre soit `item-query`.
Comme dans :
```
http://127.0.0.1:8000/items/?item-query=foobaritems
```
Mais `item-query` nest pas un nom de variable Python valide.
Le plus proche serait `item_query`.
Mais vous avez quand même besoin que ce soit exactement `item-query` ...
Vous pouvez alors déclarer un `alias`, et cet alias sera utilisé pour trouver la valeur du paramètre :
{* ../../docs_src/query_params_str_validations/tutorial009_an_py310.py hl[9] *}
## Déprécier des paramètres { #deprecating-parameters }
Disons que vous naimez plus ce paramètre.
Vous devez le laisser là quelque temps car des clients lutilisent, mais vous voulez que les documents laffichent clairement comme <abbr title="obsolète, recommandé de ne pas lutiliser">déprécié</abbr>.
Passez alors le paramètre `deprecated=True` à `Query` :
{* ../../docs_src/query_params_str_validations/tutorial010_an_py310.py hl[19] *}
Les documents lafficheront ainsi :
<img src="/img/tutorial/query-params-str-validations/image01.png">
## Exclure des paramètres dOpenAPI { #exclude-parameters-from-openapi }
Pour exclure un paramètre de requête du schéma OpenAPI généré (et donc, des systèmes de documentation automatiques), définissez le paramètre `include_in_schema` de `Query` à `False` :
{* ../../docs_src/query_params_str_validations/tutorial014_an_py310.py hl[10] *}
## Validation personnalisée { #custom-validation }
Il peut y avoir des cas où vous devez faire une **validation personnalisée** qui ne peut pas être réalisée avec les paramètres montrés ci-dessus.
Dans ces cas, vous pouvez utiliser une **fonction de validation personnalisée** qui est appliquée après la validation normale (par ex. après avoir validé que la valeur est une `str`).
Vous pouvez y parvenir en utilisant <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator" class="external-link" target="_blank">`AfterValidator` de Pydantic</a> à lintérieur de `Annotated`.
/// tip | Astuce
Pydantic a aussi <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-before-validator" class="external-link" target="_blank">`BeforeValidator`</a> et dautres. 🤓
///
Par exemple, ce validateur personnalisé vérifie que lID ditem commence par `isbn-` pour un numéro de livre <abbr title="International Standard Book Number - Numéro international normalisé du livre">ISBN</abbr> ou par `imdb-` pour un ID dURL de film <abbr title="IMDB (Internet Movie Database) est un site web contenant des informations sur les films">IMDB</abbr> :
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
/// info
Cest disponible avec Pydantic version 2 ou supérieure. 😎
///
/// tip | Astuce
Si vous devez faire un type de validation qui nécessite de communiquer avec un **composant externe**, comme une base de données ou une autre API, vous devez plutôt utiliser les **Dépendances de FastAPI**, vous en apprendrez davantage plus tard.
Ces validateurs personnalisés sont destinés aux éléments qui peuvent être vérifiés **uniquement** avec les **mêmes données** fournies dans la requête.
///
### Comprendre ce code { #understand-that-code }
Le point important est simplement dutiliser **`AfterValidator` avec une fonction à lintérieur de `Annotated`**. Nhésitez pas à passer cette partie. 🤸
---
Mais si vous êtes curieux de cet exemple de code spécifique et que vous êtes toujours partant, voici quelques détails supplémentaires.
#### Chaîne avec `value.startswith()` { #string-with-value-startswith }
Avez-vous remarqué ? Une chaîne utilisant `value.startswith()` peut prendre un tuple, et elle vérifiera chaque valeur du tuple :
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[16:19] hl[17] *}
#### Un élément aléatoire { #a-random-item }
Avec `data.items()` nous obtenons un <abbr title="Quelque chose que lon peut itérer avec une boucle for, comme une liste, un set, etc.">objet itérable</abbr> avec des tuples contenant la clé et la valeur pour chaque élément du dictionnaire.
Nous convertissons cet objet itérable en une `list` propre avec `list(data.items())`.
Ensuite, avec `random.choice()` nous pouvons obtenir une **valeur aléatoire** depuis la liste, nous obtenons donc un tuple `(id, name)`. Ce sera quelque chose comme `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")`.
Puis nous **affectons ces deux valeurs** du tuple aux variables `id` et `name`.
Ainsi, si lutilisateur na pas fourni dID ditem, il recevra quand même une suggestion aléatoire.
... nous faisons tout cela en **une seule ligne simple**. 🤯 Vous nadorez pas Python ? 🐍
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[22:30] hl[29] *}
## Récapitulatif { #recap }
Vous pouvez déclarer des validations et des métadonnées supplémentaires pour vos paramètres.
Validations et métadonnées génériques :
- `alias`
- `title`
- `description`
- `deprecated`
Validations spécifiques aux chaînes :
- `min_length`
- `max_length`
- `pattern`
Validations personnalisées avec `AfterValidator`.
Dans ces exemples, vous avez vu comment déclarer des validations pour des valeurs `str`.
Voyez les prochains chapitres pour apprendre à déclarer des validations pour dautres types, comme les nombres.