question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cannot return response containing pydantic model that includes aliases since FastAPI 0.47.1

See original GitHub issue

Starting in 0.47.1, responses fail validation if they include any pydantic model objects that contain field aliases

You can work around this by explicitly calling .dict(by_alias=True) on the top-level response model object before returning it from the path operation function (see the example below). However, this is super unintuitive and makes the use of field aliases painful. In our codebase we use aliases extensively (via Config.alias_generator) to expose camelCase in our public APIs while keeping our internal field names snake_case, and this issue is a real hassle.

To Reproduce

  1. Create a test.py file with:
import fastapi
import pydantic
import starlette.testclient
from typing import List

app = fastapi.FastAPI()

class Item(pydantic.BaseModel):
    my_value: int = pydantic.Field(..., alias='myValue')

class RootResponse(pydantic.BaseModel):
    items: List[Item] = pydantic.Field(...)

@app.get('/broken_1', response_model=RootResponse)
async def broken_1():
    # embedded models don't work if they have aliased fields
    return {'items': [Item(myValue=5), Item(myValue=10)]}

@app.get('/broken_2', response_model=RootResponse)
async def broken_2():
    # making the top-level response a model instance doesn't help
    return RootResponse(items=[Item(myValue=5), Item(myValue=10)])

@app.get('/workaround', response_model=RootResponse)
async def workaround():
    # workaround is to build a top-level model and then dict(by_alias=True)
    return RootResponse(items=[Item(myValue=5), Item(myValue=10)]).dict(by_alias=True)

with starlette.testclient.TestClient(app) as test_client:
    for path in ['/broken_1', '/broken_2', '/workaround']:
        try:
            print('-------------------------------------------')
            print(path)
            response = test_client.get(path)
        except Exception as exc:
            print(exc)
        else:
            print('succeeded')
  1. Run python3 test.py with FastAPI 0.47.0. All 3 cases succeed.
  2. Run python3 test.py with FastAPI 0.49.0. Only the “workaround” case succeeds.

Expected behavior

Model classes that include aliased fields (whether the alias is directly specified on the field as in the above example, or using a pydantic Config.alias_generator) should be usable with the context of a response model.

Environment

  • OS: Linux (Ubuntu 18.04)
  • FastAPI Version: 0.47.1 and above
  • Python version: 3.7, 3.8

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

5reactions
jmrieboldcommented, Mar 17, 2020

I’ve run into this as well. We solved it by subclassing BaseModel like so:

class CustomBaseModel(BaseModel):
    class Config:
        # Don't force use of aliases in class instantiation/attribute access
        allow_population_by_field_name = True

I tried running your test script using the subclassed model and it appeared to work correctly:

/broken_1
succeeded
-------------------------------------------
/broken_2
succeeded
-------------------------------------------
/workaround
succeeded
0reactions
github-actions[bot]commented, Apr 7, 2020

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

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to return Pydantic model using Field aliases instead of ...
The only issue is that the API doesn't return data in correct format. I have been stuck on it for a while. I...
Read more >
Response Model - FastAPI
You can declare the model used for the response with the parameter response_model ... function is returning the same input user that contains...
Read more >
Many-To-Many Relationships In FastAPI
Modeling this kind of data in SQLAlchemy and FastAPI actually isn't ... set up pydantic models which we can use as response models...
Read more >
Pydantic V2 Plan
Since pydantic's initial release, with the help of wonderful ... In pydantic V1 the core of all validation was a pydantic model, this...
Read more >
Django and Pydantic
This article looks at how to integrate Pydantic with a Django ... like FastAPI but still what to leverage much of what Django...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found