Créer une API en quelques minutes avec FastAPI
Kelly L @kellymlacy

Créer une API en quelques minutes avec FastAPI

FastAPI est un très bon outil pour développer rapidement des API en Python. Dans cet article, nous allons voir pourquoi le choix de ce framework et comment créer notre première application en quelques minutes.

  • Python
  • API

Pourquoi FastAPI 🚀

En consultant le site de FastAPI, la promesse est assez clair:

FastAPI framework, high performance, easy to learn, fast to code, ready for production

Le message est claire: performance et facilité. Le framework nous propose également une liste de features intéressante dont:

  • l'intégration de l'auto-documentation se basant sur OpenAPI
  • l'utilisation des dernières mises à jours de Python comme l'async/await et le typage
  • l'injéction de dépendences

Vous pouvez consulter la liste complète des features ici.

Il a été également élu "New Tool of the Year" en 2021 par stackshare

Installation

On commence avec la création de l'environnement virtuel avec le module venv de Python.

# initialisation du venvpython3 -m venv venv# activation du venvsource venv/bin/activate

Concernant les requirements, nous avons besoin d'installer:

  • Le framework FastAPI
  • Uvicorn afin d'obtenir un serveur web permettant de gérer l'asynchrone. C'est un ASGI (Asynchronous Server Gateway Interface)
# création du fichier requirementstouch requirements.txt# écriture des dépendances dans le fichiercat <<EOT >> requirements.txtfastapi==0.73.0uvicorn==0.17.4EOT# installationpip install -r requirements.txt

Création de la première route

Maintenant que toutes les dépendances sont installées, nous pouvons créer notre première route de notre projet FastAPI.

Pour cela, nous créons un dossier app et à l'intérieur de ce dernier, un fichier main.py qui va contenir la déclaration de notre première route.

# ~/app/main.pyfrom fastapi import FastAPIapp = FastAPI()@app.get("/")async def read_home():    return {"Music": "Song"}

Nous pouvons maintenant lancer uvicorn, à la racine de notre projet:

uvicorn app.main:app --reload

Vous pouvez maintenant accéder à votre API en allant sur http://127.0.0.1:8000et sur la documentation de votre route http://127.0.0.1:8000/docs.

Actions

Ok, maintenant que notre projet fonctionne et que nous pouvons visualiser le résultat de notre première route, nous allons construire notre gestion des titres de musique avec des actions simples.

Avant de commencer, un peu de typage

C'est le bon moment pour introduire pydantic qui permet de nous faciliter la vie avec la validation de notre modèle en l'occurence Song dans notre cas.

from typing import Listfrom pydantic import BaseModelclass Song(BaseModel):    id: int    title: str    artist: str    genre: List[str]# Notre liste de musiquessongs: List[Song] = [    Song(        id=1,        title='Gung Ho',        artist='Shaka Ponk',        genre=['Rock', 'Electronic rock']    ),    Song(        id=2,        title='Rusty Fonky',        artist='Shaka Ponk',        genre=['Rock', 'Electronic rock']    ),]

On déclare notre modèle Song étendu de BaseModel avec les différents attributs. Puis nous créons en dessous notre variable songs qui est typé comme liste de Song.

Lister les titres de musiques

Dans l'exemple suivant, la route retourne la collection de musique précédemment créée. response_model permet de contrôler quel forme de réponse doit retourner /songs.

@app.get("/songs", response_model=List[Song])async def get_songs():    return songs

Trouver une musique en fonction de son id

La route suivante filtre la collection de musique par son id. Notez le typage associé au paramètre song_id, FastAPI lévera automatiquement une exception si le paramètre passé n'est pas de type int.

@app.get("/songs/{song_id}", response_model=Song)async def get_song(song_id: int):    # retourne le premier résultat positif dans les dictionnaires de la liste.    song = next((s for s in songs if s['id'] == song_id), None)    if not song:        raise HTTPException(status_code=404, detail="Song not found")    return song

Créer une nouvelle musique

Pour ajouter une nouvelle musique à notre collection, nous utilisons le verbe POST. Un modèle SongCreate a aussi été créé afin de valider le body envoyé. Une fois que ce dernier est validé, on instancie une classe Song avec les données validées puis nous y ajoutons un ID unique pour notre collection. Song est ensuite ajouté à notre collection de musique.

class SongCreate(BaseModel):    title: str    artist: str    genre: List[str]@app.post("/songs", response_model=Song)async def get_songs(song: SongCreate):    last_song_registered = max(songs, key=lambda s: s.id)    new_id = last_song_registered.id + 1    new_song = Song(**song.dict(), id=new_id)    # On ajoute la nouvelle chanson à notre collection    songs.append(new_song)    return new_song

Supprimer une musique de notre collection

Enfin il nous manque l'action de supprimer une musique par son ID. Pour cela, nous utilisons le verbe DELETE. Une exception est levée si l'index n'est pas trouvé dans la collection de musique.

@app.delete("/songs/{song_id}")async def delete_songs(song_id: int):    index_song = next((index for (index, s) in enumerate(songs) if s.id == song_id), None)    if index_song is None:        raise HTTPException(status_code=404, detail=f"Song not found")    del songs[index_song]    return {}