|
from fastapi import FastAPI, HTTPException, Query |
|
from fastapi.middleware.cors import CORSMiddleware |
|
from pydantic import BaseModel |
|
from typing import Dict, Any, Optional, List |
|
from chat_service import translate_locale, get_supported_languages |
|
import logging |
|
|
|
|
|
logging.basicConfig(level=logging.INFO) |
|
logger = logging.getLogger(__name__) |
|
|
|
app = FastAPI( |
|
title="Local Translation Server", |
|
description="API per tradurre oggetti locale dall'italiano ad altre lingue", |
|
version="1.0.0" |
|
) |
|
|
|
|
|
app.add_middleware( |
|
CORSMiddleware, |
|
allow_origins=["*"], |
|
allow_credentials=True, |
|
allow_methods=["*"], |
|
allow_headers=["*"], |
|
) |
|
|
|
|
|
class LocaleRequest(BaseModel): |
|
"""Modello per la richiesta di traduzione di un oggetto locale.""" |
|
locales: Dict[str, str] |
|
|
|
model_config = { |
|
"json_schema_extra": { |
|
"example": { |
|
"locales": { |
|
"welcome_message": "Benvenuto nella nostra applicazione!", |
|
"button_save": "Salva", |
|
"error_required": "Questo campo è obbligatorio", |
|
"html_content": "<p>Clicca <a href='#'>qui</a> per continuare</p>", |
|
"template_message": "Ciao {name}, hai {count} nuovi messaggi" |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
class LocaleResponse(BaseModel): |
|
"""Modello per la risposta di traduzione.""" |
|
translated_locales: Dict[str, str] |
|
source_language: str |
|
target_language: str |
|
|
|
model_config = { |
|
"json_schema_extra": { |
|
"example": { |
|
"translated_locales": { |
|
"welcome_message": "Welcome to our application!", |
|
"button_save": "Save", |
|
"error_required": "This field is required", |
|
"html_content": "<p>Click <a href='#'>here</a> to continue</p>", |
|
"template_message": "Hello {name}, you have {count} new messages" |
|
}, |
|
"source_language": "it", |
|
"target_language": "en" |
|
} |
|
} |
|
} |
|
|
|
|
|
class LanguagesResponse(BaseModel): |
|
"""Modello per la risposta delle lingue supportate.""" |
|
supported_languages: List[str] |
|
|
|
|
|
@app.get("/", summary="Health Check") |
|
def health_check(): |
|
"""Endpoint per verificare che il server sia in esecuzione.""" |
|
return { |
|
"service": "Local Translation Server", |
|
"status": "running", |
|
"version": "1.0.0" |
|
} |
|
|
|
|
|
@app.get("/languages", response_model=LanguagesResponse, summary="Lingue Supportate") |
|
def get_languages(): |
|
"""Restituisce la lista delle lingue supportate per la traduzione.""" |
|
return LanguagesResponse(supported_languages=get_supported_languages()) |
|
|
|
|
|
@app.post("/translate", response_model=LocaleResponse, summary="Traduci Locales") |
|
async def translate_locales( |
|
request: LocaleRequest, |
|
target_language: str = Query( |
|
..., |
|
description="Codice della lingua target (es: 'en', 'fr', 'de')", |
|
example="en" |
|
) |
|
): |
|
""" |
|
Traduce un oggetto contenente locales dall'italiano alla lingua specificata. |
|
|
|
- **locales**: Dizionario chiave-valore dove ogni chiave è un identificatore |
|
e ogni valore è il testo in italiano da tradurre |
|
- **target_language**: Codice della lingua target (parametro query) |
|
|
|
Il servizio preserva: |
|
- Tag HTML nel testo |
|
- Placeholders con parentesi graffe (es: {name}, {count}) |
|
- Struttura delle chiavi originali |
|
""" |
|
try: |
|
logger.info(f"Richiesta traduzione per {len(request.locales)} locales verso {target_language}") |
|
|
|
|
|
supported_languages = get_supported_languages() |
|
if target_language not in supported_languages: |
|
raise HTTPException( |
|
status_code=400, |
|
detail=f"Lingua '{target_language}' non supportata. Lingue disponibili: {supported_languages}" |
|
) |
|
|
|
|
|
translated_data = translate_locale(request.locales, target_language) |
|
|
|
logger.info(f"Traduzione completata per {len(translated_data)} locales") |
|
|
|
return LocaleResponse( |
|
translated_locales=translated_data, |
|
source_language="it", |
|
target_language=target_language |
|
) |
|
|
|
except ValueError as e: |
|
raise HTTPException(status_code=400, detail=str(e)) |
|
except Exception as e: |
|
logger.error(f"Errore durante la traduzione: {str(e)}") |
|
raise HTTPException(status_code=500, detail=f"Errore interno del server: {str(e)}") |
|
|
|
|
|
@app.post("/translate-single", summary="Traduci Singolo Testo") |
|
async def translate_single_text( |
|
text: str = Query(..., description="Testo in italiano da tradurre"), |
|
target_language: str = Query( |
|
..., |
|
description="Codice della lingua target (es: 'en', 'fr', 'de')", |
|
example="en" |
|
) |
|
): |
|
""" |
|
Traduce un singolo testo dall'italiano alla lingua specificata. |
|
Utile per test rapidi o traduzioni singole. |
|
""" |
|
try: |
|
from chat_service import get_translation_service |
|
|
|
|
|
supported_languages = get_supported_languages() |
|
if target_language not in supported_languages: |
|
raise HTTPException( |
|
status_code=400, |
|
detail=f"Lingua '{target_language}' non supportata. Lingue disponibili: {supported_languages}" |
|
) |
|
|
|
|
|
translation_service = get_translation_service() |
|
translated_text = translation_service.translate_text(text, target_language) |
|
|
|
return { |
|
"original_text": text, |
|
"translated_text": translated_text, |
|
"source_language": "it", |
|
"target_language": target_language |
|
} |
|
|
|
except ValueError as e: |
|
raise HTTPException(status_code=400, detail=str(e)) |
|
except Exception as e: |
|
logger.error(f"Errore durante la traduzione: {str(e)}") |
|
raise HTTPException(status_code=500, detail=f"Errore interno del server: {str(e)}") |
|
|
|
|
|
if __name__ == "__main__": |
|
import uvicorn |
|
uvicorn.run(app, host="0.0.0.0", port=7860) |
|
|