first commit - MVE Incrementables Parser microservice with FastAPI, JWT, Celery, Redis
This commit is contained in:
90
app/main.py
Normal file
90
app/main.py
Normal file
@@ -0,0 +1,90 @@
|
||||
"""Main FastAPI application."""
|
||||
import logging
|
||||
import sys
|
||||
from fastapi import FastAPI, Request, status
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi.exceptions import RequestValidationError
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
from app.core.config import get_settings
|
||||
from app.api import auth
|
||||
from app.api.v1 import incrementables
|
||||
from app.schemas import HealthResponse
|
||||
|
||||
# Configure logging
|
||||
settings = get_settings()
|
||||
logging.basicConfig(
|
||||
level=getattr(logging, settings.log_level.upper()),
|
||||
format='{"time": "%(asctime)s", "level": "%(levelname)s", "name": "%(name)s", "message": "%(message)s"}',
|
||||
stream=sys.stdout
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
"""Application lifespan manager."""
|
||||
logger.info(f"Starting {settings.service_name} v{settings.service_version}")
|
||||
yield
|
||||
logger.info(f"Shutting down {settings.service_name}")
|
||||
|
||||
|
||||
# Create FastAPI app
|
||||
app = FastAPI(
|
||||
title=settings.service_name,
|
||||
version=settings.service_version,
|
||||
description="MVE Incrementables Parser - Extracts incrementables data from PDFs",
|
||||
lifespan=lifespan
|
||||
)
|
||||
|
||||
|
||||
# Exception handlers
|
||||
@app.exception_handler(RequestValidationError)
|
||||
async def validation_exception_handler(request: Request, exc: RequestValidationError):
|
||||
"""Handle validation errors with custom format."""
|
||||
logger.warning(f"Validation error: {exc.errors()}")
|
||||
return JSONResponse(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
content={
|
||||
"detail": "Validation error",
|
||||
"errors": exc.errors()
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@app.exception_handler(Exception)
|
||||
async def general_exception_handler(request: Request, exc: Exception):
|
||||
"""Handle unexpected errors."""
|
||||
logger.error(f"Unexpected error: {str(exc)}", exc_info=True)
|
||||
return JSONResponse(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
content={
|
||||
"detail": "Internal server error"
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
# Health check endpoint
|
||||
@app.get("/health", response_model=HealthResponse, tags=["Health"])
|
||||
async def health_check():
|
||||
"""
|
||||
Health check endpoint.
|
||||
|
||||
Returns service status and version information.
|
||||
"""
|
||||
return HealthResponse(
|
||||
status="ok",
|
||||
service=settings.service_name,
|
||||
version=settings.service_version
|
||||
)
|
||||
|
||||
|
||||
# Include routers
|
||||
app.include_router(auth.router)
|
||||
app.include_router(incrementables.router)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
uvicorn.run(app, host="0.0.0.0", port=9876)
|
||||
Reference in New Issue
Block a user