# HG changeset patch # User jpayne # Date 1765225083 0 # Node ID 79fa4330f2c902515af582c9bf700d2a224de352 planemo upload commit 27af5cba48986d508a67a5024a3bd35dd47bee15-dirty diff -r 000000000000 -r 79fa4330f2c9 bio2srr.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bio2srr.py Mon Dec 08 20:18:03 2025 +0000 @@ -0,0 +1,276 @@ +"Grab SRR numbers from Bioprojects and sub-bioprojects via Eutils" + +import requests +import sys +import csv +import os + +try: + from itertools import batched +except ImportError: + from itertools import islice + def batched(iterable, n): + "Batch data into tuples of length n. The last batch may be shorter." + # batched('ABCDEFG', 3) --> ABC DEF G + if n < 1: + raise ValueError('n must be at least one') + it = iter(iterable) + while batch := tuple(islice(it, n)): + yield batch +from functools import cmp_to_key +from time import sleep +from xml.etree import ElementTree as xml + +esearch = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi" +esummary = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi" +elink = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/elink.fcgi" + + +import logging +logging.basicConfig(level=logging.INFO) + +logger = logging.getLogger("bio2srr") + +extra_params = {} + +api_key = os.environ.get("NCBI_API_KEY") + +if api_key: + logger.info(f"Using NCBI API key {api_key[:4]}{'*' * (len(api_key) - 8)}{api_key[-4:]}") + extra_params["api_key"] = api_key + +def log(msg): + if api_key: + logger.info(msg.replace(api_key, f"{api_key[:4]}{'*' * (len(api_key) - 8)}{api_key[-4:]}")) # fix logging later + else: + logger.info(msg) + +def get_tag(root, tag): + val = root.find(tag) + if val is not None: + return val.text + log(f"No result for {tag}") + + + +def header_sort_override(a, b): + if a == b: + return 0 + try: + for name in ["bioproject", "srr_accession", "biosample_accession", "organism", "taxid", "package",]: + if a == name: + return -1 + if b == name: + return 1 + except: + pass + if a < b: + return -1 + else: + return 1 + +hso = cmp_to_key(header_sort_override) + +def resolve_bioproject_ids_and_links(bioproject_id_list): + "Recursively follow bioproject and biosample links, yield biosample UID's and biosample XML" + for i, (bioproject, bioproject_id) in enumerate(bioproject_id_list): + log(f"Processing {bioproject} ({bioproject_id}) {i+1}/{len(bioproject_id_list)}") + #get bioproject to bioproject links + response = requests.get(elink, params=dict(db="bioproject", dbfrom="bioproject", id=bioproject_id, format="json", **extra_params)) + response.raise_for_status() + reply = response.json() + linksets = reply.get("linksets", [{}])[0].get("linksetdbs", [0,0,{}]) + if len(linksets) >= 3: + for id in linksets[2].get("links", []): #third index is the up to down links + response = requests.get(esummary, params=dict(id=id, db="bioproject", format="json")) + response.raise_for_status() + replyy = response.json() + biop = replyy["result"][id]["project_acc"] + if id not in bioproject_id_list: + bioproject_id_list.append((biop, id)) # recurse over bioproject links + # get bioproject to biosample links + response = requests.get(elink, params=dict(db="biosample", dbfrom="bioproject", id=bioproject_id, format="json", **extra_params)) + response.raise_for_status() + reply = response.json() + links = reply.get("linksets", [{}])[0].get("linksetdbs", [{}])[0].get("links", []) + log(f"Found {len(links)} biosample links for {bioproject} ({bioproject_id})") + for ids in batched(links, 200): + response = requests.get(esummary, params=dict(id=",".join(ids), db="biosample", format="json")) + response.raise_for_status() + replyy = response.json() + for field, value in replyy.get("result", {}).items(): + if "uids" not in field: + yield bioproject, field, value["sampledata"] # this is XML, deleriously + sleep(1 if not api_key else 0.1) + + +biosample_example = """ + + + SAMN17131268 + CJP19-D996 + + + Pathogen: environmental/food/other sample from Campylobacter jejuni + + Campylobacter jejuni + + + + FDA Center for Food Safety and Applied Nutrition + + + Pathogen.env + + Pathogen.env.1.0 + + CJP19-D996 + missing + missing + CDC + missing + missing + CFSAN091032 + GenomeTrakr + FDA Center for Food Safety and Applied Nutrition + + + 681235 + + + + +""" + +def flatten_biosample_xml(biosampxml): + root = xml.fromstring(biosampxml) + accession = get_tag(root, r'.//Id[@db="BioSample"]') + # sample_name = get_tag(root, r'.//Id[@db_label="Sample name"]') + organism = get_tag(root, r".//OrganismName") + tax_id = root.find(r".//Organism").attrib.get("taxonomy_id") + package = get_tag(root, r".//Package") + sampledict = dict( + biosample_accession=accession, + # sample_name=sample_name, + organism = organism, + taxid = tax_id, + package = package + ) + for attribute in root.findall("Attributes/Attribute"): + sampledict[attribute.attrib.get("harmonized_name", attribute.attrib['attribute_name'])] = attribute.text + + return sampledict + + +def yield_sra_runs_from_sample(biosample): + sleep(1 if not api_key else 0.1) + response = requests.get(elink, params=dict(id=biosample, dbfrom="biosample", db="sra", format="json", **extra_params)) + response.raise_for_status() + reply = response.json() + for ids in batched(reply.get("linksets", [{}])[0].get("linksetdbs", [{}])[0].get("links", []), 200): + sleep(1 if not api_key else 0.1) + response = requests.get(esummary, params=dict(id=','.join(ids), db="sra", format="json", **extra_params)) + response.raise_for_status() + replyy = response.json() + for field, value in replyy.get("result", {}).items(): + if "uids" not in field: + yield field, value.get("runs") + + +runs_example = """ + + +""" + +def flatten_runs(runxml): + root = xml.fromstring(f"{runxml}") # gotta fix their garbage embedded XML since it isn't singly-rooted + for run in root.findall(".//Run"): + if run.attrib["is_public"] == "false": + logger.warning(f"Skipping non-public run {run.attrib['acc']}") + yield dict( + sra_run_accession = run.attrib["acc"], + total_spots = run.attrib["total_spots"], + total_bases = run.attrib["total_bases"], + ) + + + +def main(starting_bioproject): + rows = [] + response = requests.get(esearch, params=dict(db="bioproject", term=starting_bioproject, field="PRJA", format="json")) + response.raise_for_status() + reply = response.json() + try: + bioproject_id = reply["esearchresult"]["idlist"][0] + log(f"Found UID {bioproject_id} for '{starting_bioproject}'") + except IndexError: + logger.error(f"No results found for '{starting_bioproject}'. Error was \"{reply['esearchresult']['warninglist']['outputmessages']}\"") + sys.exit(1) + sleep(1 if not api_key else 0.1) + for bioproject, biosample, biosample_xml in resolve_bioproject_ids_and_links([(starting_bioproject, bioproject_id)]): + try: + sampledict = flatten_biosample_xml(biosample_xml) + except KeyError: + log(biosample_xml) + raise + sampledict["bioproject"] = bioproject + noruns = True + for sra, runs in yield_sra_runs_from_sample(biosample): + for run in flatten_runs(runs.strip()): + noruns = False + run.update(sampledict) + rows.append(run) + if noruns: + rows.append(sampledict) + + log(f"Writing {len(rows)} rows to metadata.tsv") + + header = set() + for row in rows: + for key in row.keys(): + header.add(key) + + header = sorted(list(header), key=hso) + # logger.info(f"Header: {header}") + + rows.sort(key=lambda x: x["biosample_accession"]) + + with open("metadata.tsv", "w") as f: + writer = csv.DictWriter(f, fieldnames=header, delimiter="\t", dialect="excel") + writer.writeheader() + writer.writerows(rows) + + # check for duplicate runs and unreleased samples + + accessions = [row.get("sra_run_accession") for row in rows if row.get("sra_run_accession")] + + raw_length = len(accessions) + + accessions = sorted(list(set(accessions))) + + if raw_length < len(rows): + logger.warning(f"Bioproject {starting_bioproject} contains unreleased samples. {len(rows) - raw_length} samples will not be included in accessions.txt") + + if len(accessions) < raw_length: + logger.warning(f"Some SRA runs may have been reached through multiple projects or samples. accessions.txt will be deduplicated but the metadata table is not") + + log(f"Writing {len(accessions)} unique accessions to accessions.txt") + + with open("accessions.txt", "w") as f: + for accession in accessions: + f.write(accession + "\n") + + +if __name__ == "__main__": + b = sys.argv[1].strip() + log(f"Starting with {b}") + try: + main(b) + except requests.HTTPError as e: + logger.error(e) + sys.exit(1) + + + + + diff -r 000000000000 -r 79fa4330f2c9 bio2srr.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bio2srr.xml Mon Dec 08 20:18:03 2025 +0000 @@ -0,0 +1,31 @@ + + Retrieve SRR accessions and sample metadata from BioProject. Recursively follows links to subprojects. + + docker.io/crashfrog/bp2srr-galaxy:latest + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r 79fa4330f2c9 job_conf.yml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/job_conf.yml Mon Dec 08 20:18:03 2025 +0000 @@ -0,0 +1,34 @@ +runners: + local: + load: galaxy.jobs.runners.local:LocalJobRunner + workers: 16 + +# handling: +# processes: +# handler0: + +execution: + default: local + environments: + local: + runner: local + docker_local: + runner: local + docker_enabled: true + # container: "auto" + docker_volumes: $defaults + # docker_set_user: null + docker_run_extra_arguments: "--entrypoint ''" + docker_set_user: root + +tools: +- id: bio2srr + # handler: handler0 + environment: docker_local + +limits: +- + # Amount of time a job can run (in any environment) before it + # will be terminated by Galaxy. + type: walltime + value: '01:00:00' \ No newline at end of file diff -r 000000000000 -r 79fa4330f2c9 test-data/accessions.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/accessions.txt Mon Dec 08 20:18:03 2025 +0000 @@ -0,0 +1,5 @@ +SRR13160357 +SRR13160358 +SRR13160359 +SRR13160360 +SRR13167188 diff -r 000000000000 -r 79fa4330f2c9 test-data/metadata.tsv --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/metadata.tsv Mon Dec 08 20:18:03 2025 +0000 @@ -0,0 +1,8 @@ +bioproject biosample_accession organism taxid package Genus ProjectAccession PublicAccession Species attribute_package collected_by collection_date geo_loc_name isolate isolate_name_alias isolation_source lat_lon project_name sequenced_by sra_run_accession strain total_bases total_spots +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 Escherichia PRJNA681235 CFSAN091029 coli environmental/food/other CDC 2019 USA CFSAN091029 missing missing GenomeTrakr FDA Center for Food Safety and Applied Nutrition SRR13160357 ECP19-2498 312756765 660858 +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 Escherichia PRJNA681235 CFSAN091029 coli environmental/food/other CDC 2019 USA CFSAN091029 missing missing GenomeTrakr FDA Center for Food Safety and Applied Nutrition SRR13160358 ECP19-2498 327001270 704624 +PRJNA681235 SAMN16946946 Escherichia coli O157:H7 83334 Pathogen.env.1.0 Escherichia PRJNA681235 CFSAN091027 coli environmental/food/other CDC 2019 USA CFSAN091027 missing missing GenomeTrakr FDA Center for Food Safety and Applied Nutrition SRR13160360 ECP19-598 316865532 683880 +PRJNA681235 SAMN16946947 Escherichia coli O157:H7 83334 Pathogen.env.1.0 Escherichia PRJNA681235 CFSAN091028 coli environmental/food/other CDC 2019 USA CFSAN091028 missing missing GenomeTrakr FDA Center for Food Safety and Applied Nutrition SRR13160359 ECP19-798 473318585 1007158 +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 Escherichia PRJNA681235 CFSAN091030 coli environmental/food/other CDC 2019 USA CFSAN091030 missing missing GenomeTrakr FDA Center for Food Safety and Applied Nutrition SRR13167188 ECP19-198 385043067 827691 +PRJNA681235 SAMN17131267 Campylobacter jejuni 197 Pathogen.env.1.0 CDC missing missing CFSAN091031 missing missing GenomeTrakr FDA Center for Food Safety and Applied Nutrition CJP19-D445 +PRJNA681235 SAMN17131268 Campylobacter jejuni 197 Pathogen.env.1.0 CDC missing missing CFSAN091032 missing missing GenomeTrakr FDA Center for Food Safety and Applied Nutrition CJP19-D996 diff -r 000000000000 -r 79fa4330f2c9 test-data/metadata.tsv.bak --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/metadata.tsv.bak Mon Dec 08 20:18:03 2025 +0000 @@ -0,0 +1,92 @@ +bioproject biosample_accession organism taxid package total_bases lat_lon geo_loc_name collection_date isolate_name_alias isolate sra_run_accession Species sequenced_by strain isolation_source attribute_package project_name total_spots ProjectAccession collected_by PublicAccession Genus +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 1008246 missing USA 2019 CFSAN091029 SRR288080 coli FDA Center for Food Safety and Applied Nutrition ECP19-2498 missing environmental/food/other GenomeTrakr 3835 PRJNA681235 CDC CFSAN091029 Escherichia +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 63477063 missing USA 2019 CFSAN091029 SRR005375 coli FDA Center for Food Safety and Applied Nutrition ECP19-2498 missing environmental/food/other GenomeTrakr 237172 PRJNA681235 CDC CFSAN091029 Escherichia +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 21805775 missing USA 2019 CFSAN091029 SRR005372 coli FDA Center for Food Safety and Applied Nutrition ECP19-2498 missing environmental/food/other GenomeTrakr 88278 PRJNA681235 CDC CFSAN091029 Escherichia +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 59522375 missing USA 2019 CFSAN091029 SRR000090 coli FDA Center for Food Safety and Applied Nutrition ECP19-2498 missing environmental/food/other GenomeTrakr 222843 PRJNA681235 CDC CFSAN091029 Escherichia +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 392964 missing USA 2019 CFSAN091029 SRR000091 coli FDA Center for Food Safety and Applied Nutrition ECP19-2498 missing environmental/food/other GenomeTrakr 1467 PRJNA681235 CDC CFSAN091029 Escherichia +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 872292 missing USA 2019 CFSAN091029 SRR000092 coli FDA Center for Food Safety and Applied Nutrition ECP19-2498 missing environmental/food/other GenomeTrakr 3261 PRJNA681235 CDC CFSAN091029 Escherichia +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 60878431 missing USA 2019 CFSAN091029 SRR000093 coli FDA Center for Food Safety and Applied Nutrition ECP19-2498 missing environmental/food/other GenomeTrakr 227850 PRJNA681235 CDC CFSAN091029 Escherichia +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 1311175 missing USA 2019 CFSAN091029 SRR000094 coli FDA Center for Food Safety and Applied Nutrition ECP19-2498 missing environmental/food/other GenomeTrakr 4908 PRJNA681235 CDC CFSAN091029 Escherichia +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 592711 missing USA 2019 CFSAN091029 SRR000095 coli FDA Center for Food Safety and Applied Nutrition ECP19-2498 missing environmental/food/other GenomeTrakr 2214 PRJNA681235 CDC CFSAN091029 Escherichia +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 35726106 missing USA 2019 CFSAN091029 SRR000078 coli FDA Center for Food Safety and Applied Nutrition ECP19-2498 missing environmental/food/other GenomeTrakr 136244 PRJNA681235 CDC CFSAN091029 Escherichia +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 33865731 missing USA 2019 CFSAN091029 SRR000079 coli FDA Center for Food Safety and Applied Nutrition ECP19-2498 missing environmental/food/other GenomeTrakr 128606 PRJNA681235 CDC CFSAN091029 Escherichia +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 43110538 missing USA 2019 CFSAN091029 SRR000072 coli FDA Center for Food Safety and Applied Nutrition ECP19-2498 missing environmental/food/other GenomeTrakr 164772 PRJNA681235 CDC CFSAN091029 Escherichia +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 834018 missing USA 2019 CFSAN091029 SRR000073 coli FDA Center for Food Safety and Applied Nutrition ECP19-2498 missing environmental/food/other GenomeTrakr 3206 PRJNA681235 CDC CFSAN091029 Escherichia +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 1191933 missing USA 2019 CFSAN091029 SRR000074 coli FDA Center for Food Safety and Applied Nutrition ECP19-2498 missing environmental/food/other GenomeTrakr 4540 PRJNA681235 CDC CFSAN091029 Escherichia +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 817514 missing USA 2019 CFSAN091029 SRR000075 coli FDA Center for Food Safety and Applied Nutrition ECP19-2498 missing environmental/food/other GenomeTrakr 3107 PRJNA681235 CDC CFSAN091029 Escherichia +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 53028372 missing USA 2019 CFSAN091029 SRR000076 coli FDA Center for Food Safety and Applied Nutrition ECP19-2498 missing environmental/food/other GenomeTrakr 201721 PRJNA681235 CDC CFSAN091029 Escherichia +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 322254 missing USA 2019 CFSAN091029 SRR000077 coli FDA Center for Food Safety and Applied Nutrition ECP19-2498 missing environmental/food/other GenomeTrakr 1226 PRJNA681235 CDC CFSAN091029 Escherichia +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 69214301 missing USA 2019 CFSAN091029 SRR000070 coli FDA Center for Food Safety and Applied Nutrition ECP19-2498 missing environmental/food/other GenomeTrakr 262057 PRJNA681235 CDC CFSAN091029 Escherichia +PRJNA681235 SAMN16946945 Escherichia coli O157:H7 83334 Pathogen.env.1.0 56794062 missing USA 2019 CFSAN091029 SRR000071 coli FDA Center for Food Safety and Applied Nutrition ECP19-2498 missing environmental/food/other GenomeTrakr 215192 PRJNA681235 CDC CFSAN091029 Escherichia +PRJNA681235 SAMN16946946 Escherichia coli O157:H7 83334 Pathogen.env.1.0 1008246 missing USA 2019 CFSAN091027 SRR288080 coli FDA Center for Food Safety and Applied Nutrition ECP19-598 missing environmental/food/other GenomeTrakr 3835 PRJNA681235 CDC CFSAN091027 Escherichia +PRJNA681235 SAMN16946946 Escherichia coli O157:H7 83334 Pathogen.env.1.0 59522375 missing USA 2019 CFSAN091027 SRR000090 coli FDA Center for Food Safety and Applied Nutrition ECP19-598 missing environmental/food/other GenomeTrakr 222843 PRJNA681235 CDC CFSAN091027 Escherichia +PRJNA681235 SAMN16946946 Escherichia coli O157:H7 83334 Pathogen.env.1.0 392964 missing USA 2019 CFSAN091027 SRR000091 coli FDA Center for Food Safety and Applied Nutrition ECP19-598 missing environmental/food/other GenomeTrakr 1467 PRJNA681235 CDC CFSAN091027 Escherichia +PRJNA681235 SAMN16946946 Escherichia coli O157:H7 83334 Pathogen.env.1.0 872292 missing USA 2019 CFSAN091027 SRR000092 coli FDA Center for Food Safety and Applied Nutrition ECP19-598 missing environmental/food/other GenomeTrakr 3261 PRJNA681235 CDC CFSAN091027 Escherichia +PRJNA681235 SAMN16946946 Escherichia coli O157:H7 83334 Pathogen.env.1.0 60878431 missing USA 2019 CFSAN091027 SRR000093 coli FDA Center for Food Safety and Applied Nutrition ECP19-598 missing environmental/food/other GenomeTrakr 227850 PRJNA681235 CDC CFSAN091027 Escherichia +PRJNA681235 SAMN16946946 Escherichia coli O157:H7 83334 Pathogen.env.1.0 1311175 missing USA 2019 CFSAN091027 SRR000094 coli FDA Center for Food Safety and Applied Nutrition ECP19-598 missing environmental/food/other GenomeTrakr 4908 PRJNA681235 CDC CFSAN091027 Escherichia +PRJNA681235 SAMN16946946 Escherichia coli O157:H7 83334 Pathogen.env.1.0 592711 missing USA 2019 CFSAN091027 SRR000095 coli FDA Center for Food Safety and Applied Nutrition ECP19-598 missing environmental/food/other GenomeTrakr 2214 PRJNA681235 CDC CFSAN091027 Escherichia +PRJNA681235 SAMN16946946 Escherichia coli O157:H7 83334 Pathogen.env.1.0 35726106 missing USA 2019 CFSAN091027 SRR000078 coli FDA Center for Food Safety and Applied Nutrition ECP19-598 missing environmental/food/other GenomeTrakr 136244 PRJNA681235 CDC CFSAN091027 Escherichia +PRJNA681235 SAMN16946946 Escherichia coli O157:H7 83334 Pathogen.env.1.0 33865731 missing USA 2019 CFSAN091027 SRR000079 coli FDA Center for Food Safety and Applied Nutrition ECP19-598 missing environmental/food/other GenomeTrakr 128606 PRJNA681235 CDC CFSAN091027 Escherichia +PRJNA681235 SAMN16946946 Escherichia coli O157:H7 83334 Pathogen.env.1.0 69214301 missing USA 2019 CFSAN091027 SRR000070 coli FDA Center for Food Safety and Applied Nutrition ECP19-598 missing environmental/food/other GenomeTrakr 262057 PRJNA681235 CDC CFSAN091027 Escherichia +PRJNA681235 SAMN16946946 Escherichia coli O157:H7 83334 Pathogen.env.1.0 56794062 missing USA 2019 CFSAN091027 SRR000071 coli FDA Center for Food Safety and Applied Nutrition ECP19-598 missing environmental/food/other GenomeTrakr 215192 PRJNA681235 CDC CFSAN091027 Escherichia +PRJNA681235 SAMN16946947 Escherichia coli O157:H7 83334 Pathogen.env.1.0 1008246 missing USA 2019 CFSAN091028 SRR288080 coli FDA Center for Food Safety and Applied Nutrition ECP19-798 missing environmental/food/other GenomeTrakr 3835 PRJNA681235 CDC CFSAN091028 Escherichia +PRJNA681235 SAMN16946947 Escherichia coli O157:H7 83334 Pathogen.env.1.0 59522375 missing USA 2019 CFSAN091028 SRR000090 coli FDA Center for Food Safety and Applied Nutrition ECP19-798 missing environmental/food/other GenomeTrakr 222843 PRJNA681235 CDC CFSAN091028 Escherichia +PRJNA681235 SAMN16946947 Escherichia coli O157:H7 83334 Pathogen.env.1.0 392964 missing USA 2019 CFSAN091028 SRR000091 coli FDA Center for Food Safety and Applied Nutrition ECP19-798 missing environmental/food/other GenomeTrakr 1467 PRJNA681235 CDC CFSAN091028 Escherichia +PRJNA681235 SAMN16946947 Escherichia coli O157:H7 83334 Pathogen.env.1.0 872292 missing USA 2019 CFSAN091028 SRR000092 coli FDA Center for Food Safety and Applied Nutrition ECP19-798 missing environmental/food/other GenomeTrakr 3261 PRJNA681235 CDC CFSAN091028 Escherichia +PRJNA681235 SAMN16946947 Escherichia coli O157:H7 83334 Pathogen.env.1.0 60878431 missing USA 2019 CFSAN091028 SRR000093 coli FDA Center for Food Safety and Applied Nutrition ECP19-798 missing environmental/food/other GenomeTrakr 227850 PRJNA681235 CDC CFSAN091028 Escherichia +PRJNA681235 SAMN16946947 Escherichia coli O157:H7 83334 Pathogen.env.1.0 1311175 missing USA 2019 CFSAN091028 SRR000094 coli FDA Center for Food Safety and Applied Nutrition ECP19-798 missing environmental/food/other GenomeTrakr 4908 PRJNA681235 CDC CFSAN091028 Escherichia +PRJNA681235 SAMN16946947 Escherichia coli O157:H7 83334 Pathogen.env.1.0 592711 missing USA 2019 CFSAN091028 SRR000095 coli FDA Center for Food Safety and Applied Nutrition ECP19-798 missing environmental/food/other GenomeTrakr 2214 PRJNA681235 CDC CFSAN091028 Escherichia +PRJNA681235 SAMN16946947 Escherichia coli O157:H7 83334 Pathogen.env.1.0 42230342 missing USA 2019 CFSAN091028 SRR000080 coli FDA Center for Food Safety and Applied Nutrition ECP19-798 missing environmental/food/other GenomeTrakr 158320 PRJNA681235 CDC CFSAN091028 Escherichia +PRJNA681235 SAMN16946947 Escherichia coli O157:H7 83334 Pathogen.env.1.0 48201615 missing USA 2019 CFSAN091028 SRR000081 coli FDA Center for Food Safety and Applied Nutrition ECP19-798 missing environmental/food/other GenomeTrakr 180220 PRJNA681235 CDC CFSAN091028 Escherichia +PRJNA681235 SAMN16946947 Escherichia coli O157:H7 83334 Pathogen.env.1.0 35726106 missing USA 2019 CFSAN091028 SRR000078 coli FDA Center for Food Safety and Applied Nutrition ECP19-798 missing environmental/food/other GenomeTrakr 136244 PRJNA681235 CDC CFSAN091028 Escherichia +PRJNA681235 SAMN16946947 Escherichia coli O157:H7 83334 Pathogen.env.1.0 33865731 missing USA 2019 CFSAN091028 SRR000079 coli FDA Center for Food Safety and Applied Nutrition ECP19-798 missing environmental/food/other GenomeTrakr 128606 PRJNA681235 CDC CFSAN091028 Escherichia +PRJNA681235 SAMN16946947 Escherichia coli O157:H7 83334 Pathogen.env.1.0 69214301 missing USA 2019 CFSAN091028 SRR000070 coli FDA Center for Food Safety and Applied Nutrition ECP19-798 missing environmental/food/other GenomeTrakr 262057 PRJNA681235 CDC CFSAN091028 Escherichia +PRJNA681235 SAMN16946947 Escherichia coli O157:H7 83334 Pathogen.env.1.0 56794062 missing USA 2019 CFSAN091028 SRR000071 coli FDA Center for Food Safety and Applied Nutrition ECP19-798 missing environmental/food/other GenomeTrakr 215192 PRJNA681235 CDC CFSAN091028 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 1008246 missing USA 2019 CFSAN091030 SRR288080 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 3835 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 63477063 missing USA 2019 CFSAN091030 SRR005375 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 237172 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 21805775 missing USA 2019 CFSAN091030 SRR005372 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 88278 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 59522375 missing USA 2019 CFSAN091030 SRR000090 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 222843 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 392964 missing USA 2019 CFSAN091030 SRR000091 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 1467 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 872292 missing USA 2019 CFSAN091030 SRR000092 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 3261 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 60878431 missing USA 2019 CFSAN091030 SRR000093 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 227850 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 1311175 missing USA 2019 CFSAN091030 SRR000094 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 4908 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 592711 missing USA 2019 CFSAN091030 SRR000095 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 2214 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 35726106 missing USA 2019 CFSAN091030 SRR000078 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 136244 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 33865731 missing USA 2019 CFSAN091030 SRR000079 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 128606 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 43110538 missing USA 2019 CFSAN091030 SRR000072 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 164772 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 834018 missing USA 2019 CFSAN091030 SRR000073 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 3206 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 1191933 missing USA 2019 CFSAN091030 SRR000074 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 4540 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 817514 missing USA 2019 CFSAN091030 SRR000075 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 3107 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 53028372 missing USA 2019 CFSAN091030 SRR000076 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 201721 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 322254 missing USA 2019 CFSAN091030 SRR000077 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 1226 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 69214301 missing USA 2019 CFSAN091030 SRR000070 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 262057 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 56794062 missing USA 2019 CFSAN091030 SRR000071 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 215192 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 63395546 missing USA 2019 CFSAN091030 SRR000068 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 247135 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN16956340 Escherichia coli O157:H7 83334 Pathogen.env.1.0 57476129 missing USA 2019 CFSAN091030 SRR000069 coli FDA Center for Food Safety and Applied Nutrition ECP19-198 missing environmental/food/other GenomeTrakr 224837 PRJNA681235 CDC CFSAN091030 Escherichia +PRJNA681235 SAMN17131267 Campylobacter jejuni 197 Pathogen.env.1.0 1008246 missing missing missing CFSAN091031 SRR288080 FDA Center for Food Safety and Applied Nutrition CJP19-D445 missing GenomeTrakr 3835 CDC +PRJNA681235 SAMN17131267 Campylobacter jejuni 197 Pathogen.env.1.0 42230342 missing missing missing CFSAN091031 SRR000080 FDA Center for Food Safety and Applied Nutrition CJP19-D445 missing GenomeTrakr 158320 CDC +PRJNA681235 SAMN17131267 Campylobacter jejuni 197 Pathogen.env.1.0 48201615 missing missing missing CFSAN091031 SRR000081 FDA Center for Food Safety and Applied Nutrition CJP19-D445 missing GenomeTrakr 180220 CDC +PRJNA681235 SAMN17131267 Campylobacter jejuni 197 Pathogen.env.1.0 35726106 missing missing missing CFSAN091031 SRR000078 FDA Center for Food Safety and Applied Nutrition CJP19-D445 missing GenomeTrakr 136244 CDC +PRJNA681235 SAMN17131267 Campylobacter jejuni 197 Pathogen.env.1.0 33865731 missing missing missing CFSAN091031 SRR000079 FDA Center for Food Safety and Applied Nutrition CJP19-D445 missing GenomeTrakr 128606 CDC +PRJNA681235 SAMN17131267 Campylobacter jejuni 197 Pathogen.env.1.0 63395546 missing missing missing CFSAN091031 SRR000068 FDA Center for Food Safety and Applied Nutrition CJP19-D445 missing GenomeTrakr 247135 CDC +PRJNA681235 SAMN17131267 Campylobacter jejuni 197 Pathogen.env.1.0 57476129 missing missing missing CFSAN091031 SRR000069 FDA Center for Food Safety and Applied Nutrition CJP19-D445 missing GenomeTrakr 224837 CDC +PRJNA681235 SAMN17131267 Campylobacter jejuni 197 Pathogen.env.1.0 63790620 missing missing missing CFSAN091031 SRR000066 FDA Center for Food Safety and Applied Nutrition CJP19-D445 missing GenomeTrakr 242673 CDC +PRJNA681235 SAMN17131267 Campylobacter jejuni 197 Pathogen.env.1.0 66936400 missing missing missing CFSAN091031 SRR000067 FDA Center for Food Safety and Applied Nutrition CJP19-D445 missing GenomeTrakr 255351 CDC +PRJNA681235 SAMN17131268 Campylobacter jejuni 197 Pathogen.env.1.0 1008246 missing missing missing CFSAN091032 SRR288080 FDA Center for Food Safety and Applied Nutrition CJP19-D996 missing GenomeTrakr 3835 CDC +PRJNA681235 SAMN17131268 Campylobacter jejuni 197 Pathogen.env.1.0 155025677 missing missing missing CFSAN091032 SRR287817 FDA Center for Food Safety and Applied Nutrition CJP19-D996 missing GenomeTrakr 1414888 CDC +PRJNA681235 SAMN17131268 Campylobacter jejuni 197 Pathogen.env.1.0 64994909 missing missing missing CFSAN091032 SRR000089 FDA Center for Food Safety and Applied Nutrition CJP19-D996 missing GenomeTrakr 250945 CDC +PRJNA681235 SAMN17131268 Campylobacter jejuni 197 Pathogen.env.1.0 62912540 missing missing missing CFSAN091032 SRR000088 FDA Center for Food Safety and Applied Nutrition CJP19-D996 missing GenomeTrakr 242861 CDC +PRJNA681235 SAMN17131268 Campylobacter jejuni 197 Pathogen.env.1.0 1051130 missing missing missing CFSAN091032 SRR000087 FDA Center for Food Safety and Applied Nutrition CJP19-D996 missing GenomeTrakr 4049 CDC +PRJNA681235 SAMN17131268 Campylobacter jejuni 197 Pathogen.env.1.0 525756 missing missing missing CFSAN091032 SRR000086 FDA Center for Food Safety and Applied Nutrition CJP19-D996 missing GenomeTrakr 2047 CDC +PRJNA681235 SAMN17131268 Campylobacter jejuni 197 Pathogen.env.1.0 436118 missing missing missing CFSAN091032 SRR000085 FDA Center for Food Safety and Applied Nutrition CJP19-D996 missing GenomeTrakr 1684 CDC +PRJNA681235 SAMN17131268 Campylobacter jejuni 197 Pathogen.env.1.0 466139 missing missing missing CFSAN091032 SRR000084 FDA Center for Food Safety and Applied Nutrition CJP19-D996 missing GenomeTrakr 1803 CDC +PRJNA681235 SAMN17131268 Campylobacter jejuni 197 Pathogen.env.1.0 1251016 missing missing missing CFSAN091032 SRR000083 FDA Center for Food Safety and Applied Nutrition CJP19-D996 missing GenomeTrakr 4841 CDC +PRJNA681235 SAMN17131268 Campylobacter jejuni 197 Pathogen.env.1.0 1227889 missing missing missing CFSAN091032 SRR000082 FDA Center for Food Safety and Applied Nutrition CJP19-D996 missing GenomeTrakr 4753 CDC +PRJNA681235 SAMN17131268 Campylobacter jejuni 197 Pathogen.env.1.0 42230342 missing missing missing CFSAN091032 SRR000080 FDA Center for Food Safety and Applied Nutrition CJP19-D996 missing GenomeTrakr 158320 CDC +PRJNA681235 SAMN17131268 Campylobacter jejuni 197 Pathogen.env.1.0 48201615 missing missing missing CFSAN091032 SRR000081 FDA Center for Food Safety and Applied Nutrition CJP19-D996 missing GenomeTrakr 180220 CDC +PRJNA681235 SAMN17131268 Campylobacter jejuni 197 Pathogen.env.1.0 35726106 missing missing missing CFSAN091032 SRR000078 FDA Center for Food Safety and Applied Nutrition CJP19-D996 missing GenomeTrakr 136244 CDC +PRJNA681235 SAMN17131268 Campylobacter jejuni 197 Pathogen.env.1.0 33865731 missing missing missing CFSAN091032 SRR000079 FDA Center for Food Safety and Applied Nutrition CJP19-D996 missing GenomeTrakr 128606 CDC +PRJNA681235 SAMN17131268 Campylobacter jejuni 197 Pathogen.env.1.0 63395546 missing missing missing CFSAN091032 SRR000068 FDA Center for Food Safety and Applied Nutrition CJP19-D996 missing GenomeTrakr 247135 CDC +PRJNA681235 SAMN17131268 Campylobacter jejuni 197 Pathogen.env.1.0 57476129 missing missing missing CFSAN091032 SRR000069 FDA Center for Food Safety and Applied Nutrition CJP19-D996 missing GenomeTrakr 224837 CDC +PRJNA681235 SAMN17131268 Campylobacter jejuni 197 Pathogen.env.1.0 63790620 missing missing missing CFSAN091032 SRR000066 FDA Center for Food Safety and Applied Nutrition CJP19-D996 missing GenomeTrakr 242673 CDC +PRJNA681235 SAMN17131268 Campylobacter jejuni 197 Pathogen.env.1.0 66936400 missing missing missing CFSAN091032 SRR000067 FDA Center for Food Safety and Applied Nutrition CJP19-D996 missing GenomeTrakr 255351 CDC diff -r 000000000000 -r 79fa4330f2c9 tests.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests.py Mon Dec 08 20:18:03 2025 +0000 @@ -0,0 +1,42 @@ +import pytest + +from bio2srr import * + + +def test_element_tree_xpath(): + from xml.etree import ElementTree as xml + root = xml.fromstring(biosample_example) + assert root.find(".//Id[@db='BioSample']") is not None + +def test_flatten_biosample_xml(): + d = flatten_biosample_xml(biosample_example) + assert d['biosample_accession'] == 'SAMN17131268' + assert d['organism'] == 'Campylobacter jejuni' + assert d['isolate'] == 'CFSAN091032' + +def test_flatten_runs(): + d = list(flatten_runs(runs_example)) + assert len(d) == 2 + +def test_header_sort_override_consistency(): + import random + L = ["C", "B", "A", "taxid", "bioproject"] + L.sort(key=hso) + # assert L[0] == "bioproject" + A = L.copy() + assert A == L + R = [] + for _ in range(100): + random.shuffle(A) + A.sort(key=hso) + R.append(A == L) + assert all(R) + +def test_hso_override(): + assert header_sort_override("bioproject", "taxid") < 0 + assert header_sort_override("taxid", "bioproject") > 0 + assert header_sort_override("taxid", "taxid") == 0 + +def test_hso_regular(): + assert header_sort_override("A", "B") < 0 + assert header_sort_override("B", "A") > 0 \ No newline at end of file