Mind-Reframe / ai-core /app /main.py
cuongpm-cs's picture
Initial commit
f171e60
Raw
History Blame Contribute Delete
4.92 kB
from fastapi import FastAPI, Request, Depends
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from slowapi import _rate_limit_exceeded_handler
from slowapi.errors import RateLimitExceeded
from app.config import settings
from app.utils.errors import AIException
from app.models.responses import ErrorResponse
from app.api.v1.router import api_router
from app.middleware.logging import RequestLoggingMiddleware
from app.middleware.rate_limit import limiter, rate_limit_exceeded_handler
from app.utils.logger import logger
app = FastAPI(
title=settings.APP_NAME,
version=settings.APP_VERSION,
debug=settings.DEBUG,
description="""
# AI-Core API
API for LLM integration with support for multiple providers and prompt templates.
## Features
* **Multiple LLM Providers**: OpenAI, Anthropic (coming soon)
* **Chat & Completion**: Support for both conversational and completion endpoints
* **Streaming**: Real-time streaming responses
* **Prompt Templates**: Pre-built and custom prompt templates
* **Template Management**: Create, list, and execute prompt templates
* **Rate Limiting**: Automatic rate limiting to prevent abuse
* **Authentication**: API key-based authentication (optional)
## Authentication
When authentication is enabled, include your API key in the request header:
```
X-API-Key: your-api-key-here
```
## Rate Limits
* Default: 60 requests per minute per IP
* Hourly: 1000 requests per hour per IP
Response headers will include rate limit information:
* `X-RateLimit-Limit`: Maximum requests allowed
* `X-RateLimit-Remaining`: Remaining requests
* `X-RateLimit-Reset`: Time when limit resets
## Support
For issues or questions, please contact the development team.
""",
contact={
"name": "AI-Core Team",
"email": "support@ai-core.com",
},
license_info={
"name": "MIT",
}
)
# Add rate limiter to app state
app.state.limiter = limiter
# Add rate limit exception handler
app.add_exception_handler(RateLimitExceeded, rate_limit_exceeded_handler)
# Logging Middleware (đầu tiên)
app.add_middleware(RequestLoggingMiddleware)
# CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Exception handlers
@app.exception_handler(AIException)
async def ai_exception_handler(request: Request, exc: AIException):
"""Handle custom AI exceptions"""
return JSONResponse(
status_code=400,
content=ErrorResponse(
error=exc.message,
code=exc.code,
detail=exc.detail
).model_dump()
)
@app.exception_handler(Exception)
async def general_exception_handler(request: Request, exc: Exception):
"""Handle general exceptions"""
logger.error(
f"Unhandled exception: {str(exc)}",
exc_info=True,
extra={
"path": request.url.path,
"method": request.method
}
)
return JSONResponse(
status_code=500,
content=ErrorResponse(
error="Internal server error",
code="INTERNAL_ERROR",
detail=str(exc) if settings.DEBUG else None
).model_dump()
)
# Startup event
@app.on_event("startup")
async def startup_event():
"""Actions on startup"""
logger.info(f"Starting {settings.APP_NAME} v{settings.APP_VERSION}")
logger.info(f"Debug mode: {settings.DEBUG}")
logger.info(f"Server: {settings.HOST}:{settings.PORT}")
logger.info(f"Rate limiting: {'Enabled' if settings.RATE_LIMIT_ENABLED else 'Disabled'}")
logger.info(f"Authentication: {'Enabled' if settings.AUTH_ENABLED else 'Disabled'}")
# Shutdown event
@app.on_event("shutdown")
async def shutdown_event():
"""Actions on shutdown"""
logger.info(f"Shutting down {settings.APP_NAME}")
# Mount API router
app.include_router(api_router, prefix="/api/v1")
@app.get("/")
@limiter.limit("10/minute") # Rate limit cho root endpoint
async def root(request: Request):
"""Root endpoint with rate limiting"""
logger.debug("Root endpoint accessed")
return {
"message": "Welcome to AI-Core API",
"version": settings.APP_VERSION,
"docs": "/docs",
"api_v1": "/api/v1",
"rate_limit": {
"enabled": settings.RATE_LIMIT_ENABLED,
"per_minute": settings.RATE_LIMIT_PER_MINUTE
},
"auth": {
"enabled": settings.AUTH_ENABLED,
"type": "API Key" if settings.AUTH_ENABLED else None
}
}
if __name__ == "__main__":
import uvicorn
uvicorn.run(
"app.main:app",
host=settings.HOST,
port=settings.PORT,
reload=settings.DEBUG,
log_level="info"
)