Step 1
Step 1 — Why Python · FastAPI
25 min
Step 1 — Why Python · FastAPI
Python is the agreed-upon language for data, ML, and automation. FastAPI adds lightweight, type-safe web APIs to the stack.
1. Where Python leads
- Data processing (pandas, numpy, polars)
- ML (PyTorch, TensorFlow, scikit-learn)
- Crawling (Playwright, Scrapy, BeautifulSoup)
- Scripting / automation
- Backend APIs (FastAPI, Django, Flask)
For system-level extreme performance, use Rust / C++ / Go.
2. Five FastAPI wins
- Type hints double as validation + OpenAPI
- Native async (
async def) - Auto
/docs(Swagger) and/redoc - Fast — Starlette + Pydantic, Node-class speed
- Small surface — start with 1/10 of Spring
3. First API
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
tags: list[str] = []
@app.get("/")
def hello():
return {"message": "hello from FastAPI"}
@app.post("/items")
def create_item(item: Item):
return {"created": item, "id": 1}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "query": q}
uv run uvicorn main:app --reload
/docs→ Swagger UI (interactive)/redoc→ ReDoc/openapi.json→ spec
4. uv — the Python package manager
curl -LsSf https://astral.sh/uv/install.sh | sh # macOS/Linux
powershell -c "irm https://astral.sh/uv/install.ps1 | iex" # Windows
uv init my-api
cd my-api
uv add fastapi "uvicorn[standard]" pydantic
uv add --dev pytest ruff
uv run uvicorn main:app --reload
uv replaces pip + venv + Poetry. Rust-based, 10–100x faster, reproducible lockfile.
5. Pydantic validation
from pydantic import BaseModel, Field, EmailStr
class User(BaseModel):
id: int
email: EmailStr
nickname: str = Field(min_length=2, max_length=30)
age: int | None = Field(default=None, ge=0, le=150)
Bad input → FastAPI returns 422 automatically.
6. Dependency injection
from fastapi import Depends
def get_db():
db = SessionLocal()
try: yield db
finally: db.close()
@app.get("/users")
def list_users(db = Depends(get_db)):
return db.query(User).all()
Easy to swap for mocks in tests.
7. Async
import httpx
@app.get("/external")
async def call_external():
async with httpx.AsyncClient() as client:
r = await client.get("https://api.example.com/data")
return r.json()
Handles thousands of concurrent requests.
8. vs Spring
| Axis | Spring Boot 4 | FastAPI |
|---|---|---|
| Types | Java static | Python hints (optional) |
| Startup | 5–10s | ~0.5s |
| Learning curve | steep | gentle |
| Ecosystem | enterprise everything | data / ML |
| RAM | 200 MB+ | ~50 MB |
Small-to-mid APIs and data pipelines → FastAPI. Large enterprise → Spring.
9. Gotchas
uvicornvsgunicorn— dev vs prod (gunicorn + uvicorn workers)- Mixing sync and async → blocks the event loop
- Pydantic v1 vs v2 — 2026 is v2.
.dict()→.model_dump() .envnot loading — usepydantic-settingsorpython-dotenv
10. Try it
uv run uvicorn main:app --reload
curl http://localhost:8000
curl -X POST http://localhost:8000/items -H "Content-Type: application/json" \
-d '{"name":"apple","price":1000}'
Then visit http://localhost:8000/docs.
Deeper
Next
Step 2 — expand this single file into a maintainable folder structure.