How-To Package and Release a Python Program
Introduction
I write lots of Python scripts for my own use. Someday I’d love to write them for the use of other people: I’d love to have an installer that people could download and install an executable version of my scripts for their own use. I’d love if it could work on Windows or Linux. I’d love it if I could figure out what licenses I would need to cite to keep everything nice and legal and friendly.
So, what I’m going to do is kill two birds with one stone: I’m going to create a template command-line project that has all of the neat stuff I talked about and will serve as the basis for whatever new script I dream up. Then, whenever I have an idea, I just have to export my generic project into a new folder, customize it and initialize a new git repo on top of it, then I’ll have a nice command-line utility that does whatever I want that has all of the bells and whistles.
Template Project
I’ve already started the template project here.
Executable Generation
I’m going to use PyInstaller to generate my executables. See my article on generating executables from Python scripts here.
PyInstaller leaves me with one file for my output: pyCli.exe
That’s muy bueno.
Installation
Installation is going to follow a two-pronged path: Windows and Linux.
But first, what directory structure do we use for the installation folder?
The program itself will be just an executable file, but there will be lots of other things that I want to include (manuals, config files, etc.)
What I think I’m going to do is put the exe into the root of the install folder, then have multiple subdirectories. The ones I can think of at the moment are:
- logs - For any log files
- cfg - Configuration files
- res - Resources such as graphics, database files, etc.
- docs - For any documentation and license files
Windows Installation
I’m going to use NSIS for generating a Windows installer.
Windows Installation Path
I need to figure out where to install the software so that I don’t have to worry too much about admin privileges.
My first instinct is to install it somewhere in the user directory because that doesn’t require admin privileges. One issue with that is that no other users other than the one who installed it would be able to use the application. The other is that there doesn’t seem to be a standard location within the user directory to install things. I know that Python did that on my work machine when I didn’t have admin privileges.
There’s a question about it on superuser.com with various answers:
- C:\Tools - I’ve seen some machines have permissions issues with placing anything in the root folder the same as they might with Program Files
- C:\Users\Steven - Given that this is just the user folder, so
- C:\Users\Steven\AppData - This folder is supposed to be for data, not full program installs. Nevertheless, some applications install themselves here for one user
- C:\Users\Steven\AppData\Microsoft\Installer<ProductId> - This is apparently where applications with MSI installers will install their application when installed for the current user only. I think I’ll pass
Given all of these options I think I’m just going to use Program Files.
Of course, there’s a rub - do I install in the x64 Program Files directory, or the x32 version?
I don’t for sure know if my Python installation is x64. I don’t know if all of my libraries that I use are. I also don’t really know the difference between installing the program in either of those two locations: will the Microsoft Police come and arrest me if I put an x32 program in the x64 Program Files directory?
I’m just going to use the x32 Program Files directory. Because I hate thinking too hard about decisions.
NSIS Script
I need an NSIS script to generate the installer. I had an article that I wrote about that here
One of my first problems is where to put the install script. What subdirectory?
The issue is that NSIS usually puts the installer executable into the same directory as the install script. You can change this configuration, but it still begs the question: Where does the script go and where do the installers go?
I’d like the installers to all go in one directory so I can .gitignore it, but the script?
I think I’ll have an ‘install’ subdirectory where I can put the installers and an ‘nsis’ subdirectory which includes the script.
I’m going to copy the script that I started there and modify it below:
Linux Installation
I’ll probably use a makefile of some sort.