Skip to main content

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 CLI 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, or safety opportunistically
  • 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 no dependencies at all? Vendor it

Prefer not to add a dependency? Two supported paths (see docs/usage/vendoring.md):

  • Vendor the full package — internal imports are relative, so copying do_i_need_to_upgrade/ into yourapp/_vendor/ just works (needs packaging, which you almost certainly already have).
  • diu_lite.py — 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 entirely
  • DO_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, or disabled_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 for pipx, 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, and uv 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 --outdated and upgrade packages via python -m pip install --upgrade <package>, but it is not an application-embedded self-update helper and does not detect whether a CLI was installed by pipx, 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. For pipx -installed apps, the correct upgrade command is generally pipx upgrade <app>, not an in-process pip install --upgrade.

  • uv / uv tool installs and runs Python command-line tools in managed tool environments, similar to pipx. It is another main package-manager target this project should detect. For uv tool installs, the correct upgrade command is generally uv tool upgrade <tool>, not direct mutation of the tool environment with pip.

  • 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 --self mode. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

do_i_need_to_upgrade-0.0.1.tar.gz (45.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

do_i_need_to_upgrade-0.0.1-py3-none-any.whl (44.9 kB view details)

Uploaded Python 3

File details

Details for the file do_i_need_to_upgrade-0.0.1.tar.gz.

File metadata

  • Download URL: do_i_need_to_upgrade-0.0.1.tar.gz
  • Upload date:
  • Size: 45.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for do_i_need_to_upgrade-0.0.1.tar.gz
Algorithm Hash digest
SHA256 f86ce7468d45590a5bc398b134653dab720174b2d1d1cdc9d7f66d5318a6127a
MD5 979d667b2974f4f3dc4d972cf7663921
BLAKE2b-256 bfcff7a23a8acc73a012930d5258443074b423262cc8a6649af8da941267250c

See more details on using hashes here.

Provenance

The following attestation bundles were made for do_i_need_to_upgrade-0.0.1.tar.gz:

Publisher: release.yml on matthewdeanmartin/do_i_need_to_upgrade

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file do_i_need_to_upgrade-0.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for do_i_need_to_upgrade-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5289a48537ccd94a1e888396407a3f0a25fee5e42edf9fbfcae54911425a2d6b
MD5 0dff5d920af4d46ed40557436a118fb3
BLAKE2b-256 f4f29b9c2a2bc4c60d4b51e52b066effcdc55cda8e067184f48a9d9f68bc206f

See more details on using hashes here.

Provenance

The following attestation bundles were made for do_i_need_to_upgrade-0.0.1-py3-none-any.whl:

Publisher: release.yml on matthewdeanmartin/do_i_need_to_upgrade

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page