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. View Footer/Header in Word 2016

    This post is more for me to have a public reference point when I have this problem again. 1 Out of the box, Word 2016 for macOS has a problem of not showing the header or footer when you create a new document.

    For the longest time I was trying ...

  3. iPad vs Mac (for the power user)

    Sometimes a great idea isn't your own. And lately another engineer has been beating me to the punch on my ideas. Dr. Drang (@DrDrang) has a recent post that covers the next area I was looking at in my iPad experiment - the power of the iPad vs the Mac ...

  4. The Case of the iPad Experiment

    When I started thinking about going iPad only, I knew typing only on the screen keyboard was not going to be an option. My previous iPad was a Clam Case keyboard case and I knew I wanted something similar again. While the first Clam Case took it's share of ...

  5. Accidental iPad Experiment

    Sometimes you go out to try something new. Other times you're backed into a corner to adapt to a changing situation. A couple of months ago my MBP died. I didnt' panic1 about not having a computer because I still had my iPad and my work MBP. My ...

Top