mrkeyoor.com_
Sat 19 Sept 18:47 UTC
PyPIWeb Backendupdated 19 Sept 2026

fastapi review

FastAPI 0.141.1 is a Python ASGI framework that turns type-annotated endpoint functions into request parsing, Pydantic validation, response serialization, and an OpenAPI contract. Starlette supplies the HTTP and WebSocket layer; Pydantic handles data models. Our Python 3.12 install was pure Python, carried py.typed for type checkers, and imported successfully. The 0.141 line adds app.frontend() to coordinate a frontend during fastapi dev, while 0.141.1 fixes headers and background tasks contributed by dependencies inside that feature.

Verdict

FastAPI 0.141.1 installed in 0.4 seconds, used 10 MB across 10 packages, imported in 1.30 seconds, and had no pip-audit findings in our sandbox, which makes it a low-friction base for typed Python APIs. Choose Django instead when the product needs a complete web stack, and keep blocking calls out of async def handlers.

We installed it

Lab card: what happened when we installed fastapiScreenshot of fastapi documentation
Install✓ · 0.4s10 packages on disk · 10 MB
Importimport fastapi in 1.30s · pure Python · py.typed · requires Python >=3.10
Known vulns0(pip-audit)

Answers from our run

Does fastapi install cleanly?

Yes. In a fresh container with an empty cache, pip install fastapi finished in 0.4s, leaving 10 packages and 10 MB on disk. pip-audit reported no known vulnerabilities.

What does fastapi need to run?

Python >=3.10, and nothing compiled: it is pure Python. In our run import fastapi succeeded in 1.30s, and the package ships py.typed for type checkers.

fastapi or django: which should you use?

Pick django when the backend needs an ORM, migrations, authentication, templates, forms, and admin under one project. FastAPI 0.141.1 installed in 0.4 seconds, used 10 MB across 10 packages, imported in 1.30 seconds, and had no pip-audit findings in our sandbox, which makes it a low-friction base for typed Python APIs.

When should you not use fastapi?

You need an integrated ORM, migrations, session authentication, forms, templates, and an admin interface. Django owns that wider stack; FastAPI does not.

API stability3/5FastAPI 0.141.1 retains the route decorators, Depends injection, response_model filtering, HTTPException, BackgroundTasks, and TestClient patterns familiar from earlier releases. It is still a 0.x framework layered on Starlette and Pydantic, and the Pydantic 2 migration required real model and validation changes. The new app.frontend() API also needed a same-day patch for dependency headers and background tasks, so minor upgrades deserve application tests.
Docs5/5FastAPI's official site covers request data, response models, dependency cleanup, security schemes, files, WebSockets, background tasks, lifespan, testing, workers, containers, and async scheduling with executable examples. The async guide states exactly when def code enters a thread pool, and the upload guide distinguishes bytes from spooled UploadFile objects. The volume can hide operational choices, but release notes and version-specific APIs are easy to trace.
Maintenance5/5GitHub reports 101,858 stars, 78 open issues and pull requests combined, and a repository push on 2026-08-26; the project is neither archived nor disabled. Releases 0.141.0 and 0.141.1 both arrived on 2026-07-29, adding app.frontend() and then correcting two integration paths in it. That quick follow-up and continued repository activity show active maintenance, though frequent releases increase the need for pinned dependencies.
Ecosystem5/5FastAPI records 127,838,650 weekly downloads in the current package data and sits on the Starlette and Pydantic ecosystems. Official material covers Uvicorn, HTTPX testing, OAuth2 helpers, WebSockets, templates, uploads, workers, and container deployment, while third-party database and observability packages commonly document FastAPI integration. That breadth does not select an ORM or job queue for you, so compatibility testing still spans several independently versioned packages.

Discussed on

  1. hnFastAPI framework, high perf, easy to learn, fast to code, ready for production508 points
  2. hnShow HN: Faster FastAPI with simdjson and io_uring on Linux 5.19290 points
  3. hnPEP 563, PEP 649 and the future of pydantic and FastAPI282 points
  4. hnShow HN: Thinc, a new deep learning library by the makers of spaCy and FastAPI250 points
  5. hnSQLModel – SQL Databases in FastAPI224 points

Use it if

  • A Python JSON API should derive runtime validation and OpenAPI output from the same annotated endpoint definitions.
  • The service needs ASGI features such as WebSockets, streamed responses, lifespan resources, or async network clients.
  • Pydantic models already describe inputs and outputs and should also control response filtering.
  • The team is prepared to choose its own database layer, migration tool, authentication policy, and job queue.
Skip it if

Setup reality

We installed FastAPI 0.141.1 in a clean Python 3.12 Bookworm sandbox in 0.4 seconds. The environment ended with 10 packages using 10 MB. Our package record counted 32 direct dependencies, found pure Python code and a py.typed marker, and required Python 3.10 or newer. pip-audit found 0 known vulnerabilities. The measured license field was unknown.

Importing fastapi worked on our box and took 1.30 seconds. A plain fastapi install gives the framework core; fastapi[standard] also installs the CLI, Uvicorn, multipart parsing, templates, email validation, and settings helpers. The standard-no-fastapi-cloud-cli extra omits the cloud CLI. Use fastapi dev for reload during development and fastapi run, Uvicorn, or another ASGI process command for production.

Normal def endpoints and dependencies run in FastAPI's thread pool. async def runs on the event loop, so use awaitable clients there and move blocking calls to a sync dependency or an explicit thread. Lifespan setup creates one pool or model per worker process. BackgroundTasks starts after the response in that worker and supplies no durable handoff if the process exits.

Version 0.141 introduces app.frontend(check_dir="auto") for local frontend coordination; 0.141.1 repairs dependency-provided headers and background tasks in that path. File uploads need python-multipart. UploadFile uses a spooled file, while receiving bytes stores the complete body in memory. Multiple workers replicate application memory, and the deployment guide recommends one Uvicorn process per container for Kubernetes-style replication.

Patterns

Validate path and query values declare-route

from fastapi import FastAPI

app = FastAPI()

@app.get('/items/{item_id}')
async def read_item(item_id: int, q: str | None = None):
    return {'item_id': item_id, 'query': q}

FastAPI treats item_id as a required integer path value and q as an optional query parameter because only item_id appears in the route string.

Validate JSON with Pydantic parse-json-body

from pydantic import BaseModel, Field

class ItemIn(BaseModel):
    name: str
    quantity: int = Field(default=1, ge=1)

@app.post('/items', status_code=201)
async def create_item(item: ItemIn):
    return item

A quantity below 1 is rejected before create_item runs, and the model schema becomes part of the generated OpenAPI document.

Exclude internal response fields filter-response

class UserOut(BaseModel):
    id: int
    email: str

@app.get('/users/{user_id}', response_model=UserOut)
def read_user(user_id: int):
    return users.fetch_with_password_hash(user_id)

response_model validates and filters the return value, so an extra password_hash field from storage is not serialized.

Clean up a request-scoped session inject-dependency

from typing import Annotated
from fastapi import Depends

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

@app.get('/orders')
def list_orders(db: Annotated[Session, Depends(get_db)]):
    return db.query(Order).all()

Code after yield runs as dependency cleanup. This synchronous session belongs in def code rather than an async def event-loop handler.

Raise a typed HTTP failure return-http-error

from fastapi import HTTPException

@app.get('/items/{item_id}')
def read_one(item_id: int):
    item = store.get(item_id)
    if item is None:
        raise HTTPException(status_code=404, detail='item not found')
    return item

HTTPException must be raised. Returning the object can turn an intended 404 into a normal serialized response.

Call an upstream API asynchronously await-http-client

import httpx

@app.get('/rates')
async def read_rates():
    async with httpx.AsyncClient(timeout=5.0) as client:
        response = await client.get('https://api.example.com/rates')
        response.raise_for_status()
        return response.json()

An async def endpoint runs on the event loop. Use an awaitable client here because requests.get() would block that worker.

Open one resource per process manage-lifespan

from contextlib import asynccontextmanager
from fastapi import FastAPI

@asynccontextmanager
async def lifespan(app: FastAPI):
    app.state.pool = await create_pool()
    yield
    await app.state.pool.close()

app = FastAPI(lifespan=lifespan)

Lifespan runs once in each worker process. Four workers therefore create four separate pools unless the resource lives outside the application.

Read an uploaded file in chunks accept-file-upload

from fastapi import UploadFile

@app.post('/documents')
async def save_document(document: UploadFile):
    while chunk := await document.read(1024 * 1024):
        await object_store.write(chunk)
    await document.close()
    return {'filename': document.filename}

UploadFile requires python-multipart and uses a spooled file. Declaring bytes instead would hold the complete upload in memory.

Run non-durable work after response schedule-small-task

from fastapi import BackgroundTasks

@app.post('/events', status_code=202)
def accept_event(event: Event, tasks: BackgroundTasks):
    tasks.add_task(write_audit_copy, event.model_dump())
    return {'accepted': True}

BackgroundTasks executes in the web process after the response and has no persistence or retry. Use a queue when loss is unacceptable.

Replace a dependency in tests override-test-dependency

from fastapi.testclient import TestClient
from main import app, current_user

app.dependency_overrides[current_user] = lambda: {'id': 7}
client = TestClient(app)

def test_profile():
    assert client.get('/profile').status_code == 200

app.dependency_overrides.clear()

dependency_overrides is global to the app object. Clear it after the test so later cases do not inherit user id 7.

Send an SSE response stream-server-events

from collections.abc import AsyncIterator
from fastapi.sse import EventSourceResponse, ServerSentEvent

async def events() -> AsyncIterator[ServerSentEvent]:
    yield ServerSentEvent(data='ready', event='status')

@app.get('/events')
async def event_stream():
    return EventSourceResponse(events())

FastAPI 0.140 added its SSE response API. Keep the generator async when it waits on queues or sockets.

Start production worker processes run-workers

fastapi run main.py --host 0.0.0.0 --port 8000 --workers 4

# Local development only:
# fastapi dev main.py

Four workers create four application processes and four copies of process memory. The official Kubernetes guidance favors one process per container.

Alternatives

PackageRegistryPick it when
djangoPyPIPick it when the backend needs an ORM, migrations, authentication, templates, forms, and admin under one project.
flaskPyPIPick it for a small synchronous WSGI service whose team wants a minimal core and mature extension conventions.
django-ninjaPyPIPick it when typed API endpoints should live inside an existing Django project and reuse Django's ORM and auth.
starlettePyPIPick it when ASGI routing and middleware are enough and automatic Pydantic request contracts would get in the way.

More web backend guides

urllib3 · requests · ws · anyio · undici · httpx · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.