Skip to content

Commit 72992d9

Browse files
authored
Merge pull request #535 from dandi/gh-533
Support parsing & navigating asset download URLs
2 parents 2f7e3d6 + 3511a1c commit 72992d9

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

dandi/dandiarchive.py

+20-3
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,19 @@ def navigate_url(url):
5151
asset_id["version"] = r["most_recent_version"]["version"]
5252
args = (asset_id["dandiset_id"], asset_id["version"])
5353
kwargs["include_metadata"] = True
54-
if asset_id.get("location"):
54+
if asset_id.get("location") or asset_id.get("asset_id"):
5555
with client.session():
5656
dandiset = client.get_dandiset(*args)
5757
if asset_type == "folder":
5858
assets = client.get_dandiset_assets(
5959
*args, path=asset_id["location"]
6060
)
6161
elif asset_type == "item":
62-
asset = client.get_asset_bypath(*args, asset_id["location"])
63-
assets = [asset] if asset is not None else []
62+
if "location" in asset_id:
63+
asset = client.get_asset_bypath(*args, asset_id["location"])
64+
assets = [asset] if asset is not None else []
65+
else:
66+
assets = [client.get_asset(*args, asset_id["asset_id"])]
6467
else:
6568
raise NotImplementedError(
6669
f"Do not know how to handle asset type {asset_type} with location"
@@ -183,6 +186,16 @@ class _dandi_url_parser:
183186
{"server_type": "api"},
184187
"https://<server>[/api]/dandisets/<dandiset id>[/versions[/<version>]]",
185188
),
189+
(
190+
re.compile(
191+
rf"{server_grp}(?P<asset_type>dandiset)s/{dandiset_id_grp}"
192+
r"/versions/(?P<version>[.0-9]{5,}|draft)"
193+
r"/assets/(?P<asset_id>[^/]+)(/(download/?)?)?"
194+
),
195+
{"server_type": "api"},
196+
"https://<server>[/api]/dandisets/<dandiset id>/versions/<version>"
197+
"/assets/<asset id>[/download]",
198+
),
186199
# But for drafts files navigator it is a bit different beast and there
187200
# could be no versions, only draft
188201
# https://deploy-preview-341--gui-dandiarchive-org.netlify.app/#/dandiset/000027/draft/files?_id=5f176583f63d62e1dbd06943&_modelType=folder
@@ -353,6 +366,7 @@ def parse(cls, url, *, map_instance=True):
353366
dandiset_id = groups.get("dandiset_id")
354367
version = groups.get("version")
355368
location = groups.get("location")
369+
asset_key = groups.get("asset_id")
356370
if location:
357371
location = urlunquote(location)
358372
# ATM carries leading '/' which IMHO is not needed/misguiding somewhat, so
@@ -371,6 +385,9 @@ def parse(cls, url, *, map_instance=True):
371385
else:
372386
asset_type = "item"
373387
asset_ids["location"] = location
388+
elif asset_key:
389+
asset_type = "item"
390+
asset_ids["asset_id"] = asset_key
374391
# TODO: remove whenever API supports "draft" and this type of url
375392
if groups.get("id"):
376393
assert version == "draft"

dandi/tests/test_dandiarchive.py

+11
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,17 @@ def test_parse_girder_url(url, asset_type, asset_id):
129129
# "folder_id": "5f176583f63d62e1dbd06943",
130130
# },
131131
# )
132+
(
133+
"https://api.dandiarchive.org/api/dandisets/000003/versions/draft"
134+
"/assets/0a748f90-d497-4a9c-822e-9c63811db412/download/",
135+
"dandi-api",
136+
"item",
137+
{
138+
"dandiset_id": "000003",
139+
"version": "draft",
140+
"asset_id": "0a748f90-d497-4a9c-822e-9c63811db412",
141+
},
142+
),
132143
],
133144
)
134145
def test_parse_api_url(url, instance, asset_type, asset_id):

0 commit comments

Comments
 (0)