Package management in Python is considered excellent, compared to other programming languages. And I agree with this popular opinion.
The problem that these package managers solve is the dependencies issue. What they don't solve though is how to keep those dependencies updated regularly. While developing your web app, when you decide that you will use a new library you will most probably install the latest version at the time. But over the app's lifetime, those libraries you decided to use must remain updated to ensure that the web app is working properly and securely.
Most Python apps, keep a
requirements.txt file to keep track of all the dependencies. This is a good practice in general. The next step is to keep the dependencies mentioned in
requiements.txt to their latest version.
The manual way
The most obvious way is to go through each one of your dependencies and check PyPI for the latest version. This is a slow process but gives you complete control over what is updated and what stays the same (for instance libraries that have a high risk of breaking the app).
An alternative way in case you using an IDE is if they have a built-in mechanism to indicate which libraries are outdated. For instance, in PyCharm you can update to the latest version using a one-click (per library) approach.
The automated way
There's a Python utility, called Pur, that offers to bring all the dependencies listed in
requirements.txt to their latest version. Just
pip install pur and you are ready to get started!
After installing, just run:
pur -r requirements.txt
The utility will list the changes that have been made for you to review:
Updated whitenoise: 5.1.0 -> 6.3.0
Updated stripe: 2.50.0 -> 5.0.0
Updated sentry-sdk: 1.5.12 -> 1.13.0
All requirements up-to-date.
The utility offers a few more interesting options for common use cases. For instance, if you use an LTS (long-term support) version of a package, you can use the
--minor MY_PACKAGE argument to ensure that only the minor version will be updated. Additionally, you can use the
--interactive argument for the utility to ask for each dependency whether to update to the latest version (instead of reviewing the changes afterward). Check the official website for a full list of arguments available.
Now there's no excuse to keep your Python web app out-of-date. With a single command, you can use the latest versions of your dependencies. Of course, whether the app breaks due to the usage of a newer library is a different story. Having excellent test coverage mitigates this issue but discussing this is outside of the scope of this post.
Hopefully, you can now easily and quickly keep your Python projects fresh.