Pydantic: удалить значение дискриминатора распознаваемого объединения из loc-поля ValidationErrorPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Pydantic: удалить значение дискриминатора распознаваемого объединения из loc-поля ValidationError

Сообщение Anonymous »

В настоящее время я использую FastAPI для университетского проекта, где он служит моей серверной частью.
Один из потоков моего приложения требует, чтобы я отправил полезную нагрузку из внешнего интерфейса в серверная часть, где одно из полей имеет множество вариантов. Эту полезную нагрузку необходимо проверить с помощью pydantic на серверной стороне. Для этого я решил использовать дискриминируемое объединение.
Предположим, что класс структурирован таким образом.

Код: Выделить всё

class ClassA(pydantic.BaseModel):
type: Literal["a"]
field_a: int

class ClassB(pydantic.BaseModel):
type: Literal["b"]
...

ClassUnion = Annotated[Union[ClassA, ClassB], pydantic.Field(discriminator="type")]

class Parent(pydantic.BaseModel):
child: ClassUnion
field_parent: str
У меня есть родительский класс, у которого есть дочернее поле, содержащее объединение классов ClassA и ClassB, различающихся по типу. Таким образом, если поле типа в полезных данных JSON содержит «a», pydantic разрешит его как ClassA. Дискриминированное объединение работает по счастливому пути (когда нет ошибок), однако, если я заполняю child.field_a недопустимым значением (скажем, строкой), я ожидаю возникновения ValidationError, чтобы серверная часть могла уведомить интерфейс о том, где находится ошибка.
Для этого у меня есть собственный обработчик ошибок, который перехватывает любую ошибку RequestValidationError из FastAPI, преобразует различные ошибки из ValidationError pydantic в более простую форму. Детали обработчика ошибок не имеют значения; важно то, что обработчик ошибок зависит от поля «loc» в ValidationError.
Например, если ошибка возникает в «field_parent», то поле «loc» будет указывать на место ошибки; это существо («body», «field_parent»). Обратите внимание, что «тело» — это именно то место, где произошла ошибка в запросе FastAPI. Для простоты мы можем предположить, что loc — это просто ("field_parent").
Однако, если в "field_a" встречается loc, то я ожидаю, что loc должен быть: ("child ", "поле_а"). Таким образом, я могу преобразовать поле в форму, соответствующую введенным данным:

Код: Выделить всё

{
"child": {
"field_a": "Error message"
}
}
Однако похоже, что pydantic также включает дискриминатор объединения в поле «loc». Помните, что «field_a» находится в распознаваемом объединении (точнее, в классе A) и различается по «типу». Если type = «a», то «дочерний» становится ClassA. Это значение дискриминатора в конечном итоге включается в «loc» и становится («child», «a», «field_a»). Очевидно, это мешает моему внешнему обработчику исключений, поскольку поля больше не совпадают с входными данными.
Есть ли способ удалить значение дискриминатора из поля loc?< /strong> Я не нашел ни одной опции, которая могла бы отключить это поведение (если его вообще можно отключить) в документации по дискриминируемому объединению FastAPI. Это не проблема настройки ошибок проверки запросов FastAPI; а скорее проблема с тем, как Pydantic форматирует поле «loc».
Альтернативные решения:
  • Я' Я рассматривал возможность использования WrapValidators для перехвата ValidationError и последующего его изменения, но документации о внутреннем устройстве ValidationError мало (просмотр кода Python тоже не помогает, так как он, вероятно, реализован где-то еще).
  • Фильтрация распознаваемых значений объединения вручную кажется грязным решением, к тому же существует риск того, что дискриминатор будет иметь то же имя, что и поле, поэтому я тоже отказался от этого.
  • Я не могу просто настроить проверку ошибок для одного или двух маршрутов, поскольку модель будет повторно использоваться на нескольких маршрутах.
Есть предложения?

Подробнее здесь: https://stackoverflow.com/questions/791 ... onerror-lo
Реклама
Ответить Пред. темаСлед. тема

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

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

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

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

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

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