# How Versioning Is Managed in lfnovo/open-notebook: A Complete Technical Guide

> Discover how Open Notebook manages versioning seamlessly using pyproject.toml, GitHub checks, and a public API. Stay updated with ease. Learn the technical details now.

- Repository: [Luis Novo/open-notebook](https://github.com/lfnovo/open-notebook)
- Tags: how-to-guide
- Published: 2026-06-26

---

**Open Notebook manages versioning through a centralized [`pyproject.toml`](https://github.com/lfnovo/open-notebook/blob/main/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`](https://github.com/lfnovo/open-notebook/blob/main/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`](https://github.com/lfnovo/open-notebook/blob/main/pyproject.toml). This static declaration ensures the version is accessible to both the Python package manager and the running application.

```toml
[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`](https://github.com/lfnovo/open-notebook/blob/main/api/routers/config.py) module implements `get_version()` to load the TOML file using Python's built-in `tomllib` module:

```python
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`](https://github.com/lfnovo/open-notebook/blob/main/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`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/utils/version_utils.py) module provides `get_version_from_github_async`, which fetches the raw [`pyproject.toml`](https://github.com/lfnovo/open-notebook/blob/main/pyproject.toml) from the repository's main branch and parses it:

```python
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`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/utils/version_utils.py) returns discrete integers to indicate relative ordering:

```python
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`](https://github.com/lfnovo/open-notebook/blob/main/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 `/config` endpoint 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:

```json
{
    "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`](https://github.com/lfnovo/open-notebook/blob/main/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.toml`](https://github.com/lfnovo/open-notebook/blob/main/pyproject.toml) under the `[project]` table.
- **Local reading**: [`api/routers/config.py`](https://github.com/lfnovo/open-notebook/blob/main/api/routers/config.py) uses `tomllib` to read the version at runtime without package imports.
- **Remote detection**: [`open_notebook/utils/version_utils.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/utils/version_utils.py) fetches the latest version from GitHub's raw content API asynchronously.
- **PEP 440 compliance**: Version comparisons use `packaging.version.parse` for semantic versioning support.
- **Intelligent caching**: A 24-hour TTL cache in the config router prevents unnecessary network requests.
- **Resilient API**: The `/config` endpoint 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`](https://github.com/lfnovo/open-notebook/blob/main/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`](https://github.com/lfnovo/open-notebook/blob/main/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`](https://github.com/lfnovo/open-notebook/blob/main/api/routers/config.py). Subsequent requests within the 24-hour window return cached results instantly, minimizing network overhead and preventing rate limiting.