A lightweight, zero-dependency ASGI web framework kernel β FastAPI-like API, minimal footprint.
ylmz is a pure-Python ASGI web framework that delivers the developer experience of FastAPI β type-safe request/response handling, automatic OpenAPI docs, dependency injection, and rich data validation β all without mandatory third-party dependencies.
| Category | Highlights |
|---|---|
| Routing | @app.get/post/put/delete/patch/websocket β path params {id} with type coercion {id:int} |
| Type System | BaseModel with Field(ge/le/gt/lt/min_length/max_length/pattern/alias), @validator, model_dump[_json], model_validate |
| Rich Types | str int float bool Decimal datetime date time UUID Enum Optional[T] Union[A,B] list[T] dict[K,V] nested models |
| Dependency Injection | Depends() with automatic sub-dependency resolution and per-request caching |
| Parameter Descriptors | Path() Query() Body() Header() Cookie() β explicit source + constraints |
| Background Tasks | BackgroundTasks.add_task() β fire-and-forget after response |
| Lifespan | @app.on_event("startup"/"shutdown") + app.state |
| Middleware | Class-based middleware chain + built-in cors_middleware_factory() |
| Exception Handling | HTTPException, custom @app.exception_handler() |
| OpenAPI Docs | setup_docs(app) β auto-generated /docs (Swagger) + /redoc |
| WebSocket | Native WebSocket with send_text/send_json/send_bytes/receive/close |
| File Upload | UploadFile with read() / save() |
| Status Codes | status.OK, status.CREATED, status.NOT_FOUND β¦ β named constants |
| Zero Deps | Core framework has zero mandatory dependencies β just uvicorn to run |
pip install -e . # framework only
pip install -e ".[dev]" # + uvicorn, pytest, httpxfrom ylmz import Ylmz
app = Ylmz()
@app.get("/")
async def root():
return {"hello": "world"}PYTHONPATH=. uvicorn hello:app --reloadOpen http://localhost:8000/docs for interactive Swagger UI.
@app.get("/items/{item_id:int}")
async def get_item(item_id: int):
return {"item_id": item_id}
@app.get("/search")
async def search(q: str = "", page: int = 1):
return {"q": q, "page": page}from enum import Enum
from datetime import datetime
from ylmz import BaseModel, Field, validator
class Category(str, Enum):
ELECTRONICS = "electronics"
BOOKS = "books"
class Item(BaseModel):
name: str = Field(min_length=1, max_length=100, description="Item name")
price: float = Field(ge=0)
category: Category
tags: list[str] | None = None
created_at: datetime | None = None
@validator("name")
def normalize(cls, v):
return v.strip()
# Automatic validation
item = Item(name=" Widget ", price=9.99, category="electronics")
assert item.name == "Widget"
print(item.model_dump_json()) # β JSON string@app.post("/items", status_code=201)
async def create_item(item: Item):
# item is already validated
return {"created": item.model_dump()}from ylmz import Depends
async def get_db():
return {"connected": True}
@app.get("/data")
async def read_data(db=Depends(get_db)):
return {"db": db}
# Sub-dependencies work automatically:
async def get_repo(db=Depends(get_db)):
return f"repo({db['connected']})"
@app.get("/repo")
async def read_repo(repo=Depends(get_repo)):
return {"repo": repo}from ylmz import Path, Query, Body, Header, Cookie
@app.get("/items/{item_id}")
async def get_item(
item_id: int = Path(description="The item ID"),
verbose: bool = Query(default=False),
):
...
@app.post("/items")
async def create(item: Item = Body(description="Item data")):
...
@app.get("/whoami")
async def whoami(user_agent: str = Header()):
return {"ua": user_agent}from ylmz import BackgroundTasks
@app.post("/send-email")
async def send(background_tasks: BackgroundTasks):
background_tasks.add_task(send_email_async, to="user@example.com")
return {"queued": True}@app.on_event("startup")
async def startup():
app.state.db = await init_db()
@app.on_event("shutdown")
async def shutdown():
await app.state.db.close()class RateLimitExceeded(Exception):
pass
@app.exception_handler(RateLimitExceeded)
async def handle_rate_limit(request, exc):
return JSONResponse(
{"error": "rate_limited", "retry_after": 60},
status_code=429,
)from ylmz import WebSocket
@app.websocket("/ws")
async def ws_endpoint(ws: WebSocket):
await ws.accept()
while True:
msg = await ws.receive()
if msg["type"] == "websocket.disconnect":
break
await ws.send_text(f"Echo: {msg['text']}")from ylmz import Router
admin = Router(prefix="/admin")
@admin.get("/health")
async def health():
return {"status": "ok"}
app.include_router(admin) # β /admin/healthfrom ylmz import UploadFile
@app.post("/upload")
async def upload(file: UploadFile):
content = await file.read()
await file.save(f"./uploads/{file.filename}")
return {"filename": file.filename, "size": file.size}from ylmz import setup_docs
app = Ylmz(title="My API")
setup_docs(app)
# Now available: /docs (Swagger) /redoc /openapi.jsonfrom ylmz.middleware import cors_middleware_factory
app.add_middleware(
cors_middleware_factory(
allow_origins=["http://localhost:3000"],
allow_methods=["GET", "POST"],
allow_headers=["*"],
)
)from ylmz import status
raise HTTPException(status.NOT_FOUND, "Item not found")ylmz-python/
βββ ylmz/ # framework source (zero mandatory deps)
β βββ app.py # Ylmz ASGI application
β βββ routing.py # route matching + parameter resolution
β βββ types.py # BaseModel type system
β βββ depends.py # dependency injection
β βββ params.py # Path/Query/Body/Header/Cookie
β βββ response.py # JSON/HTML/Plain/Streaming responses
β βββ request.py # Request object
β βββ middleware.py # middleware + CORS
β βββ background.py # BackgroundTasks
β βββ websocket.py # WebSocket support
β βββ uploads.py # UploadFile
β βββ exceptions.py # HTTPException
β βββ status.py # named status codes
β βββ openapi.py # OpenAPI 3.0 + Swagger/ReDoc
βββ examples/
β βββ basic.py # full-featured demo app
βββ tests/ # 88 tests across 3 files
PYTHONPATH=. python3 -m pytest tests/ -vylmz is designed as a from-scratch alternative to FastAPI with zero mandatory dependencies:
| ylmz | FastAPI | |
|---|---|---|
| Core dependencies | 0 | Pydantic + Starlette |
| Framework source | ~2000 lines | ~50,000+ lines |
| Type validation | Built-in BaseModel |
Pydantic |
| OpenAPI docs | Built-in CDN-based | Built-in |
| Startup time | instant | slower (heavy imports) |
| Python version | 3.9+ | 3.8+ |
MIT