Spaces:
Running
Running
File size: 4,217 Bytes
b0b150b fb96efc b0b150b fb96efc b0b150b c87cf42 b0b150b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
"""
MEXAR Core Engine - FastAPI Backend Application
Main entry point for the MEXAR Phase 2 API.
This is a clean, minimal main.py that only includes routers.
All endpoints are handled by the api/ modules.
"""
import os
import logging
from pathlib import Path
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
# Ensure data directories exist
DATA_DIRS = [
Path("data/storage"),
Path("data/temp"),
]
for dir_path in DATA_DIRS:
dir_path.mkdir(parents=True, exist_ok=True)
# Lifespan context manager
@asynccontextmanager
async def lifespan(app: FastAPI):
"""Application lifespan handler - database initialization."""
logger.info("MEXAR Core Engine starting up...")
# Initialize database tables
try:
from core.database import engine, Base
from models.user import User
from models.agent import Agent, CompilationJob
from models.conversation import Conversation, Message
from models.chunk import DocumentChunk
from sqlalchemy import text
# Enable vector extension
with engine.connect() as conn:
conn.execute(text("CREATE EXTENSION IF NOT EXISTS vector"))
conn.commit()
Base.metadata.create_all(bind=engine)
logger.info("Database tables created/verified successfully")
except Exception as e:
logger.warning(f"Database initialization: {e}")
yield
logger.info("MEXAR Core Engine shutting down...")
# Create FastAPI app
app = FastAPI(
title="MEXAR Core Engine",
description="Multimodal Explainable AI Reasoning Assistant - Phase 2",
version="2.0.0",
lifespan=lifespan
)
# Configure CORS
# Configure CORS
# CRITICAL: Configure CORS for Vercel frontend
FRONTEND_URL = os.getenv("FRONTEND_URL", "http://localhost:3000")
allow_origins = [
"*",
FRONTEND_URL,
"https://*.vercel.app",
"http://localhost:3000",
"http://localhost:3001"
]
app.add_middleware(
CORSMiddleware,
allow_origins=allow_origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Import and include Phase 2 routers
from api import auth, agents, chat, compile, websocket, admin, prompts, diagnostics
app.include_router(auth.router)
app.include_router(agents.router)
app.include_router(chat.router)
app.include_router(compile.router)
app.include_router(websocket.router)
app.include_router(admin.router)
app.include_router(prompts.router)
app.include_router(diagnostics.router)
# ===== CORE UTILITY ENDPOINTS =====
@app.get("/")
async def root():
"""Root endpoint - serves landing page."""
from fastapi.responses import FileResponse
from pathlib import Path
html_path = Path(__file__).parent / "static" / "index.html"
if html_path.exists():
return FileResponse(html_path, media_type="text/html")
else:
# Fallback to JSON if HTML not found
return {
"name": "MEXAR Core Engine",
"version": "2.0.0",
"status": "operational",
"docs": "/docs"
}
@app.get("/api/health")
async def health_check():
"""Health check endpoint."""
return {
"status": "healthy",
"groq_configured": bool(os.getenv("GROQ_API_KEY"))
}
# ===== ERROR HANDLERS =====
@app.exception_handler(Exception)
async def global_exception_handler(request, exc):
"""Global exception handler."""
logger.error(f"Unhandled exception: {exc}")
return JSONResponse(
status_code=500,
content={
"success": False,
"error": "Internal server error",
"detail": str(exc)
}
)
# ===== MAIN ENTRY POINT =====
if __name__ == "__main__":
import uvicorn
uvicorn.run(
"main:app",
host="0.0.0.0",
port=8000,
reload=True,
log_level="info"
)
|