Serveurs de jeux & OuiPanel15 décembre 2025 3 vues

Comment déployer une API Flask ou FastAPI sur OuiPanel

Comment déployer une API Flask ou FastAPI sur OuiPanel

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.0 et non localhost ou 127.0.0.1 pour être accessible depuis l'extérieur.


⚡ Option B : API avec FastAPI

⚠️ Attention : FastAPI nécessite pydantic qui doit être compilé. Cela requiert beaucoup d'espace disque (plusieurs Go) pendant l'installation. Si vous avez une erreur No 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

  1. Connectez-vous à OuiPanel
  2. Sélectionnez votre serveur Python
  3. Dans le menu latéral, cliquez sur Gestionnaire de fichiers

Image

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

Image

⚠️ Ne pas uploader : Le fichier .env sera créé directement sur le serveur (plus sécurisé).


Via SFTP (Recommandé pour plusieurs fichiers)

  1. Connectez-vous en SFTP avec FileZilla
  2. Glissez-déposez tout le contenu de votre dossier API
  3. 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

  1. Dans le Gestionnaire de fichiers, cliquez sur Nouveau fichier
  2. Nommez-le .env (avec le point devant)
  3. 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

Image

  1. 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

  1. Dans le menu latéral, cliquez sur Configuration
  2. Cliquez sur Paramètres du serveur

Image


Configurer le fichier à exécuter

Repérez le champ Fichier à exécuter (ou Main File / Startup File) :Image

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

  1. Dans le menu latéral, cliquez sur Console
  2. 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

  1. Notez le port affiché dans la console (ex: 25639)
  2. Récupérez l'IP de votre serveur dans la Vue Globale
  3. L'adresse de votre API est : http://IP:PORT

Exemple : http://51.77.xxx.xxx:25639

Image

Image

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

Image


🌐 É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

  1. Dans OuiPanelProxy Manager, notez l'IP du Proxy
  2. Chez votre registrar (OVH, Cloudflare, etc.), créez un enregistrement DNS :
Type Nom Valeur
A api IP du Proxy

Ajouter le domaine dans OuiPanel

  1. Dans le menu latéral, cliquez sur Proxy Manager
  2. Cliquez sur Ajouter
  3. Remplissez :
Champ Valeur
Nom de domaine api.monsite.com
Port Le port de votre API (ex: 25639)
SSL ✅ Activé

Image

  1. 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