Spaces:
Sleeping
Sleeping
| import logging | |
| from fastapi import FastAPI, Request, Depends | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.responses import JSONResponse | |
| from starlette import status | |
| from app.utils.config import settings | |
| from app.utils.security import get_current_user_optional | |
| from app.routers import users, chat, audio, images | |
| from app.routers import cameroon_data | |
| from app.routers import ai | |
| def create_app() -> FastAPI: | |
| # Configure logging | |
| settings.configure_logging() | |
| logger = logging.getLogger(__name__) | |
| app = FastAPI( | |
| title="Carehelp API", | |
| description="Backend IA médical pour le Cameroun (Carehelp)", | |
| version="1.0.0", | |
| contact={ | |
| "name": "Carehelp", | |
| }, | |
| ) | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=settings.CORS_ALLOW_ORIGINS, | |
| allow_credentials=True, | |
| allow_methods=["*"] | |
| , | |
| allow_headers=["*"] | |
| , | |
| ) | |
| # Routers | |
| app.include_router(users.router, prefix="/api", tags=["users"]) | |
| app.include_router(chat.router, prefix="/api", tags=["chat"]) | |
| app.include_router(audio.router, prefix="/api", tags=["audio"]) | |
| app.include_router(images.router, prefix="/api", tags=["images"]) | |
| app.include_router(cameroon_data.router, prefix="/api/cameroon-data", tags=["cameroon-data"]) | |
| app.include_router(ai.router, prefix="/api", tags=["ai"]) | |
| # Log all registered routes for debugging | |
| try: | |
| route_paths = sorted([getattr(r, 'path', str(r)) for r in app.routes]) | |
| logging.getLogger(__name__).info(f"Registered routes: {route_paths}") | |
| except Exception as e: | |
| logging.getLogger(__name__).error(f"Failed to list routes: {e}") | |
| def healthcheck(): | |
| return {"status": "ok"} | |
| # Debug: return list of routes | |
| def list_routes(): | |
| return {"routes": [ | |
| { | |
| "path": getattr(r, 'path', str(r)), | |
| "name": getattr(r, 'name', None), | |
| "methods": list(getattr(r, 'methods', []) or []) | |
| } | |
| for r in app.routes | |
| ]} | |
| # No database initialization; Supabase will manage schema | |
| async def gateway(request: Request, current_user=Depends(get_current_user_optional)): | |
| """ | |
| Endpoint unique pour le frontend. | |
| - Mode actions: {"action": "chat|transcribe|analyze-image|analyze-multimodal|translate", "payload": {...}} | |
| - Mode unifié (recommandé): {"payload": {text?, image?, images?, audio?, audios?, files?, file_names?, location?, want_stats?, agent_mode?}} | |
| Si "action" est omis ou vaut l'un de {"auto", "unified", "ai"}, la requête est routée automatiquement selon les champs fournis. | |
| """ | |
| body = await request.json() | |
| action = body.get("action") | |
| payload = body.get("payload", {}) | |
| # Mode unifié: pas d'action explicitement fournie ou action spéciale | |
| if not action or str(action).lower() in {"auto", "unified", "ai"}: | |
| try: | |
| req = ai.AIRequest( | |
| text=payload.get("text"), | |
| image=payload.get("image"), | |
| images=payload.get("images"), | |
| audio=payload.get("audio"), | |
| audios=payload.get("audios"), | |
| want_stats=payload.get("want_stats", False), | |
| location=payload.get("location"), | |
| files=payload.get("files"), | |
| file_names=payload.get("file_names"), | |
| agent_mode=payload.get("agent_mode"), | |
| ) | |
| except Exception as e: | |
| return JSONResponse(status_code=status.HTTP_400_BAD_REQUEST, content={"detail": f"Payload invalide pour le mode unifié: {e}"}) | |
| # Déléguer au point d'entrée IA unifié (gère texte, image(s), audio(s), fichiers) | |
| return await ai.ai_endpoint(req) | |
| # Proxifier vers les endpoints internes | |
| if action == "chat": | |
| return await chat.handle_chat_via_gateway(payload, current_user) | |
| if action == "transcribe": | |
| return await audio.handle_transcription_via_gateway(payload, current_user) | |
| if action == "analyze-image": | |
| return await images.handle_analyze_image_via_gateway(payload, current_user) | |
| if action == "analyze-multimodal": | |
| return await images.handle_analyze_multimodal_via_gateway(payload, current_user) | |
| if action == "translate": | |
| return await chat.handle_translate_via_gateway(payload, current_user) | |
| return JSONResponse( | |
| status_code=status.HTTP_400_BAD_REQUEST, | |
| content={"detail": "Action inconnue"}, | |
| ) | |
| return app | |
| app = create_app() | |
| if __name__ == "__main__": | |
| import uvicorn | |
| uvicorn.run("main:app", host="0.0.0.0", port=int(settings.PORT), reload=True) | |