diff --git a/dandi/download.py b/dandi/download.py index 7049a4ae9..79e2f575f 100644 --- a/dandi/download.py +++ b/dandi/download.py @@ -28,7 +28,13 @@ from . import get_logger from .consts import RETRY_STATUSES, dandiset_metadata_file from .dandiapi import AssetType, BaseRemoteZarrAsset, RemoteDandiset -from .dandiarchive import DandisetURL, ParsedDandiURL, SingleAssetURL, parse_dandi_url +from .dandiarchive import ( + AssetItemURL, + DandisetURL, + ParsedDandiURL, + SingleAssetURL, + parse_dandi_url, +) from .dandiset import Dandiset from .exceptions import NotFoundError from .files import LocalAsset, find_dandi_files @@ -227,7 +233,13 @@ def download_generator(self) -> Iterator[dict]: """ with self.url.navigate(strict=True) as (client, dandiset, assets): - if isinstance(self.url, DandisetURL) and self.get_metadata: + if ( + isinstance(self.url, DandisetURL) + or ( + isinstance(self.url, AssetItemURL) + and self.url.path == "dandiset.yaml" + ) + ) and self.get_metadata: assert dandiset is not None for resp in _populate_dandiset_yaml( self.output_path, dandiset, self.existing @@ -236,6 +248,8 @@ def download_generator(self) -> Iterator[dict]: "path": str(self.output_prefix / dandiset_metadata_file), **resp, } + if isinstance(self.url, AssetItemURL): + return # TODO: do analysis of assets for early detection of needed renames # etc to avoid any need for late treatment of existing and also for diff --git a/dandi/tests/test_download.py b/dandi/tests/test_download.py index d5bc1f9a9..b6d8f8430 100644 --- a/dandi/tests/test_download.py +++ b/dandi/tests/test_download.py @@ -31,7 +31,7 @@ ) from ..exceptions import NotFoundError from ..support.digests import Digester -from ..utils import list_paths +from ..utils import list_paths, yaml_load # both urls point to 000027 (lean test dataset), and both draft and "released" @@ -182,6 +182,18 @@ def test_download_item(text_dandiset: SampleDandiset, tmp_path: Path) -> None: assert (tmp_path / "coconut.txt").read_text() == "Coconut\n" +def test_download_dandiset_yaml(text_dandiset: SampleDandiset, tmp_path: Path) -> None: + dandiset_id = text_dandiset.dandiset_id + download( + f"dandi://{text_dandiset.api.instance_id}/{dandiset_id}/dandiset.yaml", + tmp_path, + ) + assert list_paths(tmp_path, dirs=True) == [tmp_path / dandiset_metadata_file] + with (tmp_path / dandiset_metadata_file).open(encoding="utf-8") as fp: + metadata = yaml_load(fp) + assert metadata["id"] == f"DANDI:{dandiset_id}/draft" + + def test_download_asset_id(text_dandiset: SampleDandiset, tmp_path: Path) -> None: asset = text_dandiset.dandiset.get_asset_by_path("subdir2/coconut.txt") download(asset.download_url, tmp_path)