Pourquoi API REST avec FastAPI ?
FastAPI est un framework d'API moderne pour Python qui utilise le type hinting et les outils de développement asynchrones de Python 3.7+ pour créer des APIs rapides et sécurisées, tout en étant facile à apprendre et à utiliser. Les développeurs utilisent FastAPI pour construire rapidement des applications web et mobiles, des microservices, des API RESTful et même des applications graphiques.
Un cas d'usage concret serait la création d'une application de gestion de tâches. Avec FastAPI, on peut facilement créer une API qui permet aux utilisateurs de créer, lire, mettre à jour et supprimer leurs tâches en un seul endroit.
Prerequis
- Connaissance de base de Python 3.7+
- Connaissances en programmation orientée objet
- Installation de FastAPI et Uvicorn (serveur ASGI)
Vous pouvez installer FastAPI et Uvicorn via pip :
pip install fastapi uvicorn
Concepts fondamentaux
1. Route
Une route est une URL spécifique à laquelle vous voulez que votre API répondre. Vous utilisez les décorateurs de FastAPI pour définir les routes.
Exemple :
## Importer la bibliothèque FastAPI
from fastapi import FastAPI
## Créer une instance de l'application
app = FastAPI()
@app.get("/")
async def read_root():
return {"message": "Bienvenue sur ma première API avec FastAPI"}
2. Path Parameters
Les path parameters sont des variables qui apparaissent dans la route URL. Ils permettent d'extraire des informations spécifiques de l'URL.
Exemple :
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
3. Query Parameters
Les query parameters sont les paramètres qui apparaissent après le signe de interrogation (? dans la URL) et permettent d'ajouter des options supplémentaires à une requête.
Exemple :
@app.get("/items/")
async def read_item(skip: int = 0, limit: int = 10):
return {"skip": skip, "limit": limit}
4. Request Body
Le request body est le contenu de la requête HTTP qui est envoyé au serveur. Il est utilisé pour passer des données complexes.
Exemple :
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
@app.post("/items/")
async def create_item(item: Item):
return item
5. Response Model
Un response model est un modèle Pydantic qui décrit la structure de la réponse que l'API doit retourner.
Exemple :
class ItemResponse(BaseModel):
id: int
name: str
@app.post("/items/", response_model=ItemResponse)
async def create_item(item: Item):
return {"id": 1, "name": item.name}
Mise en pratique : projet fil rouge
Projet : Gestionnaire de Tâches
Nous allons créer un simple gestionnaire de tâches avec FastAPI. L'application permettra d'afficher toutes les tâches, ajouter une nouvelle tâche, mettre à jour une tâche et supprimer une tâche.
Étape 1 : Création du projet
Créez un nouveau fichier main.py :
touch main.py
Étape 2 : Importations et définition de l'application
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI()
## Base pour stocker les tâches
tasks = []
next_id = 1
class Task(BaseModel):
id: int
title: str
description: str
Étape 3 : Endpoint pour obtenir toutes les tâches
@app.get("/tasks/")
async def get_tasks():
return tasks
Étape 4 : Endpoint pour ajouter une nouvelle tâche
@app.post("/tasks/")
async def add_task(task: Task):
global next_id
task.id = next_id
next_id += 1
tasks.append(task)
return task
Étape 5 : Endpoint pour mettre à jour une tâche
@app.put("/tasks/{task_id}")
async def update_task(task_id: int, updated_task: Task):
for task in tasks:
if task.id == task_id:
task.title = updated_task.title
task.description = updated_task.description
return task
raise HTTPException(status_code=404, detail="Task not found")
Étape 6 : Endpoint pour supprimer une tâche
@app.delete("/tasks/{task_id}")
async def delete_task(task_id: int):
global tasks
tasks = [task for task in tasks if task.id != task_id]
return {"message": "Task deleted"}
Étape 7 : Exécution de l'application
Pour exécuter l'application, utilisez Uvicorn :
uvicorn main:app --reload
Structure des fichiers
Votre projet devrait ressembler à ceci :
.
├── main.py
Erreurs frequentes et debugging
Erreur :
AttributeError: module 'fastapi' has no attribute 'HTTPException'Code incorrect :
from fastapi import FastAPI, HTTPExeception # Typo dans le nom de la classeCode correct :
from fastapi import FastAPI, HTTPExceptionErreur :
TypeError: create_task() missing 1 required positional argument: 'item'Code incorrect :
@app.post("/items/") async def create_item(item): return itemCode correct :
@app.post("/items/") async def create_item(item: Item): return itemErreur :
KeyError: 'id'lors de la mise à jour d'une tâcheCode incorrect :
for task in tasks: if task.id == task_id: task.title = updated_task.title task.description = updated_task.description return taskCode correct :
Assurez-vous que
updated_taska les attributsid,title, etdescription.
Pour aller plus loin
Authentification JWT : Utilisez FastAPI pour ajouter une authentification basée sur le jeton JSON Web Token (JWT).
Middleware et Hooks : Créez des middleware et hooks pour enregistrer les requêtes et répondre aux événements spécifiques.
Documentation Swagger UI : Utilisez la documentation automatique de FastAPI avec Swagger UI ou ReDoc pour générer une interface utilisateur interactive de votre API.
Défi pratique
Créez un simple API de blog qui permet aux utilisateurs de créer, lire, mettre à jour et supprimer des articles. Utilisez les concepts que vous avez appris dans ce tutoriel.
Étape 1 : Création du projet
mkdir fastapi_blog
cd fastapi_blog
touch main.py
Étape 2 : Importations et définition de l'application
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI()
articles = []
next_id = 1
class Article(BaseModel):
id: int
title: str
content: str
Étape 3 : Endpoint pour obtenir tous les articles
@app.get("/articles/")
async def get_articles():
return articles
Étape 4 : Endpoint pour ajouter un nouvel article
@app.post("/articles/")
async def create_article(article: Article):
global next_id
article.id = next_id
next_id += 1
articles.append(article)
return article
Étape 5 : Endpoint pour mettre à jour un article
@app.put("/articles/{article_id}")
async def update_article(article_id: int, updated_article: Article):
for article in articles:
if article.id == article_id:
article.title = updated_article.title
article.content = updated_article.content
return article
raise HTTPException(status_code=404, detail="Article not found")
Étape 6 : Endpoint pour supprimer un article
@app.delete("/articles/{article_id}")
async def delete_article(article_id: int):
global articles
articles = [article for article in articles if article.id != article_id]
return {"message": "Article deleted"}
Étape 7 : Exécution de l'application
uvicorn main:app --reload
En suivant ce tutoriel, vous devriez être en mesure de créer rapidement des APIs RESTful avec FastAPI. N'oubliez pas d'apprendre à gérer les erreurs et à utiliser les outils de documentation pour rendre votre API utilisable pour d'autres développeurs.