WreathBrowse
Start

Start · one route, no ceremony

Your first Wreath application.

Create a typed ASGI application, run it on Wreath's development server, and keep the boundary small enough to understand completely.

Python 3.14any ASGI servertyped binding

Choose what to build nextBrowse the surface

Install#

Wreath targets CPython 3.14. With an existing uv project:

uv add wreath

Or create a clean project first:

uv init --python 3.14
uv add wreath

Create the application#

app.pypython
from dataclasses import dataclass
from typing import Annotated

from wreath import Request, Wreath
from wreath.binding import Body

app = Wreath()


@dataclass
class Greeting:
    name: str


@app.get("/hello/{name}")
async def hello(request: Request, name: str) -> dict:
    return {"hello": name}


@app.post("/hello")
async def create_greeting(
    request: Request,
    greeting: Annotated[Greeting, Body()],
) -> dict:
    return {"hello": greeting.name}

Path parameters and the dataclass body are bound from the handler signature. An invalid request is rejected before the handler runs.

Run it#

uv run wreath dev app:app

Then call both routes:

curl http://127.0.0.1:8000/hello/Mara
curl -X POST http://127.0.0.1:8000/hello \
  -H 'content-type: application/json' \
  -d '{"name":"Mara"}'

The application is ordinary ASGI. If another conforming server is already part of your deployment, keep it:

uv run uvicorn app:app

Test the boundary#

Wreath's test client drives the ASGI application without opening a socket.

test_app.pypython
from wreath.testing import TestClient

from app import app


async def test_hello() -> None:
    async with TestClient(app) as client:
        response = await client.get("/hello/Mara")

    assert response.status_code == 200
    assert response.json() == {"hello": "Mara"}

Run it through the project test runner:

uv run wreath test

For a complete application rather than another isolated snippet, explore the canonical camera-trap service. It combines models, migrations, typed queries, authorization, deterministic seed data and a runnable PostgreSQL-backed API.

Add the difficult part next#

Do not add architecture because a framework tour says it exists. Choose the pressure your product actually has:

esc
↑↓ navigate↵ openesc close