Skip to main content

Slim async local device drivers for Android Portal and iOS Portal, extracted from mobilerun.

Project description

mobilerun-core-cli is the slim async local-driver core of mobilerun.
No CLI, no agent, no LLM providers โ€” just local Android/iOS drivers for higher-level tools such as mobilerun-core.


  • ๐Ÿ“ฑ Drive local devices โ€” Android over ADB+Portal, Android Portal HTTP-only, or iOS Portal HTTP.
  • โšก TCP-with-content-provider fallback โ€” fast Android HTTP path over adb forward, transparent fallback to content-provider RPC.
  • ๐Ÿ”Œ HTTP-only drivers โ€” connect to already-running Android/iOS portals without taking over setup.
  • ๐Ÿ›  Portal lifecycle โ€” download, install, accessibility enablement, auto-upgrade.
  • ๐Ÿชถ Slim โ€” a small async driver package with four runtime deps (async_adbutils, httpx, requests, rich).
  • ๐Ÿ”Œ Embeddable โ€” designed to be wrapped by sync facades (e.g. mobilerun-core) or used directly.
  • ๐Ÿค In sync with upstream โ€” verbatim slice of droidrun/mobilerun; behaviour and API track upstream.

๐Ÿ“ฆ Installation

Note: Python >=3.11,<3.14. The Android ADB driver requires ADB on PATH and a device with USB debugging enabled. HTTP-only drivers require an already-running portal URL.

uv pip install mobilerun-core-cli

๐Ÿš€ Quick usage

import asyncio
from async_adbutils import adb
from mobilerun_core_cli import AndroidDriver, ensure_portal_ready


async def main():
    # 1. Make sure Portal is installed + accessibility is on.
    device = await adb.device()
    await ensure_portal_ready(device)

    # 2. Drive the device.
    driver = AndroidDriver(serial=device.serial, use_tcp=True)
    await driver.connect()

    await driver.tap(540, 1200)
    await driver.swipe(540, 1600, 540, 400, duration_ms=300)
    await driver.input_text("hello", clear=True)
    png_bytes = await driver.screenshot()
    tree = await driver.get_ui_tree()


asyncio.run(main())

HTTP-only Android:

import asyncio
from mobilerun_core_cli import AndroidPortalHttpDriver


async def main():
    driver = AndroidPortalHttpDriver(
        url="http://127.0.0.1:18080",
        token="...",
    )
    await driver.connect()
    await driver.tap(540, 1200)


asyncio.run(main())

iOS Portal:

import asyncio
from mobilerun_core_cli import IOSPortalDriver


async def main():
    driver = IOSPortalDriver("http://127.0.0.1:6643")
    await driver.connect()
    await driver.start_app("com.apple.Preferences")


asyncio.run(main())

๐Ÿงฑ Layout

mobilerun_core_cli/
โ”œโ”€โ”€ __init__.py            Re-exports the public surface
โ”œโ”€โ”€ portal.py              Portal APK lifecycle + content-provider helpers
โ”œโ”€โ”€ driver/
โ”‚   โ”œโ”€โ”€ base.py            DeviceDriver ABC, DeviceDisconnectedError
โ”‚   โ”œโ”€โ”€ android.py         AndroidDriver โ€” ADB-backed concrete driver
โ”‚   โ”œโ”€โ”€ android_http.py    AndroidPortalHttpDriver โ€” HTTP-only Android driver
โ”‚   โ””โ”€โ”€ ios.py             IOSPortalDriver โ€” ios-portal HTTP driver
โ””โ”€โ”€ transport/
    โ””โ”€โ”€ portal_client.py   PortalClient โ€” TCP-with-content-provider fallback

๐Ÿ“š Public API

Re-exported from mobilerun_core_cli:

Symbol What it is
AndroidDriver ADB+Portal device driver. Async methods: tap, swipe, input_text, press_button, start_app, install_app, screenshot, get_ui_tree, get_apps, list_packages, get_date.
AndroidPortalHttpDriver HTTP-only Android Portal driver. Requires url and bearer token; does not use ADB at runtime.
IOSPortalDriver / IOSDriver iOS Portal HTTP driver. Requires an already-running ios-portal URL.
DeviceDriver Abstract base for drivers. supported: set[str] declares which verbs a subclass implements.
DeviceDisconnectedError Raised when the device drops mid-call.
PortalClient HTTP-or-content-provider client for the on-device Portal. Used internally by AndroidDriver; can be constructed directly for low-level access.
setup_portal(device) Download + install + enable the Portal APK on a device.
ensure_portal_ready(device) Idempotent: install/upgrade Portal and enable accessibility if needed.
setup_keyboard(device) Switch the device to the Mobilerun IME.
ping_portal(device) Verify Portal is installed and reachable.
PORTAL_PACKAGE_NAME, A11Y_SERVICE_NAME Portal identifiers.
portal_content_uri(pkg, path) Build content://<pkg>/<path> URIs.
portal_a11y_service(pkg), portal_ime_id(pkg) Accessibility service / IME component names.

AndroidDriver accepts:

  • serial: str | None โ€” ADB serial; None picks the only connected device.
  • use_tcp: bool = False โ€” when True, the underlying PortalClient port-forwards Portal's HTTP server (localhost:N โ†’ device:8080) and uses it instead of the content provider. Faster but requires a working forward; falls back transparently.

๐Ÿชต Logging

All output goes through the "mobilerun_core_cli" logger. Configure it yourself; the package attaches no handlers.

import logging
logging.basicConfig(level=logging.INFO)
logging.getLogger("mobilerun_core_cli").setLevel(logging.DEBUG)

๐Ÿ”— Relationship to upstream mobilerun

This package owns local execution drivers. The full framework imports these drivers for CLI/agent flows; mobilerun-core wraps them behind a sync, backend-neutral API.

Use mobilerun-core-cli when you need async local drivers directly. Use mobilerun when you want the full LLM-agent experience, CLI/TUI, and multi-platform support out of the box.

๐Ÿ“„ License

MIT โ€” see LICENSE.

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

mobilerun_core_cli-0.2.0.tar.gz (43.8 kB view details)

Uploaded Source

Built Distribution

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

mobilerun_core_cli-0.2.0-py3-none-any.whl (30.8 kB view details)

Uploaded Python 3

File details

Details for the file mobilerun_core_cli-0.2.0.tar.gz.

File metadata

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

File hashes

Hashes for mobilerun_core_cli-0.2.0.tar.gz
Algorithm Hash digest
SHA256 dc13016c7983476cca564dd013fc281047474dc502de54f8c0bd5647b48211e2
MD5 28032c1aa272e08ad95fb2f5ddf725af
BLAKE2b-256 d67818cd91fccb2fb348a5150707245d303b6052890a9aca2c35bd391d776208

See more details on using hashes here.

Provenance

The following attestation bundles were made for mobilerun_core_cli-0.2.0.tar.gz:

Publisher: publish.yml on droidrun/mobilerun-core-cli

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

File details

Details for the file mobilerun_core_cli-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for mobilerun_core_cli-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d94c5478d299fc10ec3f8f850dc469d65e2533db4805e0d932b15925c8e5e351
MD5 f70b64918d4c0cd9ae7219d65493ce8b
BLAKE2b-256 40542fe03bf7a98fb50b70580acef5c5bf3ea1c51ccf6ef867b5df81201934ea

See more details on using hashes here.

Provenance

The following attestation bundles were made for mobilerun_core_cli-0.2.0-py3-none-any.whl:

Publisher: publish.yml on droidrun/mobilerun-core-cli

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