Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

animica_ai-0.1.0.tar.gz (6.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

animica_ai-0.1.0-py3-none-any.whl (7.5 kB view details)

Uploaded Python 3

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

Hashes for animica_ai-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ef5999e97f629a8a6e5176988adb56fe858aa58e1c04d9ea886fe0055c7d00a7
MD5 bd4ca3db2417af788962c5e6bbbe0b1f
BLAKE2b-256 81f75d265d34a240a801816a5e56077eeabda0dbb4834b985baa10868f218e4e

See more details on using hashes here.

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

Hashes for animica_ai-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c1a65226bcd6565646d81c0b68abd6d3db991d0ec20b242521c0f0985299e499
MD5 acb583cd9dbacd0a6ad6b9f577023f82
BLAKE2b-256 a1991e07fee68a76cee01e167d664aaa98440432b0ed93027bd83e3b11d90924

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page