Utilisez FastAPI pour créer des API Web – Real Python

By | juillet 14, 2021

Formation gratuite Python

Création d'API, ou interfaces de programmation d'applications, est un élément important pour rendre votre logiciel accessible à un large éventail d'utilisateurs. Dans ce tutoriel, vous apprendrez les principaux concepts de API rapide et comment l'utiliser pour créer rapidement des API Web qui implémentent les meilleures pratiques par défaut.

À la fin, vous serez en mesure de commencer à créer des API Web prêtes pour la production, et vous aurez la compréhension nécessaire pour approfondir et en savoir plus pour vos cas d'utilisation spécifiques.

Ce tutoriel est écrit par l'auteur de FastAPI. Il contient une sélection minutieuse de fragments de la documentation officielle, évitant de se perdre dans les détails techniques tout en vous aidant à être opérationnel le plus rapidement possible.

Qu'est-ce que FastAPI ?

FastAPI est un framework Web moderne et hautes performances permettant de créer des API avec Python sur la base d'indices de type standard. Il a les caractéristiques clés suivantes :

  • Rapide à courir: Il offre des performances très élevées, à égalité avec NodeJS et Va, merci à Starlette et pydantic.
  • Rapide à coder: Il permet des augmentations significatives de la vitesse de développement.
  • Nombre de bugs réduit: Il réduit la possibilité d'erreurs d'origine humaine.
  • Intuitif: Il offre une excellente prise en charge des éditeurs, avec une exécution partout et moins de temps de débogage.
  • Simple: Il est conçu pour être simple à utiliser et à apprendre, afin que vous puissiez passer moins de temps à lire la documentation.
  • Court: Il minimise la duplication de code.
  • Robuste: Il fournit un code prêt pour la production avec une documentation interactive automatique.
  • Basé sur des normes: Il est basé sur les standards ouverts pour les API, OpenAPI et JSON Schema.

Le framework est conçu pour optimiser votre expérience de développeur afin que vous puissiez écrire du code simple pour créer des API prêtes pour la production avec les meilleures pratiques par défaut.

Installer FastAPI

Comme pour tout autre projet Python, il serait préférable de commencer par créer un environnement virtuel. Si vous ne savez pas comment procéder, vous pouvez consulter l'introduction aux environnements virtuels.

La première étape consiste à installer FastAPI et Uvicorn en utilisant pépin:

$ python -m pip installer fastapi uvicor[[[[la norme]

Avec cela, FastAPI et Uvicorn sont installés et vous êtes prêt à apprendre à les utiliser. FastAPI est le framework que vous utiliserez pour créer votre API, et Uvicorn est le serveur qui utilisera l'API que vous créerez pour répondre aux demandes.

Premiers pas

Pour commencer, dans cette section, vous allez créer une application FastAPI minimale, l'exécuter avec un serveur utilisant Uvicorn, puis apprendre toutes les parties en interaction. Cela vous donnera un aperçu très rapide de la façon dont tout fonctionne.

Créer une première API

Un fichier FastAPI de base ressemble à ceci :

# py.principale

de fastapi importer API rapide

application = API rapide()

@app.obtenir("/")
asynchrone déf racine():
    revenir "un message": "Bonjour le monde"

Copiez le code ci-dessus dans un fichier nommé main.py, et juste comme ça, vous avez une application API entièrement fonctionnelle avec quelques bonnes pratiques comme la documentation automatique et la sérialisation intégrées. Vous en apprendrez plus sur ces fonctionnalités ensuite.

Ce code définit votre application, mais il ne s'exécutera pas sur lui-même si vous l'appelez avec python directement. Pour l'exécuter, vous avez besoin d'un serveur programme. Dans les étapes ci-dessus, vous avez déjà installé Uvicorn. Ce sera votre serveur.

Exécutez la première application API avec Uvicorn

Exécutez le serveur live à l'aide d'Uvicorn :

$ uvicorn main:app --reload

INFO : Uvicorn s'exécutant sur http://127.0.0.1:8000 (Appuyez sur CTRL+C pour quitter)
INFO: Processus de rechargement lancé [28720]
INFO : Processus serveur démarré [28722]
INFO : En attente du démarrage de l'application.
INFO : Démarrage de l'application terminé.

La ligne en surbrillance dans la sortie affiche l'URL où votre application est diffusée sur votre ordinateur local. Depuis que vous avez utilisé --recharger pour le développement, lorsque vous mettez à jour votre code d'application, le serveur se rechargera automatiquement.

Vérifier la réponse

Ouvrez votre navigateur pour http://127.0.0.1:8000, ce qui obligera votre navigateur à envoyer une requête à votre application. Il enverra ensuite une réponse JSON avec les éléments suivants :

"un message": "Bonjour le monde"

Ce message JSON est le même dictionnaire que vous avez renvoyé de la fonction dans votre application. FastAPI s'occupe de sérialiser le Python dict dans un objet JSON et en définissant le Type de contenu.

Consultez la documentation interactive de l'API

Ouvert http://127.0.0.1:8000/docs dans votre navigateur.

Vous verrez la documentation API interactive automatique fournie par Swagger UI :

Documents d'API interactifs fournis par Swagger UI

L'interface utilisateur Web documentant votre API est fournie et intégrée par défaut. Vous n'avez rien d'autre à faire pour en profiter avec FastAPI.

Consultez la documentation alternative de l'API interactive

Maintenant, allez à http://127.0.0.1:8000/redoc dans votre navigateur.

Vous verrez la documentation automatique alternative fournie par ReDoc :

Documents d'API interactifs fournis par ReDoc

Étant donné que FastAPI est basé sur des normes telles que OpenAPI, il existe de nombreuses alternatives pour afficher la documentation de l'API. FastAPI fournit ces deux alternatives par défaut.

La première API, étape par étape

Analysons maintenant ce code étape par étape et comprenons ce que fait chaque partie.

Étape 1 est d'importer API rapide:

# py.principale

de fastapi importer API rapide

application = API rapide()

@app.obtenir("/")
asynchrone déf racine():
    revenir "un message": "Bonjour le monde"

API rapide est une classe Python qui fournit toutes les fonctionnalités de votre API.

Étape 2 est de créer un API rapide exemple:

# py.principale

de fastapi importer API rapide

application = API rapide()

@app.obtenir("/")
asynchrone déf racine():
    revenir "un message": "Bonjour le monde"

Ici le application variable sera une instance de la classe API rapide. Ce sera le principal point d'interaction pour créer votre API.

Cette application est le même que vous avez mentionné ci-dessus dans la commande pour exécuter le serveur en direct avec uvicorne :

$ uvicorn main:app --reload

INFO : Uvicorn s'exécutant sur http://127.0.0.1:8000 (Appuyez sur CTRL+C pour quitter)

Avant de passer à l'étape 3, cela vaut la peine de prendre un moment pour se familiariser avec quelques termes. Chemin fait référence à la dernière partie de l'URL à partir de la première barre oblique (/). Ainsi, dans une URL comme https://example.com/items/foo, le chemin serait /items/toto.

Un chemin est aussi communément appelé un point final ou un route, mais le terme chemin sera utilisé dans ce tutoriel. Lorsque vous créez une API, le chemin est le principal moyen de séparer les ressources.

Un autre terme important à connaître est opération, qui est utilisé en référence à l'un des Méthodes de requête HTTP:

  • PUBLIER
  • OBTENIR
  • METTRE
  • EFFACER
  • OPTIONS
  • DIRIGER
  • PIÈCE
  • TRACE

Avec HTTP, vous pouvez communiquer avec chaque chemin en utilisant une (ou plusieurs) de ces opérations. Sachant ce que signifient ces deux termes, vous êtes prêt à passer à la troisième étape.

Étape 3 est de définir un décorateur d'opération de chemin:

# py.principale

de fastapi importer API rapide

application = API rapide()

@app.obtenir("/")
asynchrone déf racine():
    revenir "un message": "Bonjour le monde"

le @app.get("/") indique à FastAPI que la fonction juste en dessous est chargée de gérer les requêtes qui vont au chemin / utilisant un obtenir opération. C'est un décorateur lié à une opération de chemin, ou un décorateur d'opération de chemin. Si vous souhaitez en savoir un peu plus sur les décorateurs, consultez l'introduction aux décorateurs Python.

Vous pouvez également utiliser les autres opérations mentionnées ci-dessus :

  • @app.post()
  • @app.put()
  • @app.delete()
  • @app.options()
  • @app.head()
  • @app.patch()
  • @app.trace()

Dans chaque cas, vous utiliseriez le décorateur d'opération de chemin approprié au-dessus d'une fonction chargée de gérer ces demandes.

Étape 4 est de définir le fonction d'opération de chemin, ou la fonction qui va sous le décorateur d'opération de chemin :

# py.principale

de fastapi importer API rapide

application = API rapide()

@app.obtenir("/")
asynchrone déf racine():
    revenir "un message": "Bonjour le monde"

Cette fonction sera appelée par FastAPI chaque fois qu'elle recevra une requête à l'URL spécifiée (/) utilisant un OBTENIR opération. Dans ce cas, il s'agit d'un asynchrone une fonction.

Vous pouvez également le définir comme une fonction normale au lieu d'utiliser définition asynchrone:

# py.principale

de fastapi importer API rapide

application = API rapide()

@app.obtenir("/")
déf racine():
    revenir "un message": "Bonjour le monde"

Si vous ne connaissez pas la différence entre les fonctions normales et asynchrone fonctions et quand les utiliser, consultez Concurrence et async/wait dans la documentation FastAPI.

Étape 5 est de retourner le contenu :

# py.principale

de fastapi importer API rapide

application = API rapide()

@app.obtenir("/")
asynchrone déf racine():
    revenir "un message": "Bonjour le monde"

Vous pouvez renvoyer un dictionnaire, une liste ou des valeurs singulières sous forme de chaînes, d'entiers, etc. Vous pouvez également renvoyer des modèles pydantic, sur lesquels vous en apprendrez plus plus tard.

Il existe de nombreux autres objets et modèles qui seront automatiquement convertis en JSON, y compris les mappeurs objet-relationnel (ORM) et autres. Essayez d'utiliser vos favoris, il est fort probable qu'ils soient déjà pris en charge.

Paramètres de chemin : obtenir un élément par ID

Vous pouvez déclarer le chemin paramètres ou alors variables avec la même syntaxe utilisée par les chaînes au format Python :

# py.principale

de fastapi importer API rapide

application = API rapide()

@app.obtenir("/éléments/ID de l'article")
asynchrone déf read_item(ID de l'article):
    revenir "ID de l'article": ID de l'article

La valeur du paramètre de chemin ID de l'article sera passé à votre fonction en tant qu'argument ID de l'article.

Donc, si vous exécutez cet exemple et accédez à http://127.0.0.1:8000/items/foo, vous verrez cette réponse :

La réponse contient "toto", ce qui a été adopté dans le ID de l'article path puis renvoyé dans un dictionnaire.

Paramètres de chemin avec types

Vous pouvez déclarer le type d'un paramètre de chemin dans la fonction à l'aide des astuces de type Python standard :

# py.principale

de fastapi importer API rapide

application = API rapide()

@app.obtenir("/éléments/ID de l'article")
asynchrone déf read_item(ID de l'article: entier):
    revenir "ID de l'article": ID de l'article

Dans ce cas, vous déclarez ID de l'article être un entier.

Déclarer le type d'un paramètre de chemin vous donnera un support d'éditeur à l'intérieur de votre fonction, avec des vérifications d'erreur, la complétion, etc.

Conversion de données

Si vous exécutez l'exemple ci-dessus et naviguez dans votre navigateur jusqu'à http://127.0.0.1:8000/items/3, alors vous verrez la réponse suivante :

Notez que la valeur que votre fonction a reçue puis renvoyée est 3, qui est un Python entier, pas une chaîne ("3"). Ainsi, avec cette déclaration de type, FastAPI vous donne automatiquement demande d'analyse.

La validation des données

Si vous pointez votre navigateur sur http://127.0.0.1:8000/items/foo, alors vous verrez une belle erreur HTTP :


    "détail": [[[[
        
            "loc": [[[[
                "chemin",
                "ID de l'article"
            ],
            "message": "la valeur n'est pas un entier valide",
            "taper": "type_error.integer"
        
    ]

C'est parce que le paramètre de chemin ID de l'article a une valeur de "toto", ce qui n'est pas un entier.

La même erreur apparaîtrait si vous fournissez un flotter au lieu d'un entier, comme si vous ouvriez http://127.0.0.1:8000/items/4.2 dans votre navigateur. Ainsi, avec le même indice de type Python, FastAPI vous donne les deux analyse des données et la validation des données.

Notez également que l'erreur indique clairement le point exact où la validation n'a pas réussi. Ceci est incroyablement utile lors du développement et du débogage du code qui interagit avec votre API.

Documentation

Lorsque vous ouvrez votre navigateur sur http://127.0.0.1:8000/docs, vous verrez une documentation API automatique et interactive :

Documents d'API interactifs pour les opérations de chemin

Encore une fois, avec cette même déclaration de type Python, FastAPI vous fournit une documentation automatique et interactive intégrant l'interface utilisateur Swagger. Notez que le paramètre path est déclaré être un entier.

Étant donné que FastAPI est construit au-dessus de la norme OpenAPI, il fournit également une documentation API alternative utilisant ReDoc, à laquelle vous pouvez accéder à http://127.0.0.1:8000/redoc:

Documents d'API interactifs alternatifs utilisant ReDoc

Il existe de nombreux autres outils compatibles, notamment des outils de génération de code pour de nombreuses langues.

Traitement des données avec pydantic

Toute la validation des données est effectuée sous le capot par pydantic, vous en tirez donc tous les avantages et vous savez que vous êtes entre de bonnes mains.

Vous pouvez utiliser les mêmes déclarations de type avec str, flotter, bool et de nombreux autres types de données complexes.

L'ordre compte : privilégier les chemins fixes

Lors de la création d'opérations de chemin, vous pouvez rencontrer des situations où vous avez un chemin fixe, comme /utilisateurs/moi. Disons que c'est pour obtenir des données sur l'utilisateur actuel. Vous pourriez aussi avoir le chemin /users/user_id pour obtenir des données sur un utilisateur spécifique par un certain ID utilisateur.

Étant donné que les opérations de chemin sont évaluées dans l'ordre, vous devez vous assurer que le chemin pour /utilisateurs/moi est déclaré avant celui de /users/user_id:

# py.principale

de fastapi importer API rapide

application = API rapide()

@app.obtenir("/utilisateurs/moi")
asynchrone déf read_user_me():
    revenir "identifiant d'utilisateur": "l'utilisateur actuel"

@app.obtenir("/utilisateurs/identifiant d'utilisateur")
asynchrone déf read_user(identifiant d'utilisateur: str):
    revenir "identifiant d'utilisateur": identifiant d'utilisateur

Sinon, le chemin de /users/user_id correspondrait également à /utilisateurs/moi, pensant qu'il reçoit le paramètre identifiant d'utilisateur avec une valeur de "moi".

Corps de la requête : réception de données JSON

Lorsque vous devez envoyer des données d'un client à votre API, vous les envoyez en tant que corps de requête.

UNE corps de la demande sont des données envoyées par le client à votre API. UNE corps de réponse sont les données que votre API envoie au client. Votre API doit presque toujours envoyer un corps de réponse. Mais les clients n'ont pas nécessairement besoin d'envoyer des corps de requête tout le temps.

Pour déclarer un corps de requête, vous utilisez des modèles pydantic, avec toute leur puissance et leurs avantages. Vous en apprendrez plus à leur sujet ci-dessous.

Utilisez pydantic pour déclarer des modèles de données JSON (formes de données)

Tout d'abord, vous devez importer Modèle de base de pydantique puis l'utiliser pour créer des sous-classes définissant le schéma, ou des formes de données, que vous souhaitez recevoir.

Ensuite, vous déclarez votre modèle de données en tant que classe qui hérite de Modèle de base, en utilisant des types Python standard pour tous les attributs :

# py.principale

de dactylographie importer Optionnel

de fastapi importer API rapide
de pydantique importer Modèle de base

classer Article(Modèle de base):
    Nom: str
    la description: Optionnel[[[[str] = Rien
    le prix: flotter
    impôt: Optionnel[[[[flotter] = Rien

application = API rapide()

@app.Publier("/éléments/")
asynchrone déf create_item(Objet: Article):
    revenir Objet

Lorsqu'un attribut de modèle a une valeur par défaut, elle n'est pas obligatoire. Sinon, c'est obligatoire. Pour rendre un attribut facultatif, vous pouvez utiliser Rien.

Par exemple, le modèle ci-dessus déclare un objet JSON (ou Python dict) comme ça:


    "Nom": "Fou",
    "la description": "Une description facultative",
    "le prix": 45.2,
    "impôt": 3.5

Dans ce cas, puisque la description et impôt sont facultatifs car ils ont une valeur par défaut de Rien, cet objet JSON serait également valide :


    "Nom": "Fou",
    "le prix": 45.2

Un objet JSON qui omet les valeurs par défaut est également valide.

Ensuite, ajoutez le nouveau modèle pydantic à votre opération de chemin en tant que paramètre. Vous le déclarez de la même manière que vous avez déclaré les paramètres de chemin :

# py.principale

de dactylographie importer Optionnel

de fastapi importer API rapide
de pydantique importer Modèle de base

classer Article(Modèle de base):
    Nom: str
    la description: Optionnel[[[[str] = Rien
    le prix: flotter
    impôt: Optionnel[[[[flotter] = Rien

application = API rapide()

@app.Publier("/éléments/")
asynchrone déf create_item(Objet: Article):
    revenir Objet

Le paramètre Objet a un indice type de Article, ce qui signifie que Objet est déclaré comme une instance de la classe Article.

Avec cette déclaration de type Python, FastAPI :

  • Lire le corps de la requête en JSON
  • Convertissez les types correspondants si nécessaire
  • Valider les données et renvoyer une erreur claire si elle est invalide
  • Vous donner les données reçues dans le paramètre Objet-puisque vous avez déclaré qu'il était de type Article, vous aurez également tout le support de l'éditeur, avec des contrôles de complétion et de type pour tous les attributs et leurs types
  • Générez des définitions de schéma JSON pour votre modèle que vous pouvez également utiliser n'importe où ailleurs qui a du sens pour votre projet

En utilisant des astuces de type standard avec pydantic, FastAPI vous aide à créer des API qui ont toutes ces meilleures pratiques par défaut, avec peu d'effort.

Documentation automatique avec pydantic

Les schémas JSON de vos modèles pydantic feront partie de l'OpenAPI générée pour votre application et seront affichés dans la documentation API interactive :

Le schéma JSON pour les modèles pydantic est inclus dans l'interface utilisateur des documents d'API

Vous pouvez voir que les attributs de Article dans la documentation de l'API sont exactement ceux que vous avez déclarés avec votre modèle pydantic.

Ces schémas JSON seront également utilisés dans la documentation de l'API à l'intérieur de chaque opération de chemin qui en a besoin :

Le schéma JSON des modèles pydantic est inclus dans chaque opération de chemin dans l'interface utilisateur des documents de l'API

Notez que toute cette documentation automatique est basée sur votre données, en utilisant vos modèles pydantic.

Prise en charge de l'éditeur, saisie semi-automatique et vérifications de type

Dans votre éditeur, à l'intérieur de votre fonction, vous obtiendrez des conseils de type et une complétion partout. Cela ne se produirait pas si vous receviez un dict au lieu d'un modèle pydantic :

Les éditeurs fournissent des vérifications de complétion et de type pour les modèles pydantic

De cette façon, vous pouvez déclencher la saisie semi-automatique pour toutes vos données.

Vous obtenez également des contrôles d'erreur pour les opérations de type incorrect :

Les éditeurs fournissent des contrôles d'erreur pour les modèles pydantic

Dans ce cas, vous ne pouvez pas additionner un str avec un flotter, et comme l'éditeur connaît ces types, il peut vous avertir que vous avez une erreur dans votre code. Ce n'est pas par hasard : tout le cadre a été construit autour de cette conception. Il a été minutieusement testé dès la phase de conception, avant toute implémentation, pour s'assurer qu'il fonctionnerait avec tous les éditeurs. Il y a même eu quelques modifications à pydantic lui-même pour prendre en charge cette fonctionnalité.

Les captures d'écran précédentes ont été prises avec Visual Studio Code. Mais vous obtiendrez le même support d'éditeur avec PyCharm et la plupart des autres éditeurs Python :

PyCharm fournit également un support d'éditeur comme VS Code

Si vous utilisez PyCharm comme éditeur, vous pouvez utiliser le plugin pydantic PyCharm pour améliorer la prise en charge de votre éditeur. Et si vous utilisez VS Code, vous obtiendrez la meilleure expérience de développeur avec Pylance.

Utiliser le modèle pydantic

A l'intérieur de la fonction, vous pouvez accéder directement à tous les attributs de l'objet modèle :

# py.principale

de dactylographie importer Optionnel

de fastapi importer API rapide
de pydantique importer Modèle de base

classer Article(Modèle de base):
    Nom: str
    la description: Optionnel[[[[str] = Rien
    le prix: flotter
    impôt: Optionnel[[[[flotter] = Rien

application = API rapide()

@app.Publier("/éléments/")
asynchrone déf create_item(Objet: Article):
    item_dict = Objet.dict()
    si Objet.impôt:
        prix_avec_taxe = Objet.le prix + Objet.impôt
        item_dict.mettre à jour("prix_avec_taxe": prix_avec_taxe)
    revenir item_dict

Le paramètre Objet est déclaré comme une instance de la classe Article, et FastAPI s'assurera que vous recevez exactement ça dans votre fonction au lieu d'un dictionnaire ou autre chose.

Paramètres de corps de requête et de chemin

Vous pouvez déclarer des paramètres de chemin et un corps de requête en même temps.

FastAPI reconnaîtra que les paramètres de fonction qui correspondent aux paramètres de chemin doivent être extraits du chemin et que les paramètres de fonction déclarés être des modèles pydantic doivent être extraits du corps de la requête :

# py.principale

de dactylographie importer Optionnel

de fastapi importer API rapide
de pydantique importer Modèle de base

classer Article(Modèle de base):
    Nom: str
    la description: Optionnel[[[[str] = Rien
    le prix: flotter
    impôt: Optionnel[[[[flotter] = Rien

application = API rapide()

@app.mettre("/éléments/ID de l'article")
asynchrone déf create_item(ID de l'article: entier, Objet: Article):
    revenir "ID de l'article": ID de l'article, **Objet.dict()

De cette façon, vous pouvez déclarer des paramètres de chemin et des corps de requête JSON, et FastAPI se chargera de faire toute la validation des données, la sérialisation et la documentation pour vous. Vous pouvez le vérifier en allant à la même documentation API à /docs ou en utilisant d'autres outils comme Postman avec une interface graphique ou Curl dans la ligne de commande.

De la même manière, vous pouvez déclarer des corps de requête plus complexes, comme des listes, et d'autres types de données de requête, comme des paramètres de requête, des cookies, des en-têtes, des entrées de formulaire, des fichiers, etc.

En savoir plus sur FastAPI

À ce stade, vous en savez déjà beaucoup sur FastAPI et comment l'utiliser pour créer des API robustes et prêtes pour la production.

Mais il y a beaucoup plus que vous pourriez apprendre :

FastAPI peut couvrir la plupart des cas d'utilisation requis pour les frameworks back-end, même ceux qui ne sont pas strictement des API. Vous pouvez approfondir la documentation pour résoudre votre cas d'utilisation spécifique.

FastAPI est basé sur des fonctionnalités Python modernes et vous pouvez également tirer pleinement parti de FastAPI en en apprenant davantage sur ces fonctionnalités. Consultez Premiers pas avec les fonctionnalités asynchrones en Python et Async IO en Python : une procédure pas à pas complète pour en savoir plus sur la programmation asynchrone. Vous pouvez également consulter Python Type Checking (Guide) pour obtenir tous les avantages traditionnels des conseils de type dans votre code.

Conclusion

Dans ce tutoriel, vous avez découvert API rapide et comment l'utiliser pour créer des API prêtes pour la production qui ont les meilleures pratiques par défaut tout en offrant la meilleure expérience de développeur possible. Vous avez appris à :

  • Utiliser paramètres de chemin pour obtenir un chemin d'URL unique par élément
  • Recevez des données JSON dans vos requêtes en utilisant pydantique
  • Utilisez les meilleures pratiques d'API comme validation, sérialisation, et Documentation
  • Continuez à vous renseigner sur API rapide et pydantique pour différents cas d'utilisation

Vous êtes maintenant prêt à commencer à créer vos propres API hautement performantes pour vos projets. Si vous souhaitez plonger plus profondément dans le monde de FastAPI, vous pouvez suivre le guide de l'utilisateur officiel dans la documentation FastAPI.

[ad_2]