eeejay / pyax Goto Github PK
View Code? Open in Web Editor NEWClient library for macOS accessibility
License: MIT License
Client library for macOS accessibility
License: MIT License
After pip install pyax
ing, I tried to run
>> import pyax
in a python3 env. I get the following errror:
Traceback (most recent call last):
File "/Users/morganraereschenberg/pyax/examples/event_dump.py", line 25, in <module>
import pyax
File "/opt/homebrew/lib/python3.11/site-packages/pyax/__init__.py", line 46, in <module>
mix_class(AXUIElementMixin)
File "/opt/homebrew/lib/python3.11/site-packages/pyax/_mixin.py", line 79, in mix_class
setattr(cls, "_mix_" + name, old_method)
File "/opt/homebrew/lib/python3.11/site-packages/objc/_transform.py", line 473, in transformAttribute
raise objc.BadPrototypeError(
objc.BadPrototypeError: '_mix:::str::' expects 5 arguments, <slot wrapper '__str__' of 'object' objects> has 0 positional arguments
This was a little bit of work, so I wanted to share this example script that crawls the tree AND outputs all attributes. Actually, it would be nice if some of this logic made it into pyax
core.
import json
import re
from typing import Any, Dict
import pyax
from ApplicationServices import (
AXUIElementRef,
AXValueGetType,
AXValueRef,
CFArrayGetTypeID,
CFGetTypeID,
NSPointFromString,
NSRangeFromString,
NSRectFromString,
NSSizeFromString,
kAXValueCFRangeType,
kAXValueCGPointType,
kAXValueCGRectType,
kAXValueCGSizeType,
)
from typeguard import typechecked
@typechecked
def parse_ax_value(value: Any) -> Any:
if value is None:
return value
elif isinstance(value, (bool, int, str, float)):
return value
elif isinstance(value, list) or CFGetTypeID(value) == CFArrayGetTypeID():
return [parse_ax_value(item) for item in value]
elif isinstance(value, AXUIElementRef):
return f"AXUIElement: {repr(value)}"
elif isinstance(value, AXValueRef):
return parse_ax_value_ref(value)
else:
return str(value)
@typechecked
def parse_ax_value_ref(value: AXValueRef) -> Dict[str, Any]:
ax_value_type = AXValueGetType(value)
ax_type_map = {
kAXValueCGSizeType: NSSizeFromString,
kAXValueCGPointType: NSPointFromString,
kAXValueCFRangeType: NSRangeFromString,
kAXValueCGRectType: NSRectFromString,
}
if ax_value_type in ax_type_map:
extracted_str = re.search(r"\{.*\}", str(value)).group()
parsed_value = ax_type_map[ax_value_type](extracted_str)
if ax_value_type == kAXValueCGPointType:
return {"x": parsed_value.x, "y": parsed_value.y}
elif ax_value_type == kAXValueCGSizeType:
return {"width": parsed_value.width, "height": parsed_value.height}
elif ax_value_type == kAXValueCFRangeType:
return {"location": parsed_value.location, "length": parsed_value.length}
elif ax_value_type == kAXValueCGRectType:
return {
"x": parsed_value.origin.x,
"y": parsed_value.origin.y,
"width": parsed_value.size.width,
"height": parsed_value.size.height,
}
else:
return {"unknown_type": str(value)}
@typechecked
def traverse_ui_elements_json(
element: AXUIElementRef, depth: int = 0
) -> Dict[str, Any]:
element_data = {
"pid": element.pid,
"role": element.get_attribute_value("AXRole"),
"subrole": element.get_attribute_value("AXSubrole"),
"title": element.get_attribute_value("AXTitle"),
"attributes": {},
"children": [],
}
try:
for attribute in element.attribute_names:
value = element.get_attribute_value(attribute)
element_data["attributes"][attribute] = parse_ax_value(value)
except Exception as e:
element_data["error"] = f"Error accessing attributes: {e}"
try:
children = element.get_attribute_value("AXChildren")
for child in children or []:
child_data = traverse_ui_elements_json(child, depth + 1)
element_data["children"].append(child_data)
except Exception as e:
element_data["error"] = f"Error accessing children: {e}"
return element_data
if __name__ == "__main__":
import sys
app_name = sys.argv[-1]
acc = pyax.get_application_by_name(app_name)
tree_data = traverse_ui_elements_json(acc)
# Output the data to JSON
print(json.dumps(tree_data, indent=4))
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.