CS504070 - FastAPI Tutorials
  • 🧩CS504070 - FastAPI Tutorials
  • 🔎Unit 1: Python Type Hint
  • ⚙️Unit 2: Pydantic
  • 🔃Unit 3: Concurrency
  • 💾Unit 4: Install FastAPI
  • 🍉Unit 5: Hello World!
  • 🍌Unit 6: Path Parameters
  • 🍋Unit 7: Query Parameters
  • 🍊Unit 8: Request Body
  • 🍐Unit 9: Query Parameters and Validations
  • 🍎Unit 10: Path Parameters and Validations
  • 🍏Unit 11: Multiple Parameters
  • 🍇Unit 12: Request Body - List Fields and Nested Models
  • 🍓Unit 13: Data Types
  • 🍪Unit 14: Cookie Parameters
  • 🫐Unit 15: Header Parameters
  • 🍈Unit 16: Response Model - Return Type
  • 🍒Unit 17: Additional Models
  • 🥑Unit 18: Implementing JWT Authentication with FastAPI
  • ⚙️Appendix A
  • 🍭Appendix B
Powered by GitBook
On this page
  • Introduction
  • Example program
  • Reduce code duplication

Unit 17: Additional Models

Introduction

In this unit, we will implement a demo program that includes many Pydantic models for specific use-cases:

  • The input model needs to be able to have a password.

  • The output model should not have a password.

  • The database model would probably need to store a hashed password.


Example program

from fastapi import FastAPI
from pydantic import BaseModel, EmailStr

app = FastAPI()

class UserIn(BaseModel):
    username: str
    password: str
    email: EmailStr
    full_name: str = None

class UserOut(BaseModel):
    username: str
    email: EmailStr
    full_name: str = None

class UserDB(BaseModel):
    username: str
    hashed_password: str
    email: EmailStr
    full_name: str = None

def fake_password_hasher(raw_password: str):
    """This is a fake password hasher, don't use it in production."""
    return "salted_" + raw_password

def fake_save_user(user_in: UserIn):
    hashed_password = fake_password_hasher(user_in.password)
    user_db = UserDB(**user_in.model_dump(), hashed_password=hashed_password)
    print("User has been saved to an imaginary database!")
    return user_db

@app.post("/user/", response_model=UserOut)
async def create_user(user: UserIn):
    user_saved = fake_save_user(user)
    return user_saved

Within function definitions, the double asterisk, **, is used in conjunction with the parameter name **kwargs (though kwargs itself is not mandatory). This allows you to accept a variable number of keyword arguments when the function is called.

Reduce code duplication

In the above program, there are code snippets duplicated across class definition. As code duplication increases the chances of bugs, security issues, code desynchronization issues (when you update in one place but not in the others), etc.

from fastapi import FastAPI
from pydantic import BaseModel, EmailStr

app = FastAPI()

class UserBase(BaseModel):
    username: str
    email: EmailStr
    full_name: str = None

class UserIn(UserBase):
    password: str

class UserOut(UserBase):
    pass

class UserDB(UserBase):
    hashed_password: str

def fake_password_hasher(raw_password: str):
    """This is a fake password hasher, don't use it in production."""
    return "salted_" + raw_password

def fake_save_user(user_in: UserIn):
    hashed_password = fake_password_hasher(user_in.password)
    user_db = UserDB(**user_in.model_dump(), hashed_password=hashed_password)
    print("User has been saved to an imaginary database!")
    return user_db

@app.post("/user/", response_model=UserOut)
async def create_user(user: UserIn):
    user_saved = fake_save_user(user)
    return user_saved
PreviousUnit 16: Response Model - Return TypeNextUnit 18: Implementing JWT Authentication with FastAPI

Last updated 1 year ago

🍒
Page cover image