|
""" |
|
Sema Translation API - Main Application |
|
Enterprise-grade translation API with proper FastAPI structure |
|
""" |
|
|
|
from fastapi import FastAPI |
|
from fastapi.middleware.cors import CORSMiddleware |
|
from fastapi.middleware.trustedhost import TrustedHostMiddleware |
|
from slowapi import _rate_limit_exceeded_handler |
|
from slowapi.errors import RateLimitExceeded |
|
|
|
from .core.config import settings |
|
from .core.logging import configure_logging, get_logger |
|
from .middleware.request_middleware import request_middleware |
|
from .services.translation import load_models |
|
from .api.v1.endpoints import router as v1_router, limiter |
|
|
|
|
|
configure_logging() |
|
logger = get_logger() |
|
|
|
|
|
def create_application() -> FastAPI: |
|
"""Create and configure the FastAPI application""" |
|
|
|
app = FastAPI( |
|
title=settings.app_name, |
|
description=""" |
|
## π Enterprise Translation API |
|
|
|
A powerful, production-ready translation API supporting 200+ languages with automatic language detection. |
|
|
|
### π Key Features |
|
- **Automatic Language Detection**: Detects source language if not provided |
|
- **200+ Language Support**: Full FLORES-200 language code support |
|
- **Rate Limiting**: 60 requests/minute per IP address |
|
- **Usage Tracking**: Character count and request metrics |
|
- **High Performance**: CTranslate2 optimized inference |
|
- **Enterprise Monitoring**: Prometheus metrics and structured logging |
|
|
|
### π Rate Limits |
|
- **Per IP**: 60 requests per minute |
|
- **Character Limit**: 5000 characters per request |
|
- **Concurrent Requests**: Async processing for optimal performance |
|
|
|
### π Monitoring |
|
- **Health Checks**: `/health` endpoint for system monitoring |
|
- **Metrics**: `/metrics` endpoint for Prometheus integration |
|
- **Request Tracking**: Unique request IDs for debugging |
|
|
|
### π Language Support |
|
Supports all FLORES-200 language codes including: |
|
- **African Languages**: Swahili (swh_Latn), Kikuyu (kik_Latn), Luo (luo_Latn) |
|
- **European Languages**: English (eng_Latn), French (fra_Latn), Spanish (spa_Latn) |
|
- **And 190+ more languages** |
|
|
|
### π Usage Examples |
|
```bash |
|
# Basic translation with auto-detection |
|
curl -X POST "/translate" \\ |
|
-H "Content-Type: application/json" \\ |
|
-d '{"text": "Habari ya asubuhi", "target_language": "eng_Latn"}' |
|
|
|
# Translation with specified source language |
|
curl -X POST "/translate" \\ |
|
-H "Content-Type: application/json" \\ |
|
-d '{"text": "Hello world", "source_language": "eng_Latn", "target_language": "swh_Latn"}' |
|
``` |
|
""", |
|
version=settings.app_version, |
|
docs_url="/docs", |
|
redoc_url="/redoc", |
|
openapi_url="/openapi.json", |
|
contact={ |
|
"name": "Sema AI Team", |
|
"url": "https://github.com/lewiskimaru/sema", |
|
"email": "support@sema.ai" |
|
}, |
|
license_info={ |
|
"name": "MIT License", |
|
"url": "https://opensource.org/licenses/MIT" |
|
}, |
|
servers=[ |
|
{ |
|
"url": "https://sematech-sema-api.hf.space", |
|
"description": "Production server" |
|
}, |
|
{ |
|
"url": "http://localhost:8000", |
|
"description": "Development server" |
|
} |
|
] |
|
) |
|
|
|
|
|
app.state.limiter = limiter |
|
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler) |
|
|
|
|
|
if settings.allowed_hosts != ["*"]: |
|
app.add_middleware(TrustedHostMiddleware, allowed_hosts=settings.allowed_hosts) |
|
|
|
|
|
app.add_middleware( |
|
CORSMiddleware, |
|
allow_origins=settings.cors_origins, |
|
allow_credentials=True, |
|
allow_methods=["GET", "POST", "OPTIONS"], |
|
allow_headers=["*"], |
|
) |
|
|
|
|
|
app.middleware("http")(request_middleware) |
|
|
|
|
|
app.include_router(v1_router, prefix="/api/v1") |
|
app.include_router(v1_router) |
|
|
|
return app |
|
|
|
|
|
|
|
app = create_application() |
|
|
|
|
|
@app.on_event("startup") |
|
async def startup_event(): |
|
"""Initialize the application on startup""" |
|
logger.info("application_startup", version=settings.app_version, environment=settings.environment) |
|
|
|
print(f"\nπ΅ Starting {settings.app_name} v{settings.app_version}") |
|
print("πΌ Loading the Orchestra... π¦") |
|
|
|
try: |
|
load_models() |
|
logger.info("models_loaded_successfully") |
|
print("π API started successfully!") |
|
print(f"π Metrics enabled: {settings.enable_metrics}") |
|
print(f"π Environment: {settings.environment}") |
|
print(f"π Documentation: /docs") |
|
print(f"π Metrics: /metrics") |
|
print(f"β€οΈ Health: /health") |
|
print(f"π API v1: /api/v1/") |
|
print() |
|
|
|
except Exception as e: |
|
logger.error("startup_failed", error=str(e)) |
|
print(f"β Startup failed: {e}") |
|
raise |
|
|
|
|
|
@app.on_event("shutdown") |
|
async def shutdown_event(): |
|
"""Cleanup on application shutdown""" |
|
logger.info("application_shutdown") |
|
print("\nπ Shutting down Sema Translation API...") |
|
print("π§Ή Cleaning up resources...") |
|
print("β
Shutdown complete\n") |
|
|
|
|
|
if __name__ == "__main__": |
|
import uvicorn |
|
uvicorn.run( |
|
"app.main:app", |
|
host="0.0.0.0", |
|
port=8000, |
|
reload=settings.debug |
|
) |
|
|