exlab_wizard.lims.catalogue#

Offline LIMS project catalogue read/write. Backend Spec §7.2.9.

A catalogue is a single JSON document at a NAS-shared path that lets a disconnected workstation populate its LIMS-project picker without reaching the live LIMS API. The producer workstation writes the file on every successful LIMS refresh; the consumer workstation reads it when its local SQLite cache is empty AND the LIMS API is unreachable (see §7.2.9.3 for the consumer trigger).

This module provides only the file-format I/O. The producer-vs-consumer trigger logic, the warning-and-fall-through behavior on parse errors, and the picker-badge annotation are integrated by the caller (typically the LIMSClient or its supervising controller).

File format (§7.2.9.1):

```json {

“schema_version”: “1.0”, “produced_by”: “LAB_STATION_01”, “produced_at”: “2026-05-05T14:23:00Z”, “lims_endpoint”: “https://lims.lab.example/api/v1”, “projects”: [ {LIMSProject row}, … ]

}#

Atomic write (§7.2.9.2): write to <path>.tmp.<pid>, fsync, then os.replace to the final path. Concurrent producers are benign – each rename is atomic; the last writer wins.

Functions

read_catalogue(path, *, expected_endpoint)

Read and validate the catalogue file.

write_catalogue(path, catalogue)

Atomically write catalogue to path.

Classes

OfflineCatalogue(schema_version, ...)

Decoded offline catalogue.

class exlab_wizard.lims.catalogue.OfflineCatalogue(schema_version, produced_by, produced_at, lims_endpoint, projects)[source]#

Bases: object

Decoded offline catalogue. Backend Spec §7.2.9.1.

schema_version is pinned to the constant declared in exlab_wizard.constants.schema_versions; mismatches surface as exlab_wizard.errors.ConfigError.

lims_endpoint is verified by read_catalogue() against the consumer’s configured LIMS endpoint; mismatches are rejected per §7.2.9.3 to defend against accidentally pointing at a different lab’s LIMS.

Parameters:
lims_endpoint: str#
produced_at: str#
produced_by: str#
projects: list[LIMSProject]#
schema_version: str#
exlab_wizard.lims.catalogue.read_catalogue(path, *, expected_endpoint)[source]#

Read and validate the catalogue file.

Raises exlab_wizard.errors.ConfigError on any of:

  • file missing / unreadable

  • JSON parse error

  • schema_version is not the constant exlab_wizard.constants.OFFLINE_CATALOGUE_VERSION

  • lims_endpoint differs from expected_endpoint (per §7.2.9.3 the producer’s LIMS must match the consumer’s configuration; cross-lab leakage is rejected, not warned).

Parameters:
  • path (Path)

  • expected_endpoint (str)

Return type:

OfflineCatalogue

exlab_wizard.lims.catalogue.write_catalogue(path, catalogue)[source]#

Atomically write catalogue to path. Backend Spec §7.2.9.2.

Protocol: serialize, write to <path>.tmp.<pid>, fsync, then os.replace to the final path. Concurrent producers do not corrupt the file – each rename is atomic; the last writer wins.

Parameters:
Return type:

None