How to remotely update Python applications
Asked Answered
B

4

33

What is the best method to push changes to a program written in Python? I have a piece of software that is written in Python that will regularly be updated. What would be the best way to do this? All the machines will have Windows 7.

Also, excuse the ambiguity of my question. This will be my first time having to implement an updating procedure. Feel free to mention specifics you would like me ot add.

Bleed answered 3/8, 2011 at 19:50 Comment(2)
are you currently packaging up your application for installation/distribution? Is it just a script file? Does the application code need updating or are you just talking about fetching data updates from the web?Coercion
similar: https://mcmap.net/q/453474/-auto-updating-a-python-executable-generated-with-pyinstallerFeverfew
P
23

If you're not already packaging your program with InnoSetup, I strongly recommend you switch to it, because it has facilities to make this sort of thing easier. You can specify any special situations, such as files that should not be updated if they already exist (i.e. if you have any internal configuration files or things like that), in the InnoSetup script.

Next, to allow the client machine to find out about new versions of your app, keep a very small file on your public web server that has the version number of the current release and the URL to the latest version's installer exe. For this file to be useful, whenever you release a newer version of your program you must update this file, as well as the version number in the InnoSetup script, and also some kind of APP_VERSION constant in your program.

Then, you'll need to handle these parts of the updater yourself:

  1. Detecting when a newer version is available by retrieving the current-version file from your web server over HTTP, and comparing the version number there to the app's own APP_VERSION. Make sure to do this query in a way that fails gracefully if the client machine doesn't have Internet access, and that doesn't block the GUI while it is doing the request (in case there's a network issue that forces the query to wait a long while for a timeout).
  2. If a newer version is available, asking the user if they want to update, and if they say yes downloading an updated installer to the TEMP directory. Depending on what GUI toolkit you are using, there are various mechanisms for displaying a progress dialog during the download; this is a good idea since the installer is likely to be at least an MB.
  3. Closing your app, running a special update script in the background, then starting up the app again.

The update script will wait for the original process to die completely (easiest way to do this is to pass in the original process's PID as a command line argument and have the update script send a query signal 0 to that process every second or so until it goes away.) It can then run the installer silently in the background, perhaps while displaying a "Please Wait..." dialog to the user. Once the installer is done and reports success in its return code, the updater can restart your program.

Depending on how big your app is, this is more wasteful of bandwidth than the method using git or another SCM. Every update with this approach would involve downloading the entire installer for the latest version of the app, whereas an SCM would only download the files that have changed. However, it has the advantage that it requires no special server facilities except a regular web server, and no special installation of the SCM client on the user's computer.

Plus, InnoSetup is just generally cool. :-)

Postman answered 4/8, 2011 at 1:38 Comment(1)
Another more technically sweet way to check if your existing app is still open or not, is to have your app obtain a read lock on a temp file with a pre-determined name whenever it is running. This is cool because it avoids an unlikely but possible race condition scenario where your app frees its PID but another new app immediately takes that same PID. It also would prevent the user from starting multiple instances of your app, which could confuse the updater.Postman
B
8

I would suggest using a source control program such as git or subversion. Also, if you are okay with everyone seeing the code, you can post the code on github, where anyone can pull from it. You could make it private, but you would have to pay for it and all the users would also have create a github account and set it up with their git install.

If you use a source control program, the other people will have to pull the edits manually by running a command, but you could make a script pr batch file that does this and have it run at start up or at regular intervals.

Just to be clear, if you want to do this, you will have to put the code on a server with and SSH support and set up git. If you don't want to go through all of the server set up, I would reccomend github.

git- http://git-scm.com/ (For windows version, go to downloads and select msysGit)

github - https://github.com/

Bozo answered 3/8, 2011 at 22:9 Comment(1)
Neil is spot-on here. Mercurial and git would both be good options, and you could easily write a short 'auto-update' script that gets called every x days and just pulls the latest version of the repo.Lemuel
D
3

For those of you that would be looking into something a little less dated, I was just looking at how to create python applications that can be updated remotely (though not limited to Windows like OP).

It seems like esky as been a solution for a while. Though it's been deprecated since 2018.

The latest and most up to date solution seem to be a combination of pyinstaller and pyupdater. Note that I don't have personal experience with it, I'm looking for a friend.

It seems to support windows, linux and Mac though and both python 2 and 3 so definitely worth having a look.

Demon answered 25/11, 2019 at 8:19 Comment(1)
This is a recommended modern answer.Ferment
F
2

The basic principles of application updates are described well by DSimon's answer.

However, update security is a different matter altogether: You don't want your clients to end up installing malicious files.

PyUpdater, as suggested in jlengrand's answer, does provide some secure update functionality, but, unfortunately, PyUpdater 4.0 is broken and there has not been a new release in over half a year (now Aug 2022).

There's also python-tuf, which is the reference implementation of The Update Framework (TUF). TUF (python-tuf) does everything humanly possible to ensure your update files are distributed securely. However, it does not handle application-specific things like checking for new application versions and installation on the client side.

Update 2023: PyUpdater is no longer maintained. The project was archived on Sep 26, 2022. To provide an alternative, we created a layer on top of python-tuf to handle the application-specific parts. This replacement for PyUpdater is now available as tufup.

Feverfew answered 1/8, 2022 at 11:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.