Tuesday, April 4, 2017

Deploying Python Executables on Windows

Overview


Today I experimented with deploying self-contained python applications using WinPython , py2exe and cx_freeze.

cx_freeze seems to be more up to date since it claims to support python 3.5 and 3.6, but that is not as clear as it seems.  py2exe supports up to python 3.4.

My goal was to deploy a python application to a server without installing any software on it.

Update 4/13/17: After trying to build and deploy a real application I ran into a number of difficulties with py2exe and third party python packages (e.g. requests).  This has made me realize that cx_freeze is far more reliable and easier to use despite some minor limitations.

WinPython


WinPython is great because it is a python instance that doesn't require installation and is separate from any other python instance.  This is similar to virtualenv, but does not require running a python installer beforehand.

The benefits may not be obvious.  What it means is I can deploy as many WinPython folders to my server as I want without needing administrator rights to install python on the server.  In addition, the dependencies of each python instance are separate, so I can have two instances of python with different versions of the same package installed.

That way applications can have different dependent libraries and we never break an application that runs on one python instance by upgrading dependencies in a separate python instance.  This makes it easier to maintain Python applications in an enterprise environment.

py2exe

Py2exe transforms a python script into an executable program.  It supports Windows only.  As of this article's date (4/4/17) it only supports up to python 3.4.  

The benefit of py2exe is it compiled my simple program with very little configuration necessary.  With a few extra steps I got it to compile (mostly) into a single executable file, something cx_freeze doesn't support.  Having fewer files to will make deployment much easier.  For example, if a dependency changes I don't need to clear out the previous files first -- I only need to clear out the single executable.

cx_freeze

Cx_freeze is similar to py2exe in that it builds an executable program from a python script.  The advantage is it is cross-platform.  It can build executable files for MacOS, Windows, or Linux based systems.  It supports up to Python 3.6 as of this writing.  

When it comes to Windows, however, it requires the machine running your application to have the MSVCR (Microsoft Visual C++ Redistributable) package installed for instances of Python 3.5 or 3.6. 

Since my goal is to deploy python without installing anything on the server, I had to use Python 3.4. Recall that my goal is to deploy a python application with these restrictions:
  1. I only want to deploy to Windows
  2. I don't want to install anything to the server 
I would have to use Python 3.4 in order to avoid any installation.  That brings cx_freeze on par with py2exe in most cases.  Cx_freeze seems to be more configurable, which could be either good or bad depending on if you want simplicity (bad) or you have a complex use case to accommodate (good).  

One disadvantage of cx_freeze is it cannot package the application into a single executable file.  This means any deployment involves copying hundreds of files to the target location.

Conclusion

In the end I prefer py2exe to achieve my goal.  I like that it works out of the box without too much configuration and that I can get a single executable as a result.  

cx_freeze would be better for cross-platform applications or services.  Since my goal for this application is targeted for a Windows ecosystem this was not an advantage in my view.  That said, it wouldn't be too difficult to change my py2exe build to a cx_freeze build.  

Files and configurations can be seen in Screenshots 

Update 4/13/17: after trying unsuccessfully to get py2exe to include some rather simple packages, cx_freeze was able to build an executable with no issues.  I would recommend anyone trying to package python into windows executables to use cx_freeze instead of py2exe.  


No comments:

Post a Comment