Python SDK
pip install --pre herald-run
Python 3.11 or later; the import name is herald. It reads HERALD_API_KEY (or HERALD_TOKEN) and HERALD_URL, or takes api_key and url.
import asyncio
from herald import Herald
async def main():
async with Herald() as herald:
await herald.send(title="Build passed", body="Preview is **ready**.")
answer = await herald.ask_action(
title="Deploy to production?",
actions=[
{"id": "approve", "label": "Approve", "values": {}},
{"id": "reject", "label": "Reject", "values": {}},
],
timeout=600,
)
print(answer.action_id)
asyncio.run(main())
Without asyncio
SyncHerald has the same methods for blocking code:
from pathlib import Path
from herald import SyncHerald
with SyncHerald() as herald:
file = herald.upload("report.pdf", Path("report.pdf").read_bytes(), "application/pdf")
herald.send(title="Nightly report", body="Attached.", attachments=[file])
API
Methods mirror the TypeScript SDK in snake_case: send, ask, ask_action, wait, cancel, get, messages, watch, thread_messages, upload, download, register, claim_task, heartbeat_task, update_task, task_logs, collect_secrets, reveal_secrets, account and token. They return Pydantic models; .wire() gives the JSON. watch() is an async iterator.
create_keys, seal, unseal and verify_webhook are top-level functions. Failures raise HeraldError with status, code, message_id and retry_after.