Zero-dependency Python client for the HiAPI unified async task API (/v1/tasks).
Project description
HiAPI Python SDK
Zero-dependency Python client for the HiAPI unified async task API (/v1/tasks) — submit an image / video / audio generation task, poll it to completion, and read the output in one call.
- Zero runtime dependencies. Standard library only (
urllib,json,hmac). - One-call workflow.
client.tasks.run(...)submits and waits for you. - Typed. Dataclasses throughout, ships
py.typed. - Webhook verification. HMAC-SHA256 signature + replay check, built in.
For OpenAI-compatible chat/image endpoints, keep using the
openailibrary withbase_url="https://api.hiapi.ai/v1". This SDK focuses on what the OpenAI client can't do: the asynchronous submit → poll → download lifecycle.
Install
pip install hiapi
Requires Python 3.8+.
Quick start
from hiapi import HiAPI
client = HiAPI(api_key="sk-...") # or set HIAPI_API_KEY
task = client.tasks.run(
model="seedance-2-0",
input={"prompt": "a cyan glass data center entrance", "resolution": "1080p"},
on_update=lambda t: print("status:", t.status),
)
for out in task.output:
print(out.type, out.url) # e.g. "video https://cdn.hiapi.ai/tasks/..."
run() blocks until the task reaches a terminal state. It raises TaskFailed
if the task fails and PollTimeout if it doesn't finish within timeout
(default 600s).
Lower-level control
created = client.tasks.create(
model="seedance-2-0",
input={"prompt": "...", "resolution": "720p"},
callback={"url": "https://your-app.com/hiapi/callback", "when": "final"},
)
print(created.task_id)
task = client.tasks.retrieve(created.task_id) # one status check
task = client.tasks.wait(created.task_id, poll_interval=3, timeout=900)
page = client.tasks.list(page=1, size=20) # newest first
input fields are defined per model — see the relevant
model page. Don't put callback fields inside
input; pass callback separately.
Webhooks
If you set a Webhook signing key in the HiAPI console, terminal callbacks are signed. Verify them against the raw request body:
# Flask example
from flask import Flask, request
from hiapi import HiAPI, WebhookVerificationError
app = Flask(__name__)
client = HiAPI(api_key="sk-...", webhook_secret="whsec_...")
@app.post("/hiapi/callback")
def callback():
try:
task = client.webhooks.verify(request.get_data(), request.headers)
except WebhookVerificationError:
return "", 400
if task.succeeded:
print(task.output[0].url)
return "", 200 # ack with 2xx; HiAPI retries non-2xx
Callbacks are delivered at least once — deduplicate by task.task_id.
Errors
| Exception | When |
|---|---|
AuthenticationError |
401 — bad/missing API key |
NotFoundError |
404 — unknown task or not yours |
InvalidRequestError |
INVALID_REQUEST — fix the request |
ModelUnavailableError |
MODEL_UNAVAILABLE — retry or switch model |
TaskTimeoutError / StorageUnavailableError |
retryable upstream errors |
ServiceUnavailableError |
503 — platform busy (auto-retried) |
APIConnectionError |
network failure (auto-retried for reads only — not create()) |
TaskFailed |
a polled task ended in status=fail |
PollTimeout |
run()/wait() exceeded its timeout |
WebhookVerificationError |
bad signature or stale timestamp |
429/503 are retried automatically with exponential backoff (max_retries, default 2;
honours Retry-After). Network errors are retried only for idempotent GETs
(retrieve / list, and the polling inside wait / run). The POST that create()
issues is never retried on a network failure, so a dropped connection can't silently
create a second, double-charged task — if create() raises APIConnectionError, confirm
with list() before retrying.
Configuration
HiAPI(
api_key=None, # falls back to HIAPI_API_KEY
base_url="https://api.hiapi.ai/v1",
timeout=60.0, # per-request seconds
max_retries=2,
webhook_secret=None, # falls back to HIAPI_WEBHOOK_SECRET
)
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hiapi-0.1.0.tar.gz.
File metadata
- Download URL: hiapi-0.1.0.tar.gz
- Upload date:
- Size: 12.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
75a15944544177ca043fcb3e07002eb1e7a07ef8cb05c8587fefe2fb7d163df9
|
|
| MD5 |
23277600c4f6e6a9415b4191db530128
|
|
| BLAKE2b-256 |
834885f2a5c988236f0b132fc4aacf761e68a9e2e7aaeff5ec3cc8493cd3ee8c
|
File details
Details for the file hiapi-0.1.0-py3-none-any.whl.
File metadata
- Download URL: hiapi-0.1.0-py3-none-any.whl
- Upload date:
- Size: 16.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9b8cebeb253d38731443ba8aa3f5ccc67d693f1efdb9be0030fdd4dc7aae512e
|
|
| MD5 |
ead0b85620c75446583cdc8e401cac48
|
|
| BLAKE2b-256 |
939900a18efd9a70eab4443999ba130846aeffbeca986c8059c12d61b7654d49
|