Official Python SDK for the Animica API (OpenAI-compatible inference, embeddings, usage, and webhook verification).
Project description
animica-ai
Official, dependency-free Python SDK for the Animica API.
The Animica API is OpenAI-compatible, so this client mirrors the familiar
chat/completions, completions, embeddings, and models surface while
adding Animica-specific helpers (usage reporting and webhook signature
verification).
- Zero third-party dependencies — uses only the Python standard library.
- Python 3.9+
- Streaming support via server-sent events.
- Idempotency keys for safe retries.
- Webhook verification built in.
Install
pip install animica-ai
The import package is animica_ai:
from animica_ai import Animica, AnimicaError, verify_webhook
Authentication
Get an API key from your Animica dashboard. Production keys look like
anm_live_...; test keys look like anm_test_.... The key is sent as
Authorization: Bearer <api_key>.
from animica_ai import Animica
client = Animica(api_key="anm_live_xxx")
# Optional: override the base URL (defaults to https://api.animica.org/v1).
# client = Animica(api_key="anm_live_xxx", base_url="https://console.animica.org/v1")
OpenAI drop-in
Because the API is OpenAI-compatible, you can also use the official OpenAI SDK by pointing it at the Animica base URL — no other code changes required:
from openai import OpenAI
client = OpenAI(
base_url="https://api.animica.org/v1",
api_key="anm_live_xxx",
)
resp = client.chat.completions.create(
model="anm-fast-8b",
messages=[{"role": "user", "content": "Hello from OpenAI's SDK!"}],
)
print(resp.choices[0].message.content)
Use animica-ai when you want a tiny, dependency-free client (and the webhook
helper); use the OpenAI SDK if you already depend on it.
Models
Available models include:
| Model | Purpose |
|---|---|
anm-fast-8b |
Fast general chat |
anm-code-7b |
Code generation |
anm-pro-70b |
High-quality reasoning |
anm-bittensor-router |
Routed inference |
anm-embed |
Embeddings |
anm-worker-small |
Worker tasks |
anm-worker-code |
Worker code tasks |
for m in client.models()["data"]:
print(m["id"])
Quickstart
Chat completions
resp = client.chat_completions(
model="anm-fast-8b",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Write a haiku about mining."},
],
temperature=0.7,
max_tokens=128,
)
print(resp["choices"][0]["message"]["content"])
print(resp["usage"]) # {prompt_tokens, completion_tokens, total_tokens}
Extra parameters such as top_p, stop, and n are passed straight through:
resp = client.chat_completions(
model="anm-pro-70b",
messages=[{"role": "user", "content": "List 3 primes."}],
top_p=0.9,
stop=["\n\n"],
)
Streaming
When stream=True, chat_completions returns a generator that yields parsed
chat.completion.chunk dicts and stops at [DONE]:
stream = client.chat_completions(
model="anm-fast-8b",
messages=[{"role": "user", "content": "Stream a short story."}],
stream=True,
)
for chunk in stream:
delta = chunk["choices"][0]["delta"]
if "content" in delta:
print(delta["content"], end="", flush=True)
print()
Text completions
resp = client.completions(
model="anm-fast-8b",
prompt="Once upon a time",
max_tokens=64,
)
print(resp["choices"][0]["text"])
Embeddings
resp = client.embeddings(
model="anm-embed",
input=["hello world", "goodbye world"],
)
for item in resp["data"]:
print(item["index"], len(item["embedding"]))
print(resp["usage"]) # {prompt_tokens, total_tokens}
Usage
u = client.usage()
print(u["totalSpentUsd"], u["count"])
Idempotency
Pass idempotency_key to make POST requests safe to retry — the server replays
the stored response for a repeated key:
resp = client.chat_completions(
model="anm-fast-8b",
messages=[{"role": "user", "content": "Charge me once."}],
idempotency_key="order-12345",
)
Error handling
Non-2xx responses raise AnimicaError, which carries the OpenAI-shaped error
fields plus the HTTP status and the x-request-id response header:
from animica_ai import Animica, AnimicaError
client = Animica(api_key="anm_live_xxx")
try:
client.chat_completions(
model="anm-fast-8b",
messages=[{"role": "user", "content": "Hi"}],
)
except AnimicaError as e:
print("status:", e.status) # e.g. 429
print("type:", e.type) # authentication_error | invalid_request_error |
# insufficient_quota | rate_limit_error |
# permission_error | api_error
print("code:", e.code)
print("message:", e.message)
print("request_id:", e.request_id) # from x-request-id, for support
Rate-limit responses (HTTP 429) include a retry-after header and the
x-ratelimit-* headers are present on all responses.
Webhook verification
Animica signs webhook deliveries with the header:
X-Animica-Signature: t=<unixSeconds>,v1=<hex>
where hex = HMAC_SHA256(endpointSecret, f"{t}.{rawRequestBody}"). Verify the
raw request body (not re-serialized JSON) with verify_webhook, which does
a constant-time comparison and enforces a timestamp tolerance (default 300s):
from animica_ai import verify_webhook
# Flask example
from flask import Flask, request, abort
import json
app = Flask(__name__)
ENDPOINT_SECRET = "whsec_xxx"
@app.post("/animica/webhook")
def webhook():
raw = request.get_data() # bytes — must be the raw body
sig = request.headers.get("X-Animica-Signature", "")
if not verify_webhook(ENDPOINT_SECRET, raw, sig):
abort(400)
event = json.loads(raw)
print(event["type"], event["id"]) # evt_...
return "", 204
payload may be str or bytes. Set tolerance_sec=0 to disable the
timestamp window (not recommended in production).
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 animica_ai-0.1.0.tar.gz.
File metadata
- Download URL: animica_ai-0.1.0.tar.gz
- Upload date:
- Size: 6.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef5999e97f629a8a6e5176988adb56fe858aa58e1c04d9ea886fe0055c7d00a7
|
|
| MD5 |
bd4ca3db2417af788962c5e6bbbe0b1f
|
|
| BLAKE2b-256 |
81f75d265d34a240a801816a5e56077eeabda0dbb4834b985baa10868f218e4e
|
File details
Details for the file animica_ai-0.1.0-py3-none-any.whl.
File metadata
- Download URL: animica_ai-0.1.0-py3-none-any.whl
- Upload date:
- Size: 7.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c1a65226bcd6565646d81c0b68abd6d3db991d0ec20b242521c0f0985299e499
|
|
| MD5 |
acb583cd9dbacd0a6ad6b9f577023f82
|
|
| BLAKE2b-256 |
a1991e07fee68a76cee01e167d664aaa98440432b0ed93027bd83e3b11d90924
|