StackScholar
  • System Design Interview Preparation

    Beginner to advanced, with interactive simulators and full design case studies.

  • Python Full-Stack Interview Preparation

    Master backend + frontend questions with real-world cases.

  • AI/ML Engineer Interview Preparation

    ML, deep learning, LLMs, RAG, MLOps and system design - with mock interviews.

Rapid Review CSnewDSA VisualizerReviewBlog
Search⌘K
System Design Interview PreparationPython Full-Stack Interview PreparationAI/ML Engineer Interview Preparation
Rapid Review CSnewDSA VisualizerReviewBlog
CurriculumAll questionsFlashcardsGlossaryVisualizersDSA Visualizer

Navigate by Range

  • Q&A Python-1-5
  • Q&A Python-6-10
  • Q&A Python-11-15
  • Q&A Python-16-20
  • Q&A Python-21-25
  • Q&A Python-26-30
  • Q&A Python-31-35
  • Q&A Python-36-40
  • Q&A Python-41-45
  • Q&A Python-46-50
  • Q&A Python-51-55
  • Q&A Python-56-60
  • Q&A Python-61-65
  • Q&A Python-66-70
  • Q&A Python-71-75
  • Q&A Python-76-80
  • Q&A Python-81-85
  • Q&A Python-86-90
  • Q&A DB-MySQL-1-5
  • Q&A DB-MySQL-6-10
  • Q&A DB-MySQL-11-15
  • Q&A DB-MySQL-16-20
  • Q&A DB-MySQL-21-25
  • Q&A DB-MySQL-26-30
  • Q&A DB-MySQL-31-35
  • Q&A DB-MySQL-36-40
  • Q&A DB-MySQL-41-45
  • Q&A DB-MySQL-46-50
  • Q&A Django-1-5
  • Q&A Django-6-10
  • Q&A Django-11-15
  • Q&A Django-16-20
  • Q&A Django-21-25
  • Q&A Django-26-30
  • Q&A Django-31-35
  • Q&A Django-36-40
  • Q&A Django-41-45
  • Q&A Django-46-50
  • Q&A FastAPI-01-05
  • Q&A FastAPI-06-10
  • Q&A FastAPI-11-15
  • Q&A FastAPI-16-20
  • Q&A FastAPI-21-25
  • Q&A FastAPI-26-30
  • Q&A FastAPI-36-40
  • Q&A FastAPI-41-45
  • Q&A FastAPI-31-35
  • Q&A FastAPI-46-50
  • Q&A FastAPI-51-55
  • Q&A FastAPI-56-60
  • Q&A FastAPI-61-65
  • Q&A HTML-01-05
  • Q&A HTML-06-10
  • Q&A HTML-11-15
  • Q&A HTML-16-20
  • Q&A CSS-01-05
  • Q&A CSS-06-10
  • Q&A CSS-11-15
  • Q&A CSS-16-20
  • Q&A JavaScript-1-5
  • Q&A JavaScript-6-10
  • Q&A JavaScript-11-15
  • Q&A JavaScript-16-20
  • Q&A JavaScript-21-25
  • Q&A JavaScript-26-30
  • Q&A JavaScript-31-35
  • Q&A JavaScript-36-40
  • Q&A JavaScript-41-45
  • Q&A JavaScript-46-50
  • Q&A React-1-5
  • Q&A React-6-10
  • Q&A React-11-15
  • Q&A React-16-20
  • Q&A React-21-25
Loading…

Navigate by Range

  • Q&A Python-1-5
  • Q&A Python-6-10
  • Q&A Python-11-15
  • Q&A Python-16-20
  • Q&A Python-21-25
  • Q&A Python-26-30
  • Q&A Python-31-35
  • Q&A Python-36-40
  • Q&A Python-41-45
  • Q&A Python-46-50
  • Q&A Python-51-55
  • Q&A Python-56-60
  • Q&A Python-61-65
  • Q&A Python-66-70
  • Q&A Python-71-75
  • Q&A Python-76-80
  • Q&A Python-81-85
  • Q&A Python-86-90
  • Q&A DB-MySQL-1-5
  • Q&A DB-MySQL-6-10
  • Q&A DB-MySQL-11-15
  • Q&A DB-MySQL-16-20
  • Q&A DB-MySQL-21-25
  • Q&A DB-MySQL-26-30
  • Q&A DB-MySQL-31-35
  • Q&A DB-MySQL-36-40
  • Q&A DB-MySQL-41-45
  • Q&A DB-MySQL-46-50
  • Q&A Django-1-5
  • Q&A Django-6-10
  • Q&A Django-11-15
  • Q&A Django-16-20
  • Q&A Django-21-25
  • Q&A Django-26-30
  • Q&A Django-31-35
  • Q&A Django-36-40
  • Q&A Django-41-45
  • Q&A Django-46-50
  • Q&A FastAPI-01-05
  • Q&A FastAPI-06-10
  • Q&A FastAPI-11-15
  • Q&A FastAPI-16-20
  • Q&A FastAPI-21-25
  • Q&A FastAPI-26-30
  • Q&A FastAPI-36-40
  • Q&A FastAPI-41-45
  • Q&A FastAPI-31-35
  • Q&A FastAPI-46-50
  • Q&A FastAPI-51-55
  • Q&A FastAPI-56-60
  • Q&A FastAPI-61-65
  • Q&A HTML-01-05
  • Q&A HTML-06-10
  • Q&A HTML-11-15
  • Q&A HTML-16-20
  • Q&A CSS-01-05
  • Q&A CSS-06-10
  • Q&A CSS-11-15
  • Q&A CSS-16-20
  • Q&A JavaScript-1-5
  • Q&A JavaScript-6-10
  • Q&A JavaScript-11-15
  • Q&A JavaScript-16-20
  • Q&A JavaScript-21-25
  • Q&A JavaScript-26-30
  • Q&A JavaScript-31-35
  • Q&A JavaScript-36-40
  • Q&A JavaScript-41-45
  • Q&A JavaScript-46-50
  • Q&A React-1-5
  • Q&A React-6-10
  • Q&A React-11-15
  • Q&A React-16-20
  • Q&A React-21-25
StackScholar

StackScholar is your go-to destination for exploring technology from every angle - from bit to supercomputer.

Quick Links

  • Home
  • Search
  • Daily Review
  • Blog
  • About
  • Contact
  • Privacy Policy

DSA Visualizer

  • DSA Visualizer
  • Sorting Algorithms
  • Binary Search Tree
  • Dijkstra's Algorithm
  • A* Pathfinding
  • Dynamic Programming

Rapid Review CS

  • Rapid Review CS
  • Operating Systems
  • DBMS
  • Computer Networks
  • Data Structures & Algorithms
  • Computer Architecture

Interview Preparation

  • System Design Interview
  • System Design Toolkit
  • System Design Patterns
  • Python Full-Stack Interview
  • AI/ML Engineer Interview
  • ML Mock Interview
  • AI/ML Glossary

Get new lessons and visualizers in your inbox

Occasional email when something substantial ships. No spam, unsubscribe anytime.

© 2026 StackScholar. All rights reserved.

FastAPI Interview Questions 11-15 (Validation, Nested Models, & Responses)

Hello again! In this section, we are going to tackle data integrity. Building an API isn't just about moving data from A to B; it is about ensuring that the data is correct, safe, and structured.

FastAPI shines here because it automates the boring work of checking data types. Instead of writing dozens of if statements to check if an age is a number or an email is valid, we use Pydantic. We will also cover how to protect sensitive data (like passwords) from being sent back to the user and how to communicate properly using HTTP status codes.

11. How do you validate request data in FastAPI?

In traditional frameworks, you often have to write manual validation logic (e.g., "is this field present?", "is it an integer?"). In FastAPI, validation is declarative and automatic.

You validate data by defining a Pydantic model and declaring it as a type hint in your path operation function.

When a request arrives, FastAPI does the following automatically:

  • Reads the JSON body.
  • Converts types (e.g., string "5" becomes integer 5).
  • Validates the data against your model rules.
  • Returns a clear error (422 Unprocessable Entity) if validation fails.
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr

app = FastAPI()

# Define validation rules here
class UserSignup(BaseModel):
    username: str
    email: EmailStr  # Requires 'pip install pydantic[email]'
    age: int

@app.post("/signup/")
def signup(user: UserSignup):
    # If we reach this line, 'user' is guaranteed to be valid.
    # 'user.age' is definitely an int.
    return {"message": f"User {user.username} validated successfully"}

Sample Output (Invalid Request):

{
  "detail": [
    {
      "loc": ["body", "email"],
      "msg": "value is not a valid email address",
      "type": "value_error.email"
    }
  ]
}

12. What are Pydantic models?

If FastAPI is the car, Pydantic is the engine. Pydantic modelsare Python classes that inherit from BaseModel. They represent the "shape" or "blueprint" of your data.

Analogy: The Cookie Cutter
Think of raw data (JSON) as dough. A Pydantic model is a cookie cutter. You press the cutter onto the dough. If the dough fits the shape, you get a perfect, structured object. If the dough is the wrong consistency (wrong data type), it doesn't work.

Key capabilities of Pydantic models:

  • Type Enforcement: Ensuring an int is an int.
  • Data Parsing: Parsing a JSON string into a Python object.
  • Helper Methods: Exporting data back to a dictionary (.model_dump()) or JSON (.model_dump_json()).

Interview note (Pydantic v1 vs v2): Pydantic v2 rewrote the validation core in Rust and renamed most of the public API. A lot of older tutorials still show the v1 names, so knowing the mapping is an easy way to show you have used it recently:

  • .dict() → .model_dump()
  • .json() → .model_dump_json()
  • .parse_obj() → .model_validate()
  • class Config → model_config = ConfigDict(...)
  • orm_mode → from_attributes
  • @validator → @field_validator, and @root_validator → @model_validator
from pydantic import BaseModel, field_validator

class Product(BaseModel):
    name: str
    price: float
    in_stock: bool = True  # Default value

    @field_validator("price")
    @classmethod
    def price_must_be_positive(cls, v: float) -> float:
        if v <= 0:
            raise ValueError("price must be greater than zero")
        return v

# Creating an instance (Parsing)
external_data = {"name": "Smartphone", "price": "999.99"}
product = Product(**external_data)

print(product.price)
# Output: 999.99 (the string was coerced to a float)

print(product.model_dump())
# {'name': 'Smartphone', 'price': 999.99, 'in_stock': True}

13. How do you handle nested Pydantic models?

Real-world data is rarely flat. You might have a user who has an address, and that address has a city and zip code. FastAPI handles this effortlessly using Nested Models.

You simply define a Pydantic model for the child (e.g., Address) and use it as a type hint inside the parent model (e.g., User). FastAPI understands this hierarchy and expects the incoming JSON to match it.

from typing import List
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

# Child Model
class Image(BaseModel):
    url: str
    name: str

# Parent Model
class Item(BaseModel):
    name: str
    description: str
    # Nesting: An item has a list of Images
    tags: List[str] = []
    images: List[Image] = [] 

@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
    return {"item_name": item.name, "image_count": len(item.images)}

This allows clients to send complex JSON structures like:

{
  "name": "Keyboard",
  "description": "Mechanical",
  "tags": ["tech", "sale"],
  "images": [
    {"url": "http://img.com/1.png", "name": "Front View"},
    {"url": "http://img.com/2.png", "name": "Side View"}
  ]
}

14. Explain response models in FastAPI.

A Response Model is used to define what data should be sent back to the client. This is critical for security.

The Problem: Your database object might contain a hashed_password field. If you just return the object directly, that secret data might be sent to the frontend.

The Solution: You define a Pydantic model that includes only the fields you want to share (e.g., username, email) and exclude the secrets. You pass this model to the response_model parameter in the decorator.

class UserIn(BaseModel):
    username: str
    password: str
    email: str

class UserOut(BaseModel):
    username: str
    email: str
    # Notice: 'password' is missing here

@app.post("/user/", response_model=UserOut)
def create_user(user: UserIn):
    # We are returning the full 'user' object (which has the password)
    # BUT, FastAPI will filter it through 'UserOut' before sending.
    return user

Tip: This also automatically generates the correct schema for your API documentation, letting users know exactly what fields they will receive in the response.

15. How do you add custom response status codes?

HTTP status codes tell the client what happened. By default, FastAPI returns200 OK. However, if you create a new resource, you should return201 Created. If something is missing, you should return 404 Not Found.

There are two main ways to handle this:

  • 1. For Success: Use the status_code parameter in the decorator.
  • 2. For Errors: Raise an HTTPException inside the function.
from fastapi import FastAPI, status, HTTPException

app = FastAPI()

tasks = {"1": "Buy milk"}

# 1. Success: explicitly set 201 Created
@app.post("/tasks/", status_code=status.HTTP_201_CREATED)
def create_task(task_id: str, name: str):
    tasks[task_id] = name
    return {"task_id": task_id, "name": name}

# 2. Error: dynamically raise 404
@app.get("/tasks/{task_id}")
def read_task(task_id: str):
    if task_id not in tasks:
        raise HTTPException(
            status_code=404, 
            detail="Task not found"
        )
    return {"task": tasks[task_id]}

Using status.HTTP_201_CREATED is preferred over just writing 201because it makes your code more readable and prevents typos.

Check your understanding

3 questions · no sign-up, nothing stored

0/3 answered
Question 1

1.In Pydantic v2, how do you convert a model to a dict?

Question 2

2.Which config lets a Pydantic v2 model read from a SQLAlchemy object?

Question 3

3.Which decorator validates a single field in Pydantic v2?

0 / 74 ranges

Progress is stored in this browser only - no sign-up, nothing sent anywhere.

PreviousNext