pixelactions (Python)
Drive desktop interactions from a session a human marked — click a label, not a coordinate, and confirm it landed.
pip install pixelactions
Needs the pixelactions binary on PATH:
brew install nolindnaidoo/tap/pixelactions # macOS
cargo install pixelactions # anywhere with Rust
Use it
from pixelactions import Session
with Session("~/captures/login") as ui:
ui.click("email")
ui.write("me@example.com")
ui.key("tab")
ui.write("hunter2")
ui.click("submit")
ui.wait("dashboard")
Mark email, submit and dashboard once, by hand, with
pixelcoords. The script then survives the window
moving: every step re-locates its region before acting.
Compare the usual version, which is wrong the moment anything shifts:
pyautogui.click(812, 440)
Verbs
| Method | Does |
|---|---|
click(label) · double_click(label) |
click the region's point |
write(text) |
type text — write, because type is a keyword |
key(chord) |
a chord like cmd+s, arriving as keys not characters |
drag(start, end) |
press at one region, release at another |
scroll(label, n, horizontal=False) |
wheel over a region; negative reverses |
verify(label) |
is the region still what it was? |
wait(label) · gone(label) |
block until it matches, or until it disappears |
changed(label, tolerance=…) |
did it change? the strongest post-action check |
pause(ms) |
when there is genuinely no observable |
relocate() |
where is everything now, without acting |
Failure is two different things
from pixelactions import StepFailed, ProtocolError
try:
ui.wait("dashboard")
except StepFailed as e: # it ran, and the answer is no
print(e.report.detail) # "timed out after 30s (48 polls, best 0.71)"
except ProtocolError as e: # the question was wrong
print(e) # 'no selection labeled "dashbord"'
That is the same line the binary's exit codes draw, and it is worth keeping: a timeout is a fact about the screen, a typo'd label is a fact about your code.
Pass raise_on_failure=False to get the report back instead of an
exception.
Settings
Anything the flow file's [settings] table takes:
Session("~/captures/login", settings={"failsafe": False, "timeout_ms": 5000})
failsafe is the corner kill switch — park the pointer in a screen corner
and a run stops. It cannot work on Wayland, which will not report the
pointer, so a flow there must turn it off deliberately.
How it works
A pixelactions serve child process and newline-delimited JSON over its
stdin and stdout — the
line protocol.
No FFI, no native module, no dependencies.
The version tracks the binary it drives. There is no separate client version to reason about.
Releasing
Manual, like the crates — PyPI will not let a version be replaced, only yanked, so it is a button someone presses rather than a side effect of a tag.
Run the Publish the Python client workflow from the Actions tab. It
defaults to TestPyPI; choose pypi for the real thing. The version comes
from pyproject.toml, which a test holds equal to the workspace — there
is no version input to get wrong.
Publishing uses Trusted
Publishing, so there is no API
token stored anywhere. One-time setup on each side — owner nolindnaidoo, repository
pixelactions, workflow publish-python.yml, and environment matching
the target (testpypi or pypi).
MIT.
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 pixelactions-0.9.7.tar.gz.
File metadata
- Download URL: pixelactions-0.9.7.tar.gz
- Upload date:
- Size: 10.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
88604644dcc22e1ca618b32c82d804de146493c40e7ed51852c302583a5e57ba
|
|
| MD5 |
e7346f789d8e906762ee924492d07023
|
|
| BLAKE2b-256 |
014596f0af42bac96021f336f9eee883a16d8ddf552012e926d42b4724f36e17
|
Provenance
The following attestation bundles were made for pixelactions-0.9.7.tar.gz:
Publisher:
publish-python.yml on nolindnaidoo/pixelactions
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pixelactions-0.9.7.tar.gz -
Subject digest:
88604644dcc22e1ca618b32c82d804de146493c40e7ed51852c302583a5e57ba - Sigstore transparency entry: 2345926991
- Sigstore integration time:
-
Permalink:
nolindnaidoo/pixelactions@d38676d2ca912de7d44767564e65333c581f668e -
Branch / Tag:
refs/heads/main - Owner: https://github.com/nolindnaidoo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-python.yml@d38676d2ca912de7d44767564e65333c581f668e -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file pixelactions-0.9.7-py3-none-any.whl.
File metadata
- Download URL: pixelactions-0.9.7-py3-none-any.whl
- Upload date:
- Size: 11.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3a54cc05b273c6b8e1eaf7cbdf8febc6bbefd8fca6395e5e7d8197ee68edbb78
|
|
| MD5 |
0dbed503a8262f5a8899030a31930056
|
|
| BLAKE2b-256 |
a85b91362a580c63ffe0c7ec9a495d436081fe1aefd173a49ad6d93646e474c2
|
Provenance
The following attestation bundles were made for pixelactions-0.9.7-py3-none-any.whl:
Publisher:
publish-python.yml on nolindnaidoo/pixelactions
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pixelactions-0.9.7-py3-none-any.whl -
Subject digest:
3a54cc05b273c6b8e1eaf7cbdf8febc6bbefd8fca6395e5e7d8197ee68edbb78 - Sigstore transparency entry: 2345927621
- Sigstore integration time:
-
Permalink:
nolindnaidoo/pixelactions@d38676d2ca912de7d44767564e65333c581f668e -
Branch / Tag:
refs/heads/main - Owner: https://github.com/nolindnaidoo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-python.yml@d38676d2ca912de7d44767564e65333c581f668e -
Trigger Event:
workflow_dispatch
-
Statement type: