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.phones, 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.ENTER)  # submits / fires the keyboard's Go action (ENTER is the only named key today)

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.phones.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.phones Acquire and inspect phones available(), mine(), allocate(), deallocate(), 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_inferences()
client.billing Balance, subscription, invoices get_balance(), get_subscription(), get_history()
client.argus Vision (OCR + element detection) detect(), locate(), list_models()
client.api_keys Manage API keys list(), create(), regenerate(), delete()

Organization and user account management aren't exposed here by design — use the dashboard for those.

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

  • 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.9.0.tar.gz (126.1 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.9.0-py3-none-any.whl (241.4 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for axilio-0.9.0.tar.gz
Algorithm Hash digest
SHA256 63eb8ee59be05126e199de9b5ec09f90af9ee0561fd5203d5735af134044d60b
MD5 521b8deea17a32c8941436d795526d22
BLAKE2b-256 ee41bfa42091218055de7ce7272d0dbeff6f49993ac66cda8c1b6046858b6c16

See more details on using hashes here.

Provenance

The following attestation bundles were made for axilio-0.9.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.9.0-py3-none-any.whl.

File metadata

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

File hashes

Hashes for axilio-0.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6321374850e0a45712d0021cfdd126da3522d1614b8e22f7f67d0b9df5d20eac
MD5 8d23d78ccdb4f0dee3118148d4cf2c38
BLAKE2b-256 a01d95e49896a94d6695a075e5e91bece4c622296c8840bd1dc37fa1fdb4ec46

See more details on using hashes here.

Provenance

The following attestation bundles were made for axilio-0.9.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