π Build a FastAPI Todo App the Right Way (Using uv)
Want to build a lightning-fast API without the Python packaging mess?
Letβs build a Todo API using FastAPI β but with a twist: weβll use uv, the next-gen Python package manager that automates virtual environments, handles dependency resolution, and gets out of your way.
π§© What is uv?
uv is a modern Python package manager that replaces pip and virtualenv with:
- π Ultra-fast dependency installation
- π¦ Automatic virtual environment creation
- π§Ό Cleaner project setup with zero
requirements.txt
It's built in Rust and is ideal for fast, reproducible Python workflows β perfect for APIs, CLI tools, and data apps.
π οΈ Step 1: Set Up the Project
mkdir fastapi-todo && cd fastapi-todo
uv init --app
uv add fastapi --extra standard
π§ Step 2: Create the Todo Model in models.py
from pydantic import BaseModel
class Todo(BaseModel):
id: int
title: str
completed: bool = False
βοΈ Step 3: Build the API in main.py
from fastapi import FastAPI, HTTPException
from models import Todo
app = FastAPI()
todos = []
@app.get("/")
def home():
return {"message": "Welcome to the FastAPI Todo App"}
@app.get("/todos")
def list_todos():
return todos
@app.post("/todos", status_code=201)
def add_todo(todo: Todo):
if any(t.id == todo.id for t in todos):
raise HTTPException(status_code=400, detail="Todo with this ID already exists.")
todos.append(todo)
return todo
@app.put("/todos/{todo_id}")
def update(todo_id: int, updated: Todo):
for i, t in enumerate(todos):
if t.id == todo_id:
todos[i] = updated
return updated
raise HTTPException(status_code=404, detail="Todo not found")
@app.delete("/todos/{todo_id}")
def delete(todo_id: int):
global todos
todos = [t for t in todos if t.id != todo_id]
return {"message": "Todo deleted"}
π Step 4: Run the Server
uv run fastapi dev
This spins up the app at http://127.0.0.1:8000.
Try out your endpoints using the auto-generated docs at:





Top comments (0)