Skip to content

Instantly share code, notes, and snippets.

@tsibley
Created March 23, 2023 17:30
Show Gist options
  • Save tsibley/1f5d43e8320fd6777738f4bada0fa7b4 to your computer and use it in GitHub Desktop.
Save tsibley/1f5d43e8320fd6777738f4bada0fa7b4 to your computer and use it in GitHub Desktop.
commit 481c822bc0eff8173be7788ca9b4acc48359c0c2
Author: Thomas Sibley <[email protected]>
Date: Wed Nov 9 09:39:37 2022 -0800
wip! remote download: not in manifest
diff --git a/nextstrain/cli/remote/nextstrain_dot_org.py b/nextstrain/cli/remote/nextstrain_dot_org.py
index 4c7f5c8..fd4c420 100644
--- a/nextstrain/cli/remote/nextstrain_dot_org.py
+++ b/nextstrain/cli/remote/nextstrain_dot_org.py
@@ -127,6 +127,20 @@ class SubResource(NamedTuple):
file_extension: str
primary: bool = False
+ def __str__(self) -> str:
+ type, subtype = self.media_type.split("/", 1)
+ subtype_tree = tuple(subtype.split("."))
+
+ resource = (
+ "dataset" if subtype_tree[0:3] == ("vnd", "nextstrain", "dataset") else
+ "narrative" if subtype_tree[0:3] == ("vnd", "nextstrain", "narrative") else
+ self.media_type
+ )
+
+ sidecar = sidecar_suffix(self.media_type)
+
+ return f"{resource} ({sidecar})" if sidecar else resource
+
class Dataset(Resource):
"""
@@ -336,7 +350,18 @@ def download(url: urllib.parse.ParseResult, local_path: Path, recursively: bool
with requests.Session() as http:
http.auth = auth()
- resources = _ls(path, recursively = recursively, http = http)
+ if recursively:
+ resources = _ls(path, recursively = recursively, http = http)
+ else:
+ # Avoid the query and just try to download the single resource.
+ # This saves a request for single-dataset (or narrative) downloads,
+ # but also allows downloading core datasets which aren't in the
+ # manifest. (At least until the manifest goes away.)
+ # -trs, 9 Nov 2022
+ if narratives_only(path):
+ resources = [Narrative({"request": path})]
+ else:
+ resources = [Dataset({"request": path})]
if not resources:
raise UserError(f"Path {path} does not seem to exist")
@@ -361,7 +386,9 @@ def download(url: urllib.parse.ParseResult, local_path: Path, recursively: bool
# Check for bad response
raise_for_status(response)
- assert content_media_type(response) == subresource.media_type
+
+ if content_media_type(response) != subresource.media_type:
+ raise UserError(f"Path {path} does not seem to be a {subresource}.")
# Local destination
if local_path.is_dir():
@@ -485,7 +512,7 @@ def remote_path(url: urllib.parse.ParseResult) -> NormalizedPath:
return normalize_path(url.path)
-def normalize_path(path: str) -> NormalizedPath:
+def normalize_path(path: Union[str, NormalizedPath]) -> NormalizedPath:
"""
Ensure the URL *path* starts with a single ``/`` and ends without one, then
wrap in a :class:`PurePosixPath` subclass (:class:`NormalizedPath`), for
@@ -500,6 +527,8 @@ def normalize_path(path: str) -> NormalizedPath:
>>> normalize_path("/")
NormalizedPath('/')
"""
+ if isinstance(path, NormalizedPath):
+ return path
return NormalizedPath("/" + path.strip("/"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment