o2o-negosium-original/agent/router/router.py

78 lines
2.7 KiB
Python

import os
import time
from contextlib import asynccontextmanager
from fastapi import FastAPI, Request
from fastapi.middleware.gzip import GZipMiddleware
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse
from common.database.db_session_manager import DB_SESSION_MNG
from common.logger import LOG
from common.utils.gtime import GTime
from router.middleware.tenant_middleware import TenantMiddleware
import router.v1.health.health
import router.v1.negotiation.negotiation
import router.v1.chat.chat
import router.v1.learning.learning
import router.v1.card.card
API_SERVER_START_TIME = GTime.UTCStr()
@asynccontextmanager
async def lifespan(app: FastAPI):
# startup: 공유 베이스(_base) 없으면 자동 시드 (운영 자동화, P5)
from bootstrap.lifespan import ensure_base_seeded
await ensure_base_seeded()
yield
# shutdown: DB 엔진 커넥션 풀 정리
await DB_SESSION_MNG.dispose_all()
app = FastAPI(title="Negosium Agent Server", lifespan=lifespan)
# Accept-Encoding: gzip 요청에 대해 1000 bytes 이상 응답을 압축.
app.add_middleware(GZipMiddleware, minimum_size=1000)
# 테넌트 라우팅 미들웨어 (헤더 X-Tenant-ID → request.state.tenant_id).
app.add_middleware(TenantMiddleware)
# 데모 HTML(file:// 또는 타 출처)에서 호출 가능하도록 CORS 허용 (개발용 — 운영은 출처 제한 권장).
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
@app.middleware("http")
async def log_time(request: Request, call_next):
start_time = time.time()
response = await call_next(request)
elapsed = time.time() - start_time
LOG.d(f"took: {elapsed:.4f} - {request.url.path}")
return response
@app.get(path="/healthz", responses={404: {"description": "Not found"}})
async def healthz():
return API_SERVER_START_TIME
# 간단 테스트 프론트 (tests/negotiation_demo.html). 같은 출처로 서빙 → CORS 불필요.
_DEMO_HTML = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "tests", "negotiation_demo.html")
@app.get(path="/demo", include_in_schema=False)
async def demo():
return FileResponse(_DEMO_HTML)
# 각 도메인 라우터 등록. 새 기능 추가 시 router.v1.<domain>.<file> import 후 include.
# (chat / card / learning / qtable 라우터는 P7 에서 Chat_server 14개 API 이식하며 추가)
app.include_router(router.v1.health.health.router)
app.include_router(router.v1.negotiation.negotiation.router)
app.include_router(router.v1.chat.chat.router)
app.include_router(router.v1.learning.learning.router)
app.include_router(router.v1.card.card.router)