Creating python binaries and updating those binaries is a vital part of a good application. When a user is required to go out of their way to download a seperate binary and install it (or worse, manually overwrite it), it worsens the experience.
As such most users would prefer if their applications updated automatically without them having to do anything (or at least offer a simple button to update). This guide aims to provide an example on how to do just that.
Since we're distributing apps to our users, ideally we don't just send them a
.py file. For that purpose we are going to use pyinstaller. This will allow us to bundle our script into an executable file (that works even if they don't have python 😀).
Let's install all the required packages so we can work start working:
pip install pyinstaller pip install flask
To keep things simple our app will just print out it's current version. We'll create a file called
myapp.py, with the contents:
app_version = "1.0.0" print(app_version)
We'll change the variable
app_version by increasing the version number to emulate how an update would change the behaviour of the script.
In keeping with the spirit of python, we'll use flask to build the update server.
Let's create a failed called
server.py with the content:
from flask import Flask, send_from_directory app = Flask(__name__) @app.route("/app") def download(): return send_from_directory(".", "myapp.exe")
Note, I used
myapp.exe here since I'm doing this on windows, and that is what pyinstaller will generate, replace that with whatever your correct filename is.
In order to run flask, we first need to set the environment variable
FLASK_APP to the name of your server file (without .py). This is OS specific, so set the environment in the terminal in whatever way the OS supports it. Then launch the flask app with
flask run. e.g., for windows it would be:
$env:FLASK_APP="server" flask run
The updater script is what will actually download the latest version, and launch the app. Let's create a file called
import requests import os url = "http://localhost:5000/app" r = requests.get(url) open("myapp.exe", "wb").write(r.content) os.startfile("myapp.exe")
In order to be able to share our python app, we need to create an executable that will work regardless if the user has python or not.
pyinstaller --onefile myapp.py pyinstaller --onefile updater.py
Running this will create two executables in the
dist folder. We want to give our users the
updater.exe (on windows), which will download and execute
myapp.exe (our actual app).
myapp.exe into the root directory of where the server is, so going to
localhost:5000/app will download it.
updater.exe to a new empty folder and run it. Make sure the server is running!
You will se a new
myapp.exe appear, and start. We've just pulled downloaded the latest version of the app 🙌
Next let's try updating it. Increase the version in
myapp.py and recompile it with
pyinstaller --onefile myapp.py, and move the
myapp.exe into the root folder of the server.
updater.exe again... it redownloaded our app, and it's the latest version!
We've just implemented updating into our app 🎉
Of course this was just a simple example, meant to illustrate the steps required to implement updating into your app. Ideally we wouldn't download the whole
myapp.exe everytime, but rather use a versioning system to check if an update is even needed.
Hopefully now that you've seen a small example on how to implement updates into your apps, you'll consider this as a way to improve the user experience of your app.
While in this guide we had to setup everything, from the update logic to the server. We didn't really need to do all of this. Since this is such a common issue, we built pakkly, a service that hopes to make updating and installing (thats a topic for a future post 😀) seamless and easy.
Regardless if you decide to check out pakkly, hopefully this guide was useful to you, thanks for reading and stay tuned for more!