Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/sddb/_catalog_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@
"disease_group": "string",
"disease_group_id": "string",
# technology
# From schema 3: ``technology`` is the vocabulary id (e.g. "10x_visium"), ``vendor`` its vendor id (required in a
# schema-3 catalog) and ``variant`` one of the technology's variant ids or null; labels are in technology.json.
# ``assay`` stays as the legacy label.
"technology": "string",
"vendor": "string",
"variant": "string",
"assay": "string",
"panel_size": "Int64",
# validation
Expand Down Expand Up @@ -191,6 +196,8 @@
"disease",
"development_stage",
"technology",
"vendor",
"variant",
"assay",
"modalities",
"tier",
Expand All @@ -210,7 +217,7 @@
# ``catalog_schema_version`` (in release_info.json / the parquet metadata) is refused on load; a
# catalog that declares none is a legacy (<= 2) catalog and loads. Bump when the client learns a
# new schema's columns.
SUPPORTED_CATALOG_SCHEMA = 2
SUPPORTED_CATALOG_SCHEMA = 3

# Columns the client derives on load (not in the published parquet): ``source`` is the lowercased
# ``study_id`` prefix before ":" (geo, hest, 10x, ...), null for rows without a study_id.
Expand Down
25 changes: 25 additions & 0 deletions src/sddb/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ def __init__(
self._refresh = refresh
self._genes: GeneIndex | None = None
self._features: FeatureIndex | None = None
self._technologies: dict[str, Any] | None = None
self._path = fetch_catalog(url, cache_dir=cache_dir, refresh=refresh)
ver = _catalog_schema_version(self._path)
if ver is not None and ver > schema.SUPPORTED_CATALOG_SCHEMA:
Expand All @@ -252,6 +253,8 @@ def __init__(
pass # left for validate() to report
try:
schema.validate(df)
if ver is not None and ver >= 3 and "vendor" not in df.columns:
raise schema.SchemaError("a schema-3 catalog needs a 'vendor' column")
except schema.SchemaError as err:
raise schema.SchemaError(f"catalog at {url} is invalid: {err}") from err
if "study_id" in df.columns and "source" not in df.columns:
Expand All @@ -271,6 +274,28 @@ def from_file(cls, path: str | Path, *, cache_dir: str | Path | None = None) ->
"""
return cls(str(path), cache_dir=cache_dir)

def technologies(self) -> dict[str, Any]:
"""The release's technology vocabulary (``technology.json`` beside the catalog).

``{"schema_version", "release", "readouts", "vendors", "technologies"}``: each technology has its ``id`` (the
catalog's ``technology``), ``label``, ``vendor_id``, ``readout``, ``modality``, ``variants`` (``id`` and
``label``, the catalog's ``variant``) and the ``legacy_assay`` labels it replaces. Raises ``ValueError`` for a
file whose schema major version is newer than this client supports.
"""
if self._technologies is None:
from sddb.features import sibling_url

url = sibling_url(self.url, "technology.json")
vocab = json.loads(fetch_catalog(url, cache_dir=self._cache_dir, refresh=self._refresh).read_text())
major = int(str(vocab.get("schema_version", "0")).split(".")[0])
if major > schema.SUPPORTED_CATALOG_SCHEMA:
raise ValueError(
f"technology.json at {url} has schema version {vocab['schema_version']}, but this sddb client "
f"supports up to {schema.SUPPORTED_CATALOG_SCHEMA}. Upgrade with `pip install -U spatialdata-db-client`."
)
self._technologies = vocab
return self._technologies

@property
def generated_at(self) -> str | None:
"""Generation timestamp from the parquet metadata, if present."""
Expand Down
Loading
Loading