Spaces:
Runtime error
Runtime error
| from contextlib import asynccontextmanager | |
| from fastapi import FastAPI, HTTPException | |
| from .core.models import get_vector_collection, load_notices_cache | |
| from .schemas import ( | |
| HealthResponse, | |
| NoticeItem, | |
| RecommendRequest, | |
| RecommendResponse, | |
| SearchRequest, | |
| SearchResponse, | |
| ) | |
| from .services.recommend_service import recommend_notices, summarize_notice | |
| from .services.search_service import ( | |
| generate_llm_reply, | |
| hybrid_search, | |
| ) | |
| async def lifespan(app: FastAPI): | |
| yield | |
| app = FastAPI( | |
| title="์์ํ์ธ๋ API", | |
| description="ํ์ฑ๋ํ๊ต ๊ณต์ง์ฌํญ ๊ฒ์ ๋ฐ ์ถ์ฒ API", | |
| version="1.0.0", | |
| lifespan=lifespan, | |
| ) | |
| def health_check(): | |
| notices = load_notices_cache() | |
| try: | |
| indexed = get_vector_collection().count() | |
| except Exception: | |
| indexed = 0 | |
| return HealthResponse( | |
| status="ok", | |
| notices_count=len(notices), | |
| indexed_count=indexed, | |
| ) | |
| def search(req: SearchRequest): | |
| try: | |
| raw_results = hybrid_search( | |
| query=req.query, | |
| top_k=req.top_k, | |
| alpha=req.alpha, | |
| category_filter=req.category, | |
| candidate_k=50 if req.feature_rerank else None, | |
| feature_rerank=req.feature_rerank, | |
| profile=req.profile, | |
| ) | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"๊ฒ์ ์ค๋ฅ: {e}") | |
| # SearchRequest์ profile์ด ์์ผ๋ฏ๋ก ๋น dict ์ ๋ฌ (์ด๋ฆ ์ธ์ฌ๋ง ์๋ต) | |
| reply = generate_llm_reply( | |
| user_query=req.query, | |
| results=raw_results, | |
| profile=req.profile, | |
| is_first=req.is_first, | |
| ) | |
| items = [ | |
| NoticeItem( | |
| title=r["title"], | |
| url=r["url"], | |
| date=r["date"], | |
| category=r.get("category", "๊ธฐํ"), | |
| score=r["score"], | |
| ) | |
| for r in raw_results | |
| ] | |
| return SearchResponse(reply=reply, results=items) | |
| def recommend(req: RecommendRequest): | |
| profile = { | |
| "college": req.college, | |
| "track": req.track, | |
| "grade": req.grade, | |
| "interests": req.interests, | |
| } | |
| try: | |
| raw_results = recommend_notices(profile, top_k=req.top_k) | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"์ถ์ฒ ์ค๋ฅ: {e}") | |
| notices = load_notices_cache() | |
| body_map = {n["url"]: n.get("body", "") for n in notices} | |
| items = [] | |
| for r in raw_results: | |
| body = body_map.get(r["url"], "") | |
| summary = summarize_notice(r["title"], body) if body else None | |
| items.append(NoticeItem( | |
| title=r["title"], | |
| url=r["url"], | |
| date=r["date"], | |
| category=r.get("category", "๊ธฐํ"), | |
| score=r["score"], | |
| summary=summary, | |
| )) | |
| return RecommendResponse(results=items) | |