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.