Source code for manna.archives
"""Archive registry — discovery, selection, and the active-set accessor.
Each `archives/<short_name>.py` module exports a module-level ``ARCHIVE`` of
type :class:`Archive`. This package discovers every archive physically present,
validates the full set, then narrows to the deployment's active set via
``MANNA_ARCHIVES`` (an optional comma-separated allow-list of short_names;
unset/empty => all).
Two ways to shape a deployment:
* **Physical** — delete an ``archives/<name>.py`` file (forking a deployment).
* **Runtime** — set ``MANNA_ARCHIVES=datalab,alma`` from a shared image.
Archives here are purely additive: absence removes the server's *claims* about
an archive (usage_notes, schema quirks, endpoint examples, cosmetic label),
never its reachability. See docs/archives-spec.md.
`get_active_archives()` is cached like `get_settings()`; tests that toggle the
environment call ``get_active_archives.cache_clear()``.
"""
import importlib
import pkgutil
from functools import lru_cache
from manna.archives import _select
from manna.archives._audit import Audit
from manna.archives._model import Archive, Note, Schema
from manna.config import get_settings
__all__ = [
"Archive",
"Audit",
"Note",
"Schema",
"discover_archives",
"get_active_archives",
]
[docs]
def discover_archives() -> tuple[Archive, ...]:
"""Import every archive module in this package and collect its ``ARCHIVE``.
Modules whose name starts with ``_`` are skipped: the leaf dataclasses and
pure helpers (``_model``, ``_select``, ``_audit``) plus the derived-view
helper modules (``_endpoints``, ``_knowledge``) — none of them define an
``ARCHIVE``. A non-underscore module without an ``ARCHIVE`` attribute is a
developer error and raises. The returned tuple is validated
(:func:`_select.validate_archives`) and sorted by (priority, short_name).
"""
archives: list[Archive] = []
for module_info in pkgutil.iter_modules(__path__):
if module_info.name.startswith("_"):
continue
module = importlib.import_module(f"{__name__}.{module_info.name}")
archive = getattr(module, "ARCHIVE", None)
if archive is None:
raise ValueError(
f"Archive module {module_info.name!r} defines no module-level "
f"ARCHIVE. Every archives/<name>.py must export "
f"`ARCHIVE = Archive(...)`."
)
archives.append(archive)
result = tuple(archives)
_select.validate_archives(result)
return _select.sort_archives(result)
[docs]
@lru_cache(maxsize=1)
def get_active_archives() -> tuple[Archive, ...]:
"""The archives active for this deployment, ordered.
Discovers all physically-present archives, then narrows by
``MANNA_ARCHIVES`` (unset/empty => all). Resolved once per process;
frozen at first call.
"""
settings = get_settings()
all_archives = discover_archives()
allow = _select.parse_allow(settings.archives)
return _select.select_archives(all_archives, allow=allow)