Getting Up To Speed With Pythonista
I am a Systems Engineer with 20+ years experience as a Software Engineer (I have discounted my last 15 years as a Systems Engineer as I have had little opportunity to write any software).
I recently found myself needing (or wanting!) to write some code to simplify a task I was undertaking for the choir of which I am a member and, despite previously learning Ruby, chose to learn Python. I used SoloLearn’s Learn to Code with Python iOS app to introduce me to the language and subsequently used Exercism to start developing my Python skills. I hosted the Exercism exercises within Dropbox so I could work on them both at home and during my work lunchbreaks.
However, that wasn’t enough and I decided I wanted to be able to code on the go, using my iPhone or iPad when nothing else was available. For that I needed a decent code editor and chose Pythonista based on its review ratings, integration with Dropbox, etc.
On paying my dues, I discovered the integration was of the self-help variety where the user had to download and install Python scripts. The questions then were which scripts and how do you download and install them?
The Pythonista Community Forum
The Pythonista Community Forum is one place to ask questions. It provides answers, often without you having to ask your questions as others have been there before you. However there are a lot of topics and it doesn’t always seem easy to find the right ones or to pick the ones with the best answers.
Installing Python Scripts and Packages
Now I might be being dense and rather lazy, but to the uninitiated it doesn’t feel very intuitive when you are first trying to install scripts and packages. So, just in case there are others out there who want more power to their Pythonista elbow but feel at a loss as to how to get it, I thought I would document how I got going.
Really what I wanted was to be able to sync the development of my Python scripts between iPhone, iPad and PC. For me the obvious solution was to use Dropbox. By digging around I found a number of scripts that worked with Dropbox but at the time of writing I could only find two that worked with the new Dropbox API v2, and only one of them actually promised to sync Dropbox files rather than just import them: Mark Hamilton’s Synchronator. It comes with instructions but they include references to Stash and the Dropbox Python package. So below is how I got the Synchronator working.
StaSh stands for Pythonista Shell and is a serious attempt to implement a Bash-like shell for Pythonista.
That’s nice, but why do I need it? Well, probably for a number of reasons but in this instance to provide access to the Python package manager pip to ensure the latest version of the dropbox Python package is installed.
pipcan be run from within Pythonista without installing StaSh (see Installing Python Modules), but StaSh has so many other useful features it seems to get recommended quite regularly in Pythonista Community Forum topics.
To install StaSh from within Pythonista, swipe left to show the console panel, paste at the ‘>’ prompt at the bottom of the screen the one line Python command provided in the StaSh README.md on GitHub and press return. Currently that command is:
import requests as r; exec(r.get('http://bit.ly/get-stash').text)
Once StaSh is installed, restart Pythonista, tap
≡to reveal the library pane and tap on
launch_stash.py. This will load the file into the middle editor pane. Tap
▷to run the script. This will take you to the console pane where StaSh will be running and you should see the
If you haven’t just installed StaSh, it is worth ensuring it is up-to-date. This can be achieved from within StaSh with the
Pythonista comes with a number of Python packages already installed as Pythonista Modules. These can be found in the library pane under
Modules & Templates/Standard Library (2.7)and
Modules & Templates/Standard Library (3.5). However, performing a
pip updatefrom StaSh will not work. Further, the
Modules and Templatesfolder is not visible from within StaSh, so I can only assume it is installed as part of Pythonista and not something the user can modify. Consequently a
pip installis required.
Along with the
Standard Library*folders, the
Modules and Templatesfolder includes three
site-packagesfolder is included in the default import path of both Python interpreters (2.7 and 3.5), so that you can put reusable modules there. The
site-packages-3folders are for modules that are not compatible with both Python versions. It is worth noting that site packages will not be reloaded automatically when you run a script. This is different from modules in other user directories, so you should typically only put modules here that you don’t intend to change, presumably including packages.
Installing Packages with StaSh
By default StaSh does not appear to put packages in any of the
site-packagesfolders. Maybe that is by design, but I think I would rather I could find them easily. Consequently I have chosen to direct the installation using the
pip install -d <DIRECTORY> <PACKAGE>option. The next question is which folder to use. The dropbox package is compatible with Python 2.7 and 3.4+ so it would make sense to install it in
site-packages, though if you were only ever going to use one version of Python it could be installed in one of the other two folders.
Installing the Latest Version of the Dropbox Package
After an initial abortive attempt, I have been advised a number of packages need to be updated in order to get Synchronator working, not just the dropbox package. These are:
These are all compatible wih Python 2 and 3, and can therefore be installed to
site-packagesfrom the StaSh prompt. However there currently appears to be an issue with StaSh’s implementation of
pipthat can cause it to install the wrong versions of packages. Therefore I suggest you use the links above to identify the current versions of each and specify the version as follows:
pip install -d ~/Documents/site-packages <package>==<version>
In order to install the latest versions available at the time of writing use the following commands in the order specified:
pip install -d ~/Documents/site-packages chardet==3.0.4 pip install -d ~/Documents/site-packages dropbox==8.4.0 pip install -d ~/Documents/site-packages idna==2.6 pip install -d ~/Documents/site-packages certifi==2017.7.27.1 pip install -d ~/Documents/site-packages urllib3==1.22 pip install -d ~/Documents/site-packages requests==2.18.4
So now we can follow the Synchronator installation instructions provided on GitHub. It is worth noting I tried using the Clone iOS App and found quotation marks and inverted commas were being changed by the App which corrupted the Python scripts. I have reported the issue but in the meantime have found the iOctocat Git repository client for iOS works fine as a replacement. The current instructions are:
- Inside [a suitable git client] that is able to access [the markhamilton1/Synchronator] GitHub project, I select and copy the entire contents of the file DropboxSetup.py.
- Switch to Pythonista and create a new Python file.
- Paste the contents of DropboxSetup.py into the new Python file.
- Change the name of the new file to DropboxSetup.py.
- Switch back to [the git client] and select the Synchronator.py file and copy the entire contents of it.
- Switch to Pythonista and create a new Python file.
- Paste the contents of Synchronator.py into the new Python file.
- Change the name of the new file to Synchronator.py.
- Go to the Dropbox Developers Page.
- Create an App using the Dropbox API (NOT the Dropbox Business API).
- Select the App Folder option.
- Enter the name of your “App”. I suggest something like “Synchronator-JohnDoe”. Your App name MUST be unique.
- Select the Create App button. This will take you to the App Properties page.
- Find the property “Generated Access Token” and select the Generate button.
- Select and copy the generated Access Token to the clipboard.
- Switch back to Pythonista and execute
Synchronator.pyin Pythonista on your iOS device.
- Paste the Access Token at the prompt and hit enter.
At this point Synchronator will download the files from your App Folder on Dropbox (which is presumably empty) and then upload to your App Folder any scripts that you may have in Pythonista.
Works for me!
There is a problem with the way StaSh
piphandles installing minimum versions. I have raised an issue on GitHub (see Pip installed wrong version of urllib3). To get round the problem, check the latest version of the package you are trying to install using PyPI - the Python Package Index and install that version using:
pip install [-d <directory>] <package>==<version>
And if a package gets installed as a dependency for another, check its version and if it is wrong perform a
pip removeand install the correct version.
I am documenting exactly how I am getting this to work and, once it does, I will post it on this forum.
@JonB I killed and restarted Pythonista and got:
>>> import requests /private/var/mobile/Containers/Shared/AppGroup/77E4F4DB-EDA3-49C3-8AAD-D4452754B812/Pythonista3/Documents/site-packages/requests/__init__.py:80: RequestsDependencyWarning: urllib3 (1.4) or chardet (3.0.4) doesn't match a supported version! RequestsDependencyWarning) Traceback (most recent call last): File "<string>", line 1, in <module> File "/private/var/mobile/Containers/Shared/AppGroup/77E4F4DB-EDA3-49C3-8AAD-D4452754B812/Pythonista3/Documents/site-packages/requests/__init__.py", line 90, in <module> from urllib3.exceptions import DependencyWarning ImportError: cannot import name 'DependencyWarning'
Did some more digging and found that StaSh had installed urllib3 version 1.4 whereas the latest version is 1.22. Fortunately I am still at the beginning of my journey with Pythonista so I have deleted and reinstalled it. I will try again.
@Phuket2, I am probably as much out of my depth as you are. I’m new to both Python and Pythonista. Your point about being able to get back to a known state is a good one. I have also discovered the "Modules and Templates" folder is not visible from within StaSh, so I can only assume it is installed as part of the App and not something the user can modify. Presumably the site-packages folders appear first in any search path so user-installed packages are found first.
I know I can use StaSh to perform a
pip installbut would it therefore make sense to delete the relevant packages in "Standard Library (2.7)" and "Standard Library (3.5)" or would they just reappear if Pythonista gets updated? I presume the Standard Library is last on the search path so packages subsequently installed will be picked up in preference.
Pythonista indicates in its documentation it includes some third party modules including "Dropbox for Python" and "Requests - HTTP for Humans". I've found them in "Standard Library (3.5)/site-packages". So how should I go about updating them? Installing Python Modules indicates you can use
python -m pip install --upgrade SomePackagefrom the command line but when I try updating dropbox I get:
>>> python -m pip install --upgrade dropbox File "<string>", line 1 python -m pip install --upgrade dropbox ^ SyntaxError: invalid syntax
When I use StaSh with the command
pip update dropboxI get:
[~/Documents]$ pip update dropbox Error: package not installed: dropbox [~/Documents]$
So how do I go about updating them? And do I have to check all the"Standard Library (3.5)" modules before performing a
pip installin case the package I'm trying to install is already available?