Skip to main content

pyautoassist

Playwright-style desktop automation with native OS accessibility backends.

pyautoassist brings the developer experience of Playwright to desktop automation. No more time.sleep(). No more fragile coordinate-based clicking. Just explicit locators, native auto-waiting, and real OS accessibility APIs.

import pyautoassist

app = pyautoassist.using_backend()

# XPath-style locators targeting OS accessibility properties
app.locator("//Button[@Name='Submit']").click()
app.locator("//Edit[@AutomationId='email-input']").fill("Hello World")

# CSS-style shorthand
app.locator("button.submit-btn").click()
app.locator("edit-text#main-input").fill("Hello")

# Auto-waiting: no time.sleep() needed
app.locator("//Button[@Name='Save']").click()  # waits until clickable

Why pyautoassist?

Feature pyautogui pywinauto pyautoassist
Locator style Coordinates/fragile selectors Custom syntax CSS/XPath-style
Auto-waiting None Basic Full (Playwright-style)
OS backend Screen capture Win32 COM Native UIA/AX/AT-SPI
Codegen recorder No No Yes (pyautoassist record)
Cross-platform Yes Windows only Windows/macOS/Linux

Installation

# Core (auto-detects platform)
pip install pyautoassist

# Platform-specific extras
pip install pyautoassist[windows]   # Windows UIA
pip install pyautoassist[macos]     # macOS Accessibility
pip install pyautoassist[linux]     # Linux AT-SPI2

Quick Start

import pyautoassist

# Create an automation session
app = pyautoassist.using_backend()

# Find a window
notepad = app.open("Notepad")

# Use locators (auto-waits for element)
app.locator("//Edit").fill("Hello, pyautoassist!")

# Chain locators within elements
notepad.locator("//MenuItem[@Name='File']").click()
notepad.locator("//MenuItem[@Name='Save']").click()

Selectors

XPath Style

Target elements by their OS accessibility properties:

# By control type and name
app.locator("//Button[@Name='Submit']")
app.locator("//Edit[@Name='Username']")

# By AutomationId (most reliable)
app.locator("//Button[@AutomationId='btn-submit']")
app.locator("//Edit[@AutomationId='email-input']")

# By ClassName
app.locator("//Pane[@ClassName='Notepad']")

# Chained: nested elements
app.locator("//Pane[@ClassName='Notepad']//Button[@Name='File']")

CSS Style

Shorthand selectors for quick access:

# Type + ID (AutomationId)
app.locator("button#submit-btn")

# Type + class (ClassName)
app.locator("button.submit")

# Type + attribute
app.locator('button[name="OK"]')

# Child combinator
app.locator("pane > button")

Supported Control Types

button, edit/edit-text/textbox, pane, window/dialog, menu, menuitem, checkbox, radio/radiobutton, combobox/dropdown, list, listitem, tree, treeitem, toolbar, tab, tabitem, image, hyperlink, slider, progressbar, scrollbar, group, tooltip, statusbar, header, separator, document, dataitem, custom

Auto-Waiting

Every action on a Locator automatically waits for the element to be ready:

# Waits up to 30s for the button to exist, be visible, and be enabled
app.locator("//Button[@Name='Submit']").click()

# Custom timeout
app.locator("//Button[@Name='Submit']").with_timeout(5000).click()

# Wait for specific states
app.locator("//Button[@Name='Loading']").visible().click()
app.locator("//Edit[@Name='Email']").enabled().click()

Element Actions

el = app.locator("//Button[@Name='Submit']")

el.click()              # Left click
el.double_click()       # Double click
el.right_click()        # Context menu
el.fill("text")         # Set value (input fields)
el.type_text("text")    # Type character by character
el.clear()              # Clear input
el.select_option(label="Option 1")  # Dropdown selection
el.focus()              # Move keyboard focus
el.hover()              # Move mouse to element
el.press_key("Enter")   # Send key press

Window Management

# List all windows
for w in app.get_windows():
    print(f"{w.title} (PID: {w.pid})")

# Find by title
notepad = app.find_window(title="Notepad")
notepad.focus()
notepad.move(100, 100)
notepad.resize(800, 600)
notepad.close()

# Find by PID
window = app.find_window(pid=12345)

Codegen Recorder

Generate automation code by clicking around:

# Start recording (Windows)
pyautoassist record

# Save to file
pyautoassist record --output recorded.py

# Specify backend
pyautoassist record --backend macos

The recorder hooks into OS mouse events, inspects the accessibility tree at each click location, and prints pyautoassist-style code in real time.

Architecture

pyautoassist/
  __init__.py              # Public API
  _impl/
    pyautoassist.py           # Main entry point (pyautoassist class)
    locator.py             # Playwright-style Locator with auto-wait
    element.py             # Element wrapper with actions
    window.py              # Window management
    selector.py            # CSS/XPath-style selector engine
    wait.py                # Auto-wait polling loop
    types.py               # Data types and enums
    backend.py             # Abstract backend interface
  backends/
    windows_backend.py     # Windows UIA (UIA3 COM API)
    macos_backend.py       # macOS AXUIElement (PyObjC)
    linux_backend.py       # Linux AT-SPI2 (GObject)
  recorder/
    cli.py                 # Codegen CLI tool

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyautoassist-0.1.0.tar.gz (69.2 kB view details)

Uploaded Source

Built Distribution

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

pyautoassist-0.1.0-py3-none-any.whl (62.6 kB view details)

Uploaded Python 3

File details

Details for the file pyautoassist-0.1.0.tar.gz.

File metadata

  • Download URL: pyautoassist-0.1.0.tar.gz
  • Upload date:
  • Size: 69.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.10

File hashes

Hashes for pyautoassist-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a73ade45debc465b315299f3f63de72a554477571e763b07ddce82b959440cbe
MD5 e24ca9d4074ecefe08b0e7e43eb1a0b4
BLAKE2b-256 df76e41f5f4c4998384e386bbba63551c9f7302ab418eb6af26e0cb4b84edb18

See more details on using hashes here.

File details

Details for the file pyautoassist-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pyautoassist-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 62.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.10

File hashes

Hashes for pyautoassist-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4d8c447738236aca7acdbea924bbe30cf7c3f5576d8072ecb313af0299e88627
MD5 793b67b6f3f6771925f089b0fdea4166
BLAKE2b-256 5b8912254c9e6c38662f8dbf75806dc7797ecd3ebfc883a572bc4c405068e485

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page