How to make Pydantic's BaseModel accept some special case input types in fastapi app

I have a fastapi app, which takes in "application/json" among other input types and returns "appliction/json". I have a input-validator written sub-classing pydantic's BaseModel and I would like to make it accept some cases of inputs which I do receive and not generate fastapi.exceptions.RequestValidationError on them.

some accepted inputs (List[List[float]]):

  1. {"input_json":[[1.0, 2.0, 3.0, 4.0]]}
  2. {"input_json":[[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0]]}

I would like to make it accept following input cases:

  1. {"input_json":[[1.0, 2.0, .0, 4.]]} (no number after decimal point, numpy arrays and python lists accept such inputs by populating 0 after period, but pydantic throws validation error.)
  2. {"input_json":[1.0, 2.0, 3.0, 4.0]} (no list of lists, but just a list. i will handle the shape internally doing numpy.my_array.reshape(-1, 4), but I want pydantic to not generate RequestValidationError and send the input to my fastapi endpoints.)
  3. {"input_json":[[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0],]} (comma at the end of second nested list. both numpy and python lists accept such inputs, but pydantic doesn't.)

Here's how my validaiton class is written:

from pydantic import BaseModel, validator

class InputResponse(BaseModel):
    input_json: List[List[float]]

    @validator("input_json")
    def check_dimensionality(cls, list_of_lists):
        for nested_list in list_of_lists:
            if len(nested_list) != 4:
                raise ValueError(incomplete_msg)
        return list_of_lists

what changes do I make to be able to accept all of those input cases?


For that, you can either define a TypeVar or use a union type. In code that looks like

from typing import TypeVar, Union
T = TypeVar("T", list[list[float]], list[float])

# Option with TypeVar
class InputResponse(BaseModel):
    input_json: T

# Option with Union type
class InputResponse(BaseModel):
    input_json: Union[list[list[float]], list[float]]

Regarding the missing zero after the decimal point, I haven't seen an issue with that.