init: 使用装饰器封装处理统一的接口响应

main
chenzhirong 5 months ago
parent 93190ac0e5
commit 44cbb4ca49

@ -1,27 +1,27 @@
[project]
name = "rg-agno-agent"
name = "rg-fastapi-template"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"fastapi[standard]>=0.116.1",
"langchain>=0.3.27",
"langchain-openai>=0.3.33",
"langchainhub>=0.1.21",
"mcp>=1.14.0",
"openai>=1.107.3",
"fastapi[standard]>=0.116.1",
"fastapi-pagination>=0.14.1", # fastapi统一分页
"sqlalchemy[asyncio]>=2.0.43",
"sqlmodel>=0.0.25",
"ruamel-yaml>=0.18.6,<0.19.0", # YAML处理
"cachetools==5.3.3", # 缓存工具
"filelock==3.15.4", # 文件锁
"itsdangerous==2.1.2", # 安全签名,用于 SessionMiddleware
"langchain-openai>=0.3.33",
"langchainhub>=0.1.21",
"httpx-sse>=0.4.1",
"sqlmodel>=0.0.25",
"aiomysql>=0.2.0",
"beartype>=0.21.0",
"fastapi-pagination>=0.14.1",
"psutil>=7.1.0",
"beartype>=0.21.0", # 类型检查
"psutil>=7.1.0", # 系统资源
"pytz>=2025.2", #处理时区
]
[[tool.uv.index]]
url = "https://mirrors.aliyun.com/pypi/simple"

@ -1,11 +1,45 @@
import inspect
import logging
from typing import Union, Type
from functools import wraps
from typing import Union, Type, Callable, TypeVar
from datetime import datetime
import pytz
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel
from starlette.responses import JSONResponse
from config import get_settings
from entity.dto import HttpResp
from exceptions.base import AppException
from utils import get_uuid
RT = TypeVar('RT') # 返回类型
def unified_resp(func: Callable[..., RT]) -> Callable[..., RT]:
"""统一响应格式
接口正常返回时,统一响应结果格式
"""
@wraps(func)
async def wrapper(*args, **kwargs) -> RT:
if inspect.iscoroutinefunction(func):
resp = await func(*args, **kwargs) or []
else:
resp = func(*args, **kwargs) or []
return JSONResponse(
content=jsonable_encoder(
# 正常请求响应
{'code': HttpResp.SUCCESS.code, 'msg': HttpResp.SUCCESS.msg, 'data': resp},
by_alias=False,
# 自定义日期时间格式编码器
custom_encoder={
datetime: lambda dt: dt.replace(tzinfo=pytz.utc).astimezone(pytz.timezone(get_settings().timezone))
.strftime(get_settings().datetime_fmt)}),
media_type='application/json;charset=utf-8'
)
return wrapper
class BaseController:

@ -2,6 +2,7 @@ import logging
from fastapi import APIRouter, Depends
from router import unified_resp
from server_info import ServerInfo
logger = logging.getLogger(__name__)
@ -10,6 +11,7 @@ router = APIRouter(prefix='/monitor', tags=["缓存监控服务"])
@router.get('/server',summary='服务监控')
@unified_resp
def monitor_server():
"""服务器信息监控"""
return {

@ -1,7 +1,7 @@
from fastapi import APIRouter, Query
from entity.dto.UserDto import UserQueryPageReq, UserQueryReq
from router import BaseController
from router import BaseController, unified_resp
from service.user_service import UserService
router = APIRouter(prefix="/user", tags=["用户"])
@ -9,9 +9,11 @@ base_service = UserService
base_app = BaseController(base_service)
@router.get("/page")
@unified_resp
async def get_page(req:UserQueryPageReq=Query(...)):
return await base_service.get_by_page(req)
@router.get("/list")
@unified_resp
async def get_list(req:UserQueryReq=Query(...)):
return await base_service.get_list(req)

@ -864,6 +864,15 @@ wheels = [
{ url = "https://mirrors.aliyun.com/pypi/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104" },
]
[[package]]
name = "pytz"
version = "2025.2"
source = { registry = "https://mirrors.aliyun.com/pypi/simple" }
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3" }
wheels = [
{ url = "https://mirrors.aliyun.com/pypi/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00" },
]
[[package]]
name = "pywin32"
version = "311"
@ -1044,6 +1053,7 @@ dependencies = [
{ name = "mcp" },
{ name = "openai" },
{ name = "psutil" },
{ name = "pytz" },
{ name = "ruamel-yaml" },
{ name = "sqlalchemy", extra = ["asyncio"] },
{ name = "sqlmodel" },
@ -1065,6 +1075,7 @@ requires-dist = [
{ name = "mcp", specifier = ">=1.14.0" },
{ name = "openai", specifier = ">=1.107.3" },
{ name = "psutil", specifier = ">=7.1.0" },
{ name = "pytz", specifier = ">=2025.2" },
{ name = "ruamel-yaml", specifier = ">=0.18.6,<0.19.0" },
{ name = "sqlalchemy", extras = ["asyncio"], specifier = ">=2.0.43" },
{ name = "sqlmodel", specifier = ">=0.0.25" },

Loading…
Cancel
Save