# app/main.py from fastapi import FastAPI, Request, status from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse from fastapi.exceptions import RequestValidationError import logging from app.config import settings from app.database import init_db # Настройка логирования logging.basicConfig( level=logging.INFO if not settings.DEBUG else logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) # Создаем приложение FastAPI app = FastAPI( title=settings.APP_NAME, version="1.0.0", description="Form Builder Backend API with PostgreSQL", docs_url="/docs" if settings.DEBUG else None, redoc_url="/redoc" if settings.DEBUG else None, ) # Настройка CORS app.add_middleware( CORSMiddleware, allow_origins=settings.BACKEND_CORS_ORIGINS, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Инициализация БД при запуске @app.on_event("startup") async def startup_event(): logger.info("Starting application...") logger.info(f"Environment: {settings.APP_ENV}") logger.info(f"Database: {settings.DATABASE_URL}") try: init_db() logger.info("Database initialized successfully") except Exception as e: logger.error(f"Database initialization failed: {e}") @app.on_event("shutdown") async def shutdown_event(): logger.info("Shutting down application...") # Обработчики ошибок @app.exception_handler(RequestValidationError) async def validation_exception_handler(request: Request, exc: RequestValidationError): """Обработка ошибок валидации""" return JSONResponse( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, content={ "error": "Validation Error", "details": exc.errors(), "status_code": 422 } ) @app.exception_handler(Exception) async def general_exception_handler(request: Request, exc: Exception): """Обработка всех непредвиденных ошибок""" logger.error(f"Unhandled exception: {exc}", exc_info=True) return JSONResponse( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={ "error": "Internal Server Error", "detail": str(exc) if settings.DEBUG else "An unexpected error occurred", "status_code": 500 } ) # Импортируем и регистрируем роутеры from app.api.v1 import forms, submissions, analytics, export app.include_router(forms.router, prefix="/api/v1") app.include_router(submissions.router, prefix="/api/v1") app.include_router(analytics.router, prefix="/api/v1") app.include_router(export.router, prefix="/api/v1") # Корневой эндпоинт @app.get("/", tags=["root"]) async def root(): return { "message": f"Welcome to {settings.APP_NAME} API", "version": "1.0.0", "docs": "/docs" if settings.DEBUG else None, "status": "running" } # Health check @app.get("/health", tags=["health"]) async def health_check(): """Проверка состояния приложения""" return { "status": "healthy", "timestamp": "2024-01-01T00:00:00Z", "version": "1.0.0", "database": "connected" }