High-performance Enterprise GUI Automation for Progress OpenEdge & Win32
Project description
pywingui: The Enterprise Standard for Progress OpenEdge & Win32 Automation
Stop automating. Start solving. Eliminate the fragility of traditional UI testing.
PyWinGUI is a high-performance automation engine engineered to dominate the most challenging enterprise environments. While traditional tools struggle with Progress OpenEdge’s owner-drawn controls and unpredictable modal behavior, PyWinGUI thrives.
💎 Features
PyWinGUI introduces a robust paradigm for enterprise ERP automation:
🧠 1. AI-Driven Recovery
The AIAgentErrorEngine handles validation popups automatically, executing standard fixes and continuing the test runs seamlessly.
📍 2. Proximity Mapping
Forget fragile pixel coordinates or dynamic AutomationIDs that change every build. PyWinGUI utilizes semantic proximity to intelligently locate fields based on nearby label text, keeping your scripts resilient.
⚡ 3. High-Performance Discovery
Uses a high-performance hybrid discovery engine to attach to windows and elements rapidly with zero lag.
🛡️ 4. Absolute Privacy
Designed for zero-outbound exposure. Your automation logic, system metadata, and project specifics remain 100% local and secure.
🆚 Comparison
| Feature | Traditional RPA / Win32 | PyWinGUI |
|---|---|---|
| Discovery | Fixed IDs / Coordinates | Proximity Anchoring |
| Error Handling | Hardcoded Try/Except | Self-Healing Recovery |
| Grid Handling | OCR Only (Slow/Unreliable) | Hybrid Smart-Scraping |
| Maintenance | High (Breaks on build) | Ultra-Low (Anchor-based) |
| Speed | Slow (Image matching) | Instant (Native Hooks) |
🚀 The Business ROI
- Maintenance Reduction: Reduce script maintenance by 70% via Proximity Mapping and AI recovery.
- Execution Speed: Standardize on the Hybrid Engine to cut test cycle times by 50%.
- Stability: Achieve 99.9% pass rates in complex E2E flows by eliminating "Flaky" failures.
📦 Installation
Install PyWinGUI via pip:
pip install pywingui
🚀 Quick Start
PyWinGUI includes a powerful CLI to jumpstart your project configuration.
1. Initialize Your Project
From your project's root directory, run the setup command to create your local configuration:
# General setup
pywingui --setup
# Recommended: Setup with your specific Application Name
pywingui --setup "My App Name"
This creates a pywingui_config.py file in your directory. This file is your primary control center—uncomment and edit any setting to override the library's defaults for your specific application.
2. Connect Your First Window
With your configuration set, connecting to your application is as simple as:
from pywingui import AppContext
ctx = AppContext()
ctx.connect() # Automatically uses the App Name from your config!
🎥 Universal GUI Recorder
PyWinGUI includes a built-in Universal GUI Recorder that observes your manual interactions and translates them into semantic automation details.
1. Launch the Recorder
From your terminal, run:
pywingui recorder
2. Interact with Your App
As you click elements, type text, or navigate, the recorder will output real-time logs in your console identifying text labels, button names, focus paths, and error dialogs.
3. Stop Recording
Press Ctrl+C in your terminal to end the session. Use the captured labels and actions to build your Page Objects.
📖 Comprehensive API Reference
🚀 1. AppContext (Session Management)
Gateway to the automation engine. Handles backend selection and application connection.
| Method | Description |
|---|---|
AppContext(backend=None, config_overrides=None) |
Initializes the context. backend: "uia" or "win32". |
connect(title_regex=None, handle=None, path=None) |
Connects to a running app or starts a new process. |
get_desktop() |
Returns a raw pywinauto.Desktop object for global searches. |
🪟 2. BaseWindow (Window API)
Primary interface for interacting with a specific application window.
| Method | Description |
|---|---|
BaseWindow(context, window_title) |
Initializes a window instance. |
dlg (Property) |
Returns the raw pywinauto window wrapper object. Handles auto-focus. |
click(button_text, index=1) |
Finds a button by text and clicks it. |
fill(label_text, value, index=1) |
Finds an input field by its nearby label and types the value. |
get(label_text, index=1) |
Extracts data (text) from a specific field near a label. |
select(label_text, item_text, index=1) |
Selects a dropdown item by text in a combo box near a label. |
select_by_index(label_text, item_index, index=1) |
Selects a dropdown item by its 1-based position. |
select_tab(tab_name, index=1) |
Switches to a specific tab by clicking on its text label. |
table_context_select(option_text) |
Right-clicks the table and selects a context menu item (e.g., 'Create', 'Update'). |
table_get_data(index=1) |
Extracts visible table data using local OCR. Returns structured JSON. |
click_menu(menu_path) |
Navigates top-level menus (e.g., "File > Exit"). |
execute(actions) |
Processes an ordered dictionary of actions (e.g., {"Name": "John", "btn:OK": True}). |
read_form(labels, include_tiny_flags=True) |
Reads multiple fields at once into a dictionary. |
handle_errors(max_cycles=None) |
Triggers AI self-healing logic to detect and clear error popups. |
wait_for_window(timeout=30.0) |
Waits until the window becomes visible. |
wait_for_disappear(timeout=30.0) |
Waits until the window is closed/removed from the OS. |
send_keys(keys) |
Sends raw keyboard input to the window (e.g., "{ENTER}", "^a"). |
fill_active(value) |
Clears the currently focused control and types the value. |
close() |
Gracefully attempts to close the window. |
kill() |
Force-closes the specific window handle using Win32 PostMessage. |
kill_process() |
Force-terminates the entire application process. |
blind_center_click_and_enter() |
A rescue method that clicks the center of the window and hits ENTER. |
🌲 3. TreeNavigator (Tree API)
Specialized for deep menu navigation in ERP systems.
| Method | Description |
|---|---|
navigate(window_title, path) |
Expands and selects a path in a TreeView (e.g., ["Sales", "Invoices"]). |
🗺️ 4. Menu Navigation (Menu API)
Highly optimized for nested application menus. Supports robust path-based selection.
| Method | Description |
|---|---|
click_menu(menu_path) |
Navigates top-level and nested menus (e.g., "File > Exit"). |
Usage Example:
win.click_menu("File > Exit")
🎮 5. controller (Global Actions)
High-level interface for scripts that don't use the Page Object Model.
| Function | Description |
|---|---|
sync_context(ctx) |
Links the global controller to an active AppContext. |
click(label, index=1) |
Performs a click on the last active window. |
fill(label, value, index=1) |
Fills a field on the last active window. |
get_value(label, index=1) |
Retrieves data from the last active window. |
click_menu(menu_path) |
Navigates menus on the last active window. |
navigate_tree(path) |
Navigates a TreeView on the last active window. |
table_get_data(index=1) |
Extracts visible table data using local OCR. |
set_error_engine(engine) |
Registers an AIAgentErrorEngine for global self-healing. |
get_error_document_text(window_name) |
Returns OCR/text from an error window for diagnostics. |
🧱 6. UI Elements (pywingui.elements)
Individual components for targeted Page Object Model interactions.
BaseElement (Common Properties)
exists(Property): ReturnsTrueif the element is currently on screen.is_visible(Property): ReturnsTrueif the element is visible.is_enabled(Property): ReturnsTrueif the element can be interacted with.wait_for(state="exists", timeout=30.0): Polls until the element reaches a state.
TextField(page, label, index=1)
fill(text): Clears and types text.get(): Returns current text.clear(): Wipes the field.send_keys(keys): Sends keys to the focused field.
Button(page, label, index=1)
click(): Performs a native click.double_click(): Performs a double-click.
CheckBox(page, label, side="right", index=1)
check(): Ensures the box is checked.uncheck(): Ensures the box is unchecked.set(value): Sets toTrueorFalse.get_state(): ReturnsTrueif checked.
Radio(page, label, group_label=None, index=1)
select(): Activates the radio option.
Combo(page, label, index=1)
select(item_text): Selects item by text.select_by_index(index): Selects item by 1-based index.get(): Returns current selection.
Table(page, label="Main Table")
get_data(): Extracts visible table data.right_click_select(option_text): Right-clicks the table center and selects a context menu item.
Tab(page, label, index=1)
select(): Switches to the tab.
Image(page, image_path, index=1)
click(timeout=20): Finds image on screen and clicks.double_click(timeout=20): Finds image and double-clicks.
OCRElement(page)
get_text(provider="ocr_space"): Returns all text from the window.
🛠️ 7. Global Helpers
wait_for_window(title_substring, timeout=30): Global helper to find a window wrapper.
📍 Relative Coordinate-Based Click & Fill
PyWinGUI supports window-relative coordinates as a fallback for controls that lack labels or unique text identifiers.
# Click at coordinates (x, y) relative to top-left of the target window
win.click(coordinate=(200, 150))
# Fill at coordinates (x, y)
win.fill(value="12345", coordinate=(150, 80))
Coordinates are calculated relative to the active window wrapper, keeping them resilient against dragging or resolution changes.
📍 Page Object Model (POM) ID-Based Selectors
In addition to text-label proximity mapping, PyWinGUI's Page Object Model elements support direct child lookup using standard selector dictionaries (e.g. auto_id or control_id).
How to Use
Pass a dictionary of standard selectors instead of a string label when instantiating the element:
from pywingui.elements.textfield import TextField
from pywingui.elements.button import Button
class MyFormPage:
def __init__(self, page):
# Locate by UIA AutomationId
self.username = TextField(page, {"auto_id": "txtUsername"})
# Locate by Win32 ControlId
self.password = TextField(page, {"control_id": 1002})
# Locate by multiple selectors
self.login_btn = Button(page, {"auto_id": "btnLogin", "class_name": "Button"})
This ensures full support for both text label-based mapping and stable identifier-based targeting within the same codebase, with zero breakage to existing string-based locators.
⚙️ Project-Level Configuration (pywingui_config.py)
Every PyWinGUI project can have a local pywingui_config.py file in its root directory to tune the engine specifically for your target application.
Common overrides include:
TESSERACT_PATH: Path to your localtesseract.exe.BACKEND: Switch between"uia"and"win32".DEFAULT_APP_TITLE_RE: Set the default window name.GLOBAL_TIMEOUT: Adjust how long the engine waits for elements to appear.PROXIMITY_ROW_DELTA: Fine-tune how "nearby" elements are detected.
🛡️ Security & Integrity
- No Execution on Import: Importing PyWinGUI is a passive action. It never executes code, opens network sockets, or initiates background processes upon import.
- Zero-PII & Hardware Isolation: Our architecture is strictly isolated from your machine's identity. We do not collect MAC addresses.
- Data Sanctity: All automation logic and project data are processed strictly within your local infrastructure.
© 2020 PyWinGUI Framework. The future of Win32 and Progress OpenEdge Automation.
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 Distributions
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 pywingui-6.1.39-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: pywingui-6.1.39-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 918.5 kB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7440865eae4526776238259898302f7ec4e3c7ea434ae62937acf64296443f08
|
|
| MD5 |
a4a347b23945a090d7ed80480d19a33a
|
|
| BLAKE2b-256 |
2892cfa2c02bc3b9a4833fab20d6fc0688f8ea899dab67e775b4b33cb6987bc2
|