Fastapi: [QUESTION] Response model with pydantic's arbitrary_types_allowed not working

Created on 30 Mar 2020  路  6Comments  路  Source: tiangolo/fastapi

I use pydantic model with custom type. Set in config arbitrary_types_allowed=True.
Without setting a parameter "response_model" it's work. But when I set this model in param:

fastapi.exceptions.FastAPIError: Invalid args for response field! Hint: check that <class 'Foo'> is a valid pydantic field type 

Pydantic class definition example:

import Foo

class Model(BaseModel):
    id: str
    custom: Optional[Foo] = Field(None)
    status: str = None
    fail_message: Optional[str] = None
    params: Dict[str, Any] = None

    @validator('custom')
    def deserialize_model(cls, v):
        return Foo.loads(v)

    class Config:
        arbitrary_types_allowed = True
        json_encoders = {Foo: lambda v: v.dumps()}
question

Most helpful comment

Same problem here:

from pydantic import BaseModel
from fastapi import FastAPI


class Pair:
    def __init__(self, x: int, y: int):
        self.x: int = x
        self.y: int = y


class M(BaseModel):
    pair: Pair
    other: int

    class Config:
        arbitrary_types_allowed = True


app = FastAPI()


@app.get("/m/", response_model=M)
def just_m():
    return M(pair=Pair(x=5, y=7), other=8)

will report error:

fastapi.exceptions.FastAPIError: Invalid args for response field! Hint: check that <class 'test.Pair'> is a valid pydantic field type

All 6 comments

I see the same issue with an Arrow type returned from the SQLAlchemy model. arbitrary_types_allowed is not working when using the pydantic model in the response_model.

Please create a small self-contained example with a minimal FastAPI app that shows the error and what you would expect to happen, that way I can understand what's happening and what you want to achieve.

Assuming the original issue was solved, it will be automatically closed now. But feel free to add more comments or create new issues.

@tiangolo I think the config is getting lost in the create_cloned_field function.

new_field = create_response_field(name=field.name, type_=use_type)

Shouldn't it also pass model_config?

I ended up using a custom Pydantic field validator, instead of using arbitrary_types_allowed:

class AssociationList(_AssociationList):
    @classmethod
    def __get_validators__(cls):
        yield cls.validate

    @classmethod
    def validate(cls, v):
        if not isinstance(v, _AssociationList):
            raise TypeError("AssociationList required")
        return [UserOut.from_orm(u) for u in v]


class TeamOut(TeamBase):
    members: AssociationList
    ...

Same problem here:

from pydantic import BaseModel
from fastapi import FastAPI


class Pair:
    def __init__(self, x: int, y: int):
        self.x: int = x
        self.y: int = y


class M(BaseModel):
    pair: Pair
    other: int

    class Config:
        arbitrary_types_allowed = True


app = FastAPI()


@app.get("/m/", response_model=M)
def just_m():
    return M(pair=Pair(x=5, y=7), other=8)

will report error:

fastapi.exceptions.FastAPIError: Invalid args for response field! Hint: check that <class 'test.Pair'> is a valid pydantic field type
Was this page helpful?
0 / 5 - 0 ratings