fast api (https://chatgpt.com/c/694efe2a-8010-8323-af76-bc0187aaebfe)

 πŸ§  BIG PICTURE (IMPORTANT FIRST)

In a FastAPI + Database project, files are separated like this:

FileRoleReal-world analogy
database.pyConnects to DBPhone call connection
models.pyDatabase tablesExcel sheets
schemas.pyData validationForm checker
main.pyAPI logicOffice manager

1️⃣ database.pyDatabase Connection Layer

πŸ“Œ Purpose (Why this file exists)

  • Connects your app to the database

  • Creates a session to talk to DB

  • One place to change DB (SQLite → PostgreSQL)

Think of this as “opening a phone line” to the database.


✅ Code (Revisited)

from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker DATABASE_URL = "sqlite:///./users.db"

πŸ”Ή What this means

  • SQLite database file → users.db

  • ./ means current folder

  • No server needed (good for learning)


engine = create_engine( DATABASE_URL, connect_args={"check_same_thread": False} )

πŸ”Ή Why this line is important

  • engine = main connection object

  • check_same_thread=False → required for SQLite + FastAPI


SessionLocal = sessionmaker( autocommit=False, autoflush=False, bind=engine )

πŸ”Ή Session = DB conversation

  • Every API request uses one session

  • Safely opens & closes DB connection


Base = declarative_base()

πŸ”Ή This is SUPER IMPORTANT

  • All database tables inherit from Base

  • SQLAlchemy uses it to create tables


🧠 Mental Model

database.py = "Power switch" for database

2️⃣ models.pyDatabase Tables (Actual Storage)

πŸ“Œ Purpose

  • Defines what data is stored

  • Maps Python class → DB table

  • Persistent data (saved forever)

Think: Excel sheet with columns


✅ Code Breakdown

from sqlalchemy import Column, Integer, String from database import Base

πŸ”Ή Import tools

  • Column = column in table

  • Integer, String = data types

  • Base = parent class


class User(Base): __tablename__ = "users"

πŸ”Ή What this does

  • Creates a table named users

  • Table exists physically in DB


id = Column(Integer, primary_key=True, index=True)

πŸ”Ή Explanation

  • id → unique row identifier

  • primary_key=True → unique

  • index=True → faster search


email = Column(String, unique=True, index=True)

πŸ”Ή Why unique?

  • Prevents duplicate users

  • Enforces real-world rule


hashed_password = Column(String)

πŸ”Ή VERY IMPORTANT

  • Never store plain passwords

  • Always store hashed password


🧠 Mental Model

models.py = "Permanent storage structure"

3️⃣ schemas.pyValidation & Communication Layer

πŸ“Œ Purpose

  • Validates incoming data

  • Controls outgoing responses

  • Protects database from bad data

Think: Security guard at office gate


❗ Why not use models directly?

  • Models = database only

  • Schemas = API input/output

FastAPI enforces separation of concerns.


✅ Code Breakdown

from pydantic import BaseModel, EmailStr

πŸ”Ή Pydantic

  • Validates input automatically

  • Converts data types


class UserCreate(BaseModel): email: EmailStr password: str

πŸ”Ή Why EmailStr?

  • Ensures valid email

  • Auto error if invalid


class Token(BaseModel): access_token: str token_type: str

πŸ”Ή Used in login response

FastAPI auto-documents this in Swagger UI


🧠 Mental Model

schemas.py = "Form validation + API contract"

πŸ” DATA FLOW (VERY IMPORTANT)

πŸ”„ Signup Request Flow

Frontend ↓ Schema (validation) ↓ Model (database storage) ↓ Database

❌ COMMON BEGINNER MISTAKES (AVOID THESE)

❌ Mixing models & schemas
❌ Storing passwords directly
❌ DB logic in main.py
❌ No validation

Recruiters reject these patterns.


🧠 INTERVIEW QUESTION & PERFECT ANSWER

❓ Why do we separate models and schemas?

Answer:

Models define database structure, schemas define data validation and API contracts. This separation improves security, scalability, and maintainability.

πŸ”₯ Recruiter-approved answer.


πŸ“š HOW TO PRACTICE (DO THIS)

πŸ”Ή Exercise 1

Add username field:

  • Add in models.py

  • Add in schemas.py

  • Update signup route

πŸ”Ή Exercise 2

Create UserResponse schema:

class UserResponse(BaseModel): email: EmailStr

Use it in API response.


πŸ† SUMMARY (REMEMBER THIS)

FilePurpose
database.pyDB connection
models.pyTables
schemas.pyValidation
main.pyAPI logic



1️⃣ What engine does (MOST IMPORTANT)

πŸ“Œ Code (from database.py)

engine = create_engine( DATABASE_URL, connect_args={"check_same_thread": False} )

🧠 Think of engine like this:

Engine = Power cable between your app and the database

It does 3 main jobs:

JobMeaning
Opens connectionConnects app to DB
Sends SQLRuns CREATE, INSERT, SELECT
Manages DB driverSQLite / Postgres / MySQL

πŸ“Œ Without engineno database access


❓ Why we need engine only once?

  • Creating engine is expensive

  • One engine is reused everywhere

  • Industry best practice


πŸ” Where engine is used?

Base.metadata.create_all(bind=engine)

πŸ‘‰ This tells SQLAlchemy:

“Use this engine to create tables in DB”


🧠 Mental Model

engine = "Database power switch"

2️⃣ What SessionLocal is (VERY IMPORTANT)

πŸ“Œ Code

SessionLocal = sessionmaker( autocommit=False, autoflush=False, bind=engine )

🧠 Think of Session like this:

Session = Temporary conversation with database

Every time:

  • User signs up

  • User logs in

  • Data is read or written

πŸ‘‰ A session is created, used, then closed


πŸ” Why NOT use engine directly?

Because:

  • Engine = low-level

  • Session = safe + transactional

Session handles:

  • Rollback on error

  • Commit on success

  • Clean close


πŸ”„ Session lifecycle

Open sessionDo DB workCommit / RollbackClose session

🧠 Mental Model

Session = "Phone call with database"

3️⃣ How data is saved (STEP-BY-STEP)

Let’s say a user signs up πŸ‘‡


πŸ”Ή Step 1: User sends data

{ "email": "test@gmail.com", "password": "123456" }

πŸ”Ή Step 2: FastAPI validates data (schemas)

class UserCreate(BaseModel): email: EmailStr password: str

If invalid ❌ → request rejected automatically


πŸ”Ή Step 3: API opens DB session

db = SessionLocal()

πŸ“Œ Now app can talk to DB


πŸ”Ή Step 4: Create User object (model)

new_user = User( email=user.email, hashed_password=hash_password(user.password) )

🧠 This is NOT saved yet


πŸ”Ή Step 5: Add to session

db.add(new_user)

Think:

“Keep this data ready to save”


πŸ”Ή Step 6: Commit (SAVE)

db.commit()

πŸ”₯ THIS IS THE MOST IMPORTANT LINE
Without commit() → nothing is saved


πŸ”Ή Step 7: Close session

db.close()

Database conversation ends safely


🧠 Full Save Flow (MEMORIZE THIS)

User inputSchema validation → Model object → db.add() → db.commit() → db.close()

4️⃣ How Signup stores user in DB (REAL CODE FLOW)

πŸ“Œ Signup endpoint (simplified)

@app.post("/signup") def signup(user: UserCreate, db: Session = Depends(get_db)): new_user = User( email=user.email, hashed_password=hash_password(user.password) ) db.add(new_user) db.commit() return {"message": "User registered"}

πŸ” What Depends(get_db) does

def get_db(): db = SessionLocal() try: yield db finally: db.close()

This means:

  • Open session

  • Give it to API

  • Close automatically after request

πŸ”₯ This is professional FastAPI pattern


🧠 Mental Model (IMPORTANT)

ComponentRole
engineDB power
SessionLocalDB conversation
ModelTable structure
SchemaValidation
commitSave permanently

❌ COMMON BEGINNER MISTAKES (YOU WILL AVOID)

❌ Forgetting db.commit()
❌ Writing DB code without session
❌ Mixing schema & model
❌ Creating engine inside API

You are already ahead πŸ‘


πŸš€ FASTAPI BACKEND DEVELOPER – JOB CHEAT SHEET

🎯 What Recruiters EXPECT (Reality)

They test 3 things:
1️⃣ Can you build APIs correctly
2️⃣ Can you secure them
3️⃣ Can you work with databases


🧱 1. FASTAPI CORE (MUST KNOW)

✅ Create App

from fastapi import FastAPI app = FastAPI()

✅ Run Server

uvicorn main:app --reload

✅ Basic Route

@app.get("/") def home(): return {"msg": "Hello"}

✅ Path & Query Params

@app.get("/users/{id}") def get_user(id: int, q: str = None): return {"id": id, "q": q}

🧠 Interview Line

“FastAPI is async-first, type-safe, and auto-generates OpenAPI docs.”


πŸ” 2. AUTHENTICATION (VERY IMPORTANT)

Password Hashing

from passlib.context import CryptContext pwd = CryptContext(schemes=["bcrypt"]) pwd.hash(password) pwd.verify(password, hashed)

JWT Token

jwt.encode(data, SECRET_KEY, algorithm="HS256") jwt.decode(token, SECRET_KEY, algorithms=["HS256"])

Protected Route

@app.get("/protected") def protected(user=Depends(get_current_user)): return "Allowed"

❗ Never store plain passwords

❗ Never expose secret key


🧠 Interview Line

“I use JWT with role-based access and dependency injection.”


πŸ—„️ 3. DATABASE (SQLALCHEMY)

Engine & Session

engine = create_engine(DB_URL) SessionLocal = sessionmaker(bind=engine)

Model

class User(Base): id = Column(Integer, primary_key=True) email = Column(String, unique=True)

Save Data

db.add(obj) db.commit() db.refresh(obj)

Query Data

db.query(User).filter(User.email == email).first()

🧠 Interview Line

“I use SQLAlchemy ORM with proper session handling.”


πŸ“¦ 4. SCHEMAS (Pydantic)

class UserCreate(BaseModel): email: EmailStr password: str

❗ Models ≠ Schemas

  • Models → DB

  • Schemas → Validation


🧠 Interview Line

“Schemas ensure validation and protect database integrity.”


πŸ”„ 5. CRUD TEMPLATE (VERY COMMON)

# CREATE db.add(obj); db.commit() # READ db.query(Model).all() # UPDATE obj.field = value; db.commit() # DELETE db.delete(obj); db.commit()

⚙️ 6. DEPENDENCY INJECTION (KEY FEATURE)

def get_db(): db = SessionLocal() try: yield db finally: db.close()
@app.post("/items") def create(db=Depends(get_db)): ...

🧠 Interview Line

“Dependencies make code reusable and testable.”


πŸš€ 7. ERROR HANDLING

raise HTTPException(status_code=404, detail="Not found")

HTTP Codes to Remember

CodeMeaning
200OK
201Created
400Bad Request
401Unauthorized
403Forbidden
404Not Found
500Server Error

πŸ§ͺ 8. TESTING (BONUS BUT POWERFUL)

def test_home(): res = client.get("/") assert res.status_code == 200

🐳 9. DEPLOYMENT BASICS

Dockerfile (Minimal)

FROM python:3.10 WORKDIR /app COPY . . RUN pip install -r requirements.txt CMD ["uvicorn","main:app","--host","0.0.0.0","--port","8000"]

🧠 10. COMMON INTERVIEW QUESTIONS (WITH SHORT ANSWERS)

❓ FastAPI vs Flask?

FastAPI is faster, async, type-safe, and auto-documented.

❓ Why JWT?

Stateless authentication suitable for scalable systems.

❓ SQLite vs PostgreSQL?

SQLite for dev, PostgreSQL for production.

❓ How to protect admin routes?

Role-based JWT + dependency checks.


Comments

Popular posts from this blog

⭐ UNIT – 3 (Easy Notes + PDF References) Wireless LAN • MAC Problems • Hidden/Exposed Terminal • Near/Far • Infrastructure vs Ad-hoc • IEEE 802.11 • Mobile IP • Ad-hoc Routing

UNIT–5 (Simplified & Easy Notes) Software Architecture Documentation

ch 2 pm