Go to blue arrow
back to Tech Blog
Développement

Comment créer une API Flask avec Python : le guide complet

Code source Python avec coloration syntaxique affiché sur deux colonnes dans un éditeur de code à thème sombre.

Demandez à cinq développeurs ce qu'est Flask et vous obtiendrez cinq réponses assurées, dont la plupart ne seront qu'à moitié exactes. Voici l'enjeu réel : un projet Python Flask peut passer d'un répertoire vide à une API fonctionnelle en un après-midi, pour ensuite, sans décisions réfléchies sur la structure, la validation et le déploiement, devenir silencieusement le système que personne ne veut toucher. Rapide à démarrer. Coûteux à négliger.

Ce guide couvre les deux facettes de cette réalité. Si vous êtes développeur, nous construirons ensemble une API REST fonctionnelle, étape par étape : points de terminaison CRUD, base de données SQLite via SQLAlchemy, validation des requêtes et gestion des erreurs, documentation OpenAPI, et une structure de projet capable de supporter la croissance.

Si vous êtes CTO ou responsable technique et que vous hésitez entre Python Flask et FastAPI, passez directement aux sections sur la préparation à la production et la prise de décision pour les leaders techniques. Ces sections abordent les sujets qui vous concernent : expertise de l'équipe, risques de livraison et coûts réels de maintenance.

blue arrow to the left
Imaginary Cloud logo

Qu'est-ce que Flask et pourquoi l'utiliser pour créer des API ?

Flask est un framework web Python léger qui permet de créer des API et des applications web en associant des routes HTTP à des fonctions qui renvoient du JSON ou du HTML. Il s'agit d'un framework WSGI, et le WSGI (Web Server Gateway Interface) est simplement l'interface standard entre les applications web Python et les serveurs web qui les exécutent. Le documentation officielle de Flask le qualifie de micro-framework, ce qui est à la fois exact et légèrement trompeur.

Le terme « micro » décrit le cœur du système, pas son ambition. Flask vous fournit un châssis plutôt qu'une voiture finie : le moteur, les sièges et le tableau de bord sont vos choix, sélectionnés dans un catalogue de pièces que la communauté enrichit depuis 2010. C'est cette liberté qui fait tout son attrait (et, comme nous le verrons, tout son risque).

Python propose plusieurs frameworks : Tornado, Pyramid, Django et FastAPI, entre autres. Si vous hésitez encore sur le langage lui-même, notre présentation des avantages de Python explique pourquoi il domine le développement backend et le traitement des données.

Flask est-il toujours un choix courant ? Absolument. Dans l' enquête 2025 auprès des développeurs Stack Overflow, environ 15 % des répondants ont déclaré utiliser Flask, ce qui le place, aux côtés de FastAPI, parmi les frameworks web les plus utilisés, tous langages confondus. Le catalogue de composants est tout aussi mature : Flask-SQLAlchemy pour les bases de données, Flask-Login et Flask-JWT-Extended pour l'authentification, Flask-Migrate pour les migrations de schéma, Flask-Limiter pour la limitation de débit. Chacun est maintenu depuis des années.

D'après la pratique d'audit d'IC : La liberté offerte par Flask est à double tranchant. Elle permet de démarrer rapidement un projet Python avec Flask, mais c'est aussi la raison la plus fréquente pour laquelle on nous demande de démêler une base de code un an plus tard. Le framework n'empêchera pas trois développeurs d'inventer trois architectures différentes au sein d'une même application. Rien ne le fera, à part l'équipe elle-même.
blue arrow to the left
Imaginary Cloud logo

Qu'est-ce qu'une API REST et comment fonctionne-t-elle ?

API signifie Application Programming Interface (interface de programmation d'application) : c'est la manière dont un système communique avec un autre. Une API REST (Representational State Transfer) est un style architectural pour ces échanges, basé sur des requêtes sans état via des méthodes HTTP standard, tout en séparant strictement les responsabilités du client et du serveur.

En pratique, une API REST échange du JSON et associe des points de terminaison à quatre verbes : Créer (POST), Lire (GET), Mettre à jour (PUT ou PATCH) et Supprimer (DELETE). Ensemble, ils forment les opérations CRUD, et l'API que vous allez construire dans ce guide implémente ces quatre opérations sur une entité unique. REST n'est pas le seul style existant, bien entendu. Si vos services sont internes et sensibles à la latence, notre comparaison gRPC vs REST explique quand un protocole binaire devient pertinent.

D'après les audits réalisés par IC : le problème de conception REST le plus fréquent que nous rencontrons n'est pas l'absence d'un point de terminaison. C'est l'incohérence : une route renvoie du snake_case, une autre du camelCase ; l'une encapsule les erreurs en JSON, l'autre renvoie une page HTML brute. S'accorder sur ces conventions avant de créer le premier point de terminaison prend une heure et permet d'économiser des semaines de travail.
blue arrow to the left
Imaginary Cloud logo

Comment configurer un projet Python Flask pour une API REST

Toute API Flask nécessite les mêmes bases avant même d'écrire une ligne de code. Mettons-les en place.

Prérequis techniques

Vous devez avoir Python installé. Le code présenté ici suppose l'utilisation de Python 3 ; si vous êtes sous Windows ou si vous avez besoin de Python 2, suivez le guide d'installation de Flask.

Commencez par créer un répertoire pour le projet. À l'emplacement où vous souhaitez enregistrer le projet, exécutez les commandes suivantes dans votre terminal :

mkdir flask_api
cd flask_api

Nous avons créé le répertoire du projet et nous y sommes déplacés. Avant d'installer quoi que ce soit, créez un environnement virtuel :

python3 -m venv venv

Cela crée un dossier nommé venv dans votre projet. Activez-le en exécutant :

source venv/bin/activate

# On Windows:
venv\Scripts\activate

Désormais, toute commande Python que vous exécutez utilisera cet environnement venv. Si vous utilisez un IDE, configurez-le pour pointer vers ce même environnement (une source classique de confusion du type « ça fonctionne dans le terminal »).

Comment savoir s'il est actif ? Regardez sur la gauche de votre console : si le nom de l'environnement apparaît entre parenthèses, tout est prêt. Pour le désactiver plus tard, exécutez :

deactivate

Le flux de travail de développement d'une API Flask

Une API Python Flask classique se construit en six étapes :

  1. Configuration de l'application Flask.
  2. Définition des routes et des points de terminaison de l'API.
  3. Connexion de l'application à une base de données.
  4. Implémentation des opérations CRUD.
  5. Validation des requêtes et gestion des erreurs.
  6. Documentation de l'API à l'aide d'outils OpenAPI.

Ce guide suit cet ordre car nous l'appliquons sur les projets de nos clients. Cela permet de garder les services backend organisés dès le premier commit, plutôt qu'à partir de la quinzième refactorisation.

Flask API request flow diagram showing Client, Nginx, Gunicorn, validation, SQLAlchemy, database, and response path.
blue arrow to the left
Imaginary Cloud logo

Comment connecter une API Flask à une base de données avec SQLAlchemy

Une API qui stocke des données dans une liste Python perd tout dès que le serveur redémarre. Les applications réelles doivent conserver leurs données ; nous allons donc connecter l'API Flask à une base de données en utilisant SQLite et SQLAlchemy.

SQLite est une base de données légère qui ne nécessite aucun serveur dédié, ce qui la rend idéale pour les tutoriels et les petites applications. Parfait pour aujourd'hui. Pas forcément pour le jour du lancement.

D'après la pratique d'audit d'IC : presque tous les projets Flask dont nous héritons ont commencé avec SQLite « juste pour le moment ». C'est un bon point de départ, à condition que les modèles SQLAlchemy soient écrits en prévision d'une migration vers PostgreSQL. Car en production, c'est le plus souvent ce qui finit par arriver.

Installer SQLAlchemy et Flask-SQLAlchemy

Installez les dépendances requises :

pip install Flask Flask-SQLAlchemy

Si vous gérez vos dépendances avec un fichier requirements.txt , ajoutez :

Flask
Flask-SQLAlchemy

Dans cette configuration, SQLAlchemy est l'Object Relational Mapper (ORM). Un ORM vous permet de manipuler les enregistrements de la base de données comme des objets Python classiques au lieu d'écrire du SQL brut ; la documentation de SQLAlchemy couvre l'ensemble de ses fonctionnalités. Flask-SQLAlchemy l'intègre à Flask.

Configurer la connexion à la base de données

Indiquez à Flask où se trouve la base de données SQLite en définissant la chaîne de connexion :

from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///items.db"
db = SQLAlchemy(app)

Cela crée un fichier de base de données SQLite local nommé items.db dans le répertoire du projet.

Définir le modèle de base de données

Créez un modèle représentant la structure de la table de la base de données :

class Item(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), nullable=False)
    price = db.Column(db.Float, nullable=False)

    def to_dict(self):
        return {"id": self.id, "name": self.name, "price": self.price}

Le modèle Item définit trois champs : id (identifiant unique), name et prix. La to_dict() méthode convertit l'objet de la base de données en un dictionnaire sérialisable au format JSON.

Créer la table de base de données

Avant de lancer l'API, créez les tables à l'aide de SQLAlchemy :

with app.app_context():
    db.create_all()

Récupérer tous les éléments

Ce point de terminaison renvoie tous les éléments stockés dans la base de données :

@app.route("/items", methods=["GET"])
def get_items():
    items = Item.query.all()
    return jsonify([item.to_dict() for item in items])

Créer un nouvel élément

Ce point de terminaison lit le corps de la requête JSON, valide les données saisies, crée un enregistrement dans la base de données et renvoie l'élément créé :

@app.route("/items", methods=["POST"])
def create_item():
    data = request.get_json()
    if not data or "name" not in data or "price" not in data:
        return jsonify({"error": "Both 'name' and 'price' are required."}), 400
    item = Item(name=data["name"], price=data["price"])
    db.session.add(item)
    db.session.commit()
    return jsonify(item.to_dict()), 201

Obtenir un élément spécifique

Ce point de terminaison récupère un élément spécifique via son identifiant :

@app.route("/items/<int:item_id>", methods=["GET"])
def get_item(item_id):
    item = Item.query.get_or_404(item_id)
    return jsonify(item.to_dict())

Si l'élément n'existe pas, Flask renvoie automatiquement une erreur 404. Aucun code supplémentaire n'est requis.

Mettre à jour un élément

Ce point de terminaison met à jour un élément existant. Seuls les champs fournis sont modifiés.

@app.route("/items/<int:item_id>", methods=["PUT"])
def update_item(item_id):
    item = Item.query.get_or_404(item_id)
    data = request.get_json() or {}
    if "name" in data:
        item.name = data["name"]
    if "price" in data:
        item.price = data["price"]
    db.session.commit()
    return jsonify(item.to_dict())

Supprimer un élément

Ce point de terminaison supprime l'élément spécifié de la base de données :

@app.route("/items/<int:item_id>", methods=["DELETE"])
def delete_item(item_id):
    item = Item.query.get_or_404(item_id)
    db.session.delete(item)
    db.session.commit()
    return jsonify({"message": f"Item {item_id} deleted."})

Exécuter l'application

Démarrez le serveur de développement Flask :

python app.py

# or, with the Flask CLI:
flask --app app run --debug

Votre API est désormais disponible localement.

Exemple de requête et de réponse

Créer un nouvel élément, la requête :

curl -X POST http://localhost:5000/items \
  -H "Content-Type: application/json" \
  -d '{"name": "Keyboard", "price": 49.9}'

La réponse :

{
  "id": 1,
  "name": "Keyboard",
  "price": 49.9
}

Récupérer tous les éléments, la réponse :

[
  {
    "id": 1,
    "name": "Keyboard",
    "price": 49.9
  }
]

Pourquoi utiliser une base de données plutôt qu'une liste en mémoire ?

Parce que les listes perdent les données au redémarrage, ne peuvent pas être partagées entre plusieurs instances d'application et ne peuvent pas être interrogées efficacement. Une base de données telle que SQLite offre à votre API un stockage persistant et interrogeable : le comportement nécessaire à un véritable service backend.

Pour les systèmes en production, les équipes migrent généralement vers PostgreSQL, MySQL ou MongoDB. La structure globale de l'API Flask reste identique.

blue arrow to the left
Imaginary Cloud logo

Structure d'un projet Flask : d'un fichier unique à une architecture de production

Structure pour débutant : un projet d'API Flask simple

Considérez une API en un seul fichier comme un studio. Tout est à portée de main, aucun plan n'est nécessaire, et pour un petit projet, c'est précisément l'intérêt :

flask_api/
├── app.py
├── models.py
├── routes.py
├── requirements.txt
└── items.db

Dans cette structure, app.py crée l'application Flask et configure les extensions, models.py définit les modèles SQLAlchemy, routes.py contient les points de terminaison, requirements.txt liste les dépendances, et items.db est la base de données de développement.

Cette disposition convient aux petites API, aux prototypes et aux projets d'apprentissage. Mais personne n'élève une famille dans un studio, et personne ne devrait faire évoluer un produit dans un seul fichier.

Exemple : contenu de chaque fichier

app.py crée l'application Flask, configure la base de données et enregistre les routes.

from flask import Flask
from models import db
import routes

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///items.db"
db.init_app(app)

app.register_blueprint(routes.bp)

with app.app_context():
    db.create_all()

if __name__ == "__main__":
    app.run(debug=True)

models.py définit le modèle de base de données.

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class Item(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), nullable=False)
    price = db.Column(db.Float, nullable=False)

    def to_dict(self):
        return {"id": self.id, "name": self.name, "price": self.price}

routes.py contient les points de terminaison de l'API.

from flask import Blueprint, request, jsonify
from models import db, Item

bp = Blueprint("items", __name__)

@bp.route("/items", methods=["GET"])
def get_items():
    return jsonify([item.to_dict() for item in Item.query.all()])

# ... remaining CRUD endpoints as in snippets 11-14, using @bp.route

La séparation de l'application en plusieurs fichiers permet de clarifier les responsabilités et de réduire l'encombrement. Si vous ajoutez ultérieurement l'authentification, des utilisateurs ou des commandes, vous étendez la structure au lieu de réécrire le projet.

Structure de production : une architecture d'API Flask modulaire

Les applications Python Flask plus importantes ont besoin d'une maison plutôt que d'un appartement : des paquets au lieu de fichiers à la racine, avec une pièce dédiée à chaque domaine.

flask_api/
├── app/
│   ├── __init__.py
│   ├── models/
│   │   └── item.py
│   ├── routes/
│   │   └── items.py
│   └── schemas/
│       └── item.py
├── requirements.txt
└── run.py

Dans cette architecture, le paquet app contient la logique principale de l'application, models/ définit les modèles de base de données, routes/ regroupe les points de terminaison par ressource, et run.py lance l'application. Le dossier schemas/ gère la validation des requêtes et des réponses à l'aide de Marshmallow, une bibliothèque Python permettant de définir des schémas qui valident les données entrantes et sérialisent les réponses sortantes.

Le bénéfice est immédiat. Les points de terminaison restent organisés par ressource, les fonctionnalités telles que l'authentification ou les tâches de fond s'intègrent proprement, et plusieurs développeurs peuvent travailler en parallèle sans se gêner.

Bonne pratique : commencez par une structure simple et ne l'étendez que lorsque l'application se développe. Pour les petits projets, quelques fichiers clairement nommés suffisent. Pour les API Flask plus importantes, la disposition basée sur des paquets est ce qui permet de maintenir des coûts de maintenance stables.

Quand utiliser les Blueprints

Un blueprint est un objet très similaire à un objet d'application Flask, à la différence qu'il étend l'application existante au lieu d'en créer une nouvelle. Les blueprints permettent de diviser une API Flask en sections : par ressource, par version d'API ou par service.

Alors, quand en avez-vous réellement besoin ? Plus tôt que vous ne le pensez.

D'après les audits réalisés par IC : un fichier de routes unique commence à accumuler des conflits de fusion dès qu'un deuxième développeur rejoint l'équipe ou qu'une deuxième ressource apparaît. C'est le signal qu'il est temps de passer aux Blueprints. N'attendez pas que le fichier vous semble « trop long ».

Convertissons le code ci-dessus en blueprint et chargeons-le dans l'application principale. Créez un nouveau dossier nommé blueprints, et à l'intérieur, un dossier et un fichier pour le blueprint des éléments :

from flask import Blueprint, request, jsonify
from models import db, Item

items_bp = Blueprint("items", __name__, url_prefix="/items")

@items_bp.route("", methods=["GET"])
def get_items():
    return jsonify([item.to_dict() for item in Item.query.all()])

# ... remaining CRUD endpoints moved here unchanged

Désormais, app.py a simplement besoin de charger le blueprint créé et de l'enregistrer sur l'objet application :

from blueprints.items.routes import items_bp

app.register_blueprint(items_bp)

Les mêmes points de terminaison, mais une structure plus solide. C'est ce qui permet de garder une application Flask Python évolutive et facile à gérer.

Comment valider les requêtes et gérer les erreurs dans une API Flask

La validation est le portier de votre API. Elle vérifie les identifiants à l'entrée pour éviter d'extraire plus tard des données corrompues de la base de données, une fois qu'elles se sont déjà infiltrées dans vos rapports. Une API Flask bien conçue valide les données entrantes, renvoie des messages d'erreur explicites et utilise les codes de statut HTTP appropriés.

D'après les audits réalisés par IC : parmi les incidents de production que nous sommes appelés à diagnostiquer, l'absence de validation des requêtes est l'une des causes profondes les plus fréquentes. Les données erronées s'introduisent discrètement, puis refont surface des semaines plus tard sous forme de bug dans les rapports, dont il est coûteux de remonter jusqu'à la source.

Valider les données des requêtes entrantes

Lorsqu'un client envoie des données, le serveur doit vérifier que les champs requis sont présents et correctement formatés. La création d'un nouvel élément, par exemple, doit exiger à la fois un nom et un prix.

Voici un exemple de validation simple :

@app.route("/items", methods=["POST"])
def create_item():
    data = request.get_json()
    if not data or "name" not in data or "price" not in data:
        return jsonify({"error": "Both 'name' and 'price' are required."}), 400
    item = Item(name=data["name"], price=data["price"])
    db.session.add(item)
    db.session.commit()
    return jsonify(item.to_dict()), 201

L'API vérifie que le corps de la requête contient du JSON et que les champs requis sont présents. Si la validation échoue, elle renvoie une réponse 400 Bad Request . Le portier refuse l'accès, poliment et en JSON.

Utilisez des codes d'état HTTP explicites

Les codes d'état indiquent aux clients si une requête a réussi ou échoué. Les plus courants dans les API REST sont :

Code d'étatSignification
200 OKLa requête a réussi
201 CreatedUne ressource a été créée avec succès
400 Bad RequestLa requête est invalide
404 Not FoundLa ressource demandée n'existe pas
500 Internal Server ErrorUne erreur inattendue est survenue

Le bon code permet aux utilisateurs de l'API de traiter les réponses par programmation plutôt que d'analyser du texte d'erreur.

Gérez les ressources manquantes

Lorsqu'un client demande une ressource qui n'existe pas, l'API doit renvoyer une erreur 404. Flask-SQLAlchemy fournit une fonction pratique :

@app.route("/items/<int:item_id>", methods=["GET"])
def get_item(item_id):
    item = Item.query.get_or_404(item_id)
    return jsonify(item.to_dict())

Si l'élément n'existe pas, Flask renvoie automatiquement une réponse telle que :

{
  "error": "Resource not found"
}

Pas de réponses vides, pas de réponses trompeuses.

Ajouter un gestionnaire d'erreurs global

Dans les applications plus vastes, définissez des gestionnaires d'erreurs globaux qui renvoient des réponses cohérentes pour les erreurs courantes :

@app.errorhandler(400)
def bad_request(error):
    return jsonify({"error": "Bad request"}), 400

@app.errorhandler(404)
def not_found(error):
    return jsonify({"error": "Resource not found"}), 404

@app.errorhandler(500)
def internal_error(error):
    return jsonify({"error": "Internal server error"}), 500

Grâce à ces gestionnaires, l'API renvoie toujours du JSON structuré au lieu des pages d'erreur HTML par défaut.

Exemple de réponse d'erreur

Si un client tente de créer un élément sans les champs requis, l'API pourrait renvoyer :

{
  "error": "Both 'name' and 'price' are required."
}

Des messages d'erreur clairs permettent aux développeurs qui intègrent votre API de diagnostiquer leurs propres erreurs sans avoir à lire votre code source. Soit dit en passant, votre futur vous compte comme l'un de ces développeurs.

Pourquoi la validation et la gestion des erreurs sont importantes

Ensemble, elles empêchent les données non valides d'entrer dans la base de données, rendent les réponses prévisibles et permettent aux intégrateurs de déboguer rapidement. C'est une pratique standard dans le développement d'API moderne, et indispensable pour un service Flask en production.

blue arrow to the left
Imaginary Cloud logo

Comment générer une documentation OpenAPI pour une API Flask

Les API modernes doivent proposer une documentation lisible par machine, afin que les développeurs puissent comprendre les points de terminaison, les formats de requête et les réponses sans avoir à lire le code. La norme dominante est OpenAPI, qui décrit les API HTTP dans un format que les outils interprètent automatiquement.

Avec Flask, la solution la plus pratique est flask-smorest, une bibliothèque qui lie Flask à OpenAPI 3, à la validation des requêtes et à la documentation automatique Swagger UI.

Installer flask-smorest et marshmallow

Installez les paquets requis :

pip install flask-smorest marshmallow

Ou ajoutez-les à votre fichier requirements.txt :

flask-smorest
marshmallow

Dans cette configuration, flask-smorest génère la documentation OpenAPI et gère le routage de l'API, tandis que marshmallow (présenté dans la section sur la structure) s'occupe de la validation des requêtes et de la sérialisation des réponses.

Configurer Flask pour la documentation OpenAPI

Avant de créer des points de terminaison, configurez l'application pour générer la documentation :

from flask import Flask
from flask_smorest import Api

app = Flask(__name__)
app.config["API_TITLE"] = "Items API"
app.config["API_VERSION"] = "v1"
app.config["OPENAPI_VERSION"] = "3.0.3"
app.config["OPENAPI_URL_PREFIX"] = "/"
app.config["OPENAPI_SWAGGER_UI_PATH"] = "/swagger-ui"
app.config["OPENAPI_SWAGGER_UI_URL"] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist/"
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///items_smorest.db"

Les paramètres clés incluent API_TITLE (le nom de votre API), API_VERSION, OPENAPI_VERSION (la version de la spécification) et OPENAPI_SWAGGER_UI_PATH (l'emplacement où la documentation interactive est hébergée, par exemple /swagger-ui).

Définir les schémas de requête et de réponse

Avec flask-smorest, la structure des données que votre API accepte et renvoie est définie à l'aide de schémas Marshmallow. Créez-en un pour décrire un élément :

from marshmallow import Schema, fields

class ItemSchema(Schema):
    id = fields.Int(dump_only=True)
    name = fields.Str(required=True)
    price = fields.Float(required=True)

Un seul schéma remplit quatre fonctions : il valide les requêtes entrantes, documente le format attendu, sérialise les réponses et génère une sortie OpenAPI précise. C'est pourquoi nous recommandons l'approche « schemas-first ».

Créer des points de terminaison d'API documentés

Créez des points de terminaison en utilisant un Blueprint, regroupant les routes associées :

from flask_smorest import Blueprint

blp = Blueprint("items", __name__, url_prefix="/items", description="Operations on items")

Chaque blueprint devient une section dans la documentation générée.

Implémenter des endpoints CRUD avec validation et documentation

Implémentez maintenant les endpoints pour créer et récupérer des éléments :

@blp.route("/")
class ItemList(MethodView):
    @blp.response(200, ItemSchema(many=True))
    def get(self):
        return Item.query.all()

    @blp.arguments(ItemSchema)
    @blp.response(201, ItemSchema)
    def post(self, new_data):
        item = Item(**new_data)
        db.session.add(item)
        db.session.commit()
        return item

Ici, @blp.arguments valide le corps de la requête entrante, @blp.response documente et sérialise la sortie, et MethodView regroupe plusieurs méthodes HTTP sous une même route. Les décorateurs mettent à jour automatiquement la documentation OpenAPI.

Enregistrer le blueprint

Enregistrez le blueprint auprès de l'instance API pour activer les endpoints :

api.register_blueprint(blp)

Consulter la documentation interactive de l'API

Une fois l'application lancée, ouvrez l'URL de l'interface Swagger dans votre navigateur :

http://localhost:5000/swagger-ui

L'interface interactive Swagger vous permet de visualiser tous les endpoints, d'inspecter les paramètres, de tester les requêtes directement depuis le navigateur et d'explorer les schémas. De plus, comme OpenAPI est un standard industriel, cette même spécification permet de générer des clients et d'utiliser des outils de test d'API automatisés.

blue arrow to the left
Imaginary Cloud logo

Comment déployer une API Flask en production

Le serveur Flask intégré est-il adapté à la production ? Non. Il est conçu pour le développement ; les déploiements en production nécessitent un serveur WSGI et un serveur web pour gérer le trafic réel de manière fiable.

D'après les audits d'IC : une observation récurrente dans nos revues est l'utilisation du serveur de développement Flask en production parce qu'il « fonctionnait ». C'est vrai, jusqu'à ce qu'un trafic simultané arrive.

Une configuration de déploiement courante associe Gunicorn ou uWSGI en tant que serveur WSGI avec Nginx comme proxy inverse, hébergé sur une plateforme cloud ou de conteneurs telle que AWS, Azure ou Google Cloud. Gunicorn et uWSGI sont des serveurs WSGI de qualité production : ce sont des programmes qui exécutent plusieurs copies de votre application Python et gèrent les requêtes entrantes, ce qui est précisément la tâche pour laquelle le serveur de développement monothread n'a jamais été conçu.

Par exemple, exécutez une application Flask en production avec Gunicorn :

gunicorn -w 4 "app:app"

Dans cette commande, -w 4 lance quatre processus de travail et app:app fait référence à l'objet application Flask.

Dans les environnements modernes, les API Flask sont généralement livrées sous forme de conteneurs Docker, ce qui simplifie la mise à l'échelle, la gestion de l'environnement et le déploiement continu. Si votre équipe utilise Kubernetes, notre guide sur la création d'un pipeline CI/CD optimisé pour Kubernetes explique comment les API conteneurisées comme celle-ci passent du commit au cluster.

blue arrow to the left
Imaginary Cloud logo

Comment sécuriser une API Flask avec l'authentification

La plupart des API en production restreignent l'accès afin que seuls les utilisateurs ou services autorisés puissent atteindre les points de terminaison protégés. Les approches habituelles sont les clés API pour un accès simple de service à service, les JWT (JSON Web Tokens) pour l'authentification des utilisateurs, et OAuth 2.0 pour les intégrations tierces.

L'authentification basée sur les JWT est le modèle que nous privilégions le plus pour les API Flask. Un utilisateur se connecte avec ses identifiants, le serveur émet un jeton signé, et le client présente ce jeton à chaque requête dans l'en-tête Authorization (le nom de l'en-tête conserve son orthographe américaine car la norme HTTP le définit ainsi).

Exemple d'en-tête :

Authorization: Bearer <your-jwt-token>

Des extensions telles que Flask-JWT-Extended gèrent la manipulation des jetons et la protection des routes, vous évitant ainsi de devoir implémenter vous-même la cryptographie. Une fois l'autorisation en place, seuls les clients autorisés accèdent à l'API, les données sensibles restent protégées et l'utilisation peut être surveillée par client.

D'après la pratique d'audit d'IC : nous traitons l'authentification comme une partie intégrante de l'architecture initiale, et non comme une tâche de renforcement à effectuer à la fin. L'ajouter a posteriori sur des dizaines de points de terminaison existants est systématiquement plus coûteux que de l'intégrer dès la conception de la première route.
blue arrow to the left
Imaginary Cloud logo

Check-list de préparation à la mise en production d'API Flask par IC

Les tutoriels s'arrêtent généralement au stade où « l'API fonctionne ». Chez Imaginary Cloud, avant de valider une API Flask pour la production, celle-ci doit réussir notre check-list de préparation à la mise en production, la même procédure que nous appliquons lors de nos Audits techniques et UX.

Cinq points de cette check-list sont absents de la plupart des guides Flask :

  1. Tests: le code peut-il être modifié en toute sécurité et transmis à une nouvelle équipe ?
  2. Gestion des secrets: les identifiants sont-ils retirés du code et du contrôle de version ?
  3. Limitation du débit (Rate limiting): l'API est-elle protégée contre les abus et les pics de requêtes ?
  4. Journalisation et observabilité: en cas de panne, pouvez-vous identifier quoi et pourquoi ?
  5. Configuration CORS: les frontends qui ont besoin de l'API peuvent-ils y accéder, et eux seuls ?

Examinons-les un par un.

Comment tester une API Flask

Flask est fourni avec un client de test qui appelle vos points de terminaison sans lancer de serveur, et il s'associe naturellement à pytest. Voici à quoi ressemble un test minimal :

import pytest
from app import create_app, db

@pytest.fixture
def client():
    app = create_app(testing=True)
    with app.test_client() as client:
        with app.app_context():
            db.create_all()
        yield client

def test_create_item(client):
    response = client.post("/items", json={"name": "Keyboard", "price": 49.9})
    assert response.status_code == 201
    assert response.get_json()["name"] == "Keyboard"

Les tests unitaires couvrent les fonctions individuelles ; les tests d'intégration comme celui ci-dessus sollicitent le cycle complet de la requête, du routage à la sérialisation, en passant par la validation et la base de données. Exécutez les deux en intégration continue à chaque commit, sur une base de données éphémère.

Comment gérer la configuration et les secrets

Les URL de bases de données, les clés de signature JWT et les identifiants tiers ne doivent jamais être codés en dur ou intégrés au contrôle de version. Lisez-les plutôt à partir de variables d'environnement. En local, un fichier .env chargé avec python-dotenv rend cela pratique :

import os
from dotenv import load_dotenv

load_dotenv()
SQLALCHEMY_DATABASE_URI = os.environ["DATABASE_URL"]
JWT_SECRET_KEY = os.environ["JWT_SECRET_KEY"]

Ajoutez .env à .gitignore. En production, injectez ces mêmes variables via le gestionnaire de secrets de votre plateforme (AWS Secrets Manager, Azure Key Vault ou les secrets Kubernetes).

Comment ajouter une limitation de débit à une API Flask

La limitation de débit protège l'API contre les abus et les clients bien intentionnés bloqués dans des boucles de nouvelle tentative. Flask-Limiter l'ajoute en quelques lignes :

from flask_limiter import Limiter
from flask_limiter.util import get_remote_address

limiter = Limiter(get_remote_address, app=app, default_limits=["100 per minute"])

Les limites par route peuvent ensuite être resserrées sur les points de terminaison coûteux. Les routes de connexion et les points de terminaison de recherche sont les candidats habituels.

Comment ajouter la journalisation à une API Flask en production

Lorsqu'un incident survient en production, les journaux font toute la différence entre un diagnostic de cinq minutes et un diagnostic de cinq heures. Configurez le module standard logging de Python avec une sortie structurée, et utilisez les hooks de requête de Flask (une forme légère de middleware qui exécute du code avant et après chaque requête) pour marquer chaque ligne de journal avec un identifiant de requête :

import logging, uuid
from flask import g, request

logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s [%(request_id)s] %(message)s")

@app.before_request
def assign_request_id():
    g.request_id = request.headers.get("X-Request-ID", uuid.uuid4().hex)

Grâce aux identifiants de requête, une requête défaillante peut être tracée à travers chaque ligne de journal qu'elle a produite, et à travers les services si les appels en aval transmettent l'en-tête. Pour une observabilité complète, envoyez les journaux vers un agrégateur (CloudWatch, Grafana Loki ou une plateforme APM telle que Sentry ou Datadog) plutôt que de les laisser sur le serveur.

Comment configurer CORS dans une API Flask

Si une interface basée sur un navigateur consomme votre API depuis un domaine différent, le navigateur bloque les requêtes jusqu'à ce que l'API envoie les en-têtes CORS (Cross-Origin Resource Sharing) appropriés. Flask-CORS gère cela :

from flask_cors import CORS

CORS(app, origins=["https://app.example.com"])

Listez les origines exactes utilisées par vos interfaces. L'utilisation du caractère générique * pour les origines est un raccourci courant, et une découverte fréquente lors des audits de sécurité, car il permet à n'importe quel site web sur Internet d'appeler votre API depuis le navigateur de ses utilisateurs.

D'après la pratique d'audit d'IC : parmi ces cinq points, l'absence de tests est celui qui détermine si une base de code peut être confiée à une nouvelle équipe. Une API Flask non testée n'est pas terminée. Elle fonctionne simplement.

Flask ou FastAPI : quel framework choisir ?

Flask est l'un des frameworks web Python les plus utilisés pour créer des API, mais ce n'est pas la seule option. FastAPI a connu une croissance rapide en tant que framework moderne conçu spécifiquement pour les API haute performance.

Le sondage 2025 Stack Overflow auprès des développeurs illustre ce changement : FastAPI et Flask sont chacun utilisés par environ 15 % des répondants, et la progression de cinq points de pourcentage d'une année sur l'autre pour FastAPI est l'une des plus importantes parmi tous les frameworks web. Tous deux sont prêts pour la production. Ils diffèrent simplement par leur philosophie.

Matrice comparative des fonctionnalités

Un examen détaillé des différences techniques, couvrant l'outillage, l'architecture et l'expérience développeur :

Catégorie de fonctionnalitésFlaskFastAPI
Historique des versionsÉtabli (2010)Moderne (2018)
Capacités asynchronesPrise en charge limitéeNatif ASGI
Intégrité des donnéesNécessite MarshmallowIntégré (Pydantic)
Auto-documentationNécessite des extensionsOpenAPI automatique
Complexité d'apprentissageFaibleModérée (indications de type)

Deux termes de ce tableau méritent quelques explications. L'ASGI (Asynchronous Server Gateway Interface) est le successeur du WSGI qui permet aux applications Python de gérer de nombreuses requêtes simultanément. Pydantic est une bibliothèque Python qui valide et analyse les données à l'aide d'indices de type, et elle alimente la validation des requêtes intégrée de FastAPI.

En résumé : Flask vous offre un noyau minimal et synchrone, vous laissant assembler la validation et la documentation via des extensions comme Marshmallow et flask-smorest. FastAPI inverse ce compromis. La gestion asynchrone, la validation et la documentation OpenAPI sont intégrées, au prix d'un écosystème plus récent et d'une courbe d'apprentissage liée aux indices de type.

Quand utiliser Flask

Flask est adapté lorsque vous avez besoin d'un framework qui s'adapte à l'application plutôt que l'inverse : API de petite et moyenne taille, microservices, services backend pour applications web et projets nécessitant un contrôle total sur l'architecture. C'est également le choix pragmatique pour les équipes déjà familières avec Flask ou son écosystème d'extensions.

Quand NE PAS utiliser Flask

Il faut être honnête, certains projets ne se prêtent pas à l'utilisation de Flask. Si vous développez une nouvelle API, axée sur l'asynchrone et devant gérer des milliers de connexions simultanées (chat, streaming, intégrations haute fréquence), le modèle ASGI natif de FastAPI offre d'emblée ce que Flask ne permet qu'au prix de solutions de contournement. Il en va de même si votre équipe découvre les deux frameworks et que le projet nécessite une validation rigoureuse des requêtes : les contrôles intégrés de Pydantic vous épargnent un travail que Flask laisse à votre propre rigueur.

Quand utiliser FastAPI

FastAPI est conçu spécifiquement pour les API et propose davantage de fonctionnalités natives, comme le détaille la documentation de FastAPI . C'est le choix le plus robuste pour les API asynchrones à haute performance, les bases de code exploitant les annotations de type Python, et les équipes souhaitant une validation et une documentation interactive générées automatiquement plutôt qu'assemblées via des extensions.

Quel framework est le meilleur ?

Honnêtement, ce n'est pas la bonne question. Flask offre une flexibilité maximale et seize ans de maturité écosystémique ; FastAPI propose l'asynchrone natif ainsi qu'une validation et une documentation intégrées. Les facteurs déterminants sont l'expérience de votre équipe, les exigences de votre projet et les compromis de risque abordés ci-après, soit les mêmes facteurs qui guident toute décision technologique.

Flask vs FastAPI : comment les CTO et responsables techniques doivent trancher

Pour les CTO et les responsables techniques, le débat entre Flask et FastAPI ne porte que rarement sur les benchmarks. Il s'agit d'une question de risque : risque lié au recrutement, risque de livraison et coût à long terme de la maintenance de ce que votre équipe déploiera ce trimestre.

Flask est le choix le moins risqué si votre équipe le maîtrise déjà. Des développeurs ayant des années d'expérience sur Flask livrent plus rapidement et commettent moins d'erreurs architecturales que dans un framework appris sous la pression des délais. De plus, l'écosystème mature de Flask limite les imprévus une fois le système en production. Enfin, il s'appuie sur l'un des plus grands viviers de talents en développement web Python (environ un développeur sur sept dans l' enquête Stack Overflow 2025 l'utilise déjà), ce qui est crucial lorsque l'équipe doit s'agrandir.

FastAPI réduit un autre type de risque. Pour les API asynchrones à haut débit, sa validation et sa documentation intégrées éliminent des catégories entières de défauts que les équipes Flask doivent prévenir par la discipline et l'ajout d'extensions.

Le compromis à évaluer est celui entre la rapidité de mise sur le marché immédiate et les coûts de maintenance futurs. Dans les bases de code que nous auditons, les systèmes les plus coûteux à maintenir ne sont que rarement basés sur le « mauvais » framework : ce sont ceux où chaque développeur valide les requêtes différemment et où personne n'écrit de tests. Ces lacunes s'accumulent sous forme de dette technique quel que soit le framework choisi.

Quel est le coût sur douze mois ? Le schéma est constant : la livraison des fonctionnalités ralentit car chaque modification nécessite de réapprendre des comportements non documentés, l'intégration d'un nouveau développeur passe de quelques jours à plusieurs semaines, et le premier incident sérieux prend plus de temps à diagnostiquer qu'il ne le devrait. C'est là, et non dans le choix du framework, qu'une revue d'architecture structurée devient rentable.

Points clés : Créer des API avec Flask

En résumé : Flask est un framework web Python léger, en développement continu depuis 2010, qui permet de créer des API REST en associant des routes HTTP à des fonctions. Une API Flask prête pour la production ajoute cinq éléments à la version de base des tutoriels : la persistance des données via SQLAlchemy, la validation des requêtes avec des messages d'erreur explicites, une documentation OpenAPI générée avec flask-smorest, une structure de projet modulaire utilisant les Blueprints, et un déploiement derrière un serveur WSGI de production tel que Gunicorn.

FastAPI est l'alternative principale ; il est plus rapide pour les charges de travail asynchrones et propose une documentation automatique native. Le choix entre les deux doit reposer sur l'expertise de l'équipe et les coûts de maintenance, et non sur des benchmarks.

  • Flask est adapté aux API REST et aux microservices lorsque l'équipe souhaite garder un contrôle total sur l'architecture.
  • La préparation à la production implique la persistance, la validation, une gestion structurée des erreurs, des tests, la gestion des secrets, la limitation de débit, la journalisation et le CORS, et ne se limite pas à de simples endpoints fonctionnels.
  • SQLAlchemy fait abstraction de la couche base de données, permettant ainsi de commencer un projet avec SQLite puis de migrer vers PostgreSQL sans restructuration.
  • flask-smorest génère une documentation OpenAPI à partir des mêmes schémas Marshmallow que ceux utilisés pour valider les requêtes.
  • Le choix entre Flask et FastAPI est une question de gestion des risques et d'expertise technique pour les responsables d'ingénierie, et non un concours de performances.

S'il ne faut retenir qu'une chose, c'est celle-ci : ce ne sont pas les frameworks qui génèrent des coûts de maintenance, ce sont les habitudes.

Foire aux questions

Qu'est-ce qu'une API Flask ?

Une API Flask est un service web RESTful conçu avec le framework Flask en Python. Elle expose des points de terminaison HTTP appelés par les clients, échangeant généralement des données au format JSON.

Puis-je utiliser Flask comme backend pour mon application ?

Oui. Flask sert de backend pour les API qui alimentent des applications frontend, des applications mobiles ou des services tiers. Des extensions gèrent les fonctionnalités annexes : Flask-SQLAlchemy pour les données, Flask-JWT-Extended pour l'authentification, Flask-Limiter pour la limitation de débit.

Quelle est la différence entre Flask et REST ?

Flask est un framework web ; REST est un style architectural pour la conception d'applications en réseau. Vous utilisez Flask pour implémenter des API REST : le framework fournit le routage et la gestion des requêtes, tandis que REST fournit les conventions de conception.

Python Flask est-il adapté à la création d'API ?

Oui, pour une raison précise : son noyau léger signifie que l'API ne contient que ce que vous y ajoutez. En contrepartie, la validation, la documentation et la structure sont à votre charge, et ce guide explique comment intégrer chacun de ces aspects.

Flask est-il toujours pertinent en 2026 ?

Oui. Environ 15 % des répondants à l'enquête Stack Overflow Developer Survey 2025 utilisent Flask, soit autant que FastAPI, et son écosystème d'extensions bénéficie de seize années de maintenance continue. Ce qui a changé, c'est la norme pour les nouvelles API intensives en asynchrone, où FastAPI est désormais le choix le plus courant.

Dois-je utiliser Flask ou FastAPI pour un nouveau projet en 2026 ?

Choisissez Flask si votre équipe le maîtrise déjà, si l'API n'est pas intensive en asynchrone ou si vous étendez un système Flask existant. Choisissez FastAPI pour les nouveaux projets, les API à haut débit ou axées sur l'asynchrone, où la validation et la documentation intégrées réduisent les risques de livraison. L'analyse complète des compromis se trouve dans la section destinée aux responsables techniques ci-dessus.

Quelle est la rapidité de Flask par rapport à FastAPI ?

Pour des charges de travail CRUD synchrones derrière un serveur WSGI correctement configuré, le framework est rarement le facteur limitant. C'est généralement la base de données. FastAPI prend clairement l'avantage sur les charges de travail concurrentes limitées par les entrées/sorties, où son modèle ASGI natif gère de nombreuses requêtes simultanées qui occuperaient chacune un worker Flask.

Flask ou Django : lequel choisir ?

Ils répondent à des besoins différents. Flask est un micro-framework minimaliste qui s'enrichit selon vos choix ; Django est livré avec un ORM, une interface d'administration et un système d'authentification intégrés. Choisissez Flask pour les API et les microservices si vous souhaitez garder le contrôle ; optez pour Django si vous préférez une solution « tout compris » en acceptant ses conventions.

Flask est-il adapté à la production ?

Oui, à condition d'utiliser le bon serveur. Le serveur de développement intégré n'est pas sécurisé pour la production ; il faut donc déployer un serveur WSGI comme Gunicorn ou uWSGI derrière un proxy inverse tel qu'Nginx, généralement au sein de conteneurs Docker. Configuré ainsi, Flask gère les charges de production de manière fiable.

Comment déployer une API Flask ?

Avec un serveur WSGI et un proxy inverse. Les étapes de base sont :

  1. Empaqueter l'application et installer les dépendances.
  2. L'exécuter avec un serveur WSGI de production tel que Gunicorn.
  3. Placer un proxy inverse comme Nginx en amont pour gérer le trafic entrant.
  4. L'héberger sur un serveur cloud ou une plateforme de conteneurs.

Une commande Gunicorn classique ressemble à ceci :

gunicorn -w 4 "app:app"

Dans les infrastructures modernes, toute cette pile est déployée sous forme de conteneur Docker sur AWS, Azure ou Google Cloud.

Comment activer CORS dans une API Flask ?

Installez l'extension Flask-CORS et enregistrez-la dans votre application en spécifiant les origines exactes utilisées par vos frontends. Évitez d'utiliser des caractères génériques pour les origines avec * en production, car cela permet à n'importe quel site web d'appeler votre API depuis le navigateur de ses visiteurs. La section sur la préparation à la mise en production ci-dessus présente la configuration en deux lignes.

Quelle est la différence entre Flask et Django REST Framework ?

La différence réside dans le niveau de structure intégrée. Flask est un micro-framework léger où vous choisissez vos bibliothèques et votre architecture ; Django REST Framework est une couche complète reposant sur Django, incluant l'authentification, la sérialisation, les permissions et les vues API.

En règle générale, Flask convient aux API de petite à moyenne taille, aux microservices et aux architectures personnalisées, tandis que Django REST Framework est adapté aux applications plus vastes qui tirent parti de l'écosystème et des conventions intégrés de Django.

Si votre équipe cherche à structurer une nouvelle API ou à faire passer un service existant en production, Imaginary Cloud peut examiner votre architecture et identifier l'approche la plus adaptée à votre échelle et à votre équipe. Contactez-nous pour entamer la discussion.

Créez des produits évolutifs grâce au développement web et mobile (appel à l'action)
Pedro Martinho
Pedro Martinho

Développeur associé travaillant principalement avec les technologies Backend. Un entrepreneur qui s'intéresse à la science des données. J'adore le sport, les livres audio, le café et les mèmes !

Read more posts by this author
Tiago Franco
Tiago Franco

CEO @ Imaginary Cloud et co-auteur du livre Product Design Process. J'aime la nourriture, le vin et le Krav Maga (pas nécessairement dans cet ordre).

Read more posts by this author
Alexandra Mendes
Alexandra Mendes

Alexandra Mendes est spécialiste senior de la croissance chez Imaginary Cloud et possède plus de 3 ans d'expérience dans la rédaction de textes sur le développement de logiciels, l'IA et la transformation numérique. Après avoir suivi un cours de développement frontend, Alexandra a acquis des compétences pratiques en matière de codage et travaille désormais en étroite collaboration avec les équipes techniques. Passionnée par la façon dont les nouvelles technologies façonnent les entreprises et la société, Alexandra aime transformer des sujets complexes en contenus clairs et utiles pour les décideurs.

LinkedIn

Read more posts by this author

People who read this post, also found these interesting:

Dropdown caret icon