diff --git a/dandi/dandiapi.py b/dandi/dandiapi.py index 37d5a6682..fbd75163f 100644 --- a/dandi/dandiapi.py +++ b/dandi/dandiapi.py @@ -552,18 +552,6 @@ def _mkasset(self, data: Dict[str, Any]) -> "RemoteAsset": **data, ) - def _mkasset_from_metadata(self, metadata: Dict[str, Any]) -> "RemoteAsset": - return RemoteAsset( - client=self.client, - dandiset_id=self.identifier, - version_id=self.version_id, - identifier=metadata["identifier"], - path=metadata["path"], - size=metadata["contentSize"], - modified=metadata["dateModified"], - _metadata=metadata, - ) - def json_dict(self) -> Dict[str, Any]: """ Convert to a JSONable `dict`, omitting the ``client`` attribute and @@ -706,9 +694,10 @@ def get_asset(self, asset_id: str) -> "RemoteAsset": ID. If the given asset does not exist, a `requests.HTTPError` is raised with a 404 status code. """ - return self._mkasset_from_metadata( - self.client.get(f"{self.version_api_path}assets/{asset_id}/") - ) + metadata = self.client.get(f"{self.version_api_path}assets/{asset_id}/") + asset = self.get_asset_by_path(metadata["path"]) + asset._metadata = metadata + return asset def get_assets_with_path_prefix(self, path: str) -> Iterator["RemoteAsset"]: """ @@ -951,7 +940,6 @@ class BaseRemoteAsset(APIBase): identifier: str = Field(alias="asset_id") path: str size: int - modified: datetime #: Metadata supplied at initialization; returned when metadata is requested #: instead of performing an API call _metadata: Optional[Dict[str, Any]] = PrivateAttr(default_factory=None) @@ -974,7 +962,6 @@ def _from_metadata( identifier=metadata["identifier"], path=metadata["path"], size=metadata["contentSize"], - modified=metadata["dateModified"], _metadata=metadata, ) @@ -1116,6 +1103,10 @@ class RemoteAsset(BaseRemoteAsset): #: The identifier for the version of the Dandiset to which the asset #: belongs version_id: str + #: The date at which the asset was created + created: datetime + #: The date at which the asset was last modified + modified: datetime @property def api_path(self) -> str: diff --git a/dandi/tests/test_dandiapi.py b/dandi/tests/test_dandiapi.py index da92ae88e..f221bdd82 100644 --- a/dandi/tests/test_dandiapi.py +++ b/dandi/tests/test_dandiapi.py @@ -325,6 +325,7 @@ def test_remote_asset_json_dict(text_dandiset): assert asset.json_dict() == { "asset_id": anys.ANY_STR, "modified": anys.ANY_AWARE_DATETIME_STR, + "created": anys.ANY_AWARE_DATETIME_STR, "path": anys.ANY_STR, "size": anys.ANY_INT, } @@ -587,3 +588,17 @@ def test_refresh(text_dandiset): assert dandiset.version_id == DRAFT assert dandiset.version.modified > mtime assert dandiset.most_recent_published_version is not None + + +def test_get_asset_with_and_without_metadata(mocker, text_dandiset): + path_asset = text_dandiset["dandiset"].get_asset_by_path("file.txt") + id_asset = text_dandiset["dandiset"].get_asset(path_asset.identifier) + assert path_asset == id_asset + assert path_asset._metadata is None + assert id_asset._metadata is not None + get_spy = mocker.spy(text_dandiset["client"], "get") + id_metadata = id_asset.get_raw_metadata() + get_spy.assert_not_called() + path_metadata = path_asset.get_raw_metadata() + get_spy.assert_called_once() + assert path_metadata == id_metadata