| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- from fastapi import APIRouter, HTTPException, Body, status, Query
- from fastapi.responses import JSONResponse
- import httpx
- from ..core.logger import get_logger
- from ..core.config import settings
- from contextlib import asynccontextmanager
- logger = get_logger(__name__)
- router = APIRouter()
- # 1. 创建一个全局的 client (配置好超时和连接池)
- # limits: max_keepalive_connections 控制连接池大小
- http_client = httpx.AsyncClient(timeout=10.0, limits=httpx.Limits(max_keepalive_connections=20, max_connections=100))
- @router.get("/scoring_config", summary="[代理] 获取评分配置")
- async def proxy_get_scoring_config():
- target_url = settings.SCORE_SERVER_CONFIG_URL
- try:
- # 2. 直接使用全局 client,不需要 async with
- resp = await http_client.get(target_url)
- if resp.status_code != 200:
- logger.error(f"项目1返回错误: {resp.status_code} - {resp.text}")
- raise HTTPException(
- status_code=resp.status_code,
- detail=resp.json().get("detail", "上游服务错误")
- )
- return resp.json()
- except httpx.RequestError as exc:
- logger.error(f"连接项目1失败: {exc}")
- raise HTTPException(status_code=503, detail=str(exc))
- @router.put("/scoring_config", summary="[代理] 更新评分配置")
- async def proxy_update_scoring_config(config_data: dict = Body(...)):
- target_url = settings.SCORE_SERVER_CONFIG_URL
- try:
- # 2. 复用连接
- resp = await http_client.put(target_url, json=config_data)
- if resp.status_code != 200:
- raise HTTPException(status_code=resp.status_code, detail=f"保存失败: {resp.json()['detail']}")
- return_data = {"detail": f"{resp.json()['message']}"}
- return JSONResponse(status_code=resp.status_code, content=return_data)
- except httpx.RequestError as exc:
- logger.error(f"连接项目1失败: {exc}")
- raise HTTPException(status_code=503, detail=str(exc))
- @router.get("/severity_names", summary="[代理] 获取缺陷严重程度列表")
- async def proxy_get_severity_names(defect_label: str = Query(..., description="缺陷标签")):
- target_url = f"{settings.SCORE_SERVER_CONFIG_URL.replace('/scoring_config', '')}/severity_names"
- # 注意:settings.SCORE_SERVER_CONFIG_URL 通常是 http://host:port/api/config/scoring_config
- # 我们需要构建 http://host:port/api/config/severity_names
- # 更加稳健的写法是基于 base URL 拼接,这里假设 replace 可行,或者直接使用 query params
- # 假设 settings.SCORE_SERVER_CONFIG_URL 是完整路径 ".../scoring_config"
- # 我们需要把它替换掉
- base_url = settings.SCORE_SERVER_CONFIG_URL.rsplit('/', 1)[0]
- final_url = f"{base_url}/severity_names"
- try:
- # 发送带参数的 GET 请求
- resp = await http_client.get(final_url, params={"defect_label": defect_label})
- if resp.status_code != 200:
- logger.error(f"项目1返回错误: {resp.status_code} - {resp.text}")
- raise HTTPException(
- status_code=resp.status_code,
- detail=resp.json().get("detail", "上游服务错误")
- )
- return resp.json()
- except httpx.RequestError as exc:
- logger.error(f"连接项目1失败: {exc}")
- raise HTTPException(status_code=503, detail=str(exc))
|