# Copy the content from the main_app_file artifact above # src/main.py """ FastAPI application entry point for the self-improving code generator """ import logging import asyncio import time from contextlib import asynccontextmanager from fastapi import FastAPI, HTTPException, BackgroundTasks, Depends from fastapi.middleware.cors import CORSMiddleware from sqlalchemy import create_engine, text from sqlalchemy.orm import sessionmaker from sqlalchemy.exc import OperationalError from .utils.config import get_settings, validate_configuration from .models.database_models import Base from .api.routes import router from .services.orchestrator import SelfImprovingCodeGenerator # Configure logging logging.basicConfig( level=logging.INFO, format="%(asctime)s | %(levelname)s | %(name)s | %(message)s" ) logger = logging.getLogger(__name__) # Global variables generator: SelfImprovingCodeGenerator = None engine = None SessionLocal = None async def wait_for_database(database_url: str, max_retries: int = 30, delay: float = 2.0): """Wait for database to be available with retry logic""" for attempt in range(max_retries): try: logger.info(f"Attempting database connection (attempt {attempt + 1}/{max_retries})") test_engine = create_engine(database_url) # Test the connection with test_engine.connect() as conn: conn.execute(text("SELECT 1")) logger.info("✅ Database connection successful") test_engine.dispose() return True except OperationalError as e: if attempt < max_retries - 1: logger.warning(f"Database connection failed (attempt {attempt + 1}): {e}") logger.info(f"Retrying in {delay} seconds...") await asyncio.sleep(delay) else: logger.error(f"Failed to connect to database after {max_retries} attempts: {e}") raise except Exception as e: logger.error(f"Unexpected error connecting to database: {e}") raise return False @asynccontextmanager async def lifespan(app: FastAPI): """Application lifespan events""" global generator, engine, SessionLocal try: # Validate configuration validate_configuration() settings = get_settings() logger.info("🚀 Starting Self-Improving Code Generator") # Wait for database to be available await wait_for_database(settings.database_url) # Initialize database engine = create_engine(settings.database_url) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) # Create database tables Base.metadata.create_all(bind=engine) logger.info("✅ Database initialized") # Initialize the generator generator = SelfImprovingCodeGenerator( claude_api_key=settings.claude_api_key, database_url=settings.database_url ) logger.info("✅ Self-improving generator initialized") yield except Exception as e: logger.error(f"❌ Failed to start application: {e}") raise finally: logger.info("🛑 Shutting down Self-Improving Code Generator") if engine: engine.dispose() # Create FastAPI app app = FastAPI( title="Self-Improving Code Generator", description="AI-powered code generation with continuous quality improvement", version="1.0.0", lifespan=lifespan ) # Add CORS middleware app.add_middleware( CORSMiddleware, allow_origins=["*"], # Configure for your needs allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Include API routes app.include_router(router, prefix="/api/v1") # Dependency to get generator instance def get_generator() -> SelfImprovingCodeGenerator: """Get the global generator instance""" if generator is None: raise HTTPException(status_code=500, detail="Generator not initialized") return generator # Dependency to get database session def get_db(): """Get database session""" if SessionLocal is None: raise HTTPException(status_code=500, detail="Database not initialized") db = SessionLocal() try: yield db finally: db.close() @app.get("/") async def root(): """Root endpoint""" return { "service": "Self-Improving Code Generator", "version": "1.0.0", "status": "running", "capabilities": [ "Technology-agnostic analysis", "Progressive enhancement", "Learning from user preferences", "Real-time improvement tracking", "Multi-language support" ] } @app.get("/health") async def health_check(): """Health check endpoint""" try: settings = get_settings() # Test database connection db_status = "disconnected" if engine: try: with engine.connect() as conn: conn.execute(text("SELECT 1")) db_status = "connected" except Exception as e: logger.warning(f"Database health check failed: {e}") db_status = "error" health_status = { "status": "healthy", "service": "Self-Improving Code Generator", "version": "1.0.0", "timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), "dependencies": { "database": db_status, "claude_api": "configured" if settings.claude_api_key else "not_configured", "generator": "initialized" if generator else "not_initialized" } } # Check if all dependencies are healthy all_healthy = ( health_status["dependencies"]["database"] == "connected" and health_status["dependencies"]["claude_api"] == "configured" and health_status["dependencies"]["generator"] == "initialized" ) if not all_healthy: health_status["status"] = "unhealthy" return health_status except Exception as e: logger.error(f"Health check failed: {e}") return { "status": "error", "service": "Self-Improving Code Generator", "version": "1.0.0", "timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), "error": str(e) } if __name__ == "__main__": import uvicorn settings = get_settings() uvicorn.run( "src.main:app", host=settings.service_host, port=settings.service_port, reload=True, log_level=settings.log_level.lower() )