Drop-in application self-upgrade checker and vulnerability auditor
Project description
do_i_need_to_upgrade
Do your users need some way to know that your python application has published a new version?
A drop-in Python library that gives any application zero-cost background update checking, vulnerability auditing, and self-upgrade capabilities.
This is optimized for applications with end users, not so much for libraries. For that people should use their favorite package manager's features.
Features
- Stdlib-only PyPI client — no httpx, no requests, no urllib3
- Background check — daemon thread + atexit notification (zero cost to startup)
- JSON sidecar cache with configurable TTL and per-package snooze support
- 14-day cooloff window — suppresses alerts for brand-new releases
- Prerelease & yanked version detection
- Vulnerability auditing — uses
uv audit,pip-audit, orsafetyopportunistically - Self-upgrade — detects install method (uv tool / pipx / venv pip) and runs the right command
- Color ANSI output — respects
NO_COLOR,CI,TERM=dumb, and TTY - Generic Host protocol — drop it into any app with two lines
Installation
pipx install do_i_need_to_upgrade
Or with uv:
uv tool install do_i_need_to_upgrade
Quickstart
from do_i_need_to_upgrade import check_for_updates, GenericHost
host = GenericHost(dist_name="my-app") # cache defaults to the per-user cache dir
# Zero-cost background check; notification appears when program exits:
check_for_updates(host=host, position="start")
The background check is designed for long-running applications: the
refresh runs on a daemon thread, so the process must stay alive a few seconds
for the result to land in the cache. Short-lived CLI apps should use
position="end" (refresh after doing their real work) or "both".
Integrating into your app
Add a my-app upgrade subcommand to an existing argparse CLI in three lines:
import sys
import do_i_need_to_upgrade as diu
subparsers = parser.add_subparsers(dest="command")
diu.add_upgrade_command(subparsers, dist_name="my-app") # adds `my-app upgrade`
# ... your own subcommands ...
args = parser.parse_args()
if (rc := diu.run_if_upgrade_command(args)) is not None:
sys.exit(rc)
diu.add_check_command(...) adds a check-updates subcommand the same way.
For long-running apps, the whole feature is one line at startup:
diu.install_background_check("my-app") # cached check + exit notification
Behavior is configured with a Settings object, or shipped as defaults in
your pyproject.toml:
[tool.do_i_need_to_upgrade]
position = "start" # start | end | both | off
notify = "exit-message" # exit-message | return-only
cooloff_days = 7
check_ttl_hours = 24
check_dependencies = false
index_url = "https://pypi.example.com/pypi/{name}/json" # private index (https only)
Load with Settings.from_pyproject("my-app") (dev) or
Settings.from_toml(path, "my-app") (e.g. package data shipped in your wheel),
and pass settings= to any API function or the integrate helpers.
Want to minimize dependencies?
For lean host apps, there are two recommended integration paths ( see docs/usage/vendoring.md):
- Optional extras in the host app — keep
do_i_need_to_upgradeout of the base install and offer it behind something likemy-app[all]. The app should quietly skip update-check integration when the extra is not installed. diu_lite.pyvendoring — a generated, stdlib-only, single-file build (make build-lite) exposing exactly one function:check_for_updates("your-dist") -> str | None. Zero dependencies, MIT, ~350 lines, honors the same kill switch.
End-user kill switch
Apps embedding this library phone home to PyPI, so end users always get the last word, regardless of app settings:
DO_I_NEED_TO_UPGRADE=off— disable checks entirelyDO_I_NEED_TO_UPGRADE=no-network— cache only, no fetches~/.config/do_i_need_to_upgrade.toml(or%APPDATA%\do_i_need_to_upgrade.toml):disabled = true,no_network = true, ordisabled_for = ["some-app"]
Precedence: environment variable > user config file > app settings > defaults.
(On Python 3.10 the TOML config files are ignored — tomllib is stdlib from
3.11; programmatic Settings work everywhere.)
CLI
diu is a short alias for do_i_need_to_upgrade — same command.
diu --help
diu check # self-check: this dist + direct deps
diu check ruff black yt-dlp # check other apps, wherever installed
# (current env, uv tool, pipx, or PATH)
diu check -r requirements.txt # check everything in a requirements file
diu watch add yt-dlp # persist names to a watch list
diu check --watched # check the whole watch list
diu check --watched --quiet # exit code only — cron/prompt friendly
diu upgrade # self-upgrade via detected install method
diu upgrade ruff # upgrade another app via ITS install method
diu status # show cache without network
diu audit # vulnerability scan
diu snooze ruff==0.4.4 --days 30
diu clear-cache
diu integrity-check
Exit codes (script-friendly):
| Code | Meaning |
|---|---|
| 0 | Up to date / success |
| 1 | Error, or integrity problems found |
| 10 | Upgrades available (check) |
| 11 | Vulnerabilities with available fixes (audit) |
do_i_need_to_upgrade check --no-network || echo "time to upgrade"
Prior Art
The vast majority of tools in this space are for checking if any app or library in your virtual environment needs upgrading. Those tools are aimed at developers, build masters, etc. do_i_need_to_upgrade is aimed at being included in an application where a non-technical user can get a signal that the app is out of date and possibly do something about it.
Prior art for Application and Artifact Update Checking
-
autoupgrade is close historical prior art for an application importing a library that checks PyPI and performs an unattended upgrade, for example
AutoUpgrade("pip").upgrade_if_needed(). It appears old/stale and does not represent the modern installer-aware model needed forpipx,uv tool, PEP 668 externally-managed environments, editable installs, and other install contexts. -
selfupdate is a library for updating scripts that live inside a git repository by pulling changes from the remote repo. It is git checkout self-update prior art, not PyPI/package-manager-aware upgrade prior art.
-
PyUpdater, Esky, tufup, and notsotuf are artifact updaters for frozen, bundled, or standalone Python applications. They fetch and apply application artifacts directly, often bypassing PyPI package-manager flows such as
pip,pipx, anduv tool. They solve a related but different problem and are intentionally out of scope for package-manager-aware PyPI app self-update.
Prior Art for Library and Package Update Checking for Build Masters
-
pip is the baseline Python package installer. It can check for outdated installed packages via
python -m pip list --outdatedand upgrade packages viapython -m pip install --upgrade <package>, but it is not an application-embedded self-update helper and does not detect whether a CLI was installed bypipx,uv tool, an editable checkout, an OS package manager, or another frontend. -
pipx installs Python CLI applications into isolated virtual environments and exposes their console scripts on
PATH. It is one of the main package-manager targets this project should detect. Forpipx-installed apps, the correct upgrade command is generallypipx upgrade <app>, not an in-processpip install --upgrade. -
uv /
uv toolinstalls and runs Python command-line tools in managed tool environments, similar topipx. It is another main package-manager target this project should detect. Foruv toolinstalls, the correct upgrade command is generallyuv tool upgrade <tool>, not direct mutation of the tool environment withpip. -
update_checker is a library for checking whether a Python package has updates available. It serves the "is a newer version available?" part of the problem, but not the "how was this app installed, what command should upgrade it, and is it safe to run automatically?" part.
-
pip-review is a developer/admin CLI for listing outdated packages and interactively or automatically upgrading packages in an environment. It is environment-level tooling, not a library embedded in an application to detect and upgrade only the current app via the correct installer frontend.
-
pipupgrade is a CLI for upgrading packages across detected pip environments, including a
--selfmode. It is broad environment maintenance tooling, not a package-manager-aware self-update library for a single running PyPI CLI application. -
poetry-plugin-upgrade upgrades dependency constraints in a Poetry-managed project. It is development-time dependency maintenance tooling, not an application runtime self-update helper.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file do_i_need_to_upgrade-0.1.0.tar.gz.
File metadata
- Download URL: do_i_need_to_upgrade-0.1.0.tar.gz
- Upload date:
- Size: 45.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
401646e2790ec6a7a6d58ad5e05451842a14c28159a883cf49412953753bc4ce
|
|
| MD5 |
636ba12a8822e9d5b7bcca3d8486ba2a
|
|
| BLAKE2b-256 |
3838719b06ab16bf56052902032a57ba9d5a13707918f46def368f1739620ce2
|
Provenance
The following attestation bundles were made for do_i_need_to_upgrade-0.1.0.tar.gz:
Publisher:
release.yml on matthewdeanmartin/do_i_need_to_upgrade
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
do_i_need_to_upgrade-0.1.0.tar.gz -
Subject digest:
401646e2790ec6a7a6d58ad5e05451842a14c28159a883cf49412953753bc4ce - Sigstore transparency entry: 2071035199
- Sigstore integration time:
-
Permalink:
matthewdeanmartin/do_i_need_to_upgrade@ab8089a9f0f5303889c4214e3232105075d18a27 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/matthewdeanmartin
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ab8089a9f0f5303889c4214e3232105075d18a27 -
Trigger Event:
release
-
Statement type:
File details
Details for the file do_i_need_to_upgrade-0.1.0-py3-none-any.whl.
File metadata
- Download URL: do_i_need_to_upgrade-0.1.0-py3-none-any.whl
- Upload date:
- Size: 44.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
480597949bd007cbe3f309c5438344b60df6e2d997bbc35afb3275a612ccfe9a
|
|
| MD5 |
e02b055d76d968e8d85018b3949183ae
|
|
| BLAKE2b-256 |
55c83bc7591f68596cb5044b6826dee3dd71fda2e079ede46bab761afecd893c
|
Provenance
The following attestation bundles were made for do_i_need_to_upgrade-0.1.0-py3-none-any.whl:
Publisher:
release.yml on matthewdeanmartin/do_i_need_to_upgrade
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
do_i_need_to_upgrade-0.1.0-py3-none-any.whl -
Subject digest:
480597949bd007cbe3f309c5438344b60df6e2d997bbc35afb3275a612ccfe9a - Sigstore transparency entry: 2071035207
- Sigstore integration time:
-
Permalink:
matthewdeanmartin/do_i_need_to_upgrade@ab8089a9f0f5303889c4214e3232105075d18a27 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/matthewdeanmartin
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ab8089a9f0f5303889c4214e3232105075d18a27 -
Trigger Event:
release
-
Statement type: