Fastapi + vue3 自动化测试平台(4)-- fastapi分页查询封装

在构建自动化测试平台时,分页查询是一个非常常见的功能。本文将以 FastAPI 为例,介绍如何封装一个通用的分页查询功能,使其更便于复用。


需求背景

在测试平台中,我们可能需要对用户操作记录、测试用例、任务日志等数据进行分页展示。通过封装分页查询逻辑,可以避免重复编写分页代码,提高开发效率,同时增强代码的可维护性。


实现思路

分页查询的核心步骤包括:

  1. 接收前端传递的分页参数(如 currentPagepageSize)。
  2. 根据查询条件筛选数据。
  3. 计算分页偏移量。
  4. 查询数据并统计总数。
  5. 返回结构化的分页结果。

优点分析:

支持动态查询条件:通过 search_dict 构建动态查询条件,使得功能更灵活。
分页和排序:实现了分页和排序功能,适用于大部分场景。
关联数据处理:通过 user_id 关联查询用户名,增强了数据的可读性。
数据清洗:通过 remove_key 和 time_to_str 对数据进行了处理,提升了返回结果的质量。


工具函数

# 首先,我们封装一个通用的分页查询方法:
import json
from re import search
from datetime import datetime
from common.request_to_json import body_to_json
from common.time_str import time_to_str
from views.user.user_model import User_info


# 分页查询
async def db_page_all(db, request, key, order):
    body = await body_to_json(request)
    search_dict = {k: v for k, v in body["search"].items() if v != ''}
    db_select = db.filter(**search_dict)
    data = await db_select.offset((body["currentPage"] - 1) * body["pageSize"]).limit(
        body["pageSize"]).order_by(order).values()
    res = await remove_key(data, key)
    result = await time_to_str(res)
    count = await db_select.count()
    return {
        "content": result,
        "currentPage": body["currentPage"],
        "pageSize": body["pageSize"],
        "total": count
    }

# 处理请求体
async def body_to_json(request):
    data = await request.body()
    return json.loads(data)


# 剔除不想展示得key
async def remove_key(data, key):
    result = []
    for i in data:
        var = {k: v for k, v in i.items() if k not in key}
        result.append(var)
    return result

# 处理时区的时间格式
async def time_to_str(data):
    if isinstance(data, dict):
        if "user_id" in data.keys():
            user = await User_info.get(id=data["user_id"])
            data["username"] = user.username

        if "create_time" in data.keys():
            data["create_time"] = datetime.strftime(data["create_time"], "%Y-%m-%d %H:%M:%S")

        if "update_time" in data.keys():
            data["update_time"] = datetime.strftime(data["update_time"], "%Y-%m-%d %H:%M:%S")

        if "end_time" in data.keys():
            data["end_time"] = datetime.strftime(data["end_time"], "%Y-%m-%d %H:%M:%S")

        if "start_time" in data.keys():
            data["start_time"] = datetime.strftime(data["start_time"], "%Y-%m-%d %H:%M:%S")

        if "token_time" in data.keys():
            data["token_time"] = datetime.strftime(data["token_time"], "%Y-%m-%d %H:%M:%S")

    elif isinstance(data, list):
        for i in data:
            if "user_id" in i.keys():
                user = await User_info.get(id=i["user_id"])
                i["username"] = user.username

            if "create_time" in i.keys():
                i["create_time"] = datetime.strftime(i["create_time"], "%Y-%m-%d %H:%M:%S")

            if "update_time" in i.keys():
                i["update_time"] = datetime.strftime(i["update_time"], "%Y-%m-%d %H:%M:%S")

            if "token_time" in i.keys():
                i["token_time"] = datetime.strftime(i["token_time"], "%Y-%m-%d %H:%M:%S")

            if "end_time" in i.keys():
                i["end_time"] = datetime.strftime(i["end_time"], "%Y-%m-%d %H:%M:%S")

            if "start_time" in i.keys():
                i["start_time"] = datetime.strftime(i["start_time"], "%Y-%m-%d %H:%M:%S")
    return data
# 调用函数
from views.user.user_model import User_info
from fastapi import Request

@router.post("/user_list")
async def user_list(request: Request):
    try:
        data = await db_page_all(User_info, request, 
                                 key=["token", "token_time", "password", "account"], order="-id")
        return await res_success(data)
    except Exception as e:
        return await catch_Exception(e)

结果展示

{
    "content": [
      {
        "id": 1,
        "username": "test_user",
        "action": "login",
        "timestamp": "2025-01-22 12:34:56"
      },
      {
        "id": 2,
        "username": "another_user",
        "action": "logout",
        "timestamp": "2025-01-21 15:45:23"
      }
    ],
    "currentPage": 1,
    "pageSize": 10,
    "total": 2
  }

总结
通过封装通用的分页查询方法,我们可以在 FastAPI 中高效处理分页需求。前端结合 Vue3 的分页组件,可以轻松实现数据的分页展示。

这种方式不仅提高了代码复用性,还使得前后端协作更加高效,适合在自动化测试平台中应用。

<think>好的,我需要帮助用户了解如何使用FastAPI封装大型机器学习模型并创建API服务。首先,我应该回顾用户提供的引用内容,确保回答准确并正确引用来源。 用户提到了三个引用:[^1]介绍了FastAPI在AI模型封装中的应用,[^2]提到了FastAPI、Uvicorn和Pydantic的组合使用,[^3]提供了一个具体的YOLOv5模型封装的例子,包括Postman测试。我需要整合这些信息,给出一个结构清晰的教程。 首先,我应该按照用户的要求,分步骤讲解。可能需要包括环境准备、模型加载、接口设计、服务部署和测试等方面。要确保代码示例正确,并且符合FastAPI的最佳实践。 考虑到用户可能对FastAPI不熟悉,我需要简要说明每个步骤的目的,比如为什么使用Pydantic进行数据验证,或者Uvicorn作为服务器的重要性。同时,代码注释要详细,帮助用户理解每一部分的作用。 然后,生成相关问题。根据用户提供的示例问题,我应该围绕性能优化、异常处理、与其他框架对比、异步加载模型以及认证机制等方面提问。这些问题需要与教程内容相关,帮助用户深入理解。 需要特别注意引用标记的位置,确保在提及关键概念或步骤时正确添加引用,例如在介绍FastAPI时引用[^1],提到工具组合时引用[^2],以及在测试部分引用。 此外,要确保所有数学公式或代码块符合格式要求,比如行内公式用$...$,独立公式用$$...$$。不过在这个问题中,可能数学公式较少,主要是代码块和常规文本。 最后,检查回答是否符合中文要求,结构是否清晰,步骤是否逻辑连贯,引用是否正确自然。确保没有使用任何Markdown格式,代码块用三个反引号包围,并标明语言类型。 现在开始组织内容: 1. 环境准备:安装FastAPI、Uvicorn、Pydantic,可能还需要其他依赖如torch、transformers等。 2. 创建FastAPI应用实例,并定义模型加载函数,确保模型在启动时加载,避免重复加载。 3. 定义请求和响应模型,使用Pydantic进行数据验证,例如用户输入的文本或文件路径。 4. 编写推理接口,处理请求,调用模型进行预测,并返回结果。 5. 启动服务,使用Uvicorn运行应用。 6. 测试接口,使用Postman发送请求,检查响应是否正确。 在代码示例中,可能需要一个具体的模型,比如Hugging Face的BERT模型,处理文本分类任务。展示如何加载模型、预处理输入、推理和后处理结果。 在相关问题部分,考虑用户可能遇到的后续问题,如性能优化(异步处理、批处理)、错误处理(模型加载失败、输入校验)、扩展性(分布式部署)等。 需要确保所有引用正确,比如在介绍FastAPI时引用,在提到工具组合时引用[^2],在测试步骤提到Postman时引用[^3]。 最后检查语言是否流畅,结构是否符合要求,确保没有遗漏任何用户的要求。</think>### 使用 FastAPI 封装大模型创建 API 服务教程 以下是分步骤的实现方法,结合代码示例和关键概念说明: --- #### **1. 环境准备** 安装依赖库: ```bash pip install fastapi uvicorn pydantic python-multipart torch transformers ``` - **FastAPI**:构建 API 框架 [^2] - **Uvicorn**:高性能 ASGI 服务器 [^2] - **Pydantic**:接口参数校验工具 - `transformers`:加载预训练大模型(如 BERT、GPT) --- #### **2. 创建 FastAPI 应用并加载模型** ```python from fastapi import FastAPI, UploadFile from pydantic import BaseModel from transformers import pipeline # 初始化应用 app = FastAPI(title="大模型API服务") # 启动时加载模型(以文本生成模型为例) @app.on_event("startup") def load_model(): global model model = pipeline("text-generation", model="gpt2") # 替换为实际大模型路径 print("模型加载完成") # 定义健康检查接口 @app.get("/health") def health_check(): return {"status": "ok"} ``` --- #### **3. 定义请求/响应数据格式** 使用 Pydantic 校验输入: ```python class TextRequest(BaseModel): input_text: str max_length: int = 50 class ImageRequest(BaseModel): file: UploadFile threshold: float = 0.5 class ResponseModel(BaseModel): result: str confidence: float ``` --- #### **4. 实现推理接口** **文本生成接口示例**: ```python @app.post("/generate_text") async def generate_text(request: TextRequest): try: output = model(request.input_text, max_length=request.max_length) return ResponseModel( result=output[0]["generated_text"], confidence=1.0 ) except Exception as e: return {"error": str(e)} ``` **图像处理接口示例**(参考YOLOv5封装[^3]): ```python from PIL import Image import io @app.post("/detect_objects") async def detect_objects(request: ImageRequest): image_data = await request.file.read() image = Image.open(io.BytesIO(image_data)) # 假设已加载YOLOv5模型 results = model(image) return {"detections": results.pandas().xyxy[0].to_dict()} ``` --- #### **5. 启动服务** ```bash uvicorn main:app --host 0.0.0.0 --port 8000 --reload ``` - `--reload` 参数支持热更新(仅开发环境使用) --- #### **6. 接口测试** 使用 Postman 发送请求: 1. **POST** `http://localhost:8000/generate_text` 2. **Body** → **JSON**: ```json { "input_text": "人工智能的未来发展", "max_length": 100 } ``` 3. 查看返回的生成文本结果 --- ### **关键优化技巧** 1. **异步处理**:对 I/O 密集型操作使用 `async/await` ```python @app.post("/async_predict") async def async_predict(request: TextRequest): await preprocess(request.input_text) # 模拟异步预处理 ... ``` 2. **批处理支持**: ```python def batch_predict(texts: List[str]): return model(texts, batch_size=8) ``` 3. **模型缓存**:使用 `lru_cache` 缓存常用模型实例 --- ### **部署建议** 1. **生产环境部署**: ```bash uvicorn main:app --workers 4 --limit-concurrency 100 ``` 2. **结合 Docker** 容器化部署 3. **添加认证中间件**(参考[^1]安全实践) --- §§ 相关问题 §§ 1. 如何处理大模型的内存占用问题? 2. 如何为 FastAPI 接口添加 JWT 认证? 3. 如何实现模型的热更新而不中断服务? 4. 怎样监控 API 服务的性能指标? 5. 大模型 API 如何设计版本控制? [^1]: 在人工智能领域,将模型封装为可调用的服务接口是实现模型应用化的关键环节。 : FastAPI 是一个快速(高性能)的构建API的Web框架,Uvicorn 是高效的ASGI服务器。 [^3]: 使用 Postman 工具测试接口时需要配置与代码对应的参数格式。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

测开小林

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值