Comment déployer une API Flask ou FastAPI sur OuiPanel
Temps estimé : 15 minutes
Difficulté : Intermédiaire ⭐⭐
Type de serveur : Python
📋 Introduction
Ce guide vous explique comment héberger une API REST développée avec Flask ou FastAPI sur OuiPanel. Votre API sera accessible 24h/24, 7j/7, avec possibilité d'ajouter un nom de domaine personnalisé et HTTPS.
Flask vs FastAPI
| Critère | Flask | FastAPI |
|---|---|---|
| Difficulté | Débutant | Intermédiaire |
| Installation | Simple (pas de compilation) | Lourde (compilation Rust) |
| Espace disque requis | ~100 Mo | ~5 Go minimum |
| Performance | Bonne | Excellente (async) |
| Documentation auto | Non (extension) | Oui (Swagger/OpenAPI) |
| Validation données | Manuelle | Automatique (Pydantic) |
| Idéal pour | APIs simples, petits serveurs | APIs modernes, gros serveurs |
💡 Recommandation : Si vous avez un serveur avec peu de stockage (< 5 Go), utilisez Flask.
Ce dont vous avez besoin
| Prérequis | Description |
|---|---|
| 📁 Votre code API | Fichiers Python (app.py, main.py...) |
| 🐍 Un serveur Python | Commandé sur OuiHeberg |
| 🌐 Un nom de domaine | (Optionnel) Pour un accès via URL personnalisée |
💡 Vous n'avez pas encore de serveur Python ?
Commandez-en un sur : https://www.ouiheberg.com/fr/hebergement-python
📁 Étape 1 : Préparer les Fichiers de l'API
Structure des fichiers
Votre API doit avoir cette structure :
📁 MonAPI/
├── 📄 app.py ← Fichier principal (ou main.py)
├── 📄 requirements.txt ← Dépendances Python
├── 📄 .env ← Variables d'environnement (créé sur le serveur)
└── 📁 routes/ ← (Optionnel) Dossier des routes
🌶️ Option A : API avec Flask
Fichier requirements.txt (Flask)
flask==2.3.3
python-dotenv==1.0.0
werkzeug==2.3.7
| Package | Description |
|---|---|
flask | Framework web minimaliste |
python-dotenv | Charger les variables depuis .env |
werkzeug | Utilitaires WSGI (inclus avec Flask) |
⚠️ Important : Utilisez ces versions exactes pour éviter les problèmes de compatibilité.
Fichier principal (app.py) - Flask
import os
from dotenv import load_dotenv
# Charger les variables d'environnement depuis .env
load_dotenv()
from flask import Flask, jsonify, request
# Créer l'application Flask
app = Flask(__name__)
# ============================================
# ROUTES DE L'API
# ============================================
# Route principale
@app.route('/')
def home():
return jsonify({
'status': 'online',
'message': 'Bienvenue sur mon API Flask !',
'version': '1.0.0'
})
# Route de santé (health check)
@app.route('/health')
def health():
return jsonify({
'status': 'healthy',
'service': 'Mon API Flask'
})
# Exemple de données (simulant une base de données)
items = [
{'id': 1, 'name': 'Item 1', 'price': 10.99},
{'id': 2, 'name': 'Item 2', 'price': 24.99},
{'id': 3, 'name': 'Item 3', 'price': 5.49}
]
# GET tous les éléments
@app.route('/api/items', methods=['GET'])
def get_items():
return jsonify({
'success': True,
'data': items,
'count': len(items)
})
# GET un élément par ID
@app.route('/api/items/<int:item_id>', methods=['GET'])
def get_item(item_id):
for item in items:
if item['id'] == item_id:
return jsonify({
'success': True,
'data': item
})
return jsonify({
'success': False,
'error': 'Item non trouvé'
}), 404
# POST créer un élément
@app.route('/api/items', methods=['POST'])
def create_item():
data = request.get_json()
if not data or 'name' not in data:
return jsonify({
'success': False,
'error': 'Le champ "name" est requis'
}), 400
new_id = max(item['id'] for item in items) + 1 if items else 1
new_item = {
'id': new_id,
'name': data['name'],
'price': data.get('price', 0)
}
items.append(new_item)
return jsonify({
'success': True,
'message': 'Item créé avec succès',
'data': new_item
}), 201
# PUT modifier un élément
@app.route('/api/items/<int:item_id>', methods=['PUT'])
def update_item(item_id):
data = request.get_json()
for item in items:
if item['id'] == item_id:
item['name'] = data.get('name', item['name'])
item['price'] = data.get('price', item['price'])
return jsonify({
'success': True,
'message': 'Item modifié avec succès',
'data': item
})
return jsonify({
'success': False,
'error': 'Item non trouvé'
}), 404
# DELETE supprimer un élément
@app.route('/api/items/<int:item_id>', methods=['DELETE'])
def delete_item(item_id):
for index, item in enumerate(items):
if item['id'] == item_id:
items.pop(index)
return jsonify({
'success': True,
'message': f'Item {item_id} supprimé avec succès'
})
return jsonify({
'success': False,
'error': 'Item non trouvé'
}), 404
# ============================================
# GESTION DES ERREURS
# ============================================
@app.errorhandler(404)
def not_found(error):
return jsonify({
'success': False,
'error': 'Ressource non trouvée'
}), 404
@app.errorhandler(500)
def internal_error(error):
return jsonify({
'success': False,
'error': 'Erreur interne du serveur'
}), 500
# ============================================
# DÉMARRAGE DU SERVEUR
# ============================================
if __name__ == '__main__':
# Port : utilise SERVER_PORT (OuiPanel) ou 5000 par défaut
port = int(os.getenv('SERVER_PORT', 5000))
# IMPORTANT : Écouter sur 0.0.0.0 pour OuiPanel
app.run(host='0.0.0.0', port=port)
⚠️ IMPORTANT : L'API doit écouter sur
0.0.0.0et nonlocalhostou127.0.0.1pour être accessible depuis l'extérieur.
⚡ Option B : API avec FastAPI
⚠️ Attention : FastAPI nécessite
pydanticqui doit être compilé. Cela requiert beaucoup d'espace disque (plusieurs Go) pendant l'installation. Si vous avez une erreurNo space left on device, utilisez Flask à la place ou augmentez le stockage de votre serveur.
Fichier requirements.txt (FastAPI)
fastapi==0.104.1
uvicorn==0.24.0
python-dotenv==1.0.0
| Package | Description |
|---|---|
fastapi | Framework web moderne et rapide |
uvicorn | Serveur ASGI pour FastAPI |
python-dotenv | Charger les variables depuis .env |
💡 Recommandation stockage : Prévoyez au moins 5 Go de stockage libre pour l'installation de FastAPI.
Fichier principal (app.py) - FastAPI
import os
from dotenv import load_dotenv
# Charger les variables d'environnement depuis .env
load_dotenv()
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Optional, List
# Créer l'application FastAPI
app = FastAPI(
title="Mon API FastAPI",
description="Une API REST moderne avec FastAPI",
version="1.0.0",
docs_url="/docs", # Documentation Swagger
redoc_url="/redoc" # Documentation ReDoc
)
# ============================================
# MODÈLES PYDANTIC (validation des données)
# ============================================
class ItemCreate(BaseModel):
name: str
price: float = 0
description: Optional[str] = None
class Item(BaseModel):
id: int
name: str
price: float
description: Optional[str] = None
# ============================================
# DONNÉES EXEMPLE (simulant une base de données)
# ============================================
items_db = [
{"id": 1, "name": "Item 1", "price": 10.99, "description": "Premier item"},
{"id": 2, "name": "Item 2", "price": 24.99, "description": "Deuxième item"},
{"id": 3, "name": "Item 3", "price": 5.49, "description": "Troisième item"},
]
# ============================================
# ROUTES DE L'API
# ============================================
# Route principale
@app.get("/", tags=["General"])
async def home():
return {
"status": "online",
"message": "Bienvenue sur mon API FastAPI !",
"version": "1.0.0",
"docs": "/docs"
}
# Route de santé (health check)
@app.get("/health", tags=["General"])
async def health():
return {
"status": "healthy",
"service": "Mon API FastAPI"
}
# GET tous les éléments
@app.get("/api/items", tags=["Items"])
async def get_items():
return {
"success": True,
"data": items_db,
"count": len(items_db)
}
# GET un élément par ID
@app.get("/api/items/{item_id}", tags=["Items"])
async def get_item(item_id: int):
for item in items_db:
if item["id"] == item_id:
return {"success": True, "data": item}
raise HTTPException(status_code=404, detail="Item non trouvé")
# POST créer un élément
@app.post("/api/items", status_code=201, tags=["Items"])
async def create_item(item: ItemCreate):
new_id = max(i["id"] for i in items_db) + 1 if items_db else 1
new_item = {
"id": new_id,
"name": item.name,
"price": item.price,
"description": item.description
}
items_db.append(new_item)
return {
"success": True,
"message": "Item créé avec succès",
"data": new_item
}
# PUT modifier un élément
@app.put("/api/items/{item_id}", tags=["Items"])
async def update_item(item_id: int, item: ItemCreate):
for index, existing_item in enumerate(items_db):
if existing_item["id"] == item_id:
updated_item = {
"id": item_id,
"name": item.name,
"price": item.price,
"description": item.description
}
items_db[index] = updated_item
return {
"success": True,
"message": "Item modifié avec succès",
"data": updated_item
}
raise HTTPException(status_code=404, detail="Item non trouvé")
# DELETE supprimer un élément
@app.delete("/api/items/{item_id}", tags=["Items"])
async def delete_item(item_id: int):
for index, item in enumerate(items_db):
if item["id"] == item_id:
items_db.pop(index)
return {"success": True, "message": f"Item {item_id} supprimé"}
raise HTTPException(status_code=404, detail="Item non trouvé")
# ============================================
# DÉMARRAGE DU SERVEUR
# ============================================
if __name__ == "__main__":
import uvicorn
# Port : utilise SERVER_PORT (OuiPanel) ou 8000 par défaut
port = int(os.getenv('SERVER_PORT', 8000))
# IMPORTANT : Écouter sur 0.0.0.0 pour OuiPanel
uvicorn.run(app, host="0.0.0.0", port=port)
💡 Bonus FastAPI : La documentation interactive est automatiquement générée !
- Swagger UI :
http://votre-ip:port/docs- ReDoc :
http://votre-ip:port/redoc
📤 Étape 2 : Uploader les Fichiers sur OuiPanel
Via le Gestionnaire de Fichiers
- Connectez-vous à OuiPanel
- Sélectionnez votre serveur Python
- Dans le menu latéral, cliquez sur Gestionnaire de fichiers

- Supprimez les fichiers par défaut (s'il y en a)
- Cliquez sur Envoyer (Upload)
- Uploadez vos fichiers :
app.py(oumain.py)requirements.txt- Vos dossiers (
routes/,models/...) si nécessaire

⚠️ Ne pas uploader : Le fichier
.envsera créé directement sur le serveur (plus sécurisé).
Via SFTP (Recommandé pour plusieurs fichiers)
- Connectez-vous en SFTP avec FileZilla
- Glissez-déposez tout le contenu de votre dossier API
- Vérifiez que tous les fichiers sont bien uploadés
📖 Consultez le guide "Accès SFTP avec FileZilla" pour les instructions détaillées.
🔑 Étape 3 : Créer le Fichier .env
Créer le fichier .env
- Dans le Gestionnaire de fichiers, cliquez sur Nouveau fichier
- Nommez-le
.env(avec le point devant) - Ajoutez vos variables :
# Configuration de l'API
DEBUG=false
PORT=8000
# Base de données (si nécessaire)
DATABASE_URL=mysql://user:password@host:3306/database
# Clés API (exemples)
API_KEY=votre_cle_api_secrete
SECRET_KEY=votre_cle_secrete_pour_jwt

- Cliquez sur Créer ou Enregistrer
⚠️ Important :
- Pas d'espaces autour du
=- Pas de guillemets autour des valeurs simples
- Ne partagez jamais ce fichier
⚙️ Étape 4 : Configurer le Fichier de Démarrage
OuiPanel doit savoir quel fichier Python exécuter au démarrage.
Accéder aux paramètres
- Dans le menu latéral, cliquez sur Configuration
- Cliquez sur Paramètres du serveur

Configurer le fichier à exécuter
Repérez le champ Fichier à exécuter (ou Main File / Startup File) :
| Votre fichier principal | Valeur à mettre |
|---|---|
app.py | app.py |
main.py | main.py |
api.py | api.py |
src/app.py | src/app.py |
⚠️ Important : Le nom doit correspondre exactement à votre fichier (sensible à la casse).
🚀 Étape 5 : Démarrer l'API
Lancer le serveur
- Dans le menu latéral, cliquez sur Console
- Cliquez sur Démarrer
Installation automatique des dépendances
Au premier démarrage, le serveur installe automatiquement les packages :
Flask :
Installing requirements from requirements.txt...
Successfully installed flask-3.0.0 python-dotenv-1.0.0 gunicorn-21.2.0
Running app.py...
* Running on http://0.0.0.0:25639
FastAPI :
Installing requirements from requirements.txt...
Successfully installed fastapi-0.109.0 uvicorn-0.27.0 python-dotenv-1.0.0
Running app.py...
INFO: Uvicorn running on http://0.0.0.0:25639 ✅ Étape 6 : Tester l'API
Récupérer l'adresse
- Notez le port affiché dans la console (ex:
25639) - Récupérez l'IP de votre serveur dans la Vue Globale
- L'adresse de votre API est :
http://IP:PORT
Exemple : http://51.77.xxx.xxx:25639


Tester les endpoints
Avec un navigateur :
- Ouvrez
http://51.77.xxx.xxx:25639/→ Devrait afficher le JSON de bienvenue - Ouvrez
http://51.77.xxx.xxx:25639/health→ Health check - (FastAPI) Ouvrez
http://51.77.xxx.xxx:25639/docs→ Documentation Swagger
Avec curl :
# GET - Page d'accueil
curl http://51.77.xxx.xxx:25639/
# GET - Liste des items
curl http://51.77.xxx.xxx:25639/api/items
# GET - Un item spécifique
curl http://51.77.xxx.xxx:25639/api/items/1
# POST - Créer un item
curl -X POST http://51.77.xxx.xxx:25639/api/items \
-H "Content-Type: application/json" \
-d '{"name": "Nouvel item", "price": 29.99}'
# PUT - Modifier un item
curl -X PUT http://51.77.xxx.xxx:25639/api/items/1 \
-H "Content-Type: application/json" \
-d '{"name": "Item modifié", "price": 39.99}'
# DELETE - Supprimer un item
curl -X DELETE http://51.77.xxx.xxx:25639/api/items/1
Avec Postman / Insomnia :
- Importez l'URL de base :
http://51.77.xxx.xxx:25639 - Testez vos différents endpoints

🌐 Étape 7 : Configurer un Nom de Domaine (Proxy Manager)
Pour accéder à votre API via une URL propre avec HTTPS (ex: https://api.monsite.com), utilisez le Proxy Manager.
Configurer le DNS
- Dans OuiPanel → Proxy Manager, notez l'IP du Proxy
- Chez votre registrar (OVH, Cloudflare, etc.), créez un enregistrement DNS :
| Type | Nom | Valeur |
|---|---|---|
A | api | IP du Proxy |
Ajouter le domaine dans OuiPanel
- Dans le menu latéral, cliquez sur Proxy Manager
- Cliquez sur Ajouter
- Remplissez :
| Champ | Valeur |
|---|---|
| Nom de domaine | api.monsite.com |
| Port | Le port de votre API (ex: 25639) |
| SSL | ✅ Activé |

- Cliquez sur Créer la redirection
Résultat
Votre API est maintenant accessible via :
- ✅
https://api.monsite.com(avec HTTPS automatique) - ✅ Certificat SSL gratuit (Let's Encrypt)
Exemple d'appel :
curl https://api.monsite.com/api/items
📖 Consultez le guide "Configurer un Nom de Domaine avec le Proxy Manager" pour plus de détails.
🗄️ Bonus : Connexion à une Base de Données
MySQL avec Flask (PyMySQL)
Ajoutez dans requirements.txt :
pymysql==1.1.0
Exemple de connexion :
import pymysql
import os
# Connexion à MySQL
connection = pymysql.connect(
host=os.getenv('DB_HOST', 'localhost'),
user=os.getenv('DB_USER', 'root'),
password=os.getenv('DB_PASSWORD', ''),
database=os.getenv('DB_NAME', 'mydb'),
charset='utf8mb4'
)
# Exemple de requête
with connection.cursor() as cursor:
cursor.execute("SELECT * FROM items")
result = cursor.fetchall()
Variables .env à ajouter :
DB_HOST=mysql-host.ouiheberg.com
DB_USER=votre_user
DB_PASSWORD=votre_password
DB_NAME=votre_base
📖 Consultez le guide "Créer et Gérer une Base de Données MySQL" pour créer votre base.
🔧 Dépannage
L'API ne démarre pas
| ❌ Erreur | ✅ Solution |
|---|---|
ModuleNotFoundError: No module named 'flask' | Vérifiez requirements.txt et redémarrez |
ModuleNotFoundError: No module named 'fastapi' | Vérifiez requirements.txt et redémarrez |
ModuleNotFoundError: No module named 'dotenv' | Ajoutez python-dotenv dans requirements.txt |
SyntaxError | Erreur dans votre code Python |
Erreur "No space left on device" (FastAPI)
Cette erreur survient quand pydantic-core (dépendance de FastAPI) doit être compilé avec Rust :
error: No space left on device (os error 28)
ERROR: Failed building wheel for pydantic-core
| ✅ Solutions |
|---|
| 1. Utilisez Flask à la place (ne nécessite pas de compilation) |
| 2. Augmentez le stockage de votre serveur (5+ Go recommandés) |
| 3. Nettoyez les fichiers temporaires et réessayez |
💡 Recommandation : Pour les petits serveurs avec peu de stockage, Flask est plus adapté que FastAPI.
L'API démarre mais n'est pas accessible
| ❌ Cause | ✅ Solution |
|---|---|
Écoute sur localhost | Changez pour 0.0.0.0 |
| Mauvais port | Utilisez os.getenv('SERVER_PORT') |
Vérifiez votre code :
# ❌ MAUVAIS - écoute uniquement en local
app.run(host='localhost', port=5000)
app.run(host='127.0.0.1', port=5000)
# ✅ BON - écoute sur toutes les interfaces
app.run(host='0.0.0.0', port=port)
uvicorn.run(app, host='0.0.0.0', port=port)
Erreur 502 Bad Gateway (Proxy Manager)
| ❌ Cause | ✅ Solution |
|---|---|
| API non démarrée | Démarrez le serveur dans OuiPanel |
| Mauvais port dans Proxy Manager | Vérifiez le port configuré |
| API crashée | Consultez la Console |
Le fichier .env n'est pas lu
| ❌ Cause | ✅ Solution |
|---|---|
| python-dotenv pas installé | Vérifiez requirements.txt |
| load_dotenv() pas appelé | Ajoutez load_dotenv() au début du fichier |
| Fichier mal nommé | Le fichier doit s'appeler exactement .env |
Erreur CORS
Si vous appelez votre API depuis un frontend (React, Vue, etc.) :
| ❌ Erreur | ✅ Solution |
|---|---|
Access-Control-Allow-Origin | Ajoutez Flask-CORS ou CORSMiddleware (voir section Sécurité) |
🔒 Sécurité
Fichier .env
| ✅ À faire | ❌ À ne pas faire |
|---|---|
Créer le .env sur le serveur | Uploader le .env depuis votre PC |
Ajouter .env au .gitignore | Commit le .env sur GitHub |
| Utiliser des variables pour les secrets | Mettre les clés API dans le code |
Bonnes pratiques API
- ✅ Validez toujours les entrées utilisateur
- ✅ Utilisez HTTPS en production (Proxy Manager)
- ✅ Ne pas exposer les erreurs détaillées en production
- ✅ Ajoutez une authentification pour les routes sensibles
Activer CORS (si nécessaire)
Si votre API est appelée depuis un frontend (React, Vue, etc.) sur un autre domaine :
Flask - Ajoutez flask-cors :
# requirements.txt
flask-cors==4.0.0
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
FastAPI - Le middleware est déjà disponible :
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
📂 Structure Avancée (Recommandée)
Pour une API plus complexe, organisez votre code :
📁 MonAPI/
├── 📄 app.py ← Point d'entrée
├── 📄 requirements.txt
├── 📄 .env
├── 📁 routes/
│ ├── 📄 __init__.py
│ ├── 📄 items.py ← Routes /api/items
│ └── 📄 users.py ← Routes /api/users
├── 📁 models/
│ └── 📄 item.py ← Modèle Item
└── 📁 utils/
└── 📄 helpers.py ← Fonctions utilitaires
💡 Pour les grosses APIs, cette structure permet de mieux organiser le code et facilite la maintenance.
📝 Récapitulatif
1. Choisir le framework (Flask ou FastAPI)
2. Préparer les fichiers (app.py + requirements.txt avec python-dotenv)
3. S'assurer que le serveur écoute sur 0.0.0.0:PORT
4. Uploader les fichiers sur OuiPanel (sans le .env)
5. Créer le fichier .env sur le serveur
6. Configurer le fichier de démarrage (app.py, main.py...)
7. Démarrer le serveur
8. Tester via http://IP:PORT
9. (Optionnel) Configurer le Proxy Manager pour HTTPS
ENDPOINTS DE TEST :
├── GET / → Page d'accueil
├── GET /health → Health check
├── GET /api/items → Liste des items
├── GET /api/items/1 → Un item
├── POST /api/items → Créer un item
├── PUT /api/items/1 → Modifier un item
└── DELETE /api/items/1 → Supprimer un item
(FastAPI) Documentation auto :
├── /docs → Swagger UI
└── /redoc → ReDoc

