diff --git a/PRD.md b/PRD.md index 54ba88a..81daa41 100644 --- a/PRD.md +++ b/PRD.md @@ -188,10 +188,15 @@ Dettagli di un modello specifico ``` #### `POST /api/v1/models/{model_name}/pull` -Scarica/carica un modello +Scarica/carica un modello (**disabilitato di default**) #### `DELETE /api/v1/models/{model_name}` -Elimina un modello +Elimina un modello (**disabilitato di default**) + +#### Policy endpoint R/W +- Gli endpoint `POST/DELETE` sono **non disponibili** per default. +- Si abilitano solo con variabile ambiente `ENABLE_MODEL_RW_API=true`. +- Se non abilitati, gli endpoint non sono esposti in Swagger e rispondono con `404`. --- @@ -244,7 +249,7 @@ Elimina un modello **Componenti:** - Dockerfile multi-stage ottimizzato -- docker-compose.yml con Ollama incluso +- docker-compose.yml per la sola dashboard (Ollama esterno/remoto) - Health checks configurati - Sempre acceso fino all'arresto manuale diff --git a/README.md b/README.md index dd4890c..0177569 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,7 @@ OLLAMA_TIMEOUT=30 API_HOST=0.0.0.0 API_PORT=8000 API_WORKERS=4 +ENABLE_MODEL_RW_API=false # CORS Configuration CORS_ORIGINS=http://localhost:3000,http://localhost:5173 @@ -105,6 +106,7 @@ ENVIRONMENT=development | `API_HOST` | `0.0.0.0` | Host su cui esporre l'API | | `API_PORT` | `8000` | Porta dell'API | | `API_WORKERS` | `4` | Worker processes | +| `ENABLE_MODEL_RW_API` | `false` | Abilita endpoint `POST/DELETE` sui modelli | | `CORS_ORIGINS` | `http://localhost:3000` | Origini CORS consentite | | `LOG_LEVEL` | `INFO` | Livello di logging | | `ENVIRONMENT` | `development` | Ambiente (development/production) | @@ -151,6 +153,21 @@ GET /api/v1/models/{model_name} GET /api/v1/health ``` +#### Endpoint R/W modelli (opzionali) + +Per impostazione predefinita gli endpoint di scrittura sono **disabilitati** e non disponibili. + +```bash +POST /api/v1/models/{model_name}/pull +DELETE /api/v1/models/{model_name} +``` + +Per abilitarli, imposta nel file `.env`: + +```env +ENABLE_MODEL_RW_API=true +``` + **Risposta:** ```json @@ -215,16 +232,16 @@ docker compose restart llm-monitor ### Container sempre acceso -Il container Ollama rimarrĂ in esecuzione fino al suo arresto manuale: +Il container `llm-monitor` rimarrĂ in esecuzione fino al suo arresto manuale: ```bash # Fermare -docker compose stop ollama +docker compose stop llm-monitor # oppure docker stop llm-monitor # Riavviare -docker compose start ollama +docker compose start llm-monitor # oppure docker start llm-monitor ``` diff --git a/app/api/models.py b/app/api/models.py index 71e5bfa..9bf8250 100644 --- a/app/api/models.py +++ b/app/api/models.py @@ -13,6 +13,15 @@ from app.config import settings logger = logging.getLogger(__name__) router = APIRouter() + +def ensure_rw_api_enabled() -> None: + """Blocca le API di scrittura se non abilitate esplicitamente.""" + if not settings.ENABLE_MODEL_RW_API: + raise HTTPException( + status_code=404, + detail="Endpoint non disponibile" + ) + class ModelInfo(BaseModel): """Informazioni su un modello""" name: str @@ -165,7 +174,10 @@ async def get_model(model_name: str): detail="Errore nel recupero del modello" ) -@router.post("/models/{model_name}/pull") +@router.post( + "/models/{model_name}/pull", + include_in_schema=settings.ENABLE_MODEL_RW_API +) async def pull_model(model_name: str): """ Scarica/carica un modello in Ollama @@ -176,6 +188,7 @@ async def pull_model(model_name: str): Returns: dict: Status del download """ + ensure_rw_api_enabled() try: response = requests.post( f"{settings.OLLAMA_HOST}/api/pull", @@ -198,7 +211,10 @@ async def pull_model(model_name: str): detail="Errore nel pull del modello" ) -@router.delete("/models/{model_name}") +@router.delete( + "/models/{model_name}", + include_in_schema=settings.ENABLE_MODEL_RW_API +) async def delete_model(model_name: str): """ Elimina un modello da Ollama @@ -209,6 +225,7 @@ async def delete_model(model_name: str): Returns: dict: Confirmazione eliminazione """ + ensure_rw_api_enabled() try: response = requests.delete( f"{settings.OLLAMA_HOST}/api/delete", diff --git a/app/config.py b/app/config.py index a0e29be..8b538ad 100644 --- a/app/config.py +++ b/app/config.py @@ -16,6 +16,7 @@ class Settings(BaseSettings): API_HOST: str = "0.0.0.0" API_PORT: int = 8000 API_WORKERS: int = 4 + ENABLE_MODEL_RW_API: bool = False # CORS CORS_ORIGINS: str = "http://localhost:3000,http://localhost:5173,http://localhost:8000" diff --git a/app/web/static/favicon.ico b/app/web/static/favicon.ico new file mode 100644 index 0000000..0014651 Binary files /dev/null and b/app/web/static/favicon.ico differ diff --git a/app/web/templates/index.html b/app/web/templates/index.html index 6099f01..ffd636e 100644 --- a/app/web/templates/index.html +++ b/app/web/templates/index.html @@ -4,7 +4,7 @@