Knowing your Python scripting environment

My preferred learning method is to get a good example of how to do something and work on extending the example to do what I really want it to do. One of my favorite blogs I follow that let's me do this is @DrDrang's blog - And now it’s all this. Dr Drang has a recent series of posts on some of his screenshot automation methods (SnanClip / ScanSCP) along with a great primer on SSH keys to load screenshot images to his website.

Caveat: The good Dr Drang again beat me to the publish button on this exact topic.

So earlier this week I was working through his post on ScanClip and trying to replicate the process on my Mac. In a tweet that was way too late in the day,1 I asked in a frustrated tone about the Pashua module he used in his scripts.

@drdrang Pls add a footnote on how to get the Pashua module to load. Nothing I do can get Python to load the Pashua module.

— Jason Verly (@mygeekdaddy) February 28, 2017

I could run a test script from Terminal and load the Pashua module without any issues. Attempting the same test script in Keyboard Maestro would end up with an error similar to this:

Grrr.... so why does Terminal load the module and Keyboard Maestro won't?

After sleeping on the problem,2 I remembered that I actually have two versions of Python on my MBP. Apple has been notorious for not updating their built-in scripting environments in a timely manner.3 So I have been using a version of Python via Homebrew. So when I had to copy the Pashua.py module to my local Python environment, I copied it to my Homebrew version of Python. After realizing I had two versions of Python, I needed to see what version Terminal and Keyboard Maestro were using.

As expected, Terminal returned with the version of Python from Homebrew:

But looking at the environment from Keyboard Maestro, it returned this:

Bingo! Keyboard Maestro was using the default macOS version of Python. Since the Python version Keyboard Maestro was trying to use didn't have the Pashua.py module installed, the KM snippet borked out on my test script. After this discovery, I updated the script from Dr Drang and forced the KM snippet to use the Homebrew version of Python. The differences between the two scripts are startling.4

Dr Drang original script (top 15 lines):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/usr/bin/python

import Pashua
import tempfile
import Image
import sys, os, os.path
import subprocess
import urllib   
from datetime import date

# Parameters
dstring = date.today().strftime('%Y%m%d')
type = "png"
localdir = os.environ['HOME'] + "/Pictures/Screenshots"
....

MyGeekDaddy updated script (top 15 lines):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/usr/local/bin/python

import Pashua
import tempfile
import Image
import sys, os, os.path
import subprocess
import urllib   
from datetime import date

# Parameters
dstring = date.today().strftime('%Y%m%d')
type = "png"
localdir = os.environ['HOME'] + "/Pictures/Screenshots"
....

Simply changing the first line from #!/usr/bin/python to #!/usr/local/bin/python solved all my issues.


Update: In the scripts Dr Drang uses for his two KM snippets, ScanSCP uses a hard coded reference on what Python interpreter to use and ScanClip used the !#/usr/bin/env python. This was originally part of the problem I was struggling with because the script I originally started to look at was the ScanClip version. I switched over to the ScanSCP because I liked the idea of using scp to copy the clipped image to a folder on my website.

Dr Drang followed up on this post and pointed out:

@mygeekdaddy I will only add that if you use

#!/usr/bin/env python

you’ll also get /usr/bin/python in KM.

— Dr. Drang (@drdrang) March 2, 2017

This point wasn't obvious in my findings. The best practice is to use #!/usr/bin/env python in a Python script. However when you're scripting from inside Keyboard Maestro, using that statement to set your environment will refer back to the macOS default Python instance, and not the Homebrew version I'm normally using.


Keyboard Maestro

The KM snippet that I used to test the Python environment was:

KM will then use the built in notification tools in macOS to display the text.


  1. Or way too early. Hard to tell at 1:49am.  

  2. Which is what I should have done in the first place. 

  3. As of today, out of the box Python on macOS is 2.7.10, not the current 2.7.13. 

  4. Ok... not so startling.  



Previous posts:

  1. iOS Photo Merge for Pythonista 3

    One of the changes I've been trying to adopt with shifting more of my workflows to my iPad has been to also move to my scripting from Pythonista to Pythonista 3. The key here is the original Pythonista app used Python 2 as the core language, while Pythonista 3 ...

  2. Setting default Defer/Due time on iOS

    For many a geek, last week felt like an early Christmas. Apple released the lastest verion of iOS and many developers released updates to their flagship applications for iOS 8. [1] One of my most anticipated apps was Omnigroup’s update to OmniFocus for the iPad. The updated app hit ...

  3. Setting Default Defer/Due time in OmniFocus

    For many a geek, last week felt like an early Christmas. Apple released the lastest verion of iOS and many developers released updates to their flagship applications for iOS 8. 1 One of my most anticipated apps was Omnigroup's update to OmniFocus for the iPad. The updated app hit ...

  4. Terminal tips from Craig Hockenberry

    When you use a Mac everyday for your job, you want to find ways to do your work faster and more effectively. Craig Hockenberry (@chockenberry) has a great post on OS X command line tips. He has an extensive list of tips on how to make the most of the ...

  5. Update to Editorial FTP Image Upload

    I've been using Editorial (iTunes Link) as my primary editor due to the custom workflows you can create. One of my key workflows is my FTP Image Upload. I've finally got around to making some tweaks:

    • Image selection is now done with the iOS Photos image selector.
    • The ...
Top