Controlling macOS with Python — SitePoint

Controlling macOS with Python — SitePoint

[ad_1]

On this fast tip, excerpted from Helpful Python, Stuart seems to be at tactics to regulate the Home windows OS with Python.

Running on a Mac, we will be able to regulate virtually the whole lot in regards to the gadget the use of pyobjc, the Python-to-Goal-C bridge. Apple makes maximum of its OS controllable by the use of the AppKit module, and pyobjc provides Python get right of entry to to all of this. This will probably be most valuable if we already know the AppKit solution to do the article we would like, however with a bit of exploration it’s conceivable to make our method in the course of the running gadget APIs.

Let’s check out an instance. First, we’ll want pyobjc, which will also be put in with pip set up pyobjc. This may increasingly set up an entire checklist of running gadget API bridges, permitting get right of entry to to all types of sides of macOS. For now, we’ll imagine AppKit, which is the instrument used to construct and regulate operating apps on a Mac desktop.

We will checklist all of the packages these days operating the use of AppKit:

Python 3.9.6 (default, Oct 18 2022, 12:41:40) 
[Clang 14.0.0 (clang-1400.0.29.202)] on darwin
Sort "lend a hand", "copyright", "credit" or "license" for more info.
>>> from AppKit import NSWorkspace
>>> NSWorkspace.sharedWorkspace().runningApplications() 
(
    "<NSRunningApplication: 0x60000145c000 (com.apple.loginwindow - 148) LSASN:{hello=0x0;lo=0x6006}>",
    "<NSRunningApplication: 0x60000145c080 (com.apple.backgroundtaskmanagement.agent - 475) LSASN:{hello=0x0;lo=0xb00b}>",
    "<NSRunningApplication: 0x60000145c100 (com.apple.WindowManager - 474) LSASN:{hello=0x0;lo=0xc00c}>",
    "<NSRunningApplication: 0x60000145c180 (com.apple.CoreLocationAgent - 500) LSASN:{hello=0x0;lo=0xe00e}>",
    "<NSRunningApplication: 0x60000145c980 (com.apple.Terminal - 1302) LSASN:{hello=0x0;lo=0x24024}>",
    "<NSRunningApplication: 0x60000145ca00 (com.apple.Safari - 1303) LSASN:{hello=0x0;lo=0x25025}>",
    "<NSRunningApplication: 0x60000145cb80 (com.apple.Highlight - 1310) LSASN:{hello=0x0;lo=0x28028}>",
    "<NSRunningApplication: 0x60000145cc00 (com.apple.finder - 1306) LSASN:{hello=0x0;lo=0x29029}>",
)
>>> 

This may increasingly give an extended checklist of NSRunningApplication items. Every one corresponds to a particular software these days operating at the desktop. Many are “invisible” packages (issues which are operating however aren’t essentially appearing a window), however others are issues that we would recall to mind as precise packages that we will be able to see—similar to Safari, Terminal, and so forth. NSRunningApplication is documented at developer.apple.com, the place its homes will also be noticed. For instance, each and every software has a localizedName and a bundleIdentifier:

>>> for nsapp in NSWorkspace.sharedWorkspace().runningApplications():
...   print(f"{nsapp.localizedName()} -> {nsapp.bundleIdentifier()}")
... 
loginwindow -> com.apple.loginwindow
BackgroundTaskManagementAgent -> com.apple.backgroundtaskmanagement.agent
WindowManager -> com.apple.WindowManager
CoreLocationAgent -> com.apple.CoreLocationAgent
Terminal -> com.apple.Terminal
Safari -> com.apple.Safari
Highlight -> com.apple.Highlight
Finder -> com.apple.finder

We will additionally see {that a} NSRunningApplication object has an turn on serve as, which we will be able to name to turn on that app as even though we had clicked its icon within the Dock. So, to seek out Safari after which turn on it, we might use that turn on serve as. The decision to turn on calls for a price for choices, because the documentation describes, and that still must be imported from AppKit:

>>> from AppKit import NSWorkspace, NSApplicationActivateIgnoringOtherApps
>>> safari_list = [x for x in NSWorkspace.sharedWorkspace().runningApplications()
    if x.bundleIdentifier() == 'com.apple.Safari']
>>> safari = safari_list[0]
>>> safari.activateWithOptions_(NSApplicationActivateIgnoringOtherApps)

Now Safari is activated.

Discovering Python Variations of macOS APIs

Discovering the title of one thing in Python that corresponds to the Goal-C title is usually a little tough. As proven within the code above, the Goal-C turn on serve as is known as activateWithOptions_ in Python. There’s a algorithm for this title translation, which the pyobjc documentation explains, however it could actually infrequently be faster to make use of Python’s personal dir() serve as to turn all of the homes of an object after which pick the one who seems to be maximum believable:

>>> print(len(dir(safari)))
452

Ouch! Our safari example of an NSRunningApplication has 452 homes! Neatly, the only we would like is most probably referred to as one thing like “turn on”, so:

>>> print([x for x in dir(safari) if "activate" in x.lower()])
['activateWithOptions_', 'activateWithOptions_']

Aha! So activateWithOptions_ is the title of the serve as we want to name. In a similar way, the title of the choice we wish to move to that serve as is in AppKit itself:

>>> [x for x in dir(AppKit) if "ignoringotherapps" in x.lower()]
['NSApplicationActivateIgnoringOtherApps']

This procedure can really feel a bit of exploratory now and then, however it’s conceivable to do anything else that Goal-C can do from Python as smartly.

This newsletter is excerpted from Helpful Python, to be had on SitePoint Top rate and from book shops.



[ad_2]

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back To Top
0
Would love your thoughts, please comment.x
()
x