|
|
""" |
|
|
LocalMate Da Nang V2 - Multi-Modal Contextual Agent API. |
|
|
|
|
|
FastAPI application entry point with /chat endpoint for testing. |
|
|
""" |
|
|
|
|
|
from contextlib import asynccontextmanager |
|
|
|
|
|
from fastapi import FastAPI |
|
|
from fastapi.middleware.cors import CORSMiddleware |
|
|
|
|
|
from app.api.router import router as api_router |
|
|
from app.planner.router import router as planner_router |
|
|
from app.users.router import router as users_router |
|
|
from app.itineraries.router import router as itineraries_router |
|
|
from app.auth.router import router as auth_router |
|
|
from app.shared.db.session import engine |
|
|
from app.shared.integrations.neo4j_client import neo4j_client |
|
|
|
|
|
|
|
|
@asynccontextmanager |
|
|
async def lifespan(app: FastAPI): |
|
|
"""Application lifespan handler for startup/shutdown.""" |
|
|
|
|
|
try: |
|
|
from app.shared.integrations.siglip_client import get_siglip_client |
|
|
siglip = get_siglip_client() |
|
|
print(f"✅ SigLIP ready: {siglip.is_loaded}") |
|
|
except Exception as e: |
|
|
print(f"⚠️ SigLIP not loaded (image search disabled): {e}") |
|
|
|
|
|
yield |
|
|
|
|
|
|
|
|
await neo4j_client.close() |
|
|
await engine.dispose() |
|
|
|
|
|
|
|
|
app = FastAPI( |
|
|
title="LocalMate Da Nang V2", |
|
|
description=""" |
|
|
## Multi-Modal Contextual Agent (MMCA) API |
|
|
|
|
|
Intelligent travel assistant for Da Nang with 3 MCP tools + Trip Planner: |
|
|
|
|
|
### Tools Available: |
|
|
1. **retrieve_context_text** - Semantic search in text descriptions (reviews, menus) |
|
|
2. **retrieve_similar_visuals** - Image similarity search (find similar vibes) |
|
|
3. **find_nearby_places** - Spatial search (find places near a location) |
|
|
|
|
|
### Trip Planner: |
|
|
- Create plans and add places |
|
|
- Optimize route with TSP algorithm |
|
|
- Reorder, replace, and manage places |
|
|
|
|
|
### Examples: |
|
|
- "Tìm quán cafe gần bãi biển Mỹ Khê" |
|
|
- "Nhà hàng hải sản nào được review tốt?" |
|
|
- "Quán nào có không gian xanh mát?" (with image_url) |
|
|
""", |
|
|
version="0.3.0", |
|
|
lifespan=lifespan, |
|
|
) |
|
|
|
|
|
|
|
|
app.add_middleware( |
|
|
CORSMiddleware, |
|
|
allow_origins=["*"], |
|
|
allow_credentials=True, |
|
|
allow_methods=["*"], |
|
|
allow_headers=["*"], |
|
|
) |
|
|
|
|
|
|
|
|
app.include_router(api_router, prefix="/api/v1", tags=["Chat"]) |
|
|
app.include_router(planner_router, prefix="/api/v1", tags=["Trip Planner"]) |
|
|
app.include_router(users_router, prefix="/api/v1", tags=["Users"]) |
|
|
app.include_router(itineraries_router, prefix="/api/v1", tags=["Itineraries"]) |
|
|
app.include_router(auth_router, prefix="/api/v1", tags=["Authentication"]) |
|
|
|
|
|
|
|
|
from app.upload import router as upload_router |
|
|
app.include_router(upload_router, prefix="/api/v1", tags=["Upload"]) |
|
|
|
|
|
|
|
|
@app.get("/health", tags=["System"]) |
|
|
async def health_check(): |
|
|
""" |
|
|
Health check endpoint. |
|
|
|
|
|
Returns status of the application and connected services. |
|
|
""" |
|
|
neo4j_ok = await neo4j_client.verify_connectivity() |
|
|
return { |
|
|
"status": "healthy", |
|
|
"version": "0.2.0", |
|
|
"services": { |
|
|
"neo4j": "connected" if neo4j_ok else "disconnected", |
|
|
}, |
|
|
} |
|
|
|
|
|
|
|
|
@app.get("/", tags=["System"]) |
|
|
async def root(): |
|
|
"""Root endpoint with API info.""" |
|
|
return { |
|
|
"name": "LocalMate Da Nang V2 - MMCA API", |
|
|
"version": "0.2.0", |
|
|
"docs": "/docs", |
|
|
"description": "Multi-Modal Contextual Agent for Da Nang Tourism", |
|
|
} |
|
|
|