feat: add favicon.ico and gate model write APIs by env flag
- Generate and serve real /favicon.ico from static assets - Update HTML to use /favicon.ico - Add ENABLE_MODEL_RW_API setting (default: false) - Disable POST/DELETE model endpoints by default - Hide write endpoints from OpenAPI when disabled - Return 404 for write endpoints when disabled - Update env.example with ENABLE_MODEL_RW_API documentation - Update README and PRD with R/W API policy and remote compose notes - Add tests to verify write endpoints are disabled by default
This commit is contained in:
+19
-2
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>LLM Monitor - Dashboard Ollama</title>
|
||||
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🦙</text></svg>">
|
||||
<link rel="icon" href="/favicon.ico" sizes="any">
|
||||
<!-- Tailwind CSS (compiled for production) -->
|
||||
<link rel="stylesheet" href="/static/css/output.css">
|
||||
<!-- Fallback CDN for development (if output.css not available) -->
|
||||
|
||||
Reference in New Issue
Block a user