VersionBeacon helps applications detect available updates through a simple API, environment-based configuration and event callbacks.
- β¨ Features
- π§ How It Works
- π¦ Installation
- π Quickstart
- π± Environment Configuration
- π― VersionChecker
- π‘ Events
- π Endpoint Format
- π Results
- π‘οΈ Error Handling
- π Project Structure
- π§ͺ Testing
- π¦ Building and Publishing
- π€ Contributing
- π License
- Simple one-call API with
check() - Reusable
VersionChecker - Configuration through Python arguments or environment variables
- Explicit configuration takes precedence over environment variables
- Configurable timeout and retry handling
- Maximum response-size protection
- Structured JSON version responses
- Legacy text response support
- Three- and four-part version comparison
- Event callbacks for every check state
- Structured and typed result objects
- Safe handling of network and response errors
- No runtime dependencies outside the Python standard library
- Python 3.9 and newer
- Ready for PyPI packaging
flowchart LR
A["check()"] --> B["VersionChecker"]
B --> C["VersionBeaconConfig"]
B --> D["Version Endpoint"]
D --> E["Parse & Compare"]
E --> F["CheckResult"]
F --> G["Events"]
VersionBeacon follows a simple process:
- Load and validate the configuration.
- Request the configured version endpoint.
- Parse the remote response.
- Compare the local and remote versions.
- Return a structured
CheckResult. - Emit the corresponding events.
Install VersionBeacon with pip:
python -m pip install version-beaconFor local development:
git clone https://github.com/Lainupcomputer/VersionBeacon.git
cd VersionBeacon
python -m venv .venv
python -m pip install -e ".[dev]"python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e ".[dev]"from version_beacon import CheckStatus, check
result = check(
app_name="MyApp",
current_version="1.2.3",
version_url="https://example.com/myapp-version.json",
)
if result.status is CheckStatus.UPDATE_AVAILABLE:
print(f"Update available: {result.latest_version}")
print(f"Release URL: {result.release_url}")
elif result.status is CheckStatus.UP_TO_DATE:
print("The application is up to date.")
elif result.status is CheckStatus.CURRENT_AHEAD:
print("The local version is newer than the remote version.")
elif result.status is CheckStatus.FAILED:
print(f"Version check failed: {result.error}")VersionBeacon can load its configuration from environment variables.
The default prefix is:
VERSION_BEACON_
| Variable | Required | Default |
|---|---|---|
VERSION_BEACON_APP_NAME |
Yes | β |
VERSION_BEACON_CURRENT_VERSION |
Yes | β |
VERSION_BEACON_VERSION_URL |
Yes | β |
VERSION_BEACON_TIMEOUT |
No | 5 seconds |
VERSION_BEACON_RETRIES |
No | 0 |
VERSION_BEACON_MAX_RESPONSE_BYTES |
No | 1048576 |
VERSION_BEACON_USER_AGENT |
No | version-beacon/2 |
export VERSION_BEACON_APP_NAME="MyApp"
export VERSION_BEACON_CURRENT_VERSION="1.2.3"
export VERSION_BEACON_VERSION_URL="https://example.com/myapp-version.json"
export VERSION_BEACON_TIMEOUT="5"
export VERSION_BEACON_RETRIES="2"$env:VERSION_BEACON_APP_NAME = "MyApp"
$env:VERSION_BEACON_CURRENT_VERSION = "1.2.3"
$env:VERSION_BEACON_VERSION_URL = "https://example.com/myapp-version.json"
$env:VERSION_BEACON_TIMEOUT = "5"
$env:VERSION_BEACON_RETRIES = "2"Once configured, the check only requires:
from version_beacon import check
result = check()Configuration values are resolved in this order:
- Explicit Python arguments
- Environment variables
- Built-in defaults
from version_beacon import check
result = check(
app_name="MyApp",
current_version="1.2.3",
version_url="https://example.com/version.json",
timeout=10,
)The explicit timeout=10 value takes precedence over VERSION_BEACON_TIMEOUT.
A custom environment prefix can be used:
from version_beacon import VersionBeaconConfig
config = VersionBeaconConfig.from_env(
prefix="MY_APP_VERSION_BEACON_"
)For repeated checks, use VersionChecker directly:
from version_beacon import VersionBeaconConfig, VersionChecker
config = VersionBeaconConfig(
app_name="MyApp",
current_version="1.2.3",
version_url="https://example.com/version.json",
timeout=5,
retries=2,
)
checker = VersionChecker(config=config)
result = checker.check()
print(result.status)Or load the checker from environment variables:
from version_beacon import VersionChecker
checker = VersionChecker.from_env()
result = checker.check()VersionBeacon provides events for every important stage of a version check.
| Event | Payload |
|---|---|
check_started |
CheckStarted |
update_available |
CheckResult |
up_to_date |
CheckResult |
current_ahead |
CheckResult |
check_failed |
CheckResult |
check_finished |
CheckResult |
from version_beacon import EventName, VersionChecker
checker = VersionChecker.from_env()
@checker.on(EventName.UPDATE_AVAILABLE)
def update_available(result):
print(f"New version available: {result.latest_version}")
@checker.on(EventName.UP_TO_DATE)
def already_current(result):
print("The application is up to date.")
@checker.on(EventName.CHECK_FAILED)
def check_failed(result):
print(f"Version check failed: {result.error}")
result = checker.check()Callbacks can be removed again:
checker.off(EventName.UPDATE_AVAILABLE, update_available)Exceptions raised inside callbacks are logged and do not interrupt the version check.
The top-level check() wrapper also supports direct callback arguments:
from version_beacon import check
result = check(
on_update_available=lambda result: print(
f"Update available: {result.latest_version}"
),
on_up_to_date=lambda result: print(
"Already up to date."
),
on_check_failed=lambda result: print(
f"Check failed: {result.error}"
),
on_finished=lambda result: print(
"Check finished."
),
)Multiple events can be registered through a mapping:
from version_beacon import EventName, check
result = check(
events={
EventName.UPDATE_AVAILABLE: handle_update,
EventName.CHECK_FAILED: handle_failure,
}
)The recommended endpoint returns a JSON object:
{
"app_name": "MyApp",
"version": "1.2.4",
"release_url": "https://example.com/releases/1.2.4",
"release_notes": "Bug fixes and improvements"
}| Field | Type | Description |
|---|---|---|
version |
string |
Latest available version |
| Field | Type | Description |
|---|---|---|
app_name |
string |
Validates the application name |
release_url |
string |
Link to the release |
release_notes |
string |
Release notes or changelog |
The following aliases are supported:
applicationinstead ofapp_nameurlinstead ofrelease_urlnotesinstead ofrelease_notes
For migration compatibility, VersionBeacon also supports the legacy text format:
MyApp_version==1.2.4
The application name must match the configured app_name.
VersionBeacon supports three- and four-part numeric versions:
1.2.3
1.2.3.4
The following versions are treated as equal:
1.2.3 == 1.2.3.0
Versions are compared numerically:
2.0.0 > 1.99.99.99
1.2.4 > 1.2.3
Supported formats:
MAJOR.MINOR.PATCH
MAJOR.MINOR.PATCH.FIX
Every check returns a CheckResult object:
result = checker.check()| Field | Description |
|---|---|
app_name |
Configured application name |
current_version |
Installed application version |
latest_version |
Version reported by the endpoint |
status |
Current CheckStatus |
checked_at |
Completion timestamp |
version_url |
Requested endpoint |
release_url |
Optional release URL |
release_notes |
Optional release notes |
error |
Error message when the check fails |
Convenience properties:
result.update_available
result.up_to_date
result.current_is_ahead
result.failedPossible statuses:
| Status | Meaning |
|---|---|
up_to_date |
The installed version is current |
update_available |
A newer version is available |
current_ahead |
The local version is newer |
failed |
The check could not be completed |
Available exception classes:
from version_beacon import (
ConfigurationError,
InvalidVersionError,
VersionBeaconError,
VersionFetchError,
VersionResponseError,
)Network and response errors are returned as failed results:
result = checker.check()
if result.failed:
print(result.error)VersionBeacon includes:
- Configurable request timeouts
- Configurable retries
- Maximum response-size limits
- UTF-8 response validation
- JSON structure validation
- HTTP and HTTPS URL validation
- Numeric version validation
Configuration errors are raised while creating the configuration or checker.
from version_beacon import (
check,
VersionChecker,
VersionBeaconConfig,
EventEmitter,
EventName,
CheckResult,
CheckStarted,
CheckStatus,
Version,
parse_version,
)| Component | Purpose |
|---|---|
check() |
Simple one-call wrapper |
VersionChecker |
Reusable checker instance |
VersionBeaconConfig |
Validated configuration |
EventEmitter |
Event registration and dispatch |
EventName |
Available event names |
CheckResult |
Result of a version check |
CheckStarted |
Check-start event payload |
CheckStatus |
Possible check outcomes |
Version |
Normalized version object |
parse_version() |
Parse and validate versions |
VersionBeacon/
βββ examples/
β βββ basic.py
βββ scripts/
β βββ build.ps1
β βββ build.sh
βββ src/
β βββ version_beacon/
β βββ __init__.py
β βββ client.py
β βββ config.py
β βββ events.py
β βββ exceptions.py
β βββ models.py
β βββ versions.py
βββ tests/
β βββ test_checker.py
β βββ test_versions.py
βββ LICENSE
βββ pyproject.toml
βββ README.md
Run the complete test suite:
python -m pytestRun tests with verbose output:
python -m pytest -vRun a specific test file:
python -m pytest tests/test_checker.pyBuild source and wheel distributions:
python -m buildGenerated packages are placed in:
dist/
.\scripts\build.ps1./scripts/build.shCheck the generated distributions:
python -m twine check dist/*Publish to PyPI:
python -m twine upload dist/*VersionBeacon is intentionally focused on a small and reliable API.
The main design goals are:
- Minimal setup for application developers
- No required runtime dependencies
- Safe operation during application startup
- Explicit configuration with environment support
- Predictable result objects
- Clear event lifecycle
- Compatibility with existing version endpoints
- Easy packaging and distribution
- Version:
2.0.0 - Status: Beta
- Python:
>=3.9 - Runtime dependencies: None
- License: MIT
Contributions, bug reports and suggestions are welcome.
- Fork the repository.
- Create a feature branch.
- Install the development dependencies.
- Add or update tests.
- Run the test suite.
- Open a pull request.
Please keep changes focused and maintain the existing public API style.
VersionBeacon is released under the MIT License.
See LICENSE for the complete license text.