Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to change the output alias in pydantic?

Setup:

# Pydantic Models

class TMDB_Category(BaseModel):
    name: str = Field(alias="strCategory")
    description: str = Field(alias="strCategoryDescription")


class TMDB_GetCategoriesResponse(BaseModel):
    categories: list[TMDB_Category]


@router.get(path="category", response_model=TMDB_GetCategoriesResponse)
async def get_all_categories():
    async with httpx.AsyncClient() as client:
        response = await client.get(Endpoint.GET_CATEGORIES)
        return TMDB_GetCategoriesResponse.parse_obj(response.json())

Problem:
Alias is being used when creating a response, and I want to avoid it. I only need this alias to correctly map the incoming data but when returning a response, I want to use actual field names.

Actual response:

{
  "categories": [
    {
      "strCategory": "Beef",
      "strCategoryDescription": "Beef is ..."
    },
    {
      "strCategory": "Chicken",
      "strCategoryDescription": "Chicken is ..."
    }
}

Expected response:

{
  "categories": [
    {
      "name": "Beef",
      "description": "Beef is ..."
    },
    {
      "name": "Chicken",
      "description": "Chicken is ..."
    }
}
like image 918
Rechu Avatar asked Aug 31 '25 15:08

Rechu


2 Answers

Update (2023-10-07): Check the comments in the question for other answers and this answer in the same question for pydantic 2.0 or newer.


Switch aliases and field names and use the allow_population_by_field_name model config option:

class TMDB_Category(BaseModel):
    strCategory: str = Field(alias="name")
    strCategoryDescription: str = Field(alias="description")

    class Config:
        allow_population_by_field_name = True

Let the aliases configure the names of the fields that you want to return, but enable allow_population_by_field_name to be able to parse data that uses different names for the fields.

like image 89
Hernán Alarcón Avatar answered Sep 02 '25 17:09

Hernán Alarcón


Use the Config option by_alias.


from fastapi import FastAPI, Path, Query
from pydantic import BaseModel, Field

app = FastAPI()

class Item(BaseModel):
    name: str = Field(..., alias="keck")

@app.post("/item")
async def read_items(
    item: Item,
):
    return item.dict(by_alias=False)

Given the request:

{
  "keck": "string"
}

this will return

{
  "name": "string"
}
like image 23
Sean Avatar answered Sep 02 '25 16:09

Sean