Pourquoi Deployer FastAPI sur GCP ?
Le déploiement de FastAPI sur Google Cloud Platform (GCP) est un choix populaire pour les développeurs qui cherchent à créer des applications hautement scalables, sécurisées et performantes. En effet, GCP offre une infrastructure robuste et évolutive qui peut gérer la charge de travail croissante d'une application FastAPI tout en assurant des niveaux élevés de disponibilité et de sécurité.
Un cas concret d'utilisation serait un service API de gestion de tâches pour une petite entreprise. Avec FastAPI, vous pouvez créer rapidement une API performante et facile à maintenir, qui peut ensuite être déployée sur GCP pour s'adapter aux besoins croissants de l'entreprise.
Prerequis
Connaissances nécessaires :
- Python (minimum version 3.7)
- FastAPI
- Asynchronous programming with
asyncio - REST API design
- GCP account and basic knowledge of its services
Outils à installer :
- Python
- pip (Python package installer)
- Visual Studio Code (ou tout autre éditeur de code Python)
- Google Cloud SDK
Concepts fondamentaux
1. Environnement virtuel
Un environnement virtuel est une copie isolée d'un interpréteur Python, avec ses propres paquets et dépendances.
## Crée un environnement virtuel nommé 'venv'
python -m venv venv
## Active l'environnement virtuel (Windows)
.\venv\Scripts\activate
## Active l'environnement virtuel (Linux/MacOS)
source venv/bin/activate
2. Création d'un projet FastAPI
Un projet FastAPI est une application Python qui utilise le framework FastAPI pour définir les routes et gérer les requêtes HTTP.
## Importer la librairie FastAPI et la fonction FastAPI
from fastapi import FastAPI
## Créer une instance de l'application FastAPI
app = FastAPI()
## Définir une route GET simple
@app.get("/")
async def read_root():
return {"message": "Hello World"}
3. Gestion des routes et des méthodes HTTP
FastAPI permet de définir différentes méthodes HTTP (GET, POST, PUT, DELETE) pour chaque route.
## Définir une route POST avec un modèle de données
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
4. Sécurité et authentification
FastAPI offre des fonctionnalités robustes pour sécuriser les APIs, notamment avec OAuth2.
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
async def get_current_user(token: str = Depends(oauth2_scheme)):
if token != "fake-jwt-token":
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid authentication credentials",
headers={"WWW-Authenticate": "Bearer"},
)
return {"username": "fakeuser"}
@app.get("/users/me")
async def read_users_me(current_user: dict = Depends(get_current_user)):
return current_user
5. Déploiement sur GCP App Engine
GCP App Engine est un service pour déployer et héberger des applications web et backends.
- Créer une application App Engine :
gcloud app create --region=[YOUR_REGION]
- Définir le fichier
app.yaml:
runtime: python39
entrypoint: uvicorn main:app --host=0.0.0.0 --port=$PORT
instance_class: F2
automatic_scaling:
target_cpu_utilization: 0.65
- Déployer l'application :
gcloud app deploy
Mise en pratique : Projet fil rouge - Gestionnaire de tâches
Pour illustrer la mise en place d'un gestionnaire de tâches avec FastAPI sur GCP, nous allons créer une application simple qui permet d'ajouter et de récupérer des tâches.
Étape 1 : Création du projet
Créez un nouveau dossier pour votre projet et initialisez un environnement virtuel.
mkdir fastapi-todo
cd fastapi-todo
python -m venv venv
source venv/bin/activate
Étape 2 : Installation des dépendances
Installez FastAPI et Uvicorn (serveur ASGI pour FastAPI).
pip install fastapi uvicorn
Étape 3 : Création du fichier main.py
Créez un fichier main.py avec le code suivant :
## Importer la librairie FastAPI et les dépendances nécessaires
from fastapi import FastAPI, Depends, HTTPException, status
from pydantic import BaseModel
app = FastAPI()
## Modèle de données pour une tâche
class Task(BaseModel):
id: int
title: str
description: str = None
completed: bool = False
## Base de données simulée (liste)
tasks_db = [
Task(id=1, title="Task 1", description="Description of task 1", completed=False),
Task(id=2, title="Task 2", description="Description of task 2", completed=True)
]
## Middleware pour gérer les erreurs
@app.middleware("http")
async def add_process_time_header(request, call_next):
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
response.headers["X-Process-Time"] = str(process_time)
return response
## Route pour récupérer toutes les tâches
@app.get("/tasks/")
async def read_tasks():
return tasks_db
## Route pour ajouter une nouvelle tâche
@app.post("/tasks/")
async def create_task(task: Task):
new_task = task.copy(update={"id": len(tasks_db) + 1})
tasks_db.append(new_task)
return new_task
## Route pour récupérer une tâche par ID
@app.get("/tasks/{task_id}")
async def read_task(task_id: int):
for task in tasks_db:
if task.id == task_id:
return task
raise HTTPException(status_code=404, detail="Task not found")
## Route pour mettre à jour une tâche
@app.put("/tasks/{task_id}", response_model=Task)
async def update_task(task_id: int, task_update: Task):
for i, task in enumerate(tasks_db):
if task.id == task_id:
tasks_db[i] = task_update.copy(update={"id": task_id})
return tasks_db[i]
raise HTTPException(status_code=404, detail="Task not found")
## Route pour supprimer une tâche
@app.delete("/tasks/{task_id}", response_model=Task)
async def delete_task(task_id: int):
for i, task in enumerate(tasks_db):
if task.id == task_id:
deleted_task = tasks_db.pop(i)
return deleted_task
raise HTTPException(status_code=404, detail="Task not found")
Étape 4 : Lancement de l'application
Lancez l'application avec Uvicorn.
uvicorn main:app --reload
Étape 5 : Déploiement sur GCP App Engine
- Créer un fichier
app.yaml:
runtime: python39
entrypoint: uvicorn main:app --host=0.0.0.0 --port=$PORT
instance_class: F2
automatic_scaling:
target_cpu_utilization: 0.65
- Déployer l'application :
gcloud app deploy
Erreurs frequentes et debugging
1. ModuleNotFoundError
Lorsque vous rencontrez une erreur de module non trouvé, vérifiez que le module est correctement installé dans votre environnement virtuel.
## ❌ Mauvais
from fastapi import FastAPI
## ✅ Correct
from fastapi import FastAPI
2. AttributeError
Si vous recevez une erreur d'attribut, vérifiez que l'objet et son attribut sont correctement définis.
## ❌ Mauvais
task = Task(id=1, title="Task 1", description=None)
## ✅ Correct
task = Task(id=1, title="Task 1")
3. 500 Internal Server Error
Pour gérer les erreurs internes du serveur, utilisez des blocs try-except pour capturer et traiter les exceptions.
## ❌ Mauvais
@app.get("/tasks/{task_id}")
async def read_task(task_id: int):
for task in tasks_db:
if task.id == task_id:
return task
raise HTTPException(status_code=404, detail="Task not found")
## ✅ Correct
@app.get("/tasks/{task_id}")
async def read_task(task_id: int):
try:
return next((task for task in tasks_db if task.id == task_id), None)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
Pour aller plus loin
1. Utiliser un système de base de données
Pour une application réelle, utilisez un système de base de données comme PostgreSQL ou MongoDB pour stocker les tâches.
2. Ajouter des tests
Ajoutez des tests unitaires et d'intégration pour votre application FastAPI.
3. Optimiser le rendu des routes
Optimisez les performances de vos routes en utilisant des techniques comme la pagination, l'asynchrone et la mise en cache.
Défi pratique : Créer une API de blog
Créez une API de blog avec FastAPI qui permet d'ajouter, récupérer et supprimer des articles.
- Définir le modèle de données pour les articles
- Créer les routes pour gérer les articles
- Ajouter la gestion des erreurs
- Déployer l'application sur GCP App Engine