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 + JSONDeploying 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.