Repository: dandi/dandi-cli

Issue:
downloading multiple assets using paths does not work
two issues here:
- [ ] download for path does not work
- [ ] error logs should perhaps give instructions on how to expand error details. (for example use `-l DEBUG` and then copy and paste the entire log information)

```
$ dandi download 'https://api.dandiarchive.org/api/dandisets/000003/versions/draft/assets/?path=sub-YutaMouse20'
2021-04-10 14:49:45,345 [    INFO] Logs saved in /home/jovyan/.cache/dandi-cli/log/20210410144944Z-214.log
Error: 'asset_id'
```
and corresponding log

```
$ cat /home/jovyan/.cache/dandi-cli/log/20210410144944Z-214.log
2021-04-10T14:49:44+0000 [INFO    ] dandi 214:139639097767744 sys.argv = ['/opt/conda/bin/dandi', 'download', 'https://api.dandiarchive.org/api/dandisets/000003/versions/draft/assets/?path=sub-YutaMouse20']
2021-04-10T14:49:44+0000 [INFO    ] dandi 214:139639097767744 os.getcwd() = /home/jovyan/temp
2021-04-10T14:49:45+0000 [INFO    ] dandi 214:139639097767744 Logs saved in /home/jovyan/.cache/dandi-cli/log/20210410144944Z-214.log
```


```
$ dandi -l DEBUG download 'https://api.dandiarchive.org/api/dandisets/000003/versions/draft/assets/?path=sub-YutaMouse20'
2021-04-10 14:53:22,858 [   DEBUG] No newer (than 0.13.0) version of dandi/dandi-cli found available
2021-04-10 14:53:23,298 [   DEBUG] Caught exception 'asset_id'
2021-04-10 14:53:23,298 [    INFO] Logs saved in /home/jovyan/.cache/dandi-cli/log/20210410145322Z-401.log
Error: 'asset_id'
```
and the corresponding details
```
$ cat /home/jovyan/.cache/dandi-cli/log/20210410145322Z-401.log
2021-04-10T14:53:22+0000 [INFO    ] dandi 401:139713960601408 sys.argv = ['/opt/conda/bin/dandi', '-l', 'DEBUG', 'download', 'https://api.dandiarchive.org/api/dandisets/000003/versions/draft/assets/?path=sub-YutaMouse20']
2021-04-10T14:53:22+0000 [INFO    ] dandi 401:139713960601408 os.getcwd() = /home/jovyan/temp
2021-04-10T14:53:22+0000 [DEBUG   ] dandi 401:139713960601408 No newer (than 0.13.0) version of dandi/dandi-cli found available
2021-04-10T14:53:23+0000 [DEBUG   ] dandi 401:139713960601408 Parsing url https://api.dandiarchive.org/api/dandisets/000003/versions/draft/assets/?path=sub-YutaMouse20
2021-04-10T14:53:23+0000 [DEBUG   ] dandi 401:139713960601408 Parsed into ('api', 'https://api.dandiarchive.org/api/', 'item', {'dandiset_id': '000003', 'version': 'draft', 'asset_id': '?path=sub-YutaMouse20'})
2021-04-10T14:53:23+0000 [DEBUG   ] dandi 401:139713960601408 Parsing url https://api.dandiarchive.org/api/dandisets/000003/versions/draft/assets/?path=sub-YutaMouse20
2021-04-10T14:53:23+0000 [DEBUG   ] dandi 401:139713960601408 Parsed into ('api', 'https://api.dandiarchive.org/api/', 'item', {'dandiset_id': '000003', 'version': 'draft', 'asset_id': '?path=sub-YutaMouse20'})
2021-04-10T14:53:23+0000 [DEBUG   ] dandi 401:139713960601408 GET https://api.dandiarchive.org/api/dandisets/000003/versions/draft/
2021-04-10T14:53:23+0000 [DEBUG   ] dandi 401:139713960601408 Response: 200
2021-04-10T14:53:23+0000 [DEBUG   ] dandi 401:139713960601408 GET https://api.dandiarchive.org/api/dandisets/000003/versions/draft/assets/?path=sub-YutaMouse20/
2021-04-10T14:53:23+0000 [DEBUG   ] dandi 401:139713960601408 Response: 200
2021-04-10T14:53:23+0000 [DEBUG   ] dandi 401:139713960601408 Found identifier 000003 in 'dandiset.identifier'
2021-04-10T14:53:23+0000 [DEBUG   ] dandi 401:139713960601408 Caught exception 'asset_id'
2021-04-10T14:53:23+0000 [INFO    ] dandi 401:139713960601408 Logs saved in /home/jovyan/.cache/dandi-cli/log/20210410145322Z-401.log
```

Discussion:

Patch:
diff --git a/dandi/dandiarchive.py b/dandi/dandiarchive.py
index 5f56eacc..55e1f7d8 100644
--- a/dandi/dandiarchive.py
+++ b/dandi/dandiarchive.py
@@ -198,12 +198,22 @@ class _dandi_url_parser:
             re.compile(
                 rf"{server_grp}(?P<asset_type>dandiset)s/{dandiset_id_grp}"
                 r"/versions/(?P<version>[.0-9]{5,}|draft)"
-                r"/assets/(?P<asset_id>[^/]+)(/(download/?)?)?"
+                r"/assets/(?P<asset_id>[^?/]+)(/(download/?)?)?"
             ),
             {"server_type": "api"},
             "https://<server>[/api]/dandisets/<dandiset id>/versions/<version>"
             "/assets/<asset id>[/download]",
         ),
+        (
+            re.compile(
+                rf"{server_grp}(?P<asset_type>dandiset)s/{dandiset_id_grp}"
+                r"/versions/(?P<version>[.0-9]{5,}|draft)"
+                r"/assets/\?path=(?P<path>[^&]+)",
+            ),
+            {"server_type": "api"},
+            "https://<server>[/api]/dandisets/<dandiset id>/versions/<version>"
+            "/assets/?path=<path>",
+        ),
         # But for drafts files navigator it is a bit different beast and there
         # could be no versions, only draft
         # https://deploy-preview-341--gui-dandiarchive-org.netlify.app/#/dandiset/000027/draft/files?_id=5f176583f63d62e1dbd06943&_modelType=folder
@@ -375,6 +385,7 @@ class _dandi_url_parser:
         version = groups.get("version")
         location = groups.get("location")
         asset_key = groups.get("asset_id")
+        path = groups.get("path")
         if location:
             location = urlunquote(location)
             # ATM carries leading '/' which IMHO is not needed/misguiding somewhat, so
@@ -396,6 +407,9 @@ class _dandi_url_parser:
         elif asset_key:
             asset_type = "item"
             asset_ids["asset_id"] = asset_key
+        elif path:
+            asset_type = "folder"
+            asset_ids["location"] = path
         # TODO: remove whenever API supports "draft" and this type of url
         if groups.get("id"):
             assert version == "draft"


Test patch:
diff --git a/dandi/tests/test_dandiarchive.py b/dandi/tests/test_dandiarchive.py
index f4df0c63..4a6ee420 100644
--- a/dandi/tests/test_dandiarchive.py
+++ b/dandi/tests/test_dandiarchive.py
@@ -140,6 +140,17 @@ def test_parse_girder_url(url, asset_type, asset_id):
                 "asset_id": "0a748f90-d497-4a9c-822e-9c63811db412",
             },
         ),
+        (
+            "https://api.dandiarchive.org/api/dandisets/000003/versions/draft"
+            "/assets/?path=sub-YutaMouse20",
+            "dandi-api",
+            "folder",
+            {
+                "dandiset_id": "000003",
+                "version": "draft",
+                "location": "sub-YutaMouse20",
+            },
+        ),
     ],
 )
 def test_parse_api_url(url, instance, asset_type, asset_id):