Pydantic: Export by field name, not by alias

Created on 18 Jan 2021  路  2Comments  路  Source: samuelcolvin/pydantic

Checks

  • [*] I added a descriptive title to this issue
  • [*] I have searched (google, github) for similar issues and couldn't find anything
  • [*] I have read and followed the docs and couldn't find an answer
  • [*] After submitting this, I commit to one of:

    • Look through open issues and helped at least one other person

    • Hit the "watch" button on this repo to receive notifications and I commit to help at least 2 people that ask questions in the future

    • Implement a Pull Request for a confirmed bug

Question

Output of python -c "import pydantic.utils; print(pydantic.utils.version_info())":

pydantic version: 1.6.1

I have a model

class User(BaseModel):
    login_name: str = Field(..., alias='loginName')
    display_name: str = Field(..., alias='displayName')
    localized_name: str = Field(..., alias='localizedName')
    extension: str = Field(..., alias='extension')
    agent_id: Optional[str] = Field(..., alias='agentId')

I use alias for external API (the fields in external API like in alias). And than I have my public API
Like this:

@app.get('/users', response_model=List[User])  # type: ignore
def get_users()
    return [user.dict(by_alias=False)]

The problem is that I get in response fields by alias, but I want by field names.
If I have -> @app.get('/users', response_model=List[User])
then response -> [{"loginName":"some_login","displayName":"Mark Gordon","localizedName":"Jamie Bell","extension":"123","agentId":"8235"}]

If I have -> @app.get('/users', response_model=List[Dict])
then response -> [{"login_name":"some_login","display_name":"Mark Gordon","localized_name":"Jamie Bell","extension":"123","agent_id":"8235"}]

What I want:

  • response_model=List[User] -- it's important for swagger
  • Fields in response in snake case
    (Yes, I know about .dict(by_alias=False), but if I use User in typing -- it does not work)

As I understand, it's not possible to maintain simultaneously.

I have only one solution, duplicate User model, but without aliases and than convert to it

class ExternalUser(BaseModel):
    login_name: str
    display_name: str
    localized_name: str 
    extension: str
    agent_id: Optional[str]

Do you know better solution?

question

Most helpful comment

Thanks a bunch @koxudaxi !

All 2 comments

@romutchio
I guess your question depend on FastAPI.
You should create an issue on the FastAPI project.

I answer your question.
You can use response_model_by_alias=False on @app.get to get a response as field name

```python
from typing import List, Optional

import fastapi
import uvicorn as uvicorn
from pydantic import BaseModel, Field

app = fastapi.FastAPI()

class User(BaseModel):
login_name: str = Field(..., alias='loginName')
display_name: str = Field(..., alias='displayName')
localized_name: str = Field(..., alias='localizedName')
extension: str = Field(..., alias='extension')
agent_id: Optional[str] = Field(..., alias='agentId')

@app.get('/users', response_model=List[User], response_model_by_alias=False)
def get_users():
return [User(loginName='abc', displayName='efg', localizedName='hij', extension='xyz', agentId='123')]

if __name__ == '__main__':
uvicorn.run(app)
```

Output
bash $ curl curl http://127.0.0.1:8000/users [{"login_name":"abc","display_name":"efg","localized_name":"hij","extension":"xyz","agent_id":"123"}]

Thanks a bunch @koxudaxi !

Was this page helpful?
0 / 5 - 0 ratings

Related issues

maxrothman picture maxrothman  路  26Comments

samuelcolvin picture samuelcolvin  路  30Comments

koxudaxi picture koxudaxi  路  25Comments

chopraaa picture chopraaa  路  18Comments

kryft picture kryft  路  35Comments