Stateful CRUD Example (Phase 6)
Full CRUD with in-memory store: POST creates, GET list returns stored items, GET by id / PUT / PATCH / DELETE operate on stored resources.
Code
from typing import Annotated
from pydantic import BaseModel
from semblance import FromInput, SemblanceAPI
class CreateUser(BaseModel):
name: str = "alice"
class UserWithId(BaseModel):
id: str = ""
name: Annotated[str, FromInput("name")]
class UpdateBody(BaseModel):
name: str = "updated"
class PathIdInput(BaseModel):
id: str = ""
api = SemblanceAPI(stateful=True, seed=42)
@api.post("/users", input=CreateUser, output=UserWithId)
def create_user():
pass
@api.get("/users", input=CreateUser, output=list[UserWithId])
def list_users():
pass
@api.get("/users/{id}", input=PathIdInput, output=UserWithId)
def get_user():
pass
@api.put("/users/{id}", input=UpdateBody, output=UserWithId)
def put_user():
pass
@api.patch("/users/{id}", input=UpdateBody, output=UserWithId)
def patch_user():
pass
@api.delete("/users/{id}", input=PathIdInput)
def delete_user():
pass
app = api.as_fastapi()
Run
semblance run examples.stateful_crud.app:api --port 8000
Try
# Create two users
curl -X POST http://127.0.0.1:8000/users -H "Content-Type: application/json" -d '{"name":"alice"}'
curl -X POST http://127.0.0.1:8000/users -H "Content-Type: application/json" -d '{"name":"bob"}'
# List (returns stored)
curl http://127.0.0.1:8000/users
# Get by id (use an id from list)
curl http://127.0.0.1:8000/users/<id>
# PUT upsert (create or replace)
curl -X PUT http://127.0.0.1:8000/users/new-1 -H "Content-Type: application/json" -d '{"name":"created"}'
# PATCH update (404 if missing)
curl -X PATCH http://127.0.0.1:8000/users/new-1 -H "Content-Type: application/json" -d '{"name":"updated"}'
# DELETE
curl -X DELETE http://127.0.0.1:8000/users/new-1
Example flow (with seed=42; generated IDs are deterministic):
// POST alice
{"id": "HbolMJUevblAbkHClEQa", "name": "alice"}
// POST bob
{"id": "HbolMJUevblAbkHClEQa", "name": "bob"}
// GET /users/<id> with alice's id
{"id": "HbolMJUevblAbkHClEQa", "name": "alice"}
// PATCH with {"name": "alice-updated"}
{"id": "HbolMJUevblAbkHClEQa", "name": "alice-updated"}
// GET /users (list)
[{"id": "HbolMJUevblAbkHClEQa", "name": "alice-updated"}, {"id": "HbolMJUevblAbkHClEQa", "name": "bob"}]
Concepts
- Phase 6 — Stateful GET by id, PUT (upsert), PATCH (update), DELETE (remove) keyed by path param (e.g.
id). - Collection path is derived from the route (e.g.
/users/{id}→ store key/users). - See Stateful Mode for details.