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.argusresource. - Live run events — REST polling today; streaming subscriptions to come.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file axilio-0.3.0.tar.gz.
File metadata
- Download URL: axilio-0.3.0.tar.gz
- Upload date:
- Size: 92.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d6ffa9d6f4d6772938d4f61e18e4b97ecde457193f94913dccebd31859a15140
|
|
| MD5 |
7694bc2dc84907df844d6804e2e09f03
|
|
| BLAKE2b-256 |
18a69f3b5df0f2ba26aad59b28f299bfcc23249dc61a519c221482a30578524c
|
File details
Details for the file axilio-0.3.0-py3-none-any.whl.
File metadata
- Download URL: axilio-0.3.0-py3-none-any.whl
- Upload date:
- Size: 178.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4d5fc36cd64f6794471bbec26883274e3f734680763f53b4a9b171e3240ce3bb
|
|
| MD5 |
d794682b364780df98218f895ed6203d
|
|
| BLAKE2b-256 |
664eb721ce49062b6563d5f9897fcd4a8412b6bb743cf21986c3555e8069549d
|