Tempo stimato : 15 minuti
Difficoltà : Intermedia ⭐⭐
Tipo di server : Python
📋 Introduzione
Questa guida ti spiega come ospitare un'API REST sviluppata con Flask o FastAPI su OuiPanel. La tua API sarà accessibile 24 ore su 24, 7 giorni su 7, con la possibilità di aggiungere un nome di dominio personalizzato e HTTPS.
Flask vs FastAPI
| Criterio | Flask | FastAPI |
|---|---|---|
| Difficoltà | Principiante | Intermedio |
| Installazione | Facile (nessuna compilazione) | Pesante (compilazione Rust) |
| Spazio disco richiesto | ~100 MB | ~5 GB minimo |
| Performance | Buona | Eccellente (async) |
| Documentazione auto | No (estensione) | Sì (Swagger/OpenAPI) |
| Validazione dati | Manuale | Automatica (Pydantic) |
| Ideale per | API semplici, piccoli server | API moderne, grandi server |
💡 Raccomandazione : Se hai un server con poco spazio di archiviazione (< 5 GB), utilizza Flask.
Di cosa hai bisogno
| Prerequisiti | Descrizione |
|---|---|
| 📁 Il tuo codice API | File Python (app.py, main.py...) |
| 🐍 Un server Python | Ordinato su OuiHeberg |
| 🌐 Un nome di dominio | (Opzionale) Per un accesso tramite URL personalizzato |
💡 Non hai ancora un server Python?
Ordina uno su : https://www.ouiheberg.com/fr/hebergement-python
📁 Passo 1 : Preparare i File dell'API
Struttura dei file
La tua API deve avere questa struttura :
📁 MonAPI/
├── 📄 app.py ← File principale (o main.py)
├── 📄 requirements.txt ← Dipendenze Python
├── 📄 .env ← Variabili d'ambiente (creato sul server)
└── 📁 routes/ ← (Opzionale) Cartella delle route
🌶️ Opzione A : API con Flask
File requirements.txt (Flask)
flask==2.3.3
python-dotenv==1.0.0
werkzeug==2.3.7
| Pacchetto | Descrizione |
|---|---|
flask | Framework web minimalista |
python-dotenv | Caricare le variabili da .env |
werkzeug | Utilità WSGI (incluso con Flask) |
⚠️ Importante : Utilizza queste versioni esatte per evitare problemi di compatibilità.
File principale (app.py) - Flask
import os
from dotenv import load_dotenv
# Caricare le variabili d'ambiente da .env
load_dotenv()
from flask import Flask, jsonify, request
# Creare l'applicazione Flask
app = Flask(__name__)
# ============================================
# ROUTE DELL'API
# ============================================
# Route principale
@app.route('/')
def home():
return jsonify({
'status': 'online',
'message': 'Benvenuto nella mia API Flask!',
'version': '1.0.0'
})
# Route di salute (health check)
@app.route('/health')
def health():
return jsonify({
'status': 'healthy',
'service': 'La mia API Flask'
})
# Esempio di dati (simulando un database)
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 tutti gli elementi
@app.route('/api/items', methods=['GET'])
def get_items():
return jsonify({
'success': True,
'data': items,
'count': len(items)
})
# GET un elemento per 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': 'Elemento non trovato'
}), 404
# POST creare un elemento
@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': 'Il campo "name" è obbligatorio'
}), 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': 'Elemento creato con successo',
'data': new_item
}), 201
# PUT modificare un elemento
@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': 'Elemento modificato con successo',
'data': item
})
return jsonify({
'success': False,
'error': 'Elemento non trovato'
}), 404
# DELETE eliminare un elemento
@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'Elemento {item_id} eliminato con successo'
})
return jsonify({
'success': False,
'error': 'Elemento non trovato'
}), 404
# ============================================
# GESTIONE DEGLI ERRORI
# ============================================
@app.errorhandler(404)
def not_found(error):
return jsonify({
'success': False,
'error': 'Risorsa non trovata'
}), 404
@app.errorhandler(500)
def internal_error(error):
return jsonify({
'success': False,
'error': 'Errore interno del server'
}), 500
# ============================================
# AVVIO DEL SERVER
# ============================================
if __name__ == '__main__':
# Porta : utilizza SERVER_PORT (OuiPanel) o 5000 per impostazione predefinita
port = int(os.getenv('SERVER_PORT', 5000))
# IMPORTANTE : Ascoltare su 0.0.0.0 per OuiPanel
app.run(host='0.0.0.0', port=port)
⚠️ IMPORTANTE : L'API deve ascoltare su
0.0.0.0e nonlocalhosto127.0.0.1per essere accessibile dall'esterno.
⚡ Opzione B : API con FastAPI
⚠️ Attenzione : FastAPI richiede
pydanticche deve essere compilato. Questo richiede molto spazio disco (diversi GB) durante l'installazione. Se ricevi un erroreNo space left on device, utilizza Flask al suo posto o aumenta lo spazio di archiviazione del tuo server.
File requirements.txt (FastAPI)
fastapi==0.104.1
uvicorn==0.24.0
python-dotenv==1.0.0
| Pacchetto | Descrizione |
|---|---|
fastapi | Framework web moderno e veloce |
uvicorn | Server ASGI per FastAPI |
python-dotenv | Caricare le variabili da .env |
💡 Raccomandazione spazio di archiviazione : Prevedi almeno 5 GB di spazio libero per l'installazione di FastAPI.
File principale (app.py) - FastAPI
import os
from dotenv import load_dotenv
# Caricare le variabili d'ambiente da .env
load_dotenv()
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Optional, List
# Creare l'applicazione FastAPI
app = FastAPI(
title="La mia API FastAPI",
description="Un'API REST moderna con FastAPI",
version="1.0.0",
docs_url="/docs", # Documentazione Swagger
redoc_url="/redoc" # Documentazione ReDoc
)
# ============================================
# MODELLI PYDANTIC (validazione dei dati)
# ============================================
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
# ============================================
# DATI ESEMPIO (simulando un database)
# ============================================
items_db = [
{"id": 1, "name": "Item 1", "price": 10.99, "description": "Primo elemento"},
{"id": 2, "name": "Item 2", "price": 24.99, "description": "Secondo elemento"},
{"id": 3, "name": "Item 3", "price": 5.49, "description": "Terzo elemento"},
]
# ============================================
# ROUTE DELL'API
# ============================================
# Route principale
@app.get("/", tags=["Generale"])
async def home():
return {
"status": "online",
"message": "Benvenuto nella mia API FastAPI!",
"version": "1.0.0",
"docs": "/docs"
}
# Route di salute (health check)
@app.get("/health", tags=["Generale"])
async def health():
return {
"status": "healthy",
"service": "La mia API FastAPI"
}
# GET tutti gli elementi
@app.get("/api/items", tags=["Elementi"])
async def get_items():
return {
"success": True,
"data": items_db,
"count": len(items_db)
}
# GET un elemento per ID
@app.get("/api/items/{item_id}", tags=["Elementi"])
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="Elemento non trovato")
# POST creare un elemento
@app.post("/api/items", status_code=201, tags=["Elementi"])
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": "Elemento creato con successo",
"data": new_item
}
# PUT modificare un elemento
@app.put("/api/items/{item_id}", tags=["Elementi"])
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": "Elemento modificato con successo",
"data": updated_item
}
raise HTTPException(status_code=404, detail="Elemento non trovato")
# DELETE eliminare un elemento
@app.delete("/api/items/{item_id}", tags=["Elementi"])
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"Elemento {item_id} eliminato"}
raise HTTPException(status_code=404, detail="Elemento non trovato")
# ============================================
# AVVIO DEL SERVER
# ============================================
if __name__ == "__main__":
import uvicorn
# Porta : utilizza SERVER_PORT (OuiPanel) o 8000 per impostazione predefinita
port = int(os.getenv('SERVER_PORT', 8000))
# IMPORTANTE : Ascoltare su 0.0.0.0 per OuiPanel
uvicorn.run(app, host="0.0.0.0", port=port)
💡 Bonus FastAPI : La documentazione interattiva è generata automaticamente!
- Swagger UI :
http://tuo-ip:porta/docs- ReDoc :
http://tuo-ip:porta/redoc
📤 Passo 2 : Caricare i File su OuiPanel
Via il Gestore File
- Accedi a OuiPanel
- Seleziona il tuo server Python
- Nel menu laterale, clicca su Gestore file

- Elimina i file di default (se ci sono)
- Clicca su Invia (Upload)
- Carica i tuoi file :
app.py(omain.py)requirements.txt- Le tue cartelle (
routes/,models/...) se necessario

⚠️ Non caricare : Il file
.envsarà creato direttamente sul server (più sicuro).
Via SFTP (Consigliato per più file)
- Accedi in SFTP con FileZilla
- Trascina e rilascia tutto il contenuto della tua cartella API
- Verifica che tutti i file siano stati caricati correttamente
📖 Consulta la guida "Accesso SFTP con FileZilla" per istruzioni dettagliate.
🔑 Passo 3 : Creare il File .env
Creare il file .env
- Nel Gestore file, clicca su Nuovo file
- Nominalo
.env(con il punto davanti) - Aggiungi le tue variabili :
# Configurazione dell'API
DEBUG=false
PORT=8000
# Database (se necessario)
DATABASE_URL=mysql://user:password@host:3306/database
# Chiavi API (esempi)
API_KEY=la_tua_chiave_api_segreta
SECRET_KEY=la_tua_chiave_segreta_per_jwt

- Clicca su Crea o Salva
⚠️ Importante :
- Nessuno spazio attorno al
=- Nessuna virgolette attorno ai valori semplici
- Non condividere mai questo file
⚙️ Passo 4 : Configurare il File di Avvio
OuiPanel deve sapere quale file Python eseguire all'avvio.
Accedere alle impostazioni
- Nel menu laterale, clicca su Configurazione
- Clicca su Impostazioni del server

Configurare il file da eseguire
Trova il campo File da eseguire (o Main File / Startup File) :
| Il tuo file principale | Valore da impostare |
|---|---|
app.py | app.py |
main.py | main.py |
api.py | api.py |
src/app.py | src/app.py |
⚠️ Importante : Il nome deve corrispondere esattamente al tuo file (sensibile al maiuscolo/minuscolo).
🚀 Passo 5 : Avviare l'API
Avviare il server
- Nel menu laterale, clicca su Console
- Clicca su Avvia
Installazione automatica delle dipendenze
Al primo avvio, il server installa automaticamente i pacchetti :
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 ✅ Passo 6 : Testare l'API
Recuperare l'indirizzo
- Annota la porta visualizzata nella console (es:
25639) - Recupera l'IP del tuo server nella Vista Globale
- L'indirizzo della tua API è :
http://IP:PORT
Esempio : http://51.77.xxx.xxx:25639


Testare gli endpoint
Con un browser :
- Apri
http://51.77.xxx.xxx:25639/→ Dovrebbe visualizzare il JSON di benvenuto - Apri
http://51.77.xxx.xxx:25639/health→ Health check - (FastAPI) Apri
http://51.77.xxx.xxx:25639/docs→ Documentazione Swagger
Con curl :
# GET - Pagina principale
curl http://51.77.xxx.xxx:25639/
# GET - Lista degli elementi
curl http://51.77.xxx.xxx:25639/api/items
# GET - Un elemento specifico
curl http://51.77.xxx.xxx:25639/api/items/1
# POST - Creare un elemento
curl -X POST http://51.77.xxx.xxx:25639/api/items \
-H "Content-Type: application/json" \
-d '{"name": "Nuovo elemento", "price": 29.99}'
# PUT - Modificare un elemento
curl -X PUT http://51.77.xxx.xxx:25639/api/items/1 \
-H "Content-Type: application/json" \
-d '{"name": "Elemento modificato", "price": 39.99}'
# DELETE - Eliminare un elemento
curl -X DELETE http://51.77.xxx.xxx:25639/api/items/1
Con Postman / Insomnia :
- Importa l'URL di base :
http://51.77.xxx.xxx:25639 - Testa i tuoi diversi endpoint

🌐 Passo 7 : Configurare un Nome di Dominio (Proxy Manager)
Per accedere alla tua API tramite un URL pulito con HTTPS (es: https://api.miosito.com), utilizza il Proxy Manager.
Configurare il DNS
- In OuiPanel → Proxy Manager, annota l'IP del Proxy
- Presso il tuo registrar (OVH, Cloudflare, ecc.), crea un record DNS :
| Tipo | Nome | Valore |
|---|---|---|
A | api | IP del Proxy |
Aggiungere il dominio in OuiPanel
- Nel menu laterale, clicca su Proxy Manager
- Clicca su Aggiungi
- Compila :
| Campo | Valore |
|---|---|
| Nome di dominio | api.miosito.com |
| Porta | La porta della tua API (es: 25639) |
| SSL | ✅ Attivato |

- Clicca su Crea la redirezione
Risultato
La tua API è ora accessibile tramite :
- ✅
https://api.miosito.com(con HTTPS automatico) - ✅ Certificato SSL gratuito (Let's Encrypt)
Esempio di chiamata :
curl https://api.miosito.com/api/items
📖 Consulta la guida "Configurare un Nome di Dominio con il Proxy Manager" per ulteriori dettagli.
🗄️ Bonus : Connessione a un Database
MySQL con Flask (PyMySQL)
Aggiungi in requirements.txt :
pymysql==1.1.0
Esempio di connessione :
import pymysql
import os
# Connessione a 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'
)
# Esempio di query
with connection.cursor() as cursor:
cursor.execute("SELECT * FROM items")
result = cursor.fetchall()
Variabili .env da aggiungere :
DB_HOST=mysql-host.ouiheberg.com
DB_USER=tuo_user
DB_PASSWORD=tuo_password
DB_NAME=tuo_database
📖 Consulta la guida "Creare e Gestire un Database MySQL" per creare il tuo database.
🔧 Risoluzione dei Problemi
L'API non si avvia
| ❌ Errore | ✅ Soluzione |
|---|---|
ModuleNotFoundError: No module named 'flask' | Controlla requirements.txt e riavvia |
ModuleNotFoundError: No module named 'fastapi' | Controlla requirements.txt e riavvia |
ModuleNotFoundError: No module named 'dotenv' | Aggiungi python-dotenv in requirements.txt |
SyntaxError | Errore nel tuo codice Python |
Errore "No space left on device" (FastAPI)
Questo errore si verifica quando pydantic-core (dipendenza di FastAPI) deve essere compilato con Rust :
error: No space left on device (os error 28)
ERROR: Failed building wheel for pydantic-core
| ✅ Soluzioni |
|---|
| 1. Usa Flask al posto (non richiede compilazione) |
| 2. Aumenta il storage del tuo server (5+ GB raccomandati) |
| 3. Pulisci i file temporanei e riprova |
💡 Raccomandazione : Per i piccoli server con poco spazio di archiviazione, Flask è più adatto di FastAPI.
L'API si avvia ma non è accessibile
| ❌ Causa | ✅ Soluzione |
|---|---|
Ascolto su localhost | Cambia in 0.0.0.0 |
| Porta errata | Usa os.getenv('SERVER_PORT') |
Controlla il tuo codice :
# ❌ ERRATO - ascolta solo in locale
app.run(host='localhost', port=5000)
app.run(host='127.0.0.1', port=5000)
# ✅ CORRETTO - ascolta su tutte le interfacce
app.run(host='0.0.0.0', port=port)
uvicorn.run(app, host='0.0.0.0', port=port)
Errore 502 Bad Gateway (Proxy Manager)
| ❌ Causa | ✅ Soluzione |
|---|---|
| API non avviata | Avvia il server in OuiPanel |
| Porta errata nel Proxy Manager | Controlla la porta configurata |
| API crashata | Controlla la Console |
Il file .env non viene letto
| ❌ Causa | ✅ Soluzione |
|---|---|
| python-dotenv non installato | Controlla requirements.txt |
| load_dotenv() non chiamato | Aggiungi load_dotenv() all'inizio del file |
| File mal nominato | Il file deve chiamarsi esattamente .env |
Errore CORS
Se chiami la tua API da un frontend (React, Vue, ecc.) :
| ❌ Errore | ✅ Soluzione |
|---|---|
Access-Control-Allow-Origin | Aggiungi Flask-CORS o CORSMiddleware (vedi sezione Sicurezza) |
🔒 Sicurezza
File .env
| ✅ Da fare | ❌ Da non fare |
|---|---|
Creare il .env sul server | Caricare il .env dal tuo PC |
Aggiungere .env al .gitignore | Commit il .env su GitHub |
| Utilizzare variabili per i segreti | Mettere le chiavi API nel codice |
Buone pratiche API
- ✅ Valida sempre gli input dell'utente
- ✅ Usa HTTPS in produzione (Proxy Manager)
- ✅ Non esporre gli errori dettagliati in produzione
- ✅ Aggiungi un autenticazione per le rotte sensibili
Attivare CORS (se necessario)
Se la tua API è chiamata da un frontend (React, Vue, ecc.) su un altro dominio :
Flask - Aggiungi flask-cors :
# requirements.txt
flask-cors==4.0.0
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
FastAPI - Il middleware è già disponibile :
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
📂 Struttura Avanzata (Raccomandata)
Per un'API più complessa, organizza il tuo codice :
📁 LaMiaAPI/
├── 📄 app.py ← Punto di ingresso
├── 📄 requirements.txt
├── 📄 .env
├── 📁 routes/
│ ├── 📄 __init__.py
│ ├── 📄 items.py ← Rotte /api/items
│ └── 📄 users.py ← Rotte /api/users
├── 📁 models/
│ └── 📄 item.py ← Modello Item
└── 📁 utils/
└── 📄 helpers.py ← Funzioni utilitarie
💡 Per le grandi API, questa struttura consente di organizzare meglio il codice e facilita la manutenzione.
📝 Riepilogo
1. Scegliere il framework (Flask o FastAPI)
2. Preparare i file (app.py + requirements.txt con python-dotenv)
3. Assicurarsi che il server ascolti su 0.0.0.0:PORT
4. Caricare i file su OuiPanel (senza il .env)
5. Creare il file .env sul server
6. Configurare il file di avvio (app.py, main.py...)
7. Avviare il server
8. Testare tramite http://IP:PORT
9. (Opzionale) Configurare il Proxy Manager per HTTPS
ENDPOINT DI TEST :
├── GET / → Pagina principale
├── GET /health → Controllo di salute
├── GET /api/items → Elenco degli items
├── GET /api/items/1 → Un item
├── POST /api/items → Creare un item
├── PUT /api/items/1 → Modificare un item
└── DELETE /api/items/1 → Eliminare un item
(FastAPI) Documentazione auto :
├── /docs → Swagger UI
└── /redoc → ReDocHai bisogno di un hosting Python?
Distribuisci le tue applicazioni Python con il nostro hosting ottimizzato e supporto dedicato.
