hanzo-tasks
Durable activities on the native Hanzo Tasks engine.
The engine is Hanzo's own (hanzoai/tasks), reached over JSON at
api.hanzo.ai/v1/tasks. It speaks no protobuf and no gRPC, and this package
depends on no workflow runtime — dispatching work and running a worker are both
plain HTTP over httpx.
pip install hanzo-tasks
Dispatch
from hanzo_tasks import Tasks
async with Tasks.from_env() as tasks:
activity = await tasks.dispatch(
"render",
input={"scene": 3},
task_queue="gpu",
heartbeat_timeout="60s",
)
print(activity.id, activity.run_id, activity.status)
from_env() reads HANZO_API_KEY, HANZO_TASKS_URL and
HANZO_TASKS_NAMESPACE. The org is never named in a request: IAM validates the
bearer token and the edge mints the org from the validated claim, so a caller
cannot reach another tenant's shard by asking to.
Run a worker
The worker polls. It never accepts a push, so it needs no inbound address and runs behind NAT.
from hanzo_tasks import Tasks, Worker
tasks = Tasks.from_env()
worker = Worker(tasks, task_queue="gpu")
@worker.handler("render")
async def render(activity):
return {"frames": 120}
await worker.run()
Return a value to complete the activity; raise to fail it with that cause. Handlers may be async or plain functions.
What the engine does, so you don't
These are properties of the engine, not of this client. There is deliberately no second copy of them here, because a second copy can disagree.
- A dead worker's work comes back. The engine reaps expired leases before
every claim, so an activity whose claimant stopped heartbeating returns to
SCHEDULEDand the next poll picks it up. No client-side timer. - Two workers never claim the same activity. Claims are serialized per namespace.
- The lease is the activity's own heartbeat timeout, else the worker's
lease_seconds, else the engine default.Workerheartbeats at a third of the window the server actually granted, so a beat can be missed without losing the claim. - An empty queue is not an error. It is
204, andclaim()returnsNone. - Retries are the engine's. Pass a
RetryPolicytodispatch(); the engine counts attempts and fails the activity when they are exhausted.
Reading state
page = await tasks.activities(page_size=50)
for activity in page:
print(activity.id, activity.status, activity.attempt)
activity = await tasks.describe(id, run_id)
events, cursor = await tasks.history(id, run_id)
Errors
The engine reports {"error": ..., "code": <int>} — code is a number here,
not the status string the rest of the Hanzo API uses.
| Exception | Meaning |
|---|---|
Denied |
401/403 — no validated principal, or one carrying no org |
NotFound |
404 — no such activity in this namespace |
Terminal |
409 — already completed, failed or canceled |
TasksError |
anything else, carrying .code |
License
MIT
Metadata
Release files for hanzo-tasks 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| hanzo_tasks-0.2.0.tar.gz | 14.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hanzo_tasks-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 27.5 kB
Release files / hanzo_tasks-0.2.0.tar.gz
| Download URL | hanzo_tasks-0.2.0.tar.gz |
|---|---|
| Size | 14.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
be598b2ae2d49eab94e96f74a3c3686b111b68c8814a960eac975df592786cf5
|
|
BLAKE2b-256 checksum How to use checksums |
22c638d3ce9fafce0a7ddcd37760579fecbdef8119f8a723afada74d42dde284
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.9
|
Release files / hanzo_tasks-0.2.0-py3-none-any.whl
| Download URL | hanzo_tasks-0.2.0-py3-none-any.whl |
|---|---|
| Size | 12.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fd43336edd0d598aedf337a8f2f76b46d08ba5cc69093508d7a77979d18df665
|
|
BLAKE2b-256 checksum How to use checksums |
215dae7c254654b8eb60dc2e477466b69ed9ee85fa26bf8ea18484bc01709e24
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.9
|