A Python library designed to control BlueStacks through ADB commands, enabling seamless automation and management of Android applications on a PC.
Project description
Pymordial 🦕
Extensible Automation Framework for Python
Pymordial is an extensible automation framework designed to support any platform (Android, iOS, Windows, etc.). Currently, it features complete end-to-end support for BlueStacks 5, utilizing ADB (Android Debug Bridge) for device control and a unified vision system for UI interaction.
Key Features
- Platform Agnostic Design: Built to support custom device implementations.
- BlueStacks Integration: Native support for BlueStacks 5 (launch, kill, lifecycle management) included out-of-the-box.
- Pure Python ADB: Uses
adb-shellfor direct communication without requiring a system ADB installation. - High-Performance Streaming: Implements H.264 screen capture streaming for low-latency visual feedback.
- Unified Vision System: Seamlessly find and interact with:
- Images: Template matching with confidence thresholds.
- Text: OCR powered by Tesseract.
- Pixels: Precise color verification with tolerance.
- App Lifecycle Management: Robust
StateMachine(CLOSED → LOADING → READY) for app stability. - Type-Safe Configuration: Strictly typed configuration system via
TypedDict.
Prerequisites
- BlueStacks 5: Installed on Windows (Hyper-V, Nougat, Pie, or Android 11 instances supported).
- Enable ADB: Enable "Android Debug Bridge" in BlueStacks Settings > Advanced.
- Python 3.13+: Ensure you have a modern Python version installed.
Installation
We recommend using uv for dependency management.
uv add pymordial
Alternatively, you can use pip:
pip install pymordial
Setup BlueStacks
If you don't have BlueStacks installed, you can use the included setup script:
uv run src/pymordial/scripts/setup_bluestacks.py
Configuration
Pymordial uses a sensible default configuration suitable for most use cases. To override these settings, create a pymordial_config.yaml file in your project root.
Example pymordial_config.yaml:
adb:
default_host: "127.0.0.1"
default_port: 5555
stream:
resolution: 1024 # Stream width
bluestacks:
resolution: [1920, 1080] # Target resolution for scaling
app:
action_timeout: 45
Quick Start
1. Connect and Verify
Create a PymordialController to manage the connection.
from pymordial import PymordialController
# Initialize controller (auto-connects to default ADB host/port)
controller = PymordialController()
# Check Device Status
if controller.bluestacks.is_ready():
print("✅ BlueStacks is ready")
else:
print("⏳ Launching BlueStacks...")
controller.bluestacks.open()
if controller.adb.is_connected():
print("✅ ADB Connected")
2. Define UI Elements
Define the elements you want to interact with using PymordialImage, PymordialText, or PymordialPixel.
from pymordial import PymordialImage, PymordialPixel, PymordialText
from pathlib import Path
# Image Element (Template Matching)
start_button = PymordialImage(
label="start_button",
filepath=Path(__file__).parent / "assets/start_btn.png",
confidence=0.8,
og_resolution=(1920, 1080), # Resolution where asset was captured
)
# Text Element (OCR)
level_text = PymordialText(
label="level_indicator",
element_text="Level 1",
)
# Pixel Element (Color Check)
health_bar = PymordialPixel(
label="full_health",
position=(100, 50),
pixel_color=(0, 255, 0),
tolerance=10,
)
3. Interacting with Elements
Use the controller to find, click, or read elements.
# Check visibility
if controller.is_element_visible(start_button):
print("Start button found!")
# Click element
controller.click_element(start_button)
# Find coordinates directly
coords = controller.find_element(health_bar)
if coords:
print(f"Health bar at: {coords}")
# Read text from screen
text_lines = controller.read_text(controller.capture_screen())
print("Screen text:", text_lines)
4. Managing App Lifecycle
Use PymordialApp to robustly manage application state.
from pymordial import PymordialApp
# Define an app with a "ready marker"
my_game = PymordialApp(
app_name="MyGame",
package_name="com.example.mygame",
ready_element=start_button, # App is 'READY' when this is visible
)
# Register app with controller
controller.add_app(my_game)
# Open app and wait for it to be ready
controller.my_game.open()
if controller.my_game.is_open():
print("App represents: READY state")
Architecture Overview
The system is organized into a clean implementation hierarchy:
PymordialController
├── adb (PymordialAdbDevice)
│ ├── AdbShell (Bridge)
│ ├── Streaming (H.264 -> PyAV)
│ └── Input (Tap, Swipe, Text)
│
├── bluestacks (PymordialBluestacksDevice)
│ ├── Process Management
│ └── Lifecycle Control
│
└── ui (PymordialUiDevice)
├── Vision Strategy (OpenCV)
├── OCR Engine (Tesseract)
└── Matching Logic (Image/Pixel/Text)
Contributing
- Fork the repository.
- Create a feature branch.
- Commit your changes (please follow PEP 8).
- Submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
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 pymordial-0.3.1.tar.gz.
File metadata
- Download URL: pymordial-0.3.1.tar.gz
- Upload date:
- Size: 39.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
73221fd33bf16b34e8949c04d27b51ffe5e6a7208dd31739649223088f5c16fc
|
|
| MD5 |
9915433751b507ac80c6b362b5471b6f
|
|
| BLAKE2b-256 |
fe773580f9cf212021a3005e611975dd3e1748c7f04ab79ff6dfa1982d469587
|
Provenance
The following attestation bundles were made for pymordial-0.3.1.tar.gz:
Publisher:
release.yml on IAmNo1Special/Pymordial
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pymordial-0.3.1.tar.gz -
Subject digest:
73221fd33bf16b34e8949c04d27b51ffe5e6a7208dd31739649223088f5c16fc - Sigstore transparency entry: 841748835
- Sigstore integration time:
-
Permalink:
IAmNo1Special/Pymordial@d86ba69c66909036d767876be691306a95b24e4e -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/IAmNo1Special
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d86ba69c66909036d767876be691306a95b24e4e -
Trigger Event:
push
-
Statement type:
File details
Details for the file pymordial-0.3.1-py3-none-any.whl.
File metadata
- Download URL: pymordial-0.3.1-py3-none-any.whl
- Upload date:
- Size: 39.4 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
31427fae245ae2dd15822b99b716ba8e8f232cafd47681be760b8b28faa80d30
|
|
| MD5 |
4cd575afc8714dbabf0615a64dc667ca
|
|
| BLAKE2b-256 |
614901b35d6948c5fcf813f65168a0021c199626b255435699731a877d2b9e43
|
Provenance
The following attestation bundles were made for pymordial-0.3.1-py3-none-any.whl:
Publisher:
release.yml on IAmNo1Special/Pymordial
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pymordial-0.3.1-py3-none-any.whl -
Subject digest:
31427fae245ae2dd15822b99b716ba8e8f232cafd47681be760b8b28faa80d30 - Sigstore transparency entry: 841748843
- Sigstore integration time:
-
Permalink:
IAmNo1Special/Pymordial@d86ba69c66909036d767876be691306a95b24e4e -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/IAmNo1Special
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d86ba69c66909036d767876be691306a95b24e4e -
Trigger Event:
push
-
Statement type: