From 44cbb4ca49eb4c859c5542d6aef2cdfae85fe252 Mon Sep 17 00:00:00 2001 From: chenzhirong <826531489@qq.com> Date: Mon, 22 Sep 2025 11:39:19 +0800 Subject: [PATCH] =?UTF-8?q?init:=20=E4=BD=BF=E7=94=A8=E8=A3=85=E9=A5=B0?= =?UTF-8?q?=E5=99=A8=E5=B0=81=E8=A3=85=E5=A4=84=E7=90=86=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E7=9A=84=E6=8E=A5=E5=8F=A3=E5=93=8D=E5=BA=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 18 +++++++++--------- router/__init__.py | 36 +++++++++++++++++++++++++++++++++++- router/monitor.py | 2 ++ router/user_app.py | 4 +++- uv.lock | 11 +++++++++++ 5 files changed, 60 insertions(+), 11 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9ccaa62..d096197 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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" diff --git a/router/__init__.py b/router/__init__.py index 2523ffa..7d95d1c 100644 --- a/router/__init__.py +++ b/router/__init__.py @@ -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: diff --git a/router/monitor.py b/router/monitor.py index 0956c28..046e0a8 100644 --- a/router/monitor.py +++ b/router/monitor.py @@ -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 { diff --git a/router/user_app.py b/router/user_app.py index 082bde0..3d234d5 100644 --- a/router/user_app.py +++ b/router/user_app.py @@ -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) diff --git a/uv.lock b/uv.lock index 0a73735..9bc0347 100644 --- a/uv.lock +++ b/uv.lock @@ -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" },