self-update
Single-file, zero-dependency self-update on launch for Python CLIs. Works on Windows, Linux, and macOS with pip, pipx, and uv installations.
Usage
Install it, then add two lines at the very top of your entry point, before any setup, try/finally, or UI:
pip install auto-self-update
import selfupdate
def main():
if selfupdate.check("my-package"):
return # the updater is running; it relaunches this command
# ... your normal startup ...
"my-package" is your app's PyPI/distribution name. That is all.
Alternatively, vendor selfupdate.py into your project — it has no
dependencies beyond the standard library.
What it does
- On launch, compares the installed version against the newest stable release on PyPI (4 s hard timeout; any failure launches normally).
- A newer release spawns a detached updater and your process exits. Exiting first is deliberate: Windows locks a running process's executables, and this flow works identically everywhere.
- The updater waits for your process to disappear, runs the
installer-native upgrade command (
uv tool upgrade,pipx upgrade, or the environment's own pip), verifies the installed version actually advanced, and re-executes the original command with its arguments. - Any failure prints the manual command and leaves the old install untouched — the updater never relaunches a failed upgrade.
Skipped automatically
- Repository checkouts and editable installs (found by walking up
from the caller's file to a
pyproject.toml; the walk stops atsite-packages). - Ephemeral
uvx/pipx runcaches — a one-line note is printed instead; those refresh on their own schedule. - Kill switches: pass
enabled=False(wire your own config toggle to it), or setNO_AUTO_UPDATE/<PACKAGE>_NO_AUTO_UPDATE(uppercased, non-alphanumerics become underscores) in the environment.
Optional parameters
selfupdate.check(
"my-package",
enabled=True, # your own config toggle goes here
index_url=None, # JSON index template with {package}; PyPI default
)
Caveats
- Only dotted-numeric releases (
2.0.8) are update targets; pre-releases are never chased. - The upgrade command inherits the terminal, so its progress output is visible; the updater is detached from Ctrl+C delivery so an interruption cannot break a half-written install.
- Two instances updating simultaneously serialize on the installer's own lock; the second finds nothing to do.
- Keep your package's
__init__.pylight — good practice anyway; the updater runs this module by file path and never imports your package.
Tests
python test_selfupdate.py — 39 offline tests, no network, no spawn.
License
MIT — see LICENSE.
Metadata
Release files for auto-self-update 0.9.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| auto_self_update-0.9.0.tar.gz | 8.6 kB | Without provenance | Details for auto_self_update-0.9.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| auto_self_update-0.9.0-py3-none-any.whl | Python 3 | none | any | Details for auto_self_update-0.9.0-py3-none-any.whl |
Total release size: 17.8 kB
Release files / auto_self_update-0.9.0.tar.gz
| Download URL | auto_self_update-0.9.0.tar.gz |
|---|---|
| Size | 8.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a2eb44be643f3309fe57517f2605e0743c408524014ae106b0ab8a07dd0674d8
|
|
BLAKE2b-256 checksum How to use checksums |
50a6fc0dd060647764b0f8bba9617e0bb97509787aa32c89a353ecd1cf7f29e2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / auto_self_update-0.9.0-py3-none-any.whl
| Download URL | auto_self_update-0.9.0-py3-none-any.whl |
|---|---|
| Size | 9.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7356c8e1856324de6b40607511b401526fffd9f38eabf4011408631beb32e3ff
|
|
BLAKE2b-256 checksum How to use checksums |
7039908dc101d19a5e13e234ad0d1fa33976842f6c0d1bc9b4c6a01ef4a8e231
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for auto-self-update 0.9.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.