quote-finder / app.py
askljie
Fix synonym score calculation
3f49919
Raw
History Blame Contribute Delete
2.96 kB
import asyncio
import aiohttp
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from typing import List, Optional
import uvicorn
import os
from core.matcher import PoetryMatcher
app = FastAPI(
title="名句匹配API",
version="1.0.0",
description="输入句子或关键词,从海量名句库中找到最契合的名句"
)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
matcher = None
class MatchRequest(BaseModel):
query: str
top_k: int = 5
class QuoteResponse(BaseModel):
id: str
text: str
author: Optional[str] = None
source: Optional[str] = None
dynasty: Optional[str] = None
type: Optional[str] = None
score: float
semantic_score: Optional[float] = None
keyword_score: Optional[float] = None
synonym_score: Optional[float] = None
class MatchResponse(BaseModel):
query: str
results: List[QuoteResponse]
async def self_ping():
await asyncio.sleep(60)
port = os.getenv("PORT", "7860")
while True:
try:
async with aiohttp.ClientSession() as session:
async with session.get(f"http://localhost:{port}/health"):
pass
except:
pass
await asyncio.sleep(240)
@app.on_event("startup")
async def startup_event():
global matcher
print("Loading matcher...")
matcher = PoetryMatcher()
print(f"Matcher loaded with {matcher.get_quotes_count()} quotes")
asyncio.create_task(self_ping())
@app.get("/")
async def root():
return {
"name": "quote-finder",
"version": "1.0.0",
"description": "名句匹配API",
"endpoints": {
"POST /match": "匹配名句",
"GET /health": "健康检查"
}
}
@app.post("/match", response_model=MatchResponse)
async def match_quotes(request: MatchRequest):
if matcher is None:
raise HTTPException(status_code=503, detail="Service not ready")
try:
results = matcher.match(request.query, request.top_k)
# 确保每个结果都有id字段
formatted_results = []
for i, r in enumerate(results):
if 'id' not in r:
r['id'] = f'generated_{i}'
formatted_results.append(QuoteResponse(**r))
return MatchResponse(
query=request.query,
results=formatted_results
)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/health")
async def health_check():
return {
"status": "healthy",
"quotes_count": matcher.get_quotes_count() if matcher else 0,
"model": "moka-ai/m3e-base"
}
if __name__ == "__main__":
port = int(os.getenv("PORT", "7860"))
uvicorn.run(app, host="0.0.0.0", port=port)