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
Metadata
Release files for animica-ai 0.1.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 | |
|---|---|---|---|
| animica_ai-0.1.0.tar.gz | 6.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| animica_ai-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 14.2 kB
Release files / animica_ai-0.1.0.tar.gz
| Download URL | animica_ai-0.1.0.tar.gz |
|---|---|
| Size | 6.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ef5999e97f629a8a6e5176988adb56fe858aa58e1c04d9ea886fe0055c7d00a7
|
|
BLAKE2b-256 checksum How to use checksums |
81f75d265d34a240a801816a5e56077eeabda0dbb4834b985baa10868f218e4e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / animica_ai-0.1.0-py3-none-any.whl
| Download URL | animica_ai-0.1.0-py3-none-any.whl |
|---|---|
| Size | 7.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c1a65226bcd6565646d81c0b68abd6d3db991d0ec20b242521c0f0985299e499
|
|
BLAKE2b-256 checksum How to use checksums |
a1991e07fee68a76cee01e167d664aaa98440432b0ed93027bd83e3b11d90924
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|