File size: 5,383 Bytes
a7d24e3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
"""
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
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"
            }
        ]
    )

    # Add rate limiting
    app.state.limiter = limiter
    app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)

    # Security middleware
    if settings.allowed_hosts != ["*"]:
        app.add_middleware(TrustedHostMiddleware, allowed_hosts=settings.allowed_hosts)

    # CORS middleware
    app.add_middleware(
        CORSMiddleware,
        allow_origins=settings.cors_origins,
        allow_credentials=True,
        allow_methods=["GET", "POST", "OPTIONS"],
        allow_headers=["*"],
    )

    # Request middleware
    app.middleware("http")(request_middleware)

    # Include API routes
    app.include_router(v1_router, prefix="/api/v1")
    app.include_router(v1_router)  # Also include at root for backward compatibility

    return app


# Create the application instance
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
    )