Le paramètre de requête q a pour type Union[str, None] (ou str | None en Python 3.10), signifiant qu'il est de type str mais pourrait aussi être égal à None, et bien sûr, la valeur par défaut est None, donc FastAPI saura qu'il n'est pas requis.
Note
FastAPI saura que la valeur de q n'est pas requise grâce à la valeur par défaut = None.
Le Union dans Union[str, None] permettra à votre éditeur de vous offrir un meilleur support et de détecter les erreurs.
Comme nous devons remplacer la valeur par défaut None dans la fonction par Query(), nous pouvons maintenant définir la valeur par défaut avec le paramètre Query(default=None), il sert le même objectif qui est de définir cette valeur par défaut.
Donc :
q:Union[str,None]=Query(default=None)
... rend le paramètre optionnel, et est donc équivalent à :
q:Union[str,None]=None
Mais déclare explicitement q comme étant un paramètre de requête.
Info
Gardez à l'esprit que la partie la plus importante pour rendre un paramètre optionnel est :
=None
ou :
=Query(None)
et utilisera ce None pour détecter que ce paramètre de requête n'est pas requis.
Le Union[str, None] est uniquement là pour permettre à votre éditeur un meilleur support.
Ensuite, nous pouvons passer d'autres paramètres à Query. Dans cet exemple, le paramètre max_length qui s'applique aux chaînes de caractères :
Cela va valider les données, montrer une erreur claire si ces dernières ne sont pas valides, et documenter le paramètre dans le schéma OpenAPI de cette path operation.
Cette expression régulière vérifie que la valeur passée comme paramètre :
^ : commence avec les caractères qui suivent, avec aucun caractère avant ceux-là.
fixedquery : a pour valeur exacte fixedquery.
$ : se termine directement ensuite, n'a pas d'autres caractères après fixedquery.
Si vous vous sentez perdu avec le concept d'expression régulière, pas d'inquiétudes. Il s'agit d'une notion difficile pour beaucoup, et l'on peut déjà réussir à faire beaucoup sans jamais avoir à les manipuler.
Mais si vous décidez d'apprendre à les utiliser, sachez qu'ensuite vous pouvez les utiliser directement dans FastAPI.
vous recevriez les valeurs des multiples paramètres de requête q (foo et bar) dans une list Python au sein de votre fonction de path operation, dans le paramètre de fonction q.
Donc la réponse de cette URL serait :
{"q":["foo","bar"]}
Astuce
Pour déclarer un paramètre de requête de type list, comme dans l'exemple ci-dessus, il faut explicitement utiliser Query, sinon cela sera interprété comme faisant partie du corps de la requête.
La documentation sera donc mise à jour automatiquement pour autoriser plusieurs valeurs :
Combiner liste de paramètres et valeurs par défaut¶
Et l'on peut aussi définir une liste de valeurs par défaut si aucune n'est fournie :
Dans ce cas-là, FastAPI ne vérifiera pas le contenu de la liste.
Par exemple, List[int] vérifiera (et documentera) que la liste est bien entièrement composée d'entiers. Alors qu'un simple list ne ferait pas cette vérification.
On peut aussi ajouter plus d'informations sur le paramètre.
Ces informations seront incluses dans le schéma OpenAPI généré et utilisées par la documentation interactive ou les outils externes utilisés.
Note
Gardez en tête que les outils externes utilisés ne supportent pas forcément tous parfaitement OpenAPI.
Il se peut donc que certains d'entre eux n'utilisent pas toutes les métadonnées que vous avez déclarées pour le moment, bien que dans la plupart des cas, les fonctionnalités manquantes ont prévu d'être implémentées.
fromtypingimportUnionfromfastapiimportFastAPI,Queryapp=FastAPI()@app.get("/items/")asyncdefread_items(q:Union[str,None]=Query(default=None,title="Query string",description="Query string for the items to search in the database that have a good match",min_length=3,),):results={"items":[{"item_id":"Foo"},{"item_id":"Bar"}]}ifq:results.update({"q":q})returnresults
🤓 Other versions and variants
fromtypingimportAnnotatedfromfastapiimportFastAPI,Queryapp=FastAPI()@app.get("/items/")asyncdefread_items(q:Annotated[str|None,Query(title="Query string",description="Query string for the items to search in the database that have a good match",min_length=3,),]=None,):results={"items":[{"item_id":"Foo"},{"item_id":"Bar"}]}ifq:results.update({"q":q})returnresults
fromtypingimportAnnotated,UnionfromfastapiimportFastAPI,Queryapp=FastAPI()@app.get("/items/")asyncdefread_items(q:Annotated[Union[str,None],Query(title="Query string",description="Query string for the items to search in the database that have a good match",min_length=3,),]=None,):results={"items":[{"item_id":"Foo"},{"item_id":"Bar"}]}ifq:results.update({"q":q})returnresults
fromtypingimportUnionfromfastapiimportFastAPI,Queryfromtyping_extensionsimportAnnotatedapp=FastAPI()@app.get("/items/")asyncdefread_items(q:Annotated[Union[str,None],Query(title="Query string",description="Query string for the items to search in the database that have a good match",min_length=3,),]=None,):results={"items":[{"item_id":"Foo"},{"item_id":"Bar"}]}ifq:results.update({"q":q})returnresults
Tip
Prefer to use the Annotated version if possible.
fromfastapiimportFastAPI,Queryapp=FastAPI()@app.get("/items/")asyncdefread_items(q:str|None=Query(default=None,title="Query string",description="Query string for the items to search in the database that have a good match",min_length=3,),):results={"items":[{"item_id":"Foo"},{"item_id":"Bar"}]}ifq:results.update({"q":q})returnresults
Disons que vous ne vouliez plus utiliser ce paramètre désormais.
Il faut qu'il continue à exister pendant un certain temps car vos clients l'utilisent, mais vous voulez que la documentation mentionne clairement que ce paramètre est déprécié.
On utilise alors l'argument deprecated=True de Query :
fromtypingimportUnionfromfastapiimportFastAPI,Queryapp=FastAPI()@app.get("/items/")asyncdefread_items(q:Union[str,None]=Query(default=None,alias="item-query",title="Query string",description="Query string for the items to search in the database that have a good match",min_length=3,max_length=50,pattern="^fixedquery$",deprecated=True,),):results={"items":[{"item_id":"Foo"},{"item_id":"Bar"}]}ifq:results.update({"q":q})returnresults
🤓 Other versions and variants
fromtypingimportAnnotatedfromfastapiimportFastAPI,Queryapp=FastAPI()@app.get("/items/")asyncdefread_items(q:Annotated[str|None,Query(alias="item-query",title="Query string",description="Query string for the items to search in the database that have a good match",min_length=3,max_length=50,pattern="^fixedquery$",deprecated=True,),]=None,):results={"items":[{"item_id":"Foo"},{"item_id":"Bar"}]}ifq:results.update({"q":q})returnresults
fromtypingimportAnnotated,UnionfromfastapiimportFastAPI,Queryapp=FastAPI()@app.get("/items/")asyncdefread_items(q:Annotated[Union[str,None],Query(alias="item-query",title="Query string",description="Query string for the items to search in the database that have a good match",min_length=3,max_length=50,pattern="^fixedquery$",deprecated=True,),]=None,):results={"items":[{"item_id":"Foo"},{"item_id":"Bar"}]}ifq:results.update({"q":q})returnresults
fromtypingimportUnionfromfastapiimportFastAPI,Queryfromtyping_extensionsimportAnnotatedapp=FastAPI()@app.get("/items/")asyncdefread_items(q:Annotated[Union[str,None],Query(alias="item-query",title="Query string",description="Query string for the items to search in the database that have a good match",min_length=3,max_length=50,pattern="^fixedquery$",deprecated=True,),]=None,):results={"items":[{"item_id":"Foo"},{"item_id":"Bar"}]}ifq:results.update({"q":q})returnresults
Tip
Prefer to use the Annotated version if possible.
fromfastapiimportFastAPI,Queryapp=FastAPI()@app.get("/items/")asyncdefread_items(q:str|None=Query(default=None,alias="item-query",title="Query string",description="Query string for the items to search in the database that have a good match",min_length=3,max_length=50,pattern="^fixedquery$",deprecated=True,),):results={"items":[{"item_id":"Foo"},{"item_id":"Bar"}]}ifq:results.update({"q":q})returnresults