Pourquoi Deployer FastAPI sur AWS ?
Le déploiement d'une application FastAPI sur AWS offre plusieurs avantages pratiques pour un développement professionnel. Premièrement, AWS fournit une infrastructure robuste et évolutrice capable de gérer des charges de travail intensives sans effort supplémentaire. Deuxièmement, les services AWS offrent une grande variété de fonctionnalités telles que la sécurité, l'auto-échelle, le stockage à grande échelle et la gestion des bases de données. Enfin, AWS offre un modèle pay-as-you-go, ce qui permet d'éviter les coûts inutiles tout en offrant une flexibilité accrue.
Un cas d'utilisation concret serait l'implémentation d'une API pour un service de gestion de tâches. Cette API pourrait être utilisée par des applications mobiles ou web pour ajouter, modifier et supprimer des tâches, ainsi que pour récupérer la liste des tâches à faire.
Prerequis
Pour suivre ce tutoriel, vous aurez besoin des éléments suivants :
- Connaissances en Python (version 3.6+)
- Un compte AWS
- L'installation de l'outil
awscli - La création d'une instance EC2 (Elastic Compute Cloud) avec une image Linux (par exemple, Ubuntu Server)
Concepts fondamentaux
Rôle du déploiement continu (CI/CD)
Le déploiement continu permet de livrer automatiquement les modifications apportées au code à l'environnement de production. AWS CodePipeline et AWS CodeBuild sont des services qui facilitent le processus CI/CD.
## Importer la bibliothèque FastAPI
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Bienvenue sur votre API FastAPI"}
Utilisation de Docker pour le conteneurisation
Docker permet de créer des images standardisées et portables, facilitant ainsi le déploiement sur n'importe quel environnement. AWS Elastic Container Service (ECS) est un service qui gère les conteneurs.
## Installer Docker si ce n'est pas déjà fait
sudo apt-get update
sudo apt-get install docker.io
## Créer un fichier Dockerfile
cat <<EOF > Dockerfile
FROM python:3.8-slim
WORKDIR /app
COPY . /app
RUN pip install fastapi uvicorn
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
EOF
Configuration des variables d'environnement
AWS Systems Manager Parameter Store est un service qui permet de stocker et sécuriser les variables d'environnement.
## Importer les variables d'environnement
from fastapi import FastAPI, Depends
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
database_url: str = "sqlite:///./test.db"
app = FastAPI()
def get_settings():
return Settings()
Mise en pratique : projet fil rouge
Nous allons créer un gestionnaire de tâches simple avec FastAPI.
- Créer le fichier
main.py
## Importer les bibliothèques nécessaires
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional
app = FastAPI()
class TodoItem(BaseModel):
title: str
description: Optional[str] = None
completed: bool = False
todos = []
@app.post("/todos/", response_model=TodoItem)
def create_todo(todo_item: TodoItem):
todos.append(todo_item)
return todo_item
@app.get("/todos/", response_model=List[TodoItem])
def read_todos():
return todos
@app.put("/todos/{todo_id}", response_model=TodoItem)
def update_todo(todo_id: int, todo_item: TodoItem):
if todo_id >= len(todos):
raise HTTPException(status_code=404, detail="Todo not found")
todos[todo_id] = todo_item
return todo_item
@app.delete("/todos/{todo_id}", response_model=TodoItem)
def delete_todo(todo_id: int):
if todo_id >= len(todos):
raise HTTPException(status_code=404, detail="Todo not found")
deleted_todo = todos.pop(todo_id)
return deleted_todo
- Créer le fichier
Dockerfile
## Installer Docker si ce n'est pas déjà fait
sudo apt-get update
sudo apt-get install docker.io
## Créer un fichier Dockerfile
cat <<EOF > Dockerfile
FROM python:3.8-slim
WORKDIR /app
COPY . /app
RUN pip install fastapi uvicorn
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
EOF
- Construire et exécuter le conteneur local
## Construire l'image Docker
docker build -t fastapi-todo .
## Exécuter le conteneur localement
docker run -p 8000:80 fastapi-todo
Déployer sur AWS ECS
Créer une tâche ECS
Configurer un groupe de services ECS
Associer l'image Docker créée précédemment au groupe de services
Erreurs frequentes et debugging
Erreur 1 : ModuleNotFoundError: No module named 'fastapi'
## Code incorrect
from fastapi import FastAPI
app = FastAPI()
Correction
## Installer FastAPI
pip install fastapi uvicorn
Erreur 2 : AttributeError: 'module' object has no attribute 'get_settings'
## Code incorrect
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
database_url: str = "sqlite:///./test.db"
app = FastAPI()
def get_settings():
return Settings()
Correction
## Code correct
from fastapi import Depends, FastAPI
from pydantic_settings import BaseSettings
app = FastAPI()
class Settings(BaseSettings):
database_url: str = "sqlite:///./test.db"
@app.get("/")
async def read_root(settings: Settings = Depends(get_settings)):
return {"database_url": settings.database_url}
Erreur 3 : KeyError: 'DATABASE_URL'
## Code incorrect
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
database_url = os.getenv("DATABASE_URL")
return {"database_url": database_url}
Correction
## Définir la variable d'environnement dans AWS Systems Manager Parameter Store
aws ssm put-parameter --name /my-app/database-url --value "sqlite:///./test.db" --type String --overwrite
## Lire la variable d'environnement dans le code
from fastapi import FastAPI, Depends
import boto3
app = FastAPI()
def get_ssm_client():
return boto3.client('ssm')
@app.get("/")
async def read_root(ssm_client: boto3.client = Depends(get_ssm_client)):
response = ssm_client.get_parameter(Name='/my-app/database-url')
database_url = response['Parameter']['Value']
return {"database_url": database_url}
Pour aller plus loin
Utilisation de AWS RDS pour le stockage de données
Déploiement sur AWS Lambda et API Gateway
Intégration avec AWS Cognito pour l'authentification
Défi pratique : Créer une application FastAPI qui utilise un service d'authentification JWT (JSON Web Token) pour sécuriser les routes.