FastAPI¶
Framework FastAPI, haute performance, facile à apprendre, rapide à coder, prêt pour la production
Documentation : https://fastapi.tiangolo.com
Code Source : https://github.com/fastapi/fastapi
FastAPI est un framework web moderne et rapide (haute performance) pour la création d'API avec Python, basé sur les annotations de type standard de Python.
Les principales fonctionnalités sont :
- Rapidité : De très hautes performances, au niveau de NodeJS et Go (grâce à Starlette et Pydantic). L'un des frameworks Python les plus rapides.
- Rapide à coder : Augmente la vitesse de développement des fonctionnalités d'environ 200 % à 300 %. *
- Moins de bugs : Réduit d'environ 40 % les erreurs induites par le développeur. *
- Intuitif : Excellente compatibilité avec les IDE. Complétion complète. Moins de temps passé à déboguer.
- Facile : Conçu pour être facile à utiliser et à apprendre. Moins de temps passé à lire la documentation.
- Concis : Diminue la duplication de code. De nombreuses fonctionnalités liées à la déclaration de chaque paramètre. Moins de bugs.
- Robuste : Obtenez un code prêt pour la production. Avec une documentation interactive automatique.
- Basé sur des normes : Basé sur (et entièrement compatible avec) les standards ouverts pour les APIs : OpenAPI (précédemment connu sous le nom de Swagger) et JSON Schema.
* estimation basée sur des tests d'une équipe de développement interne, construisant des applications de production.
Sponsors¶
Opinions¶
"[...] J'utilise beaucoup FastAPI ces derniers temps. [...] Je prévois de l'utiliser dans mon équipe pour tous les services de ML chez Microsoft. Certains d'entre eux seront intégrés dans le coeur de Windows et dans certains produits Office."
"Nous avons adopté la bibliothèque FastAPI pour créer un serveur REST qui peut être interrogé pour obtenir des prédictions. [pour Ludwig]"
"Netflix a le plaisir d'annoncer la sortie en open-source de notre framework d'orchestration de gestion de crise : Dispatch ! [construit avec FastAPI]"
"Je suis très enthousiaste à propos de FastAPI. C'est un bonheur !"
"Honnêtement, ce que vous avez construit a l'air super solide et élégant. A bien des égards, c'est comme ça que je voulais que Hug soit - c'est vraiment inspirant de voir quelqu'un construire ça."
"Si vous cherchez à apprendre un framework moderne pour créer des APIs REST, regardez FastAPI [...] C'est rapide, facile à utiliser et à apprendre [...]"
"Nous sommes passés à FastAPI pour nos APIs [...] Je pense que vous l'aimerez [...]"
"Si quelqu'un cherche à construire une API Python de production, je recommande vivement FastAPI. Il est bien conçu, simple à utiliser et très évolutif. Il est devenu un composant clé dans notre stratégie de développement API first et il est à l'origine de nombreux automatismes et services tels que notre ingénieur virtuel TAC."
Typer, le FastAPI des CLI¶
Si vous souhaitez construire une application CLI utilisable dans un terminal au lieu d'une API web, regardez Typer.
Typer est le petit frère de FastAPI. Et il est destiné à être le FastAPI des CLI. ⌨️ 🚀
Prérequis¶
FastAPI repose sur les épaules de géants :
Installation¶
$ pip install fastapi
---> 100%
Vous aurez également besoin d'un serveur ASGI pour la production tel que Uvicorn ou Hypercorn.
$ pip install "uvicorn[standard]"
---> 100%
Exemple¶
Créez¶
- Créez un fichier
main.py
avec :
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
Ou utilisez async def
...
Si votre code utilise async
/ await
, utilisez async def
:
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
Note
Si vous n'êtes pas familier avec cette notion, consultez la section "Vous êtes pressés ?" à propos de async
et await
dans la documentation.
Lancez¶
Lancez le serveur avec :
$ uvicorn main:app --reload
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [28720]
INFO: Started server process [28722]
INFO: Waiting for application startup.
INFO: Application startup complete.
À propos de la commande uvicorn main:app --reload
...
La commande uvicorn main:app
fait référence à :
main
: le fichiermain.py
(le "module" Python).app
: l'objet créé à l'intérieur demain.py
avec la ligneapp = FastAPI()
.--reload
: fait redémarrer le serveur après des changements de code. À n'utiliser que pour le développement.
Vérifiez¶
Ouvrez votre navigateur à l'adresse http://127.0.0.1:8000/items/5?q=somequery.
Vous obtenez alors cette réponse JSON :
{"item_id": 5, "q": "somequery"}
Vous venez de créer une API qui :
- Reçoit les requêtes HTTP pour les chemins
/
et/items/{item_id}
. - Les deux chemins acceptent des opérations
GET
(également connu sous le nom de méthodes HTTP). - Le chemin
/items/{item_id}
a un paramètreitem_id
qui doit être unint
. - Le chemin
/items/{item_id}
a un paramètre de requête optionnelq
de typestr
.
Documentation API interactive¶
Maintenant, rendez-vous sur http://127.0.0.1:8000/docs.
Vous verrez la documentation interactive automatique de l'API (fournie par Swagger UI) :
Documentation API alternative¶
Et maintenant, rendez-vous sur http://127.0.0.1:8000/redoc.
Vous verrez la documentation interactive automatique de l'API (fournie par ReDoc) :
Exemple plus poussé¶
Maintenant, modifiez le fichier main.py
pour recevoir le corps d'une requête PUT
.
Déclarez ce corps en utilisant les types Python standards, grâce à Pydantic.
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: Union[bool, None] = None
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
return {"item_name": item.name, "item_id": item_id}
Le serveur se recharge normalement automatiquement (car vous avez pensé à --reload
dans la commande uvicorn
ci-dessus).
Plus loin avec la documentation API interactive¶
Maintenant, rendez-vous sur http://127.0.0.1:8000/docs.
- La documentation interactive de l'API sera automatiquement mise à jour, y compris le nouveau corps de la requête :
- Cliquez sur le bouton "Try it out", il vous permet de renseigner les paramètres et d'interagir directement avec l'API :
- Cliquez ensuite sur le bouton "Execute", l'interface utilisateur communiquera avec votre API, enverra les paramètres, obtiendra les résultats et les affichera à l'écran :
Plus loin avec la documentation API alternative¶
Et maintenant, rendez-vous sur http://127.0.0.1:8000/redoc.
- La documentation alternative reflétera également le nouveau paramètre de requête et le nouveau corps :
En résumé¶
En résumé, vous déclarez une fois les types de paramètres, le corps de la requête, etc. en tant que paramètres de fonction.
Vous faites cela avec les types Python standard modernes.
Vous n'avez pas à apprendre une nouvelle syntaxe, les méthodes ou les classes d'une bibliothèque spécifique, etc.
Juste du Python standard.
Par exemple, pour un int
:
item_id: int
ou pour un modèle Item
plus complexe :
item: Item
... et avec cette déclaration unique, vous obtenez :
- Une assistance dans votre IDE, notamment :
- la complétion.
- la vérification des types.
- La validation des données :
- des erreurs automatiques et claires lorsque les données ne sont pas valides.
- une validation même pour les objets JSON profondément imbriqués.
- Une conversion des données d'entrée : venant du réseau et allant vers les données et types de Python, permettant de lire :
- le JSON.
- les paramètres du chemin.
- les paramètres de la requête.
- les cookies.
- les en-têtes.
- les formulaires.
- les fichiers.
- La conversion des données de sortie : conversion des données et types Python en données réseau (au format JSON), permettant de convertir :
- les types Python (
str
,int
,float
,bool
,list
, etc). - les objets
datetime
. - les objets
UUID
. - les modèles de base de données.
- ... et beaucoup plus.
- les types Python (
- La documentation API interactive automatique, avec 2 interfaces utilisateur au choix :
- Swagger UI.
- ReDoc.
Pour revenir à l'exemple de code précédent, FastAPI permet de :
- Valider que
item_id
existe dans le chemin des requêtesGET
etPUT
. - Valider que
item_id
est de typeint
pour les requêtesGET
etPUT
.- Si ce n'est pas le cas, le client voit une erreur utile et claire.
- Vérifier qu'il existe un paramètre de requête facultatif nommé
q
(comme danshttp://127.0.0.1:8000/items/foo?q=somequery
) pour les requêtesGET
.- Puisque le paramètre
q
est déclaré avec= None
, il est facultatif. - Sans le
None
, il serait nécessaire (comme l'est le corps de la requête dans le cas duPUT
).
- Puisque le paramètre
- Pour les requêtes
PUT
vers/items/{item_id}
, de lire le corps en JSON :- Vérifier qu'il a un attribut obligatoire
name
qui devrait être unstr
. - Vérifier qu'il a un attribut obligatoire
prix
qui doit être unfloat
. - Vérifier qu'il a un attribut facultatif
is_offer
, qui devrait être unbool
, s'il est présent. - Tout cela fonctionnerait également pour les objets JSON profondément imbriqués.
- Vérifier qu'il a un attribut obligatoire
- Convertir de et vers JSON automatiquement.
- Documenter tout avec OpenAPI, qui peut être utilisé par :
- Les systèmes de documentation interactifs.
- Les systèmes de génération automatique de code client, pour de nombreuses langues.
- Fournir directement 2 interfaces web de documentation interactive.
Nous n'avons fait qu'effleurer la surface, mais vous avez déjà une idée de la façon dont tout cela fonctionne.
Essayez de changer la ligne contenant :
return {"item_name": item.name, "item_id": item_id}
... de :
... "item_name": item.name ...
... vers :
... "item_price": item.price ...
... et voyez comment votre éditeur complétera automatiquement les attributs et connaîtra leurs types :
Pour un exemple plus complet comprenant plus de fonctionnalités, voir le Tutoriel - Guide utilisateur.
Spoiler alert : le tutoriel - guide utilisateur inclut :
- Déclaration de paramètres provenant d'autres endroits différents comme : en-têtes., cookies, champs de formulaire et fichiers.
- L'utilisation de contraintes de validation comme
maximum_length
ouregex
. - Un système d'injection de dépendance très puissant et facile à utiliser .
- Sécurité et authentification, y compris la prise en charge de OAuth2 avec les jetons JWT et l'authentification HTTP Basic.
- Des techniques plus avancées (mais tout aussi faciles) pour déclarer les modèles JSON profondément imbriqués (grâce à Pydantic).
- Intégration de GraphQL avec Strawberry et d'autres bibliothèques.
- D'obtenir de nombreuses fonctionnalités supplémentaires (grâce à Starlette) comme :
- WebSockets
- de tester le code très facilement avec
requests
etpytest
- CORS
- Cookie Sessions
- ... et plus encore.
Performance¶
Les benchmarks TechEmpower indépendants montrent que les applications FastAPI s'exécutant sous Uvicorn sont parmi les frameworks existants en Python les plus rapides , juste derrière Starlette et Uvicorn (utilisés en interne par FastAPI). (*)
Pour en savoir plus, consultez la section Benchmarks.
Dépendances facultatives¶
Utilisées par Pydantic:
email-validator
- pour la validation des adresses email.
Utilisées par Starlette :
requests
- Obligatoire si vous souhaitez utiliserTestClient
.jinja2
- Obligatoire si vous souhaitez utiliser la configuration de template par défaut.python-multipart
- Obligatoire si vous souhaitez supporter le "décodage" de formulaire avecrequest.form()
.itsdangerous
- Obligatoire pour la prise en charge deSessionMiddleware
.pyyaml
- Obligatoire pour le supportSchemaGenerator
de Starlette (vous n'en avez probablement pas besoin avec FastAPI).
Utilisées par FastAPI / Starlette :
uvicorn
- Pour le serveur qui charge et sert votre application.orjson
- Obligatoire si vous voulez utiliserORJSONResponse
.ujson
- Obligatoire si vous souhaitez utiliserUJSONResponse
.
Vous pouvez tout installer avec pip install fastapi[all]
.
Licence¶
Ce projet est soumis aux termes de la licence MIT.