How Versioning Is Managed in lfnovo/open-notebook: A Complete Technical Guide
Open Notebook manages versioning through a centralized pyproject.toml declaration, GitHub-based remote version checking with 24-hour TTL caching, and exposes update availability through a public /config API endpoint.
The lfnovo/open-notebook repository implements a robust versioning system that allows self-hosted instances to detect available updates without external dependencies. By storing the canonical version in pyproject.toml and implementing asynchronous remote checks with intelligent caching, the application provides real-time update notifications through its REST API.
Centralized Version Declaration in pyproject.toml
Following PEP 621 standards, Open Notebook stores its single source of truth in the [project] table of pyproject.toml. This static declaration ensures the version is accessible to both the Python package manager and the running application.
[project]
name = "open-notebook"
version = "1.10.0"
This file serves as the only location where the version is manually updated, eliminating drift between package metadata and runtime behavior.
Runtime Version Detection
When the service starts, the application reads the local version directly from the filesystem rather than importing from package metadata. This approach ensures accuracy even when running from source or in development environments.
Reading from pyproject.toml
The api/routers/config.py module implements get_version() to load the TOML file using Python's built-in tomllib module:
def get_version() -> str:
"""Read version from pyproject.toml"""
pyproject_path = Path(__file__).parent.parent.parent / "pyproject.toml"
with open(pyproject_path, "rb") as f:
pyproject = tomllib.load(f)
return pyproject.get("project", {}).get("version", "unknown")
This function traverses the filesystem relative to the router's location, ensuring the correct pyproject.toml is loaded regardless of the working directory.
Remote Version Checking
To determine if updates are available, the application compares the local version against the latest release published on GitHub. This check happens asynchronously to avoid blocking the main thread.
Asynchronous GitHub Fetching
The open_notebook/utils/version_utils.py module provides get_version_from_github_async, which fetches the raw pyproject.toml from the repository's main branch and parses it:
async def get_version_from_github_async(repo_url: str, branch: str = "main") -> str:
parsed_url = urlparse(repo_url)
owner, repo = parsed_url.path.strip("/").split("/")[:2]
raw_url = f"https://raw.githubusercontent.com/{owner}/{repo}/{branch}/pyproject.toml"
async with httpx.AsyncClient(timeout=10.0) as client:
response = await client.get(raw_url)
response.raise_for_status()
pyproject_data = tomli.loads(response.text)
return pyproject_data["tool"]["poetry"]["version"]
Note that this utility specifically extracts the version from the tool.poetry table when reading remote files, accommodating the repository's Poetry-based build configuration.
Version Comparison and Semantics
The application performs PEP 440-compliant version comparisons using the packaging library. The compare_versions function in open_notebook/utils/version_utils.py returns discrete integers to indicate relative ordering:
def compare_versions(version1: str, version2: str) -> int:
v1, v2 = parse_version(version1), parse_version(version2)
if v1 < v2: return -1
if v1 > v2: return 1
return 0
This returns -1 if the local version is older, 0 if equal, and 1 if newer, providing a reliable boolean check for update availability.
Performance Optimization with TTL Caching
To prevent excessive GitHub API calls, api/routers/config.py implements an in-memory cache with a 24-hour time-to-live (_version_cache). The helper get_latest_version_cached fetches the remote version only when the cache expires, storing both the version string and the comparison result.
This caching strategy ensures that:
- The
/configendpoint responds immediately without network latency - Rate limits from raw.githubusercontent.com are never exceeded
- Users see consistent update status throughout a session
Exposing Version Data via the Public API
The /config endpoint aggregates local version, cached remote version, and database health status into a single JSON response. The implementation wraps remote version lookup in a try/except block to ensure the endpoint never fails due to network issues:
{
"version": "1.10.0",
"latestVersion": "1.12.0",
"hasUpdate": true,
"dbStatus": "online"
}
Clients can poll this endpoint to display update notifications in the UI without implementing their own version comparison logic.
Test Coverage
The version utilities include comprehensive unit tests in tests/test_utils.py, which validate:
- Semantic version comparison edge cases (e.g., pre-releases, post-releases)
- Network failure handling in
get_version_from_github - Correct parsing of both local and remote TOML formats
These tests ensure the versioning system remains reliable across Python version updates and dependency changes.
Summary
- Single source of truth: Version is declared statically in
pyproject.tomlunder the[project]table. - Local reading:
api/routers/config.pyusestomllibto read the version at runtime without package imports. - Remote detection:
open_notebook/utils/version_utils.pyfetches the latest version from GitHub's raw content API asynchronously. - PEP 440 compliance: Version comparisons use
packaging.version.parsefor semantic versioning support. - Intelligent caching: A 24-hour TTL cache in the config router prevents unnecessary network requests.
- Resilient API: The
/configendpoint exposes version status with graceful fallback when GitHub is unreachable.
Frequently Asked Questions
Where is the version number stored in open-notebook?
The version number is stored in pyproject.toml under the [project] table as a static string. This follows PEP 621 standards and serves as the single source of truth for both package installation and runtime version detection.
How does open-notebook check for updates without an external API?
The application fetches the raw pyproject.toml file directly from the GitHub repository's main branch using httpx via the get_version_from_github_async function. It parses the TOML content to extract the version string and compares it against the local installation using PEP 440-compliant comparison logic.
What happens if the GitHub version check fails?
The version check is wrapped in exception handling within the /config endpoint. If the remote request fails, the endpoint still returns the local version and database status, but sets hasUpdate to false and omits or preserves the last known latestVersion. This ensures the application remains functional offline.
How often does open-notebook check for new versions?
The system checks GitHub no more than once every 24 hours due to the TTL-based in-memory cache (_version_cache) implemented in api/routers/config.py. Subsequent requests within the 24-hour window return cached results instantly, minimizing network overhead and preventing rate limiting.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →