FastAPI/Pydantic返回ACK时提示字段缺失,请求排查解决
FastAPI Pydantic 响应验证错误解决案例
问题背景
定义的Pydantic模型
from pydantic import BaseModel, Optional from your_module import settings class BaseMessage(BaseModel): """ ACK/NACK响应的基础模型 """ origin: str = settings.APP_ORIGIN_NAME message: str class Success(BaseMessage): """ 成功响应的API模型 """ id: str temp_password: Optional[str] | None class ACK(BaseModel): """ ACK响应的API模型 """ ACK: Success
POST端点实现代码
from fastapi import APIRouter, status, JSONResponse from pydantic import ValidationError from typing import Union import asyncpg from your_module import Domains, DomainCreate, ENDPOINT_MESSAGES, APIResponse, get_password_hash router = APIRouter() @router.post( path="/", summary="注册新域名", description="注册一个新域名。", response_model=Union[ACK, NACK], name="domains:create-domain", status_code=status.HTTP_201_CREATED, responses={400: {"model": NACK}}, ) async def create_domain( domain: DomainCreate, ) -> JSONResponse: try: instance = Domains(**domain.dict(exclude_unset=True)) instance.domain_hashed_password = get_password_hash( instance.domain_hashed_password ) db_instance = await Domains(**instance.dict(exclude_unset=True)).save() domain_id: str = str(db_instance.domain_id) success_text: str = ENDPOINT_MESSAGES["success"] try: ack_message = ACK( message=success_text, id=domain_id, temp_password=instance.domain_hashed_password, ) return JSONResponse( status_code=status.HTTP_201_CREATED, content=jsonable_encoder(ack_message), ) except ValidationError as exc: print(exc.errors()) except asyncpg.exceptions.UniqueViolationError: failure_text: str = ENDPOINT_MESSAGES["failure"] error_text: str = f"{ENDPOINT_MESSAGES['err_unique']} domain_name" nack_message: dict = APIResponse.nack(failure_text, error_text) return JSONResponse( status_code=status.HTTP_400_BAD_REQUEST, content=nack_message )
报错信息
向该端点发送POST请求时,持续收到以下错误:
ACK field required (type=value_error.missing) fastapi.exceptions.ResponseValidationError: 1 validation errors: {'loc': ('response',), 'msg': 'none is not an allowed value', 'type': 'type_error.none.not_allowed'}
错误发生在ack_message实例化环节,但用户认为已提供所有必要字段,期望返回的响应格式为:
{ "ACK": { "origin": "APP_ORIGIN_NAME的内容", "message": "success_text的内容", "id": "domain_id的内容", "temp_password": "domain_hashed_password的内容" } }
解决方案
已解决:根据Victor的回答,将ack_message的定义修改为:
ack_message = ACKResponse( ACK={ "message": success_text, "id": domain_id, "temp_password": unhashed_password, } )
内容的提问来源于stack exchange,提问作者Mark R
相关产品推荐
相关产品推荐

