
- Update Supervisor configuration to use python -m uvicorn for reliable module loading - Fix database path resolution using absolute paths - Add in-memory SQLite database option for testing and when file access is problematic - Improve error handling in database connection module - Enhance logging configuration with more detailed output - Add environment variables and documentation for better configuration options - Update troubleshooting guide with common issues and solutions
101 lines
3.0 KiB
Python
101 lines
3.0 KiB
Python
import uvicorn
|
|
import logging
|
|
from logging.config import dictConfig
|
|
from fastapi import FastAPI, Request
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from fastapi.responses import JSONResponse
|
|
from app.api.v1.api import api_router
|
|
from app.core.config import settings
|
|
from app.core.logging import LogConfig
|
|
|
|
# Setup logging
|
|
dictConfig(LogConfig().dict())
|
|
logger = logging.getLogger("blogging_api")
|
|
|
|
app = FastAPI(
|
|
title=settings.PROJECT_NAME,
|
|
description="Blogging API with FastAPI and SQLite",
|
|
version="0.1.0",
|
|
docs_url="/docs",
|
|
redoc_url="/redoc",
|
|
openapi_url="/openapi.json",
|
|
)
|
|
|
|
# Exception handlers
|
|
@app.exception_handler(Exception)
|
|
async def global_exception_handler(request: Request, exc: Exception):
|
|
logger.error(f"Unhandled exception: {exc}", exc_info=True)
|
|
return JSONResponse(
|
|
status_code=500,
|
|
content={"detail": "Internal server error. Please check the logs for more details."},
|
|
)
|
|
|
|
# Set all CORS enabled origins
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=["*"],
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
# Include API router
|
|
app.include_router(api_router)
|
|
|
|
# Application lifecycle events
|
|
@app.on_event("startup")
|
|
async def startup_event():
|
|
logger.info("Application starting up...")
|
|
# Print current working directory and environment for debugging
|
|
import os
|
|
import sys
|
|
logger.info(f"Current working directory: {os.getcwd()}")
|
|
logger.info(f"Python path: {sys.path}")
|
|
logger.info(f"Environment: {os.environ.get('PYTHONPATH', 'Not set')}")
|
|
|
|
# Make sure we can initialize database connection
|
|
try:
|
|
from app.db.session import SessionLocal
|
|
if SessionLocal:
|
|
logger.info("Database engine initialized successfully")
|
|
else:
|
|
logger.warning("Database session is None - check connection settings")
|
|
except Exception as e:
|
|
logger.error(f"Failed to initialize database: {e}", exc_info=True)
|
|
# We allow the app to start even with DB errors, to avoid restart loops
|
|
|
|
@app.on_event("shutdown")
|
|
async def shutdown_event():
|
|
logger.info("Application shutting down...")
|
|
|
|
# Health check endpoint with database status
|
|
@app.get("/health", tags=["health"])
|
|
async def health_check():
|
|
from app.db.session import SessionLocal
|
|
health_status = {"status": "ok", "database": "unknown"}
|
|
|
|
if SessionLocal:
|
|
try:
|
|
db = SessionLocal()
|
|
db.execute("SELECT 1")
|
|
db.close()
|
|
health_status["database"] = "ok"
|
|
except Exception as e:
|
|
logger.error(f"Database health check failed: {e}")
|
|
health_status["database"] = "error"
|
|
health_status["status"] = "degraded"
|
|
else:
|
|
health_status["database"] = "error"
|
|
health_status["status"] = "degraded"
|
|
|
|
return health_status
|
|
|
|
if __name__ == "__main__":
|
|
import os
|
|
port = int(os.environ.get("PORT", 8000))
|
|
uvicorn.run(
|
|
"main:app",
|
|
host="0.0.0.0",
|
|
port=port,
|
|
reload=True,
|
|
) |