Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
835eb9c
refactor(datasets): use scverse-misc dataset registry + downloader
timtreis Jun 15, 2026
b845dc9
refactor(datasets): use scverse-misc's built-in spatialdata loader
timtreis Jun 15, 2026
915df80
fix(datasets): consistent <datasetdir>/<type>/ cache layout for visium
timtreis Jun 15, 2026
859a35f
fix(ci): update prefetch script for the scverse-misc registry
timtreis Jun 15, 2026
947e68e
refactor(datasets): track scverse-misc slim API (parse_registry + fetch)
timtreis Jun 15, 2026
07387e4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 23, 2026
0098171
refactor(datasets): collapse downloader wrapper, fix pooch/pyyaml deps
timtreis Jun 23, 2026
c517bbd
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 23, 2026
c337bcd
fix(datasets): address review feedback on scverse-misc migration
timtreis Jul 7, 2026
b04a031
Merge branch 'main' into feat/datasets-via-scverse-misc
timtreis Jul 7, 2026
6b3561a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 7, 2026
bb79072
Merge branch 'main' into feat/datasets-via-scverse-misc
timtreis Jul 7, 2026
1f3d061
chore(datasets): drop notes-dev.md changelog entry (no longer used)
timtreis Jul 7, 2026
b15de0d
Merge branch 'main' into feat/datasets-via-scverse-misc
selmanozleyen Jul 13, 2026
9aa50c0
Merge branch 'main' into feat/datasets-via-scverse-misc
timtreis Aug 10, 2026
1650cc7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 10, 2026
690e9bd
Merge branch 'main' into feat/datasets-via-scverse-misc
selmanozleyen Aug 11, 2026
89ed5f3
Merge branch 'main' into feat/datasets-via-scverse-misc
selmanozleyen Aug 11, 2026
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
17 changes: 7 additions & 10 deletions .scripts/ci/download_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@ def main(args: argparse.Namespace) -> None:
from anndata import AnnData

import squidpy as sq
from squidpy.datasets._downloader import get_downloader

downloader = get_downloader()
registry = downloader.registry
from squidpy.datasets._registry import dataset_names

# Visium samples tested in CI
visium_samples_to_cache = [
Expand All @@ -35,23 +32,23 @@ def main(args: argparse.Namespace) -> None:
logger.info("Cache: %s", settings.datasetdir)
logger.info(
"Would download: %d AnnData, %d images, %d SpatialData, %d Visium",
len(registry.anndata_datasets),
len(registry.image_datasets),
len(registry.spatialdata_datasets),
len(dataset_names("anndata")),
len(dataset_names("image")),
len(dataset_names("spatialdata")),
len(visium_samples_to_cache),
)
return

# Download all datasets - the downloader handles caching
for name in registry.anndata_datasets:
for name in dataset_names("anndata"):
obj = getattr(sq.datasets, name)()
assert isinstance(obj, AnnData)

for name in registry.image_datasets:
for name in dataset_names("image"):
obj = getattr(sq.datasets, name)()
assert isinstance(obj, sq.im.ImageContainer)

for name in registry.spatialdata_datasets:
for name in dataset_names("spatialdata"):
getattr(sq.datasets, name)()

for sample in visium_samples_to_cache:
Expand Down
8 changes: 5 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ dependencies = [
"centrosome>=1.2.3",
"cp-measure>=0.1.19,<0.2",
"cycler>=0.11",
"dask[array,distributed]>=2021.2", # distributed is the only scheduler that forks for GIL-bound featurization
"dask[array,distributed]>=2021.2", # distributed is the only scheduler that forks for GIL-bound featurization
"dask-image>=0.5",
"docrep>=0.3.1",
"fast-array-utils",
Expand All @@ -69,10 +69,12 @@ dependencies = [
"scikit-image>=0.25",
# due to https://github.com/scikit-image/scikit-image/issues/6850 breaks rescale ufunc
"scikit-learn>=0.24",
"spatialdata>=0.7.2", # 0.7.2 dropped xarray-schema (pkg_resources break, #1115)
# dataset registry + downloader now live in scverse-misc
"scverse-misc[datasets]>=0.1.1,<0.2",
"spatialdata>=0.7.2", # 0.7.2 dropped xarray-schema (pkg_resources break, #1115)
"spatialdata-plot>=0.4.1",
"statsmodels>=0.12",
"threadpoolctl>=3", # clamp BLAS/OpenMP per worker in tiled featurization
"threadpoolctl>=3", # clamp BLAS/OpenMP per worker in tiled featurization
# https://github.com/scverse/squidpy/issues/526
"tifffile!=2022.4.22",
"tqdm>=4.50.2",
Expand Down
44 changes: 18 additions & 26 deletions src/squidpy/datasets/_datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@
from pathlib import Path
from typing import TYPE_CHECKING, Any, Literal

from scanpy import settings

from squidpy.datasets._downloader import get_downloader
from squidpy.datasets._registry import DatasetType, get_registry
from squidpy.datasets._downloader import download
from squidpy.datasets._registry import dataset_names, get_registry
from squidpy.read._utils import PathLike

if TYPE_CHECKING:
Expand Down Expand Up @@ -122,19 +120,15 @@ def visium(
:class:`anndata.AnnData`
Spatial AnnData object.
"""
# Validate sample_id against known names
downloader = get_downloader()

if sample_id not in downloader.registry:
msg = f"Unknown Visium sample: {sample_id}. "
msg += f"Available samples: {downloader.registry.visium_datasets}"
raise ValueError(msg)

# Use scanpy.settings.datasetdir/visium if base_dir not specified
if base_dir is None:
base_dir = Path(settings.datasetdir) / "visium"
# guard against the visium_10x names specifically: a valid-but-wrong-type name
# (e.g. "imc", an AnnData dataset) would otherwise pass and fail deep in the
# anndata loader with a confusing ``unexpected keyword argument 'include_hires_tiff'``.
visium_samples = dataset_names("visium_10x")
if sample_id not in visium_samples:
raise ValueError(f"Unknown Visium sample: {sample_id}. Available samples: {visium_samples}")

return downloader.download(sample_id, base_dir, include_hires_tiff=include_hires_tiff)
# downloads land in <datasetdir>/visium_10x/<sample_id>/

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this used to be /x/visium/x/ on old code but it's fine I guess to move the cache path. It's also seen in

-    expected_image_path = (Path(settings.datasetdir) / "visium" / sample / "image.tif").resolve()
+    expected_image_path = (Path(settings.datasetdir) / "visium_10x" / sample / "image.tif").resolve()

but good to document

return download(sample_id, base_dir, include_hires_tiff=include_hires_tiff)


def visium_hne_sdata(folderpath: Path | str | None = None) -> sd.SpatialData:
Expand All @@ -152,8 +146,7 @@ def visium_hne_sdata(folderpath: Path | str | None = None) -> sd.SpatialData:
:class:`spatialdata.SpatialData`
The downloaded and extracted Visium H&E dataset.
"""
downloader = get_downloader()
return downloader.download("visium_hne_sdata", folderpath)
return download("visium_hne_sdata", folderpath)


def cells(folderpath: Path | str | None = None) -> sd.SpatialData:
Expand All @@ -171,8 +164,7 @@ def cells(folderpath: Path | str | None = None) -> sd.SpatialData:
:class:`spatialdata.SpatialData`
The downloaded and extracted cells dataset.
"""
downloader = get_downloader()
return downloader.download("cells", folderpath)
return download("cells", folderpath)


# =============================================================================
Expand Down Expand Up @@ -204,9 +196,9 @@ class _DocParts:
return_type=":class:`squidpy.im.ImageContainer`\n The image data.",
)

_DOC_PARTS_BY_TYPE: dict[DatasetType, _DocParts] = {
DatasetType.ANNDATA: _ANNDATA_DOC,
DatasetType.IMAGE: _IMAGE_DOC,
_DOC_PARTS_BY_TYPE: dict[str, _DocParts] = {
"anndata": _ANNDATA_DOC,
"image": _IMAGE_DOC,
}


Expand All @@ -225,12 +217,12 @@ def _make_loader(dataset_name: str):
raise ValueError(f"Unsupported type for loader factory: {entry.type}")

def loader(path: PathLike | None = None, **kwargs: Any):
return get_downloader().download(dataset_name, path, **kwargs)
return download(dataset_name, path, **kwargs)

loader.__doc__ = f"""
{entry.doc_header}
{entry.metadata.get("doc_header")}

{doc_parts.shape_prefix} ``{entry.shape}``.
{doc_parts.shape_prefix} ``{entry.metadata.get("shape")}``.

Parameters
----------
Expand Down
Loading
Loading