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.5.0.tar.gz (101.6 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.5.0-py3-none-any.whl (192.5 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for axilio-0.5.0.tar.gz
Algorithm Hash digest
SHA256 d5b3fec429712071c548a8e8b6d1938c59cbc83fde5b40b723c1e549bdb70da6
MD5 695b7be4b754aab7b2738add134b52e8
BLAKE2b-256 faf49d0cf2bb9c69295b80e358467618b3bf33cb73a5eca0d7e8220dfca2c915

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for axilio-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 07c169338bcc99458310bbcc43cdf5fbce3923b6e3f32fc155917dbc638d089e
MD5 5f630ba378b57a15038f64226377ba4f
BLAKE2b-256 034858f0a45dddb8efd86aa009a327eb7414af5d27b3b2eb80fcf739be799cd3

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