0
点赞
收藏
分享

微信扫一扫

用 AI 写「接口参数校验器」(自动生成校验代码)

场景

写接口时,参数校验代码又臭又长:判断必填、判断类型、判断范围、判断格式。可以把接口文档发给 AI,让它自动生成完整的校验代码。

准备

pip install openai==1.30.0

目录结构:

validator_generator_ai/
    api_spec.txt       # 接口参数描述
    gen_validator.py
    validators.py      # 生成的校验代码

api_spec.txt 示例:

接口:创建用户方法:POST参数:  username: 字符串,必填,3-20个字符,只能包含字母数字下划线  email: 字符串,必填,必须是合法邮箱格式  age: 整数,可选,范围0-150  phone: 字符串,可选,必须是11位手机号  role: 字符串,可选,只能是 admin/user/guest 之一

gen_validator.py

import os
from pathlib import Path
from openai import OpenAI

client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))


def read_spec(path: str) -> str:
    return Path(path).read_text(encoding="utf-8")


def ask_ai_to_generate_validator(spec: str) -> str:
    system = (
        "你是一个Python后端开发专家,擅长写参数校验代码。\n"
        "我会给你一个接口的参数描述,请帮我生成一个完整的参数校验函数。\n"
        "要求:\n"
        "1)用Python写,使用一个函数,接收一个dict参数;\n"
        "2)对每个参数进行校验,不通过则抛出 ValueError 并说明原因;\n"
        "3)代码要完整可运行,不要省略 import;\n"
        "4)用纯文本输出,不要用markdown。"
    )

    user = f"接口参数描述:\n{spec}"

    resp = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": system},
            {"role": "user", "content": user},
        ],
        temperature=0.2,
    )
    return resp.choices[0].message.content.strip()


def main():
    spec_path = input("请输入接口描述文件路径(默认 api_spec.txt):").strip() or "api_spec.txt"

    spec = read_spec(spec_path)
    print("正在生成校验代码...\n")

    code = ask_ai_to_generate_validator(spec)

    out = Path("validators.py")
    out.write_text(code, encoding="utf-8")

    print("===== 生成的校验代码 =====\n")
    print(code)
    print(f"\n代码已保存到:{out.resolve()}")


if __name__ == "__main__":
    main()

运行:

python gen_validator.py

生成的 validators.py 示例:

import re

def validate_create_user(data: dict) -> None:
    """校验创建用户接口的参数"""
    
    # username 校验
    username = data.get("username")
    if not username:
        raise ValueError("username 不能为空")
    if not isinstance(username, str):
        raise ValueError("username 必须是字符串")
    if not (3 <= len(username) <= 20):
        raise ValueError("username 长度必须在3-20个字符之间")
    if not re.match(r"^[a-zA-Z0-9_]+$", username):
        raise ValueError("username 只能包含字母、数字和下划线")
    
    # email 校验
    email = data.get("email")
    if not email:
        raise ValueError("email 不能为空")
    if not isinstance(email, str):
        raise ValueError("email 必须是字符串")
    if not re.match(r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$", email):
        raise ValueError("email 格式不合法")
    
    # age 校验(可选)
    age = data.get("age")
    if age is not None:
        if not isinstance(age, int):
            raise ValueError("age 必须是整数")
        if not (0 <= age <= 150):
            raise ValueError("age 必须在0-150之间")
    
    # phone 校验(可选)
    phone = data.get("phone")
    if phone is not None:
        if not isinstance(phone, str):
            raise ValueError("phone 必须是字符串")
        if not re.match(r"^1[3-9]\d{9}$", phone):
            raise ValueError("phone 必须是11位合法手机号")
    
    # role 校验(可选)
    role = data.get("role")
    if role is not None:
        if role not in ["admin", "user", "guest"]:
            raise ValueError("role 只能是 admin/user/guest 之一")


# 使用示例
if __name__ == "__main__":
    # 正确数据
    try:
        validate_create_user({
            "username": "zhangsan",
            "email": "zhangsan@example.com",
            "age": 25,
            "phone": "13812345678",
            "role": "user"
        })
        print("校验通过")
    except ValueError as e:
        print(f"校验失败:{e}")
    
    # 错误数据
    try:
        validate_create_user({
            "username": "ab",  # 太短
            "email": "not-an-email",
            "age": 200,  # 超出范围
        })
    except ValueError as e:
        print(f"校验失败:{e}")


举报
0 条评论