On this fast tip, excerpted from Helpful Python, Stuart appears to be like at methods to manage the Home windows OS with Python.
Engaged on a Mac, we are able to management nearly all the things in regards to the system utilizing pyobjc, the Python-to-Goal-C bridge. Apple makes most of its OS controllable by way of the AppKit module, and pyobjc
provides Python entry to all of this. This will probably be most helpful if we already know the AppKit technique to do the factor we wish, however with a bit of exploration it’s doable to make our approach via the working system APIs.
Let’s strive an instance. First, we’ll want pyobjc
, which will be put in with pip set up pyobjc
. This may set up an entire record of working system API bridges, permitting entry to all types of features of macOS. For now, we’ll contemplate AppKit, which is the device used to construct and management operating apps on a Mac desktop.
We will record all of the functions presently operating utilizing AppKit:
Python 3.9.6 (default, Oct 18 2022, 12:41:40)
[Clang 14.0.0 (clang-1400.0.29.202)] on darwin
Sort "assist", "copyright", "credit" or "license" for extra 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 give an extended record of NSRunningApplication
objects. Every one corresponds to a selected software presently operating on the desktop. Many are “invisible” functions (issues which can be operating however aren’t essentially displaying a window), however others are issues that we would consider as precise functions that we are able to see—reminiscent of Safari, Terminal, and so forth. NSRunningApplication
is documented at developer.apple.com, the place its properties will be seen. For instance, 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 activate operate, which we are able to name to activate that app as if we had clicked its icon within the Dock. So, to seek out Safari after which activate it, we might use that activate operate. The decision to activate
requires a price for choices
, because the documentation describes, and that additionally 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 identify of one thing in Python that corresponds to the Goal-C identify could be a little difficult. As proven within the code above, the Goal-C activate
operate known as activateWithOptions_
in Python. There’s a algorithm for this identify translation, which the pyobjc documentation explains, however it could generally be faster to make use of Python’s personal dir()
operate to point out all of the properties of an object after which pick the one that appears most believable:
>>> print(len(dir(safari)))
452
Ouch! Our safari
occasion of an NSRunningApplication
has 452 properties! Effectively, the one we wish might be referred to as one thing like “activate”, so:
>>> print([x for x in dir(safari) if "activate" in x.lower()])
['activateWithOptions_', 'activateWithOptions_']
Aha! So activateWithOptions_
is the identify of the operate we have to name. Equally, the identify of the choice we wish to move to that operate is in AppKit itself:
>>> [x for x in dir(AppKit) if "ignoringotherapps" in x.lower()]
['NSApplicationActivateIgnoringOtherApps']
This course of can really feel a bit of exploratory at occasions, however it’s doable to do something that Goal-C can do from Python as effectively.
This text is excerpted from Helpful Python, obtainable on SitePoint Premium and from book retailers.