FastAPI/pydantic: field_validator не учитывается при использовании пустого Depends()Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 FastAPI/pydantic: field_validator не учитывается при использовании пустого Depends()

Сообщение Anonymous »


I am following Method 2 of this answer to be able to upload multiple files in combination with additional data using fastapi. It is working fine.

After starting to implement the handling of the additional data including validation using pydantic's BaseModel i am facing an issue:

My custom field_validator is working when using the model class directly but it is not working as expected, when using it via FastAPI and Depends().

The key point is that i want to use a python Enum and i want to be able to use the Enum's names in the additional data (query parameters). For this reason i am using a custom validator to only allow names which exist in the enum.

When i initialize the model manually, the validation works as expected:

from enum import Enum from pydantic import BaseModel, field_validator, ValidationInfo, ValidationError class VehicleSubSystems(Enum): A = "A Verbose" B = "B Verbose" class EvaluationArguments(BaseModel): vehicle_sub_system: VehicleSubSystems @field_validator("vehicle_sub_system", mode='before') @classmethod def validate_vehicle_sub_system(cls, vehicle_sub_system: str, _info: ValidationInfo) -> VehicleSubSystems: """ Allows using the enum names instead of the values """ try: return VehicleSubSystems[vehicle_sub_system] except KeyError: raise ValueError(f"Can not find vehicle subsystem '{vehicle_sub_system}'. " f"Allowed values: {[e.name for e in VehicleSubSystems]}") def test_validation_is_performed(): """ Test that the validation is performed """ EvaluationArguments(vehicle_sub_system="A") try: EvaluationArguments(vehicle_sub_system="DOES_NOT_EXIST") except ValidationError: print("Test passed") else: print("Test failed") if __name__ == '__main__': test_validation_is_performed() # prints "Test passed" as expected Combining this with the FastAPI application shows unexpected behavior: The field_validator is not considered. Instead the default behavior of the model class is used.

Server code:

import uvicorn from typing import List from fastapi import FastAPI, File, Depends, UploadFile app = FastAPI() def create_args(vehicle_sub_system: str): return EvaluationArguments(vehicle_sub_system=vehicle_sub_system) @app.post("/process-works") def process_works(files: List[UploadFile] = File(...), eval_args: EvaluationArguments = Depends(create_args)): return f"Got {len(files)} files and {eval_args}" @app.post("/process-fails") def process_fails(files: List[UploadFile] = File(...), eval_args: EvaluationArguments = Depends()): return f"Got {len(files)} files and {eval_args}" if __name__ == '__main__': uvicorn.run(app, host="0.0.0.0", port=8000) Client code:

import requests if __name__ == '__main__': url = 'http://127.0.0.1:8000' files = [('files', open('d:/temp/a.txt', 'rb')), ('files', open('d:/temp/b.txt', 'rb'))] params = {"vehicle_sub_system": "A"} print("Calling process-works") resp = requests.post(url=f"{url}/process-works", params=params, files=files) print(resp.json()) print("Calling process-fails") resp = requests.post(url=f"{url}/process-fails", params=params, files=files) print(resp.json()) # Output # Calling process-works # Got 2 files and vehicle_sub_system= # Calling process-fails # {'detail': [{'type': 'enum', 'loc': ['query', 'vehicle_sub_system'], 'msg': "Input should be 'A Verbose' or 'B Verbose'", 'input': 'A', 'ctx': {'expected': "'A Verbose' or 'B Verbose'"}}]} The process-works endpoint shows the expected behavior but only when using a separate dependency Depends(create_args) which mimics the direct usage of the model class.

The process-fails endpoint (using Depends()) shows the issue. I would expect that Depends() is just making FastAPI to call the init method of the model class and uses the validation as expected. But somehow it just ignores it.

I could not figure out why, perhaps somebody can explain what happens here and if there is a solution without the workaround?


Источник: https://stackoverflow.com/questions/780 ... ty-depends
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»