on this fast tip, excerpted from useful python, stuart seems to be at methods to manage the home windows os with python.
engaged on a mac, we will management nearly every part concerning the system utilizing pyobjc, the python-to-goal-c bridge. apple makes most of its os controllable through the appkit module, and pyobjc
provides python entry to all of this. this can be most helpful if we already know the appkit method to do the factor we wish, however with just a little exploration itβs doable to make our means 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 a complete record of working system api bridges, permitting entry to all kinds of facets of macos. for now, weβll think about appkit, which is the instrument used to construct and management operating apps on a mac desktop.
we will record all of the functions at present 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 data.
>>> 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. each corresponds to a particular software at present operating on the desktop. many are βinvisibleβ functions (issues which are operating however arenβt essentially exhibiting a window), however others are issues that we’d consider as precise functions that we will seeβcorresponding to 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 perform, which we will name to activate that app as if we had clicked its icon within the dock. so, to search out safari after which activate it, we might use that activate perform. 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 title of one thing in python that corresponds to the goal-c title generally is a little difficult. as proven within the code above, the goal-c activate
perform is named activatewithoptions_
in python. thereβs a algorithm for this title translation, which the pyobjc documentation explains, however it will probably generally be faster to make use of pythonβs personal dir()
perform to indicate 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 title of the perform we have to name. equally, the title of the choice we need to go to that perform is in appkit itself:
>>> [x for x in dir(appkit) if "ignoringotherapps" in x.lower()]
['nsapplicationactivateignoringotherapps']
this course of can really feel just a little exploratory at instances, nevertheless itβs doable to do something that goal-c can do from python as properly.
this text is excerpted from useful python, accessible on Pylogix premium and from book retailers.