Python SDK

There are two Python surfaces: the animica module inside the runtime (built in, zero install), and plain HTTPS outside it. No client library is required for either.

Inside the sandbox: import animica

The runtime injects the animica module into every execution — it is the SDK. Full reference on the Runtime & ABI page:

the runtime SDK
# INSIDE a deployed function: `import animica` is the SDK.
# It is built into the runtime — nothing to install, nothing to configure.
import animica

def main(request, ctx):
    animica.log("hello from the runtime")
    return {"balance": animica.chain.balance(ctx.owner)}
  • animica.ai · animica.chain · animica.wallet · animica.state · animica.http · animica.call() · animica.log() · animica.secret()
  • Typed errors: animica.AnimicaError, animica.CapabilityDenied, animica.BudgetExceeded
Inside the sandbox there is deliberately no pip and no HTTP client — the host API is the only bridge to the world. That inversion is the security model, not a limitation of the SDK. See Supported packages.

Calling functions from Python

a deployed function is just an HTTPS endpoint
# OUTSIDE the sandbox (your laptop, a server): a function is just HTTPS.
import json, urllib.request

def call_function(owner, slug, payload, api_key=None):
    req = urllib.request.Request(
        f"https://animica.dev/api/cloud/v1/fn/{owner}/{slug}",
        data=json.dumps(payload).encode(),
        headers={"content-type": "application/json",
                 **({"authorization": f"Bearer {api_key}"} if api_key else {})},
    )
    with urllib.request.urlopen(req) as res:
        return {
            "result": json.load(res),
            "request_id": res.headers.get("x-animica-request-id"),
            "cost_nanm": int(res.headers.get("x-animica-cost-nanm", "0")),
        }

out = call_function("examples", "hello-api", {"name": "Ada"})
# requests/httpx work identically if you prefer them — this is plain HTTP + JSON

Deploying from Python

deploy in two calls
# deploying from Python is two REST calls
import json, pathlib, urllib.request

BASE = "https://animica.dev/api/cloud/v1"
KEY = "anm_mkt_…"

def api(path, body):
    req = urllib.request.Request(BASE + path, data=json.dumps(body).encode(),
        headers={"content-type": "application/json", "authorization": f"Bearer {KEY}"})
    with urllib.request.urlopen(req) as res:
        return json.load(res)

fn = api("/functions", {"slug": "hello", "timeoutMs": 10000, "memoryMb": 128})
dep = api(f"/functions/{fn['function']['id']}/versions", {
    "source": pathlib.Path("handler.py").read_text(),
    "entrypoint": "main",
    "packages": [],
})
print(dep["deployment"]["status"], dep["deployment"].get("anchorTxid"))

The deploy response carries the version number, the deployment status, the DA blob id and the on-chain anchor txid (or the honest reason there isn't one). Add an idempotency-key header to make retries safe. The full surface — estimates, logs, executions, earnings — is on the REST API page.