Skip to main content

Public Python SDK for building and running Ara apps.

Project description

Ara Python SDK

Public Python SDK for building Ara apps with a decorator-first workflow style.

Install

pip install ara-sdk

Documentation

Local testing (no uv)

python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install -e . pytest
python -m pytest -q

Run maintained examples

All maintained examples are in examples/ and ordered in examples/README.md.

cd examples
cp .env.example .env.local
# Fill ARA_API_KEY and provider keys in .env.local as needed.

Core flow per example:

ara deploy <example.py>
ara setup-auth <example.py> --ensure-runtime-key true
ara run <example.py> --agent <agent-id> --runtime-key "<runtime_key>" --message "hello"

Example-specific notes:

  • 01-c-agent-skills-loading.py uses a local custom @skill_handler decorator inside the tool function; it is not an ara-sdk primitive.
  • 02-canonical-email-chat-cron.py frontend requires VITE_ARA_APP_ID and VITE_ARA_RUNTIME_KEY in examples/.env.local.
  • 03-async-ngrok-webhook.py requires both a local callback receiver and ngrok.

Principles

  • Public SDK is generic and provider-agnostic.
  • Runtime policy, retries, and safety controls are enforced server-side.
  • Optional integrations (Cal.com, CRM, etc.) live in examples, not in the core SDK package.

Quickstart

from ara_sdk import App, Secret, invoke, runtime, schedule
import os

app = App(
    "investor-meeting-booking",
    runtime_profile=runtime(
        secrets=[
            Secret.from_dotenv(),
            Secret.from_dict({"OPENAI_API_KEY": os.environ["OPENAI_API_KEY"]}),
        ],
    ),
)

@app.tool()
def send_email(to: str, subject: str, body: str) -> dict:
    """Send one email."""
    return {"ok": True, "to": to, "subject": subject}

DAILY_FOLLOWUPS = schedule.cron(
    id="daily-followups",
    expr="0 13 * * 1-5",
    timezone="UTC",
    run=invoke.agent("booking_coordinator", input={"message": "Send pending follow-ups."}),
)

@app.agent(
    entrypoint=True,
    skills=["send_email", "automation_create", "automation_list"],
    schedules=[DAILY_FOLLOWUPS],
)
def booking_coordinator(payload: dict) -> str:
    """Coordinate scheduling requests."""
    _ = payload if isinstance(payload, dict) else {}
    return "Coordinate scheduling requests."

App(...) takes the DNS-safe project name as its first argument. Use lowercase letters, digits, and hyphens only (no underscores), e.g. my-app-1. You can pass it positionally (App("my-app-1")) or as a keyword (App(project_name="my-app-1")).

ara auth login
export OPENAI_API_KEY="your_provider_key"

ara deploy app.py
ara setup-auth app.py
ara run app.py --agent booking_coordinator --message "Need 3 slots next week"
ara run app.py --agent booking_coordinator --input-json '{"request":"Need 3 slots next week","context":{"caller":"cli"}}'
ara run-async app.py --agent booking_coordinator --message "Need 3 slots next week" --response-mode poll
ara logs app.py
ara events app.py --event-type channel.web.inbound --channel web --message "hello"
ara setup app.py

Runtime introspection and control (user API key auth, no app script required):

ara runtime capabilities --session sess-123
ara runtime skills list --session sess-123
ara runtime tools list --session sess-123 --kind builtin
ara runtime tools execute --session sess-123 --tool exec --arg command="ls -la"
ara runtime control actions --session sess-123
ara runtime control call --session sess-123 --action list_windows
ara runtime control call --session sess-123 --action launch_app --arg id=browser --arg url=https://mail.google.com

ara logs app.py streams live runtime events for the app across all active runs. Each line includes timestamp + run id + event type. To persist output, use shell piping:

ara logs app.py | tee app.logs

Environment

  • ARA_API_KEY: optional long-lived control-plane key
    • Preferred local workflow: ara auth login (stores JWT + refresh token in ~/.ara/credentials.json).
    • Google OAuth-only accounts can run ara auth login --api-key <ARA_API_KEY> to store an existing API key instead of using password login.
    • CI/headless workflows should continue to set ARA_API_KEY.
  • ARA_API_BASE_URL: optional API override (defaults to production API)
  • ARA_RUNTIME_KEY: optional runtime key override for run/events
  • ARA_APP_HEADER_KEY: optional app header key override (X-Ara-App-Key) for run/events/run-async/run-status
    • Prefer running ara setup-auth app.py to mint keys and then export them.
    • Set ARA_APP_HEADER_KEY only when explicitly using X-Ara-App-Key mode.

Local bootstrap helper:

  • ara auth login:
    • fetches Supabase auth config from /auth/cli/config
    • opens browser OAuth login (Google by default) with PKCE and localhost callback
    • exchanges callback auth code for Supabase access + refresh token
    • stores access + refresh token locally and auto-refreshes when needed
    • default callback URL is http://127.0.0.1:53682/auth/callback (allowlist it in Supabase); set ARA_CLI_OAUTH_PORT to override
    • alternative: ara auth login --api-key <ARA_API_KEY> stores an existing control-plane key locally (useful for Google OAuth-only users)
  • ara setup-auth app.py:
    • resolves app_id by app slug
    • ensures a runtime key exists (optional)
    • creates /apps/{app_id}/x-keys key when missing
    • returns both runtime_key and app_header_key in command output

Runtime env and secrets

runtime(...) supports:

  • env: plain runtime environment values (runtime_profile.env)
  • secrets: ordered secret references (runtime_profile.secret_refs)

Container bootstrap (remote, Modal-style)

For container-side setup, declare startup bootstrap commands in runtime(...) and run them inside the provisioned app sandbox. This keeps build/bootstrap logic in the cloud container instead of depending on local uv workflows.

from ara_sdk import App, entrypoint, local_file, runtime

app = App(
    "research-assistant",
    runtime_profile=runtime(
        image="python:3.12-slim",
        files=[
            local_file("./scripts/bootstrap.sh", path="scripts/bootstrap.sh", executable=True),
        ],
        startup=entrypoint("scripts/bootstrap.sh"),
    ),
)

python_packages / node_packages remain part of runtime profile metadata, but if you need deterministic install behavior today, use startup bootstrap commands in the container.

For observability, run warmup and stream runtime logs:

ara deploy app.py --warm true
ara logs app.py

Warmup/run lifecycle logs are emitted as run.warmup.* and run.*; startup failures are surfaced into those logs with command error previews.

Secret helper options:

  • Secret.from_name(name, required_keys=None) (reference only)
  • Secret.from_dict(name_or_env_dict, env_dict=None, *, required_keys=None, name=None):
    • Secret.from_dict("provider-local", {...}) for explicit naming
    • Secret.from_dict({...}) (or Secret.from_dict({...}, name="provider-local")) for programmatic local secrets
  • Secret.from_dotenv(name=None, filename=".env") (auto-named when name omitted)

Deploy behavior:

  • Local secret sources sync to /apps/{app_id}/secrets before warmup.
  • When runtime(secrets=[...]) is present, deploy reconciles the remote app secret set to match those refs (stale secrets are removed).
  • Secret references remain in manifest; plaintext values are not embedded in app manifest payloads.

Multi-sandbox proposal shape

The SDK can now declare sandbox placement and spawn intent in the manifest:

  • policy: shared | dedicated | ephemeral | inherited
  • key: logical sandbox selector used by runtime placement
  • spawn: optional child-sandbox controls (to, max_depth, max_children_per_parent, max_total_child_sessions_per_run, ephemeral_ttl_minutes, child_policy, child_runtime)

Example:

sandbox(
    policy="dedicated",
    key="research-planner",
    allow_spawn=True,
    spawn_to=["deep-researcher", "verifier"],
    max_spawn_depth=3,
    max_children_per_parent=4,
    max_total_child_sessions_per_run=10,
    ephemeral_ttl_minutes=5,
    child_policy="ephemeral",
    child_runtime=runtime(memory_mb=1024),
)

Backward compatibility is preserved by default. Non-shared placement only activates when invocation input explicitly opts in:

  • use_additional_sandbox=true, or
  • sandbox.enable_additional_sandbox=true

Scheduling model

Use one schedule shape everywhere:

  • schedule.cron(...) / schedule.every(...) for static declarations on @app.agent
  • invoke.agent(...) / invoke.tool(...) for schedule targets
  • scheduler.create(spec) for dynamic runtime automation payloads

JSON runtime input contract

Agent invocation input is JSON-first.

  • invoke.agent(..., input=<json>) now accepts any JSON-serializable payload.
  • The SDK does not enforce a fixed envelope shape; callers can pass any keys they want.
  • python app.py run and python app.py run-async support --input-json for direct JSON object input (inline string or @path/to/file.json).

Example:

from ara_sdk import invoke

invoke.agent(
    "title_case_agent",
    input={
        "text": "hello world",
        "mode": "probe",
        "context": {"caller_agent": "planner", "trace_id": "run_123"},
    },
)

Prompt-based agent contract

@app.agent(...) always records the agent function source in the manifest so runtimes can build per-run system instructions from JSON input.

  • Agent functions must accept exactly one input parameter (JSON payload) and return str (or omit the return annotation).
  • Define prompt behavior in the function body by returning the instruction string.
  • task= / instructions= are no longer part of the public agent decorator API.

Examples

See examples/ for optional integrations and demo projects:

  • examples/00-get-started.py (smallest possible app)
  • examples/01-a-agent-skills-loading.py, examples/01-b-agent-skills-loading.py, examples/01-c-agent-skills-loading.py
  • examples/02-canonical-email-chat-cron.py (+ frontend assets in examples/frontend/02-canonical-email-chat-cron/)
  • examples/03-async-ngrok-webhook.py (+ helper scripts)
  • examples/04-calcom-booking.py
  • examples/05-a-framework-adapters-langgraph.py
  • examples/05-b-framework-adapters-agno.py
  • examples/06-programmatic-secrets-redeploy.py (live probe via examples/06-programmatic-secrets-redeploy-test.py)

Security

  • Never commit API keys, runtime keys, or provider secrets.
  • Keep provider-specific credentials in environment variables.

License

This repository is source-available under a strict proprietary license. Unauthorized copying, redistribution, or derivative works are prohibited. See LICENSE for full terms.

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

ara_sdk-0.1.32.tar.gz (41.0 kB view details)

Uploaded Source

Built Distribution

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

ara_sdk-0.1.32-py3-none-any.whl (31.6 kB view details)

Uploaded Python 3

File details

Details for the file ara_sdk-0.1.32.tar.gz.

File metadata

  • Download URL: ara_sdk-0.1.32.tar.gz
  • Upload date:
  • Size: 41.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for ara_sdk-0.1.32.tar.gz
Algorithm Hash digest
SHA256 311c9e5f4c2deb668e0a16d9201e128018c47cff9a8347ab2561e708d10a7cbd
MD5 a230048525dde1d97fee2871ebefedce
BLAKE2b-256 a7f63397cec635d4651dfe29ee260a5a535f5dc009ac70fa78977314ab1e0894

See more details on using hashes here.

File details

Details for the file ara_sdk-0.1.32-py3-none-any.whl.

File metadata

  • Download URL: ara_sdk-0.1.32-py3-none-any.whl
  • Upload date:
  • Size: 31.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for ara_sdk-0.1.32-py3-none-any.whl
Algorithm Hash digest
SHA256 805f733dd63999f022e35b2f26e9843ae7701f02792f1d52d048b2709a4ebaad
MD5 ca8657068e91525e83aad1f690f3df7f
BLAKE2b-256 3609217dd2789c90bd888b7ce9f1348e94dced2bc306c9fdaf58455757b091e8

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