Skip to main content

Axilio Python SDK — manage workflows, runs, devices, usage, and control devices remotely

Project description

Axilio Python SDK

The official Python SDK for Axilio. Acquire a mobile device in the cloud and drive it with a clean, chainable API — find on-screen text and elements, tap, swipe, type, and screenshot — plus typed access to workflows, runs, usage, and billing.

Installation

pip install axilio

Requires Python 3.10+.

Quick start

from axilio.platform import Client

client = Client()  # reads AXILIO_API_KEY from the environment

# Acquire a device, drive it, and release it automatically.
with client.session("ANDROID") as driver:
    driver.find_text("Settings").tap()
    driver.find(query="the blue Continue button").tap()

    png = driver.screenshot()  # bytes (PNG)

Client is the entry point: construct it once and share it. client.session(...) acquires a device, opens the control channel, hands you a MobileDriver, and releases the device when the with block exits. The rest of the API hangs off the client as typed resource groups — client.devices, client.runs, client.workflows, client.billing, and so on.

Driving a device

The driver is built around selectors that return an Element you act on:

with client.session("ANDROID") as driver:
    # Deterministic text selectors (fast, on-device OCR).
    driver.find_text("Settings").tap()
    driver.find_text("Search").type_into("axilio")

    # Natural-language selector (vision model) for anything text can't pin down.
    driver.find(query="the heart icon next to the comment count").tap()

    # find_all_text returns every match.
    for el in driver.find_all_text(contains="Notification"):
        print(el.text, el.center)  # {"x": .., "y": ..}

    # Snapshot the screen once, then query it without re-capturing.
    screen = driver.observe()
    print(len(screen.texts), len(screen.icons))

    # Wait for the UI to settle.
    driver.wait_for_text("Welcome")
    driver.wait_until_gone("Loading")

find_text(text) returns an Element or None (no match); find(query=...) raises ElementNotFoundError if it can't locate the target. An Element's actions chain — tap(), long_press(duration_ms=…), type_into(text), swipe_to(other) — and it carries bbox, center, text, confidence, and source ("ocr" or "vlm").

Low-level input

When you already know the coordinates, drive the device directly:

driver.tap({"x": 540, "y": 1180})
driver.swipe({"x": 540, "y": 1600}, {"x": 540, "y": 400})
driver.type_text("hello")

from axilio.drivers.mobile import Key
driver.key_press(Key.HOME)  # HOME / BACK / RECENTS / VOLUME_UP / …

Picking a device

client.session("ANDROID") claims a device from your shared pool. To pin a specific dedicated device, pass its phone_id:

mine = client.devices.mine()
with client.session("ANDROID", phone_id=mine.phones[0].phone_id) as driver:
    ...

Authentication

export AXILIO_API_KEY=axl_...

Or pass it explicitly:

client = Client(api_key="axl_...")

Generate keys from the Axilio dashboard. The key is sent as the X-Axilio-Api-Key header. Each key is scoped to one organization — if you belong to several, mint one key per org.

Resources

Each group hangs off the client and returns typed responses. Highlights:

Group What it does Example methods
client.devices Acquire and inspect phones available(), mine(), allocate(), deallocate(), counts(), list_sessions()
client.runs Workflow runs create(), get(), list(), cancel(), list_events()
client.workflows Workflow CRUD + code list(), get(), create(), update(), get_code(), save_code()
client.usage Usage + metrics get_metrics(), list_sessions(), list_inferences()
client.billing Balance, subscription, invoices get_balance(), get_subscription(), get_history(), add_funds()
client.api_keys Manage API keys list(), create(), regenerate(), delete()
client.org Organization + members get(), list_members(), create_invitation(), remove_member()
client.user The calling user get_me(), delete_me()

The generated client is available as client.raw (an AxilioApi) if you need a method not surfaced here, or the async variant via from axilio import AsyncAxilioApi (both are exported from the top-level axilio package).

Errors

REST calls raise axilio.ApiError on a non-2xx response — inspect status_code and body:

from axilio.platform import ApiError

try:
    run = client.runs.get("run_123")
except ApiError as e:
    if e.status_code == 404:
        print("run not found")
    elif e.status_code == 429:
        ...  # back off and retry
    else:
        raise

Device-control calls raise typed exceptions from axilio.drivers.mobile, all of which subclass its AxilioError:

from axilio.drivers.mobile import ElementNotFoundError, TimeoutError

with client.session("ANDROID") as driver:
    try:
        driver.find(query="a button that isn't there", timeout=5).tap()
    except ElementNotFoundError:
        ...
    except TimeoutError:
        ...

Others include ConnectionError, DeviceOfflineError, NotConnectedError, InvalidArgsError, and UnauthorizedError.

Configuration

Constructor kwarg Default Description
api_key AXILIO_API_KEY env Your API key (axl_…).
base_url AXILIO_BASE_URL env, then https://api.axilio.ai API host.
timeout 30.0 Per-request timeout, in seconds.
max_retries 3 Extra attempts on 429/5xx/network errors before giving up.
Env var Description
AXILIO_API_KEY API key used to authenticate.
AXILIO_BASE_URL Override the API host.

Requests that fail with 429, a 5xx, or a transport-level error are retried automatically with exponential backoff, up to max_retries; a Retry-After response header takes precedence over the computed backoff. Other 4xx responses fail fast.

Status

Axilio is in early access and the SDK surface is still expanding. APIs may change between minor versions until 1.0 — pin a version for reproducible builds.

Roadmap

  • argus (vision inference) as a first-class client.argus resource.
  • Live run events — REST polling today; streaming subscriptions to come.

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

axilio-0.6.0.tar.gz (100.8 kB view details)

Uploaded Source

Built Distribution

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

axilio-0.6.0-py3-none-any.whl (191.5 kB view details)

Uploaded Python 3

File details

Details for the file axilio-0.6.0.tar.gz.

File metadata

  • Download URL: axilio-0.6.0.tar.gz
  • Upload date:
  • Size: 100.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for axilio-0.6.0.tar.gz
Algorithm Hash digest
SHA256 dfc08aeed0a41a5c5ee28a2c81b53623a1542c0d90667fa529af751740c534fc
MD5 e02a0b2467fc4e3efe685cf4ea966a0a
BLAKE2b-256 71bfc37b741ca9d67aff681c927e85d3c99c4221248d7c33d4879cb0a5148dc8

See more details on using hashes here.

Provenance

The following attestation bundles were made for axilio-0.6.0.tar.gz:

Publisher: publish.yml on axilioai/platform-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file axilio-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: axilio-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 191.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for axilio-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5b84cd399544e30e4380abe11ad2fa41d28183347a293d913d7c231b34a34e10
MD5 2e32536a1125a29edbf3f857faefefab
BLAKE2b-256 f3ee83b9d657658354d8891e2cea3d155dc120123848454bc95794c00eb06c39

See more details on using hashes here.

Provenance

The following attestation bundles were made for axilio-0.6.0-py3-none-any.whl:

Publisher: publish.yml on axilioai/platform-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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