medilang-tech / main.py
Dama03's picture
first push of the AI
411a994
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}")
@app.get("/health")
def healthcheck():
return {"status": "ok"}
# Debug: return list of routes
@app.get("/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
@app.post("/gateway")
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)