-
Notifications
You must be signed in to change notification settings - Fork 0
Routing
The entry point of any HTeaLeaf app is the server object. HTeaLeaf supports three variants:
| Variant | Notes |
|---|---|
ASGI |
Async, works with Uvicorn / Hypercorn |
WSGI |
Sync, works with Gunicorn / uWSGI |
CGI |
Legacy |
from HTeaLeaf import HTeaLeaf, adapters
app = HTeaLeaf(adapters.ASGI)
Run with any ASGI server, e.g. Uvicorn:
uvicorn myapp:appfrom HTeaLeaf import HTeaLeaf, adapters
app = HTeaLeaf(adapters.WSGI)
if __name__ == "__main__":
from wsgiref.simple_server import make_server
with make_server("", 8000, app) as server:
print("Serving on http://127.0.0.1:8000")
try:
server.serve_forever()
except KeyboardInterrupt:
print("\rBye")Regardless of variant, the server object manages:
- Route registry
- Session management
- Server-specific functionality (WSGI entrypoint, CGI handlers, etc.)
HTeaLeaf offers two equivalent ways to register routes.
@app.route("/hello")
def hello():
return "Hello World!"def hello():
return "Hello World!"
app.add_path("/hello", hello)Both approaches are equivalent. The decorator style is more concise for most cases; add_path is useful when routes are registered dynamically or assembled from a separate module.
Each route handler must return a valid HTTP response. Accepted types:
| Type | Description |
|---|---|
str |
Plain text or HTML string |
dict |
Serialised as JSON |
bytes |
Raw byte response |
| HTML element | Object built with HTeaLeaf.Html.Elements
|
tuple |
Full HTTP response (status, headers, body)
|
Dynamic segments are declared with curly braces {} and injected as function arguments:
@app.route("/hello/{name}")
def greet(name):
return f"Hello, {name}!"A request to /hello/John returns Hello, John!.
Add a req: Request argument to receive the full request object:
from HTeaLeaf.Server.Http import Request
@app.route("/echo")
def echo(req: Request):
return {
"method": req.method,
"path": req.path,
"body": req.text(),
"json": req.json(),
}Add a session: Session argument to access the user's session:
from HTeaLeaf.Server import Session
@app.route("/profile")
def profile(session: Session):
if session.has("userName"):
return f"Welcome, {session['userName']}"
return "Please log in"HTeaLeaf injects req and session by inspecting the handler's argument annotations, you only declare what you need.
Path parameters, req, and session can be combined freely:
@app.route("/user/{id}/settings")
def user_settings(id, session: Session):
if not session.has("userName"):
return "Unauthorized", 401
return f"Settings for user {id}"