Dans ce tutoriel, vous allez apprendre à faire une api web en python avec le framework Flask. Le framework flask est un framework python permettant la réalisation d’un site web ou d’une api web. Son principal avantage est d’être simple à utiliser, mais sans perdre de fonctionnalités. De plus, il peut quasiment tout faire grâce à de nombreuses extensions.
L’objectif de ce tutoriel est d’apprendre à :
- faire une api web en python
- traiter les requêtes
Installation
Pour commencer, il vous faut un interpréteur Python en version 3 (les exemples fonctionnent avec toute version récente de Python 3).
Linux - Ubuntu (& toutes distributions utilisant APT comme gestionnaire de paquets)
Sous linux, c’est assez simple.
Depuis un terminal, installation de python3 :
sudo apt install python3
Vous aurez ensuite besoin de pip, le gestionnaire de paquets de python. Il est souvent préinstallé avec python, mais dans le doute :
sudo apt install python3-pip
Maintenant installons flask :
pip3 install flask
Sur les distributions récentes (Debian 12, Ubuntu 23.04 et suivantes), pip refuse
d’installer des paquets dans le python du système, même avec l’option --user,
et affiche l’erreur externally-managed-environment. Dans ce cas, créez un
environnement virtuel dans le dossier de votre projet et installez Flask dedans :
sudo apt install python3-venv
python3 -m venv venv
source venv/bin/activate
pip install flask
Windows
Sur Windows, ça se complique un peu, commencez par télécharger python3 pour Windows ici et installez-le.
Déplacez-vous dans le dossier où vous avez installé python et faites :
shift + click droit -> ouvrir une fenêtre powershell (sur Windows 7, pour les
réfractaires au changement, ça doit être cmd)
Vous êtes normalement dans un terminal, entrez alors :
.\python.exe -m pip install flask
MacOS
N’ayant pas de Mac, je ne peux pas tester l’installation. Il faut toutefois aussi utiliser python et pip, et suivre les instructions pour linux afin d’installer flask.
Une requête HTTP ?
L’HyperText Transfer Protocol (HTTP, littéralement « protocole de transfert hypertexte ») est un protocole de communication client-serveur développé pour le World Wide Web.
Source Wikipédia.
Il existe 5 principales méthodes HTTP :
- GET : accéder à une ressource
- HEAD : récupérer l’en-tête d’une ressource, par exemple pour connaître la date de sa dernière modification (utile pour le système de cache d’un navigateur)
- POST : ajouter une ressource
- PUT : mettre à jour une ressource
- DELETE : supprimer une ressource
Qu’est-ce qu’une API web ?
Une API Web est une interface de programmation composée d’un ou de plusieurs endpoints exposés publiquement via le Web, le plus souvent au moyen d’un système basé sur serveur web HTTP.
Source Wikipédia.
À ne pas confondre avec une API REST, qui est une api web avec un ensemble de contraintes et de règles prédéfinies à respecter. Toutes les API web ne sont pas des API REST…
Un premier Endpoint
Créez un fichier app.py avec le contenu suivant :
from flask import Flask
app = Flask(__name__)
@app.route('/')
def super_endpoint():
return 'Hello World'
Pour lancer votre premier Endpoint :
flask run
Ou sinon :
python -m flask run
Si vous allez sur http://127.0.0.1:5000/ avec votre navigateur web, vous
devriez avoir :
Hello World
Ou alors avec curl :
curl http://127.0.0.1:5000/
Hello World
Super, nous avons notre premier “hello world”, mais comment faire pour avoir plusieurs routes possibles ?
Routing
Pour régler ce problème, nous allons utiliser une fonctionnalité intégrée à
Flask pour faire du routing par rapport à notre URL.
On crée un nouvel endpoint qu’on pourra appeler avec
l’URL : http://127.0.0.1:5000/test
@app.route('/test')
def test_endpoint():
return 'test_endpoint'
curl http://127.0.0.1:5000/test
test_endpoint
Passer des paramètres
Dans la vraie vie, il est parfois (même très souvent) nécessaire de passer des
paramètres à notre endpoint.
Pour passer des paramètres avec le routing, on utilise les <> avec un simple
argument de notre fonction :
@app.route('/test/<id_test>')
def test_endpoint(id_test):
return f'test {id_test}'
Ce qui retourne :
curl http://127.0.0.1:5000/test/1
test 1
Par défaut le type est un string, mais il est possible de forcer le cast vers
un type en ajoutant un type dans les <> de la route :
@app.route('/test/<int:id_test>')
def test_endpoint(id_test):
return f'test {id_test}'
Il existe différents convertisseurs intégrés dans flask :
- string
- int
- float
- path
- uuid
Il est également possible de créer ses propres convertisseurs si nécessaire.
Méthodes HTTP
Par défaut, une route déclarée avec @app.route ne répond qu’aux requêtes GET
(Flask ajoute aussi automatiquement HEAD et OPTIONS). Pour choisir précisément
les méthodes acceptées par l’endpoint, on ajoute dans le décorateur @app.route
un paramètre methods :
@app.route('/test', methods=["GET"])
def test_endpoint_get():
return 'test_endpoint_get'
curl -X GET http://127.0.0.1:5000/test
test_endpoint_get
Le GET avec l’aide de curl renvoie bien la bonne valeur, mais si on tente avec un POST ça ne fonctionne pas ! Flask renvoie alors une erreur 405 Method Not Allowed, car la route n’autorise pas cette méthode.
curl -X POST http://127.0.0.1:5000/test
Traiter une requête POST
Pour traiter une requête POST, on a besoin de récupérer les données de celle-ci.
On importe donc request pour cela.
from flask import request
@app.route('/test', methods=["POST"])
def test_endpoint_post():
data = request.form
# Traiter la requête
return data
L’objet request convertit automatiquement les données de la requête en dictionnaire python. Dans l’autre sens, si notre API retourne un dictionnaire, flask se charge de le convertir pour nous en json :
curl -X POST http://127.0.0.1:5000/test -d "param1=jeej"
{"param1":"jeej"}
Attention, request.form ne contient que les données envoyées sous forme de
formulaire (application/x-www-form-urlencoded ou multipart/form-data). Si le
client envoie du JSON, il faut utiliser request.get_json() pour récupérer les
données.
Exemple d’un POST avec un traitement simpliste
@app.route('/exemple', methods=["POST"])
def test2_endpoint_post():
"""
Exemple de traitement
"""
responses = {}
param1 = request.form["param1"]
responses["return1"] = param1 + "AAA"
return responses
curl -X POST http://127.0.0.1:5000/exemple -d "param1=jeej"
{"return1":"jeejAAA"}
Voilà, vous êtes maintenant capable de créer une api web simple, mais performante. D’autres tutoriels sur flask seront prochainement disponibles : par exemple pour interroger une base de données et avoir des données dynamiques ou dockeriser son application flask.
Le code complet de ce tutoriel
from flask import Flask
from flask import request
app = Flask(__name__)
@app.route('/')
def super_endpoint():
return 'Hello World'
@app.route('/test/<id_test>')
def test_endpoint(id_test):
return f'test {id_test}'
@app.route('/test', methods=["GET"])
def test_endpoint_get():
return 'test_endpoint_get'
@app.route('/test', methods=["POST"])
def test_endpoint_post():
data = request.form
# traiter la requête
return data
@app.route('/exemple', methods=["POST"])
def test2_endpoint_post():
"""
Exemple de traitement
"""
responses = {}
param1 = request.form["param1"]
responses["return1"] = param1 + "AAA"
return responses