Skip to content

Commit 95694a7

Browse files
authored
Merge pull request #149 from maxibor/download
feat: add download subcommand
2 parents 2c459ec + 1ed1e3d commit 95694a7

File tree

7 files changed

+167
-6
lines changed

7 files changed

+167
-6
lines changed

AMDirT/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "1.5.0"
1+
__version__ = "1.6.0"

AMDirT/cli.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
from AMDirT.validate import run_validation
55
from AMDirT.viewer import run_app
66
from AMDirT.convert import run_convert
7-
from AMDirT.core import get_json_path
7+
from AMDirT.core import get_json_path, get_amdir_tags, get_latest_tag
88
from AMDirT.autofill import run_autofill
99
from AMDirT.merge import merge_new_df
10+
from AMDirT.download import download as download_amdir
1011
from json import load
1112

1213

@@ -294,5 +295,45 @@ def merge(ctx, no_args_is_help=True, **kwargs):
294295
merge_new_df(**kwargs, **ctx.obj)
295296

296297

298+
@cli.command()
299+
@click.option(
300+
"-t",
301+
"--table",
302+
help="AncientMetagenomeDir table to download",
303+
type=click.Choice(get_table_list()),
304+
default="ancientmetagenome-hostassociated",
305+
show_default=True,
306+
)
307+
@click.option(
308+
"-y",
309+
"--table_type",
310+
help="Type of table to download",
311+
type=click.Choice(["samples", "libraries"]),
312+
default="samples",
313+
show_default=True,
314+
)
315+
@click.option(
316+
"-r",
317+
"--release",
318+
help="Release tag to download",
319+
type=click.Choice(get_amdir_tags()),
320+
default=get_latest_tag(get_amdir_tags()),
321+
show_default=True,
322+
)
323+
@click.option(
324+
"-o",
325+
"--output",
326+
help="Output directory",
327+
type=click.Path(writable=True),
328+
default=".",
329+
show_default=True,
330+
)
331+
def download(no_args_is_help=True, **kwargs):
332+
"""\b
333+
Download a table from the AMDirT repository
334+
"""
335+
download_amdir(**kwargs)
336+
337+
297338
if __name__ == "__main__":
298339
cli()

AMDirT/core/__init__.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import pandas as pd
66
import streamlit as st
77
from packaging import version
8+
from packaging.version import InvalidVersion
89
from importlib.resources import files as get_module_dir
910
import os
1011
import logging
@@ -65,7 +66,34 @@ def get_amdir_tags():
6566
if version.parse(tag["name"]) >= version.parse("v22.09")
6667
]
6768
else:
68-
return []
69+
logger.warning(
70+
"Could not fetch tags from AncientMetagenomeDir. Defaulting to master. Metadata may not yet be officially released."
71+
)
72+
return ["master"]
73+
74+
75+
@st.cache_data
76+
def get_latest_tag(tags):
77+
try:
78+
return sorted(tags, key=lambda x: version.Version(x))[-1]
79+
except InvalidVersion:
80+
if "master" in tags:
81+
return "master"
82+
else:
83+
raise InvalidVersion("No valid tags found")
84+
85+
86+
def check_allowed_values(ref: list, test: str):
87+
"""
88+
Check if test is in ref
89+
Args:
90+
ref(list): List of allowed values
91+
test(str): value to check
92+
"""
93+
94+
if test in ref:
95+
return True
96+
return False
6997

7098

7199
def get_colour_chemistry(instrument: str) -> int:

AMDirT/download/__init__.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
from AMDirT.core import (
2+
logger,
3+
get_amdir_tags,
4+
get_remote_resources,
5+
check_allowed_values,
6+
)
7+
import requests
8+
9+
10+
def download(table: str, table_type: str, release: str, output: str = ".") -> str:
11+
"""
12+
Download a table from the AMDirT repository.
13+
14+
Parameters
15+
----------
16+
table : str
17+
The AncientMetagenomeDir table to download.
18+
table_type : str
19+
The type of table to download. Allowed values are ['samples', 'libraries'].
20+
release : str
21+
The release of the table to download. Must be a valid release tag.
22+
output: str
23+
The output directory to save the table. Default is the current directory.
24+
25+
Returns
26+
-------
27+
str:
28+
The path to the downloaded table.
29+
30+
Raises
31+
------
32+
ValueError
33+
If an invalid table is provided.
34+
ValueError
35+
If an invalid table type is provided.
36+
ValueError
37+
If an invalid release is provided.
38+
"""
39+
40+
resources = get_remote_resources()
41+
tags = get_amdir_tags()
42+
if tags != ["master"]:
43+
if check_allowed_values(tags, release) is False:
44+
raise ValueError(f"Invalid release: {release}. Allowed values are {tags}")
45+
46+
tables = resources["samples"]
47+
if check_allowed_values(tables, table) is False:
48+
raise ValueError(f"Invalid table: {table}. Allowed values are {tables}")
49+
50+
if check_allowed_values(["samples", "libraries"], table_type) is False:
51+
raise ValueError(
52+
f"Invalid table type: {table_type}. Allowed values are ['samples', 'libraries']"
53+
)
54+
table_filename = f"{table}_{table_type}_{release}.tsv"
55+
logger.info(
56+
f"Downloading {table} {table_type} table from {release} release, saving to {output}/{table_filename}"
57+
)
58+
t = requests.get(resources[table_type][table].replace("master", release))
59+
with open(table_filename, "w") as fh:
60+
fh.write(t.text)
61+
62+
return table_filename

docs/source/how_to/download.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# download
2+
3+
## What
4+
5+
Download a copy of an AncientMetagenomeDir table.
6+
7+
## When
8+
9+
This command would be used when you want to download an AncientMetagenomeDir table locally.
10+
11+
You typically do this if you're planning to use the `convert` command later.
12+
13+
## How
14+
15+
```bash
16+
AMDirT download --table ancientsinglegenome-hostassociated --table_type samples -r v23.12.0 -o .
17+
```
18+
19+
## Output
20+
21+
This example command above will download the `ancientsinglegenome-hostassociated` `sample` table from the `v23.12.0` AncientMetagenomeDir release, and save it locally to `ancientmetagenome-hostassociated_samples_v23.12.0.tsv`

docs/source/tutorials/convert.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,15 @@ We will take use one of the previous releases of AncientMetagenomeDir as an exam
1515
```bash
1616
mkdir amdirt-convert-tutorial
1717
cd amdirt-convert-tutorial
18-
curl -LO https://github.com/SPAAM-community/AncientMetagenomeDir/releases/download/v23.09.0/AncientMetagenomeDir_v23.09.0.zip
19-
unzip AncientMetagenomeDir_v23.09.0.zip
18+
AMDirT download --table ancientmetagenome-hostassociated --table_type samples -r v23.09.0
2019
```
2120

2221
## Filter a sample metadata table
2322

2423
Next we can filter the ancient metagenome 'host-associated' sample sheet for all dental calculus tables from Germany.
2524

2625
```bash
27-
cat ancientmetagenome-hostassociated/samples/ancientmetagenome-hostassociated_samples.tsv | grep -e '^project_name' -e 'dental calculus' | grep -e '^project_name' -e 'Germany' > germany_dentalcalculus.tsv
26+
cat ancientmetagenome-hostassociated_samples_v23.09.0.tsv | grep -e '^project_name' -e 'dental calculus' | grep -e '^project_name' -e 'Germany' > germany_dentalcalculus.tsv
2827
```
2928

3029
> _The command above is not robust and is only used for system portability and demonstration purposes. For example the `Germany` string could be in a site name. In practice, you should use more robust filtering methods such more specific `grep` expressions or in R_.

tests/test_download.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from AMDirT.download import download
2+
3+
4+
def test_download():
5+
table = "ancientmetagenome-hostassociated"
6+
table_type = "samples"
7+
release = "v23.12.0"
8+
9+
d = download(table, table_type, release, output=".")
10+
assert d == "ancientmetagenome-hostassociated_samples_v23.12.0.tsv"

0 commit comments

Comments
 (0)