CORS — pourquoi ça bloque ?
Votre dashboard Streamlit communique avec l'API Flask via HTTP. Mais dans certains cas, le navigateur peut bloquer ces appels. Ce mécanisme s'appelle CORS (Cross-Origin Resource Sharing).
Le mécanisme CORS
CORS est un mécanisme de sécurité des navigateurs web. Il bloque les requêtes HTTP entre deux origines différentes.
Deux URLs ont des origines différentes si elles diffèrent par le protocole, le domaine ou le port :
http://localhost:8501(Streamlit) ethttp://localhost:5000(Flask) = origines différentes (ports différents)http://localhost:5000/api/v1/ventesethttp://localhost:5000/api/v1/stats= même origine
Quand un navigateur web tente d'appeler localhost:5000 depuis une page servie par localhost:8501, il vérifie d'abord que le serveur autorise cette origine. Si le serveur ne renvoie pas les bons headers CORS, le navigateur bloque la requête.
Requête preflight
Pour les requêtes non triviales (avec des headers personnalisés, des méthodes autres que GET/POST, etc.), le navigateur envoie d'abord une requête OPTIONS (preflight) pour demander au serveur quelles origines il autorise. C'est une vérification préalable avant l'appel réel.
requests n'est pas concerné
CORS ne s'applique qu'aux navigateurs web. requests effectue les appels HTTP depuis le processus Python, sans passer par un navigateur. CORS ne bloque donc jamais vos appels requests.get().
# Fonctionne toujours, même sans configuration CORS
response = requests.get("http://localhost:5000/api/v1/ventes/par-region")
C'est la raison pour laquelle votre dashboard Streamlit fonctionne sans aucune configuration CORS : Streamlit exécute le code Python côté serveur, pas dans le navigateur.
Pourquoi CORS ne bloque pas les appels faits avec la bibliothèque requests en Python ?
Quand CORS devient un problème
CORS vous concernera si vous ajoutez :
- Un composant JavaScript via
st.components.html()dans Streamlit - Un client frontend React ou Vue.js qui consomme la même API
- Un notebook Jupyter exécuté dans un navigateur avec des appels
fetch()
Dans ces cas, les appels HTTP sont effectués par le navigateur (via fetch() ou XMLHttpRequest), et CORS s'applique pleinement.
Configurer flask-cors
Si CORS vous bloque, la solution côté Flask :
pip install flask-cors
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
# Option 1 : autoriser toutes les origines (développement uniquement)
CORS(app)
# Option 2 : restreindre aux origines nécessaires (recommandé)
CORS(app, origins=["http://localhost:8501", "https://mon-dashboard.com"])
# Option 3 : restreindre par route
CORS(app, resources={r"/api/*": {"origins": "http://localhost:8501"}})
Ne jamais autoriser toutes les origines en production
CORS(app) sans restriction autorise n'importe quel site web à appeler votre API. Acceptable en développement, mais dangereux en production. Listez toujours explicitement les origines autorisées.
Headers ajoutés par flask-cors
flask-cors ajoute ces headers aux réponses :
| Header | Rôle | Exemple |
|---|---|---|
Access-Control-Allow-Origin | Origines autorisées | http://localhost:8501 |
Access-Control-Allow-Methods | Méthodes HTTP autorisées | GET, POST, OPTIONS |
Access-Control-Allow-Headers | Headers personnalisés autorisés | Content-Type, Authorization |
CORS = protection navigateur, pas serveur
Le serveur ne bloque rien lui-même — il indique simplement au navigateur quelles origines il autorise via ces headers. C'est le navigateur qui décide de bloquer ou non la requête en lisant ces headers. Un client comme requests ou curl ignore complètement ces headers.
Quelle commande installe le support CORS pour Flask ?
À retenir
Points clés
- CORS est une protection navigateur —
requestsen Python n'est pas affecté - Deux origines sont différentes si le protocole, le domaine ou le port diffèrent
- Le navigateur envoie une requête preflight (
OPTIONS) avant l'appel réel - flask-cors ajoute les headers nécessaires côté Flask
- En production, toujours restreindre les origines autorisées
- Votre dashboard Streamlit fonctionne sans CORS car
requestsopère côté serveur
Ressources
MDN — CORS
Explication détaillée du mécanisme CORS par Mozilla
DocumentationDocumentation flask-cors
Guide d'installation et de configuration de flask-cors
DocumentationUne API accessible publiquement pose un autre problème : comment empêcher les utilisateurs non autorisés d'y accéder ?