-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathncbi_batch_fetch.py
More file actions
109 lines (88 loc) · 3.16 KB
/
Copy pathncbi_batch_fetch.py
File metadata and controls
109 lines (88 loc) · 3.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import argparse
import urllib.request
import urllib.parse
import xml.etree.ElementTree as ET
#command line arguments
def args_parse():
"""
Argument Parsing Function
Transforms user inputs into usable variables in the code
Takes 'database', 'query' and 'output' inputs from the user
Outputs the inputs for the code to utilize
"""
parser = argparse.ArgumentParser(description="Process files")
parser.add_argument("-db", "--database", required=True, help="Database to use")
parser.add_argument("-i", "--input", required=True, help="Input file with accession numbers (one per line)")
parser.add_argument("-o", "--output", required=False, help="Output directory")
return parser.parse_args()
def esearch(db, query):
"""
eSearch Function
Searches the Database for the Query that it gets as an input
Receives the Database and Query that the user wants to utilize
Outputs the Result of the Search
"""
parameters = urllib.parse.urlencode({
"db": db,
"term": query,
"usehistory": "y",
"retmode": "xml"
})
url = f"https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?{parameters}"
with urllib.request.urlopen(url) as response:
return response.read()
def esearchParse(esearch):
"""
Parsing Function
Parses the XML file from the eSearch function
Receives the XML file as input
Outputs the information needed to get the FASTA files
"""
root = ET.fromstring(esearch)
query_Key = root.find("QueryKey").text
WebEnv = root.find("WebEnv").text
return WebEnv, query_Key
def efetch(db, query_key, WebEnv):
"""
Fetch sequences in FASTA format from NCBI using the Entrez API
Args:
db : NCBI database name.
web_env : webEnv string from esearch.
query_key : querykey string from esearch.
Returns:
str: FASTA-formatted sequences as a string.
"""
parameters = urllib.parse.urlencode({
"db" : db,
"query_key" : query_key,
"WebEnv" : WebEnv,
"rettype" : "fasta",
"retmode" : "text",
})
url = f"https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?{parameters}"
with urllib.request.urlopen(url) as response:
return response.read().decode("utf-8")
def main():
"""
Main function: orchestrates argument parsing, esearch, parsing, efetch, and output.
"""
args = args_parse()
# Read accession numbers
with open(args.input) as f:
accessions = [line.strip() for line in f if line.strip()]
# Combine into ONE query
query = " OR ".join([f"{acc}[accn]" for acc in accessions])
print(f"Running query for {len(accessions)} accessions...")
xml = esearch(args.database, query)
webenv, query_key = esearchParse(xml)
fasta = efetch(args.database, query_key, webenv)
# Save output
if args.output is not None:
with open(f"{args.output}.fasta", "w") as out:
out.write(fasta)
print(f"Saved to {args.output}.fasta")
else:
with open(f"{args.input[0:-4]}.fasta", "w") as out:
out.write(fasta)
if __name__ == "__main__":
main()