python
39 lines · 7 steps
Wiring SQLAlchemy sessions into FastAPI
A dependency-injected session powers two endpoints that create and fetch users with proper HTTP status codes.
Explained by
highlit
1from fastapi import Depends, FastAPI, HTTPException
2from sqlalchemy import create_engine
3from sqlalchemy.orm import Session, sessionmaker
4
5from .models import User
6from .schemas import UserCreate, UserRead
7
8engine = create_engine("postgresql://localhost/app", pool_pre_ping=True)
9SessionLocal = sessionmaker(bind=engine, autoflush=False, expire_on_commit=False)
10
11app = FastAPI()
12
13
14def get_db():
15 db = SessionLocal()
16 try:
17 yield db
18 finally:
19 db.close()
20
21
22@app.post("/users", response_model=UserRead, status_code=201)
23def create_user(payload: UserCreate, db: Session = Depends(get_db)):
24 if db.query(User).filter(User.email == payload.email).first():
25 raise HTTPException(status_code=409, detail="Email already registered")
26
27 user = User(email=payload.email, full_name=payload.full_name)
28 db.add(user)
29 db.commit()
30 db.refresh(user)
31 return user
32
33
34@app.get("/users/{user_id}", response_model=UserRead)
35def read_user(user_id: int, db: Session = Depends(get_db)):
36 user = db.get(User, user_id)
37 if user is None:
38 raise HTTPException(status_code=404, detail="User not found")
39 return user
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1A generator dependency cleanly opens a resource before the request and guarantees cleanup after it, even on errors.
- 2response_model separates your ORM objects from the shape you expose, validating and serializing the output.
- 3Mapping domain conditions to explicit HTTP status codes makes the API's contract clear to clients.
Related explainers
python
import click from flask.cli import AppGroup from . import db
Custom user CLI commands in Flask
cli
click
command-group
Intermediate
7 steps
javascript
import { Component } from 'react'; import { reportError } from './services/telemetry'; export class ErrorBoundary extends Component {
How a React ErrorBoundary works
error-handling
lifecycle-methods
render-props
Intermediate
8 steps
rust
use base64::engine::general_purpose::{STANDARD, URL_SAFE_NO_PAD}; use base64::{DecodeError, Engine}; pub fn encode_standard(data: &[u8]) -> String {
Base64 encode and decode in Rust
base64
encoding
error-handling
Beginner
7 steps
python
import heapq from datetime import datetime from pathlib import Path from typing import Iterator, NamedTuple
Merging sorted log files with heapq
generators
heapq
lazy-evaluation
Intermediate
6 steps
python
import datetime from dataclasses import dataclass
Parsing fixed-width records in Python
parsing
generators
dataclasses
Intermediate
8 steps
rust
use std::collections::HashMap; #[derive(Debug)] pub struct RequestHead {
Parsing an HTTP request head in Rust
parsing
error-handling
iterators
Intermediate
9 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/wiring-sqlalchemy-sessions-into-fastapi-explained-python-0004/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.