- functional app decorators called on
app - class-based decorators imported from
cpsl
Worked flow
In a real app, decorators usually work together rather than in isolation:- lifecycle hooks prepare the runtime
- message handlers decide what the user wants
- tasks own side effects and longer work
- schedules keep the app moving without user input
Functional app decorators
These requireapp = cpsl.App(..., image=cpsl.Image(), ...).
| Decorator | Purpose |
|---|---|
@app.boot() | Run once when the runtime starts |
@app.shutdown() | Run when the runtime is shutting down |
@app.enter() | Run when a new session is created |
@app.exit() | Run when a session closes |
@app.message() | Handle inbound messages |
@app.task(...) | Register a background task |
@app.schedule(cron) | Register a cron job |
@app.endpoint(...) | Register an HTTP endpoint |
@app.asgi(path=...) | Mount an ASGI app |
Class-based decorators
When you use@app.cls(...), the handler methods use the global decorator versions:
@cpsl.boot()@cpsl.shutdown()@cpsl.enter()@cpsl.exit()@cpsl.message()@cpsl.task(...)@cpsl.schedule(cron)@cpsl.endpoint(...)@cpsl.asgi(path=...)
Lifecycle hooks
boot()
Runs once when the runtime starts.
shutdown()
Runs during runtime shutdown. Good for cleanup and flush logic.
enter()
Runs when a new session is created. Receives session.
exit()
Runs when a session closes.
message()
Registers the main inbound handler.
image=cpsl.Image(python_packages=["openai"]) and secrets=["OPENAI_API_KEY"] on App(...) if you want to call the OpenAI SDK directly.
task(...)
Registers a background task and turns the function into a TaskDescriptor.
Arguments
| Argument | Meaning |
|---|---|
retries | Max retry attempts |
timeout | Task timeout in seconds |
lock | Lock template like "user:{user_id}" |
retry_for | Exception types that should retry |
callback_url | URL to POST completion/failure payloads to |
process | Run in a separate OS process |
Example
.submit(...).schedule(...).find(...).count(...).cancel(...)
schedule(cron)
Registers a cron handler.
endpoint(method="GET", path="/", authorized=True)
Registers a plain HTTP handler.
authorized=False for public webhooks.
In a real handler you would usually inspect ctx.request or just return structured data: