You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在保留UUID类型注解时重写FastAPI的UUID验证错误?

FastAPI UUID参数自定义验证响应实现

方法一:自定义Pydantic UUID类型(精准控制)

通过自定义继承自原生UUID的Pydantic类型,在验证逻辑中抛出自定义异常,直接返回定制化响应体,同时保留类型注解的语义。

实现代码

from uuid import UUID as _UUID, ValueError as UUIDValueError
from pydantic import GetJsonSchemaHandler
from pydantic_core import core_schema
from fastapi import FastAPI, HTTPException

class CustomUUID(_UUID):
    @classmethod
    def __get_pydantic_core_schema__(cls, source_type, handler: GetJsonSchemaHandler) -> core_schema.CoreSchema:
        # 定义Pydantic核心验证规则:接收字符串,验证后返回CustomUUID实例,序列化时转成字符串
        return core_schema.no_info_wrap_validator_function(
            cls.validate,
            core_schema.str_schema(),
            serialization=core_schema.plain_serializer_function_ser_schema(str),
        )

    @classmethod
    def validate(cls, v: str) -> _UUID:
        try:
            return cls(v)
        except UUIDValueError:
            # 验证失败时抛出带自定义响应体的HTTP异常
            raise HTTPException(
                status_code=400,
                detail={
                    "code": "INVALID_UUID_FORMAT",
                    "message": "请提供符合RFC4122标准的有效UUID字符串",
                    "received_value": v
                }
            )

app = FastAPI()

@app.get("/streams/{stream_id}")
async def get_stream(stream_id: CustomUUID):
    # 接口内直接使用CustomUUID实例,和原生UUID用法一致
    return {"stream_id": str(stream_id), "uuid_version": stream_id.version}

方法二:全局异常处理器(统一处理所有UUID验证错误)

利用FastAPI的异常处理器,捕获原生UUID类型参数的验证错误,替换默认响应体。这种方式无需修改类型注解,直接使用原生UUID。

实现代码

from uuid import UUID
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from pydantic import ValidationError

app = FastAPI()

@app.exception_handler(ValidationError)
async def custom_validation_exception_handler(request: Request, exc: ValidationError):
    # 遍历错误信息,判断是否为UUID解析失败的错误
    for error in exc.errors():
        if error["type"] == "uuid_parsing":
            return JSONResponse(
                status_code=400,
                content={
                    "code": "INVALID_UUID",
                    "message": "无效的UUID格式",
                    "field": error["loc"][0],
                    "received_value": error["input"]
                }
            )
    # 其他类型的验证错误,返回默认的错误响应
    return JSONResponse(
        status_code=400,
        content={"detail": exc.errors()}
    )

@app.get("/streams/{stream_id}")
async def get_stream(stream_id: UUID):
    return {"stream_id": str(stream_id)}

两种方案对比

  • 自定义类型方案:针对性强,仅对使用CustomUUID注解的参数生效,适合需要对特定接口做差异化响应的场景。
  • 异常处理器方案:全局生效,所有使用原生UUID注解的参数验证失败都会触发自定义响应,适合需要统一规范UUID错误格式的场景。

内容的提问来源于stack exchange,提问作者Oren_C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 09:25:26