CamelCase Models with FastAPI and Pydantic
By: Ahmed Nafies
Tags: Rest Api, Pydantic, Python, Fastapi, Json

The Problem

lets assume that you have the following application exposing an API endpoint that represent a resource called “User” in your “models.py”

from pydantic import BaseModel





class User(BaseModel):

first_name: str

last_name: str = None

age: int

and you have your “main.py” containing the “run” configuration

import uvicorn

from fastapi import FastAPI

from models import User





app = FastAPI()





@app.post("/user/", response_model=User)

async def create_user(user: User):

return user





if __name__ == "__main__":

uvicorn.run(app, host="0.0.0.0", port=8000)

if you run the application

python main.py

snake_case request/respose

we will see snake-cased request/response body in the OpenAPI documentation as we expected. Now we can change the field names to camelCase but that does not follow the PEP-8 standard.

Pydantic Aliases

Aliases for pydantic models can be used in the JSON serialization in camel case instead of snake case as follows:

from pydantic import BaseModel, Field





class User(BaseModel):

first_name: str = Field(..., alias='firstName')

last_name: str = Field(..., alias='lastName')

age: int = Field(..., alias='age')

That we make our schema in camelCase

camel-case request/response body

What if we have 1000 fields instead of 3, what do we do now? I wish there was a magic alias generator.

Luckily there is :)

Alias Generator

Pyndantic has a Config class which controls the behaviour of models. We can generate aliases for all of the model fields as follows:

from pydantic import BaseModel

from humps import camelize





def to_camel(string):

return camelize(string)





class User(BaseModel):

first_name: str

last_name: str = None

age: float



class Config:

alias_generator = to_camel

now lets try it out

Internal server error

Internal server error? SAY WHAAAAT?

error log

Well of course, we are using aliases (camelCase) instead of field names (snake_case), I hope there is an easy to fix that

Luckily there is :D

All what is needed to be done is to add the following to the model Config class

allow_population_by_field_name = True

so our model should look like this now

from pydantic import BaseModel

from humps import camelize





def to_camel(string):

return camelize(string)





class User(BaseModel):

first_name: str

last_name: str = None

age: float



class Config:

alias_generator = to_camel

allow_population_by_field_name = True

lets try it one last time

success repose

AND BOOM!, all of our code is in snake_case and request/response and documentation are in camelCase, isn’t that AWESOME?

One last enhancement

We would probably have many models used by many API endpoints and we want to use camelCase across them all, right? probably :)

Now lets use the power on inheritance

from pydantic import BaseModel

from humps import camelize





def to_camel(string):

return camelize(string)





class CamelModel(BaseModel):

class Config:

alias_generator = to_camel

allow_population_by_field_name = True

class User(CamelModel):

first_name: str

last_name: str = None

age: int

Great, now you can inherit from CamelModel instead of BaseModel and ENJOY!!!

I created a simple package easy to use following the above tutorial.

pip install fastapi_camelcase

from fastapi_camelcase import CamelModel class User(CamelModel):

first_name: str

last_name: str = None

age: int

The full code for this example can be found here on github