Metadata-Version: 2.4
Name: letsautomate
Version: 0.1.2
Summary: Performance-optimised UI automation and perception framework for Windows
Author: LetsAutomate
License: MIT
Keywords: automation,ui-automation,windows,win32,uiautomation,rpa,desktop-automation
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Desktop Environment
Requires-Python: >=3.14
Description-Content-Type: text/markdown
Provides-Extra: benchmark
Requires-Dist: psutil>=5.9; extra == "benchmark"
Requires-Dist: pywinauto>=0.6; extra == "benchmark"
Requires-Dist: uiautomation>=2.0; extra == "benchmark"
Requires-Dist: pyautogui>=0.9; extra == "benchmark"

# LetsAutomate

Performance-optimised UI automation and perception framework for Windows, built on UIAutomation and Win32.

LetsAutomate wraps a compiled native extension (`lacore`) that issues a single `IUIAutomationCacheRequest` COM call to batch-retrieve all UI elements in one round trip - instead of NxP individual COM calls - making it significantly faster than pywinauto or python-uiautomation for perception-heavy workloads.

## Requirements

| Requirement | Value |
|---|---|
| Python | 3.14 (CPython) |
| Platform | Windows 10/11 x64 |

## Installation

```bash
pip install letsautomate
```

## Quick Start

```python
import ctypes
from letsautomate import LetsAutomate

# Open Notepad first, then:
hwnd = ctypes.windll.user32.FindWindowW(None, "Untitled - Notepad")

with LetsAutomate() as fw:
    fw.initialise()

    # Configure which element properties to cache
    fw.configure_cache(
        properties=["name", "automation_id", "control_type", "bounding_rect", "is_enabled"],
        scope="subtree",
        mode="auto",   # "auto" | "win32" | "uia"
    )

    # Batch-retrieve all UI elements in one COM call
    elements = fw.query_elements_cached(hwnd)
    for elem in elements:
        print(elem.name, elem.control_type, elem.bounding_rect)

    # Find a live element and click it
    handle = fw.find_element(hwnd, by="name", value="File")
    fw.execute_action(handle, "click")
```

## API Reference

### `LetsAutomate`

| Method | Description |
|---|---|
| `initialise()` | Start the framework (must be called before any other method) |
| `shutdown()` | Clean shutdown; also called automatically via context manager |
| `configure_cache(properties, scope, mode)` | Set cached property list and perception mode |
| `query_elements_cached(hwnd, scope)` | Batch-retrieve all UI elements → `List[ElementSnapshot]` |
| `find_element(hwnd, by, value)` | Live element lookup → `ElementHandle` |
| `execute_action(handle, action, **params)` | Dispatch a UI action on an element |
| `subscribe_events(hwnd, event_types, scope, callback)` | Subscribe to UIAutomation events on a background thread |
| `get_active_mode()` | Return the active perception mode (`"win32"` / `"uia"`) |
| `get_diagnostic_log()` | Return the native diagnostic log string |

### Supported actions

`click` - `type` (pass `text="..."`) - `scroll` - `focus` - `hover` - `select` - `expand`

### Exceptions

All exceptions inherit from `UAException`.

| Exception | When raised |
|---|---|
| `UAInitialisationException` | Framework failed to start or `lacore` unavailable |
| `UAElementNotFoundException` | `find_element` found no matching element |
| `UAActionException` | `execute_action` failed |
| `UACacheException` | Batch cache retrieval failed |
| `UAQueryException` | Direct element query failed |
| `UAConfigurationException` | Invalid property name or scope passed to `configure_cache` |

## Benchmark suite (optional)

Install the benchmark extras to run the benchmark suite:

```bash
pip install "letsautomate[benchmark]"
```

Then run the suite from within the repository:

```bash
python -m letsautomate.benchmark.benchmark_runner
```

## Changelog

### 0.1.2
- Fixed `import lacore` → `from . import lacore` so the native extension resolves correctly when installed via pip
- Added `__init__.py` with proper package exports and `__version__`
- Added `pyproject.toml` and `setup.py` for correct platform-specific wheel builds

### 0.1.1
- Initial PyPI release (import issue)

### 0.1.0
- Initial PyPI release (import issue)

## License

MIT
