Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion phylogenetic/defaults/config.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
# Sequences must be FASTA and metadata must be TSV
# Both files must be zstd compressed

# TODO XXX - remove commented lines below - only for testing the snakemake storage stuff
inputs:
- name: ncbi
metadata: "s3://nextstrain-data/files/workflows/zika/metadata.tsv.zst"
sequences: "s3://nextstrain-data/files/workflows/zika/sequences.fasta.zst"
# metadata: "https://data.nextstrain.org/files/workflows/zika/metadata.tsv.zst"
# sequences: "https://data.nextstrain.org/files/workflows/zika/sequences.fasta.zst"
Comment thread
jameshadfield marked this conversation as resolved.
Outdated

additional_inputs:
- name: usvi
metadata: "data/metadata_usvi.tsv"
sequences: "data/sequences_usvi.fasta"
# metadata: https://raw.githubusercontent.com/nextstrain/zika/refs/heads/main/phylogenetic/data/metadata_usvi.tsv
# sequences: https://raw.githubusercontent.com/nextstrain/zika/refs/heads/main/phylogenetic/data/sequences.fasta

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However using raw.githubusercontent.com URLs didn't work (curling them was fine):

I'm surprised this didn't work, but in this case we can work around it by moving USVI data to a public s3 bucket (refer to it by http)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case it helps, uploaded usvi to a public s3:

https://data.nextstrain.org/files/workflows/zika/sequences_usvi.fasta.zst
https://data.nextstrain.org/files/workflows/zika/metadata_usvi.tsv.zst

Happy to drop the ./data directory subsequently

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this was a case of typo resulting in unexpected error? (I would have expected a 404 error)

Works fine with

Suggested change
# sequences: https://raw.githubusercontent.com/nextstrain/zika/refs/heads/main/phylogenetic/data/sequences.fasta
sequences: https://raw.githubusercontent.com/nextstrain/zika/refs/heads/main/phylogenetic/data/sequences_usvi.fasta

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo indeed! Ok that fixes it, and I've pushed up a WIP commit which we can fix up later on: cc86bd7.

The error messaging around remote files (see main PR comment) doesn't seem ideal.

@jameshadfield jameshadfield Jul 9, 2025

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case it helps, uploaded usvi to a public s3:

@j23414 can you test out those files and see if you can reproduce the error i'm getting:

$ curl  -o metadata_usvi.tsv.zst https://data.nextstrain.org/files/workflows/zika/metadata_usvi.tsv.zst

$ zstd --decompress --stdout metadata_usvi.tsv.zst
[expected TSV output]

$ augur filter --metadata metadata_usvi.tsv.zst --output-metadata x
Traceback (most recent call last):
  File "/Users/naboo/github/nextstrain/augur/augur/__init__.py", line 70, in run
    return args.__command__.run(args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/naboo/github/nextstrain/augur/augur/filter/__init__.py", line 161, in run
    return _run(args)
           ^^^^^^^^^^
  File "/Users/naboo/github/nextstrain/augur/augur/filter/_run.py", line 198, in run
    metadata_reader = read_metadata(
                      ^^^^^^^^^^^^^^
  File "/Users/naboo/github/nextstrain/augur/augur/io/metadata.py", line 96, in read_metadata
    metadata = pd.read_csv(
               ^^^^^^^^^^^^
  File "/Users/naboo/miniconda3/envs/augur-dev-snakemake-v9/lib/python3.12/site-packages/pandas/io/parsers/readers.py", line 1026, in read_csv
    return _read(filepath_or_buffer, kwds)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/naboo/miniconda3/envs/augur-dev-snakemake-v9/lib/python3.12/site-packages/pandas/io/parsers/readers.py", line 620, in _read
    parser = TextFileReader(filepath_or_buffer, **kwds)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/naboo/miniconda3/envs/augur-dev-snakemake-v9/lib/python3.12/site-packages/pandas/io/parsers/readers.py", line 1620, in __init__
    self._engine = self._make_engine(f, self.engine)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/naboo/miniconda3/envs/augur-dev-snakemake-v9/lib/python3.12/site-packages/pandas/io/parsers/readers.py", line 1898, in _make_engine
    return mapping[engine](f, **self.options)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/naboo/miniconda3/envs/augur-dev-snakemake-v9/lib/python3.12/site-packages/pandas/io/parsers/c_parser_wrapper.py", line 93, in __init__
    self._reader = parsers.TextReader(src, **kwds)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "parsers.pyx", line 574, in pandas._libs.parsers.TextReader.__cinit__
  File "parsers.pyx", line 663, in pandas._libs.parsers.TextReader._get_header
  File "parsers.pyx", line 874, in pandas._libs.parsers.TextReader._tokenize_rows
  File "parsers.pyx", line 891, in pandas._libs.parsers.TextReader._check_tokenize_status
  File "parsers.pyx", line 2053, in pandas._libs.parsers.raise_parser_error
zstd.ZstdError: zstd decompress error: Unknown frame descriptor


An error occurred (see above) that has not been properly handled by Augur.
To report this, please open a new issue including the original command and the error above:
    <https://github.com/nextstrain/augur/issues/new/choose>

(I'm getting the same errors using Snakemake HTTP storage plugin, but the above curl seemed simpler to detail)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, I'm getting the same error

...
zstd.ZstdError: zstd decompress error: Unknown frame descriptor

Versions below, I'm using isolated conda runtime:

nextstrain shell .
augur --version
#> augur 31.2.0

exit

nextstrain --version
#> Nextstrain CLI 10.2.0 (standalone)

@j23414 j23414 Jul 9, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I have an idea what happened. I've uploaded new fixed metadata_usvi.tsv.zst and sequences_usvi.fasta.zst files and the error disappeared.

Originally I had tried uploading via

# upload uncompressed TSV
envdir ~/nextstrain/env.d/seasonal-flu/ \
  nextstrain remote upload s3://nextstrain-data/files/workflows/zika/ metadata_usvi.tsv

# downloaded to verify
mkdir local; cd local
wget https://data.nextstrain.org/files/workflows/zika/metadata_usvi.tsv
less metadata_usvi.tsv

Realized that metadata_usvi.tsv had been zstd compressed during upload... geh

# renamed downloaded file to metadata_usvi.tsv.zst
mv metadata_usvi.tsv metadata_usvi.tsv.zst

# Uploaded the zst file
envdir ~/nextstrain/env.d/seasonal-flu/ \
  nextstrain remote upload s3://nextstrain-data/files/workflows/zika/ metadata_usvi.tsv.zst

I should have locally compressed and uploaded it directly

zstd metadata_usvi.tsv
envdir ~/nextstrain/env.d/seasonal-flu/ \
  nextstrain remote upload s3://nextstrain-data/files/workflows/zika/ metadata_usvi.tsv.zst

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Realized that metadata_usvi.tsv had been zstd compressed during upload... geh

Yeah, nextstrain upload does that automagically which is often what we want (e.g. for auspice JSONs), but when it's not it's always frustrating to debug! Thanks for fixing


# Config files
exclude: "exclude.txt"
Expand Down Expand Up @@ -41,3 +46,4 @@ traits:
- region
- country
sampling_bias_correction: 3
#
96 changes: 6 additions & 90 deletions phylogenetic/rules/merge_inputs.smk
Original file line number Diff line number Diff line change
Expand Up @@ -22,55 +22,7 @@ This part of the workflow usually includes the following steps:

"""


# ------------- helper functions to collect, merge & download input files ------------------- #
NEXTSTRAIN_PUBLIC_BUCKET = "s3://nextstrain-data/"

def _parse_config_input(input):
"""
Parses information from an individual config-defined input, i.e. an element within `config.inputs` or `config.additional_inputs`
and returns information snakemake rules can use to obtain the underlying data.

The structure of `input` is a dictionary with keys:
- name:string (required)
- metadata:string (optional) - a s3 URI or a local file path
- sequences:string (optional) - a s3 URI or a local file path

Returns a dictionary with optional keys:
- metadata:string - the relative path to the metadata file. If the original data was remote then this represents
the output of a rule which downloads the file
- metadata_location:string - the URI for the remote file if applicable else `None`
- sequences:string - the relative path to the sequences FASTA. If the original data was remote then this represents
the output of a rule which downloads the file
- sequences_location:string - the URI for the remote file if applicable else `None`

Raises InvalidConfigError
"""
name = input['name']

info = {'metadata': None, 'metadata_location': None, 'sequences': None, 'sequences_location': None}

def _source(uri, *, s3, local):
if uri.startswith('s3://'):
return s3
elif uri.lower().startswith(('http://','https://')):
raise InvalidConfigError("Workflow cannot yet handle HTTP[S] inputs")
# USVI files are expected to be part of the workflow source,
# and are _not_ expected to be provided via the analysis directory
elif uri.startswith('data/metadata_usvi.tsv') or uri.startswith('data/sequences_usvi.fasta'):
return workflow.source_path("../" + uri)
return local

if location:=input.get('metadata', False):
info['metadata'] = _source(location, s3=f"data/{name}/metadata.tsv", local=location)
info['metadata_location'] = _source(location, s3=location, local=None)

if location:=input.get('sequences', False):
info['sequences'] = _source(location, s3=f"data/{name}/sequences.fasta", local=location)
info['sequences_location'] = _source(location, s3=location, local=None)

return info

include: "remote_files.smk"
Comment thread
jameshadfield marked this conversation as resolved.

def _gather_inputs():
all_inputs = [*config['inputs'], *config.get('additional_inputs', [])]
Expand All @@ -85,7 +37,11 @@ def _gather_inputs():
if not all(['name' in i and ('sequences' in i or 'metadata' in i) for i in all_inputs]):
raise InvalidConfigError("Each input (config.inputs and config.additional_inputs) must have a 'name' and 'metadata' and/or 'sequences'")

return {i['name']: _parse_config_input(i) for i in all_inputs}
available_keys = set(['name', 'metadata', 'sequences'])
if any([len(set(el.keys())-available_keys)>0 for el in all_inputs]):
raise InvalidConfigError(f"Each input (config.inputs and config.additional_inputs) can only include keys of {', '.join(available_keys)}")

return {el['name']: {k:(v if k=='name' else path_or_url(v)) for k,v in el.items()} for el in all_inputs}

input_sources = _gather_inputs()

Expand All @@ -97,44 +53,6 @@ def input_sequences(wildcards):
inputs = [info['sequences'] for info in input_sources.values() if info.get('sequences', None)]
return inputs[0] if len(inputs)==1 else "results/sequences_merged.fasta"

rule download_s3_sequences:
output:
sequences = "data/{input_name}/sequences.fasta",
log:
"logs/{input_name}/download_s3_sequences.txt",
benchmark:
"benchmarks/{input_name}/download_s3_sequences.txt"
params:
address = lambda w: input_sources[w.input_name]['sequences_location'],
no_sign_request=lambda w: "--no-sign-request" \
if input_sources[w.input_name]['sequences_location'].startswith(NEXTSTRAIN_PUBLIC_BUCKET) \
else "",
shell:
r"""
exec &> >(tee {log:q})

aws s3 cp {params.no_sign_request:q} {params.address:q} - | zstd -d > {output.sequences}
"""

rule download_s3_metadata:
output:
metadata = "data/{input_name}/metadata.tsv",
log:
"logs/{input_name}/download_s3_metadata.txt",
benchmark:
"benchmarks/{input_name}/download_s3_metadata.txt"
params:
address = lambda w: input_sources[w.input_name]['metadata_location'],
no_sign_request=lambda w: "--no-sign-request" \
if input_sources[w.input_name]['metadata_location'].startswith(NEXTSTRAIN_PUBLIC_BUCKET) \
else "",
shell:
r"""
exec &> >(tee {log:q})

aws s3 cp {params.no_sign_request:q} {params.address:q} - | zstd -d > {output.metadata}
"""

rule merge_metadata:
"""
This rule should only be invoked if there are multiple defined metadata inputs
Expand Down Expand Up @@ -180,5 +98,3 @@ rule merge_sequences:

seqkit rmdup {input:q} > {output.sequences:q}
"""

# -------------------------------------------------------------------------------------------- #
9 changes: 9 additions & 0 deletions phylogenetic/rules/prepare_sequences.smk
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ rule filter:
--min-length {params.min_length:q}
"""

rule upload_filter:
"""TESTING ONLY TODO XXX REMOVE"""
input: "results/filtered.fasta"
output: path_or_url("s3://nextstrain-scratch/testing-zika-filtered.fasta")
shell:
r"""
cp {input[0]} {output[0]}
"""

rule align:
"""
Aligning sequences to {input.reference}
Expand Down
82 changes: 82 additions & 0 deletions phylogenetic/rules/remote_files.smk
Comment thread
joverlee521 marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
"""
Helper functions to set-up storage plugins for remote inputs/outputs.
See the docstring of `path_or_url` for usage instructions.

<https://snakemake.readthedocs.io/en/stable/snakefiles/storage.html>
"""

from urllib.parse import urlparse

PUBLIC_BUCKETS = set(['nextstrain-data']) # TODO XXX

_storage_registry = {} # keeps track of registered storage plugins to enable reuse

def _storage_s3(*, bucket, keep_local, force_signed):
"""
Returns a Snakemake storage plugin for S3 endpoints
"""
retries=2 # num S3 retries attempted

# If the bucket is public then we make an unsigned request (i.e. no AWS credentials
# need to be set). Note that this won't work for uploads.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should drop this special-treatment of known public buckets? It would simplify the code and let us avoid the force_signed argument. For dev purposes I find it frustrating to have to load credentials to fetch data in s3://nextstrain-data, but we could instead avoid this by using https://data.nextstrain.org/... URLs.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm open to public buckets being referred to by the https: URLs.

And then keeping s3 handling for less public (private? restricted use?) datasets in case that usecase shows up if it hasn't already.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for removing the special treatment for public buckets.

I say follow our own guidance from ncov/remote_inputs docs:

If you’re running workflows on AWS or GCP compute that fetch this data, please use the S3 or GS URLs, respectively, for cheaper (for us) and faster (for you) data transfers. Otherwise, please use the https://data.nextstrain.org/ URLs.

Note that even though the s3://nextstrain-data/ and gs://nextstrain-data/ buckets are public, the defaults for most S3 and GS clients require some user to be authenticated, though the specific user/account doesn’t matter. In the rare case you need to access the S3 or GS buckets anonymously, the easiest way is to configure your inputs using https://nextstrain-data.s3.amazonaws.com/files/ncov/open/ or https://storage.googleapis.com/nextstrain-data/files/ncov/open/ URLs instead.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I'd say that advice is conditioned on the situation where we have to be authenticated for public bucket requests. But this PR shows we don't. So if we pay a small code-complexity price we can get cheaper & faster transfers (S3) without the frustrating UX of needing to provide credentials. If it were only data downloading I'd keep this PR as is, it was only when testing/considering uploads that I started to question it. I'll think about this some more.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the misleading errors around credentials, should we enforce credential requirements here, e.g.:

assert "AWS_ACCESS_KEY_ID" in os.environ and "AWS_SECRET_ACCESS_KEY" in os.environ, \
        "Must set `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables for S3 files"

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the code and I'm happy with the UX now. Here's the logic of when we use signed vs unsigned:

If the bucket is public then we may use an unsigned request which has the nice UX of not needing credentials to be present. If we've made other signed requests or credentials are present then we just sign everything. This has implications for upload: if you attempt to upload to a public bucket without credentials then we allow that here and you'll get a subsequent AccessDenied error when the upload is attempted.

and a table of situations:

S3 buckets credentials present credentials missing
download private / private + public signed Error 1
public signed unsigned
upload private / private + public signed Error 1
public signed Error 2

Error 1:

AWS credentials are required to access <S3 URI>

Error 2:

WorkflowError:
Failed to store output in storage <S3 URI>
ClientError: An error occurred (AccessDenied) when calling the CreateBucket operation: Anonymous users cannot invoke this API. Please authenticate.
WorkflowError:
Failed to get mtime of <S3 URI>
ClientError: An error occurred (AccessDenied) when calling the ListObjects operation: Access Denied

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for thinking this through @jameshadfield, I really like the outlined behavior!

Providing bad credentials produce slightly different errors, but they should be informative for the user:

$ nextstrain build --image nextstrain/base:branch-snakemake-v9 --env AWS_ACCESS_KEY_ID=foo --env AWS_SECRET_ACCESS_KEY=bar phylogenetic/ --forcerun merge_metadata
Assuming unrestricted shared filesystem usage.
host: 0f11191f17e0
Building DAG of jobs...
WorkflowError:
Failed to retrieve input from storage.
WorkflowError:
    Failed to get mtime of s3://nextstrain-data/files/workflows/zika/metadata.tsv.zst
    ClientError: An error occurred (InvalidAccessKeyId) when calling the ListObjects operation: The AWS Access Key Id you provided does not exist in our records.
$ nextstrain build --image nextstrain/base:branch-snakemake-v9 --env AWS_ACCESS_KEY_ID=foo --env AWS_SECRET_ACCESS_KEY=bar phylogenetic/ --forcerun filter
Assuming unrestricted shared filesystem usage.
host: 2d666b298294
Building DAG of jobs...
WorkflowError:
Failed to check existence of s3://nextstrain-data/files/workflows/zika/metadata.tsv.zst
ClientError: An error occurred (403) when calling the HeadObject operation: Forbidden

if not force_signed and bucket in PUBLIC_BUCKETS:
if provider:=_storage_registry.get('s3_unsigned', None):
return provider

from botocore import UNSIGNED
storage s3_unsigned:
provider="s3",
signature_version=UNSIGNED,
retries=retries,
keep_local=keep_local,

_storage_registry['s3_unsigned'] = storage.s3_unsigned
return _storage_registry['s3_unsigned']

# Default: resource fetched via a signed request, which will require AWS credentials
if provider:=_storage_registry.get('s3_signed', None):
return provider

# the tag appears in the local file path, so reference 'signed' to give a hint about credential errors
storage s3_signed:
provider="s3",
retries=retries,
keep_local=keep_local,

_storage_registry['s3_signed'] = storage.s3_signed
return _storage_registry['s3_signed']

def _storage_http(*, keep_local):
if provider:=_storage_registry.get('http', None):
return provider

storage:
provider="http",
allow_redirects=True,
supports_head=True,
keep_local=keep_local,

_storage_registry['http'] = storage.http
return _storage_registry['http']

def path_or_url(uri, *, keep_local=True, force_signed=False):
"""
Returns the URI wrapped by an applicable storage plugin.
Local filepaths will be returned unchanged.

TODO XXX - document usage more thoroughly
"""
info = urlparse(uri)

if info.scheme=='': # local
return uri # no storage wrapper

if info.scheme=='s3':
return _storage_s3(bucket=info.netloc, keep_local=keep_local, force_signed=force_signed)(uri)

if info.scheme in ['http', 'https']:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to support plain HTTP? Requiring HTTPS doesn't feel onerous and is kind of a security best-practice

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's currently supported in ncov so I think we're trying to keep the functionality the same here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...ok, but -- is it actually used in ncov? because this feels like a great time for a deprecation…

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True! Especially since the Snakemake upgrade is a breaking change anyways...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return _storage_http(keep_local=keep_local)(uri)

# TODO XXX - Google? We allowed this in ncov <https://github.com/nextstrain/ncov/blob/41cf6470d3140963ff3e02c29241f80ae8ed9c33/workflow/snakemake_rules/remote_files.smk#L62>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for supporting GS urls if possible (e.g. Terra users, etc)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, I've included the GS plugin (snakemake-storage-plugin-gcs) in nextstrain/docker-base#257

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good - can one of you add it to this PR?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added in 70e16f8, but not sure how to test here...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@j23414 are you able to test the GS stuff? I presume Broad is mirroring the zika files?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, seems like Broad is mirroring everything in nextstrain-data to GS, so I found
https://storage.googleapis.com/nextstrain-data/files/workflows/zika/metadata.tsv.zst
(gs://nextstrain-data/files/workflows/zika/metadata.tsv.zst) which we can use to test.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@j23414 and I discussed GS in person yesterday.

We ran into authentication errors that indicates you need to set up Application Default Credentials in order to use the GS plugin. I have not found any way of passing in credentials via envvars for this plugin....

Even the old Snakemake v7 GS provider required you to login via gcloud auth before running Snakemake. I'm not sure how well this ever worked with the Docker runtime. The gcloud auth command creates a JSON file that is stored at ~/.config/gcloud/application_default_credentials.json, which is not accessible in the docker runtime. You can use GOOGLE_APPLICATION_CREDENTIALS to define a separate location for the credentials file, so you could create the credentials JSON within the pathogen repo and pass the --env GOOGLE_APPLICATION_CREDENTIALS=... to use it in the Docker runtime, but I'm not sure how safe that is...

All that is to say, I'm walking back on my support for GS and think it's not worth the trouble.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for testing! I'm going to take this code over to ncov now and will remove GS. I'll add a specific conditional to catch the GS scheme (and HTTP) and raise an error telling users to get in touch with us because we can add those functionality if pushed to do so.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


raise Exception(f"Input address {uri!r} (scheme={info.scheme!r}) is from a non-supported remote")
Loading