Keyboard Maestro Macro Call From A Python Script

I have a macro called Compress PDF that is in a macro group i) called __Finder and ii) is only available in Finder.

I have a second macro called Process PDF that is in a macro group i) called __Downloads and ii) is available in all applications.

In the previous iteration of the Process PDF I was able to successfully call Compress PDF using the below Keyboard Maestro even though Compress PDF is only available in Finder.

In the current refactored iteration of Process PDF I am trying to call Compress PDF from within a Python Script but cannot get Compress PDF to whether simply call it by name or by using a (AppleScript , Keyboard Maestro CLI, Python Script or other) trigger.

It appears that the 'block" is that Compress PDF is only available in Finder because when I have the Python Script first activate Finder and then call Compress PDF, the macro fires.

The related questions are:

  1. Is my testing / understanding correct that the block in firing Compress PDF from a Python Script with Process PDF is Compress PDF's requirement that Finder be active and, if not , why not.

  2. What is the explanation / reason that Process PDF can successfully call Compress PDF using a Keyboard Maestro action but cannot do so with on Python Script? I would love to understand the difference and the reason!

  3. What is the optimal method / workaround for Process PDF's Python Script to successfully call Compress PDF not in the best idea I came up with (which is essentially to build a bridge between Process PDF and Compress PDF) was as follows:

    a. Create a third macro called Call Compress PDF in the __Downloads macro group.

    b. Have Process PDF's Python Script call Call Compress PDF with the appropriate parameters which should work because they are in teh same macro group.

    c. Have Call Compress PDF call Compress PDF with the appropriate parameters which should work because either is from a Keyboard Maestro.

  4. What method -- if any -- exists for Process PDF's Python Script to directly and successfully cl Compress PDF?

Much thanks.

Yes, generally macros can only be triggered if the are enabled and active. There are some occasional exceptions, which generally require that the macro be very explicitly specified.

I believe you outlined the correct solution, but I will put it my way. If you want to execute a macro and have it do things, that macro should be enabled and active. So:

  • Have the macro that does stuff permanently enabled and active.
  • Have the macro that is triggered with conditional activation execute the first macro.
  • Have the external script run the first macro.

Appreciated and makes sense.

Is my understanding correct that the Keyboard Maestro actions such as Execute Macro bypass the Active requirement?

If yes, what other Keyboard Maestro actions bypass the Active requirement?

Thank you.

It's my understanding (and I'm sure I'll be corrected if wrong!) that it is the macro's Triggers that are enabled/active or otherwise. And 99% of the time you call them by Trigger -- including the script Triggers you listed, hot keys, and so on through the list on the Wiki.

Notably absent from that list are the "Execute a Macro" Action and the Editor's "Run" button and, even though they give %Trigger% values when tested, both ignore any enabled/active criteria.

If you want a crazy extra method -- use an osascript call in your Python script to execute the XML of the "Execute" Action. The AppleScript would be:

set theXML to "<array>
	<dict>
		<key>Asynchronously</key>
		<false/>
		<key>MacroActionType</key>
		<string>ExecuteMacro</string>
		<key>MacroUID</key>
		<string>7D220027-3554-4C6C-8FA7-06AEB656A400</string>
		<key>TimeOutAbortsMacro</key>
		<true/>
		<key>UseParameter</key>
		<false/>
	</dict>
</array>"

tell application "Keyboard Maestro Engine"
	do script theXML
end tell

...changing the UUID to match that of your "Compress PDF" macro.

But much easier to ensure you're in the right context in the first place :wink:

@Nige_S

Fantastic, I greatly appreciate the above which confirms my testing.

I agree that the correct path is to ensure that I am in the correct context and have adopted Peter's master / worker approach to ensure so. To do so I:

  1. Created Call Compress PDF in the __Finder macro group that replicates Compress PDF's hot key tiggers.

  2. Moved Compress PDF to an always active macro group (i.e., no more Finder active restrictions) with no hot keys.

  3. With the changes:
    a. I can now call Compress PDF directly from my Python Script.
    b. I have preserved the __Finder (and, for that other matter, all other macro group's) use of Compress PDF's previous hot keys.

This is lesson you taught me about being able to call macros from different methods, spot on. Your challenge is not forgotten and next up! :grin:

Much thanks!

Basically, you should consider this undocumented behaviour.

If you ask to execute a macro that is inactive, you should expect it to fail, but it might not. If it doesn't fail, it might in a different version of Keyboard Maestro.

Basically, my recommendation is "don't do that", and as such there isn't a documented answer to your second question.

1 Like

Agreed, appreciated and apologies for tripping over this, I did not mean to cause any issues.

I have adopted your worker / trigger model to make sure everything works as it should based on being enabled and active.

UPDATE I found a solution which seems to work per the below.

tell application "Keyboard Maestro Engine"
    do script "<dict><key>MacroActionType</key><string>Notification</string><key>Text</key><string>..." & message & "...</string><key>Title</key><string>Keyboard Maestro</string></dict>"
end tell

1 Like