History

OpenScience: an open-source AI research agent for the browser

A model-agnostic AI co-scientist for ML engineering and scientific research. Give it a goal and it reads the literature, writes and runs code, runs experiments, and writes up results. Run `openscience` to open the workspace in your browser. Bring your own API key from any provider, or use Atlas for managed models and compute. Built with Bun and TypeScript. Apache License 2.0.

ishaan1124 committed 4 months ago

Commit 79c26bcNo parent (first commit)3865 files · +912032 −-100Browse files

Showing the changes to backend/cli/skills/databases/string-database/scripts/string_api.py (1 of 3865 files). Show all

Unified · Split

backend/cli/skills/databases/string-database/scripts/string_api.py+369−0
@@ -0,0 +1,369 @@
1"""
2STRING Database REST API Helper Functions
3
4This module provides Python functions for interacting with the STRING database API.
5All functions return raw response text or JSON which can be parsed as needed.
6
7API Base URL: https://string-db.org/api
8Documentation: https://string-db.org/help/api/
9
10STRING provides protein-protein interaction data from over 40 sources covering
115000+ genomes with ~59.3 million proteins and 20+ billion interactions.
12"""
13
14import urllib.request
15import urllib.parse
16import urllib.error
17import json
18from typing import Optional, List, Union, Dict
19
20
21STRING_BASE_URL = "https://string-db.org/api"
22
23
24def string_map_ids(identifiers: Union[str, List[str]],
25 species: int = 9606,
26 limit: int = 1,
27 echo_query: int = 1,
28 caller_identity: str = "claude_scientific_skills") -> str:
29 """
30 Map protein names, synonyms, and identifiers to STRING IDs.
31
32 Args:
33 identifiers: Single protein identifier or list of identifiers
34 species: NCBI taxon ID (default: 9606 for human)
35 limit: Number of matches to return per identifier (default: 1)
36 echo_query: Include query term in output (1) or not (0)
37 caller_identity: Application identifier for tracking
38
39 Returns:
40 str: TSV format with mapping results
41
42 Examples:
43 # Map single protein
44 result = string_map_ids('TP53', species=9606)
45
46 # Map multiple proteins
47 result = string_map_ids(['TP53', 'BRCA1', 'EGFR'], species=9606)
48 """
49 if isinstance(identifiers, list):
50 identifiers_str = '\n'.join(identifiers)
51 else:
52 identifiers_str = identifiers
53
54 params = {
55 'identifiers': identifiers_str,
56 'species': species,
57 'limit': limit,
58 'echo_query': echo_query,
59 'caller_identity': caller_identity
60 }
61
62 url = f"{STRING_BASE_URL}/tsv/get_string_ids"
63 data = urllib.parse.urlencode(params).encode('utf-8')
64
65 try:
66 with urllib.request.urlopen(url, data=data) as response:
67 return response.read().decode('utf-8')
68 except urllib.error.HTTPError as e:
69 return f"Error: {e.code} - {e.reason}"
70
71
72def string_network(identifiers: Union[str, List[str]],
73 species: int = 9606,
74 required_score: int = 400,
75 network_type: str = "functional",
76 add_nodes: int = 0,
77 caller_identity: str = "claude_scientific_skills") -> str:
78 """
79 Get protein-protein interaction network data.
80
81 Args:
82 identifiers: Protein identifier(s) - use STRING IDs for best results
83 species: NCBI taxon ID (default: 9606 for human)
84 required_score: Confidence threshold 0-1000 (default: 400 = medium confidence)
85 network_type: 'functional' or 'physical' (default: functional)
86 add_nodes: Number of additional nodes to add to network (0-10)
87 caller_identity: Application identifier for tracking
88
89 Returns:
90 str: TSV format with interaction data
91
92 Examples:
93 # Get network for single protein
94 network = string_network('9606.ENSP00000269305')
95
96 # Get network with multiple proteins
97 network = string_network(['9606.ENSP00000269305', '9606.ENSP00000275493'])
98
99 # Get network with additional interacting proteins
100 network = string_network('TP53', add_nodes=5, required_score=700)
101 """
102 if isinstance(identifiers, list):
103 identifiers_str = '%0d'.join(identifiers)
104 else:
105 identifiers_str = identifiers
106
107 params = {
108 'identifiers': identifiers_str,
109 'species': species,
110 'required_score': required_score,
111 'network_type': network_type,
112 'add_nodes': add_nodes,
113 'caller_identity': caller_identity
114 }
115
116 url = f"{STRING_BASE_URL}/tsv/network?" + urllib.parse.urlencode(params)
117
118 try:
119 with urllib.request.urlopen(url) as response:
120 return response.read().decode('utf-8')
121 except urllib.error.HTTPError as e:
122 return f"Error: {e.code} - {e.reason}"
123
124
125def string_network_image(identifiers: Union[str, List[str]],
126 species: int = 9606,
127 required_score: int = 400,
128 network_flavor: str = "evidence",
129 add_nodes: int = 0,
130 caller_identity: str = "claude_scientific_skills") -> bytes:
131 """
132 Get network visualization as PNG image.
133
134 Args:
135 identifiers: Protein identifier(s)
136 species: NCBI taxon ID (default: 9606 for human)
137 required_score: Confidence threshold 0-1000 (default: 400)
138 network_flavor: 'evidence', 'confidence', or 'actions' (default: evidence)
139 add_nodes: Number of additional nodes to add (0-10)
140 caller_identity: Application identifier for tracking
141
142 Returns:
143 bytes: PNG image data
144
145 Example:
146 # Get network image
147 img_data = string_network_image(['TP53', 'MDM2', 'ATM'])
148 with open('network.png', 'wb') as f:
149 f.write(img_data)
150 """
151 if isinstance(identifiers, list):
152 identifiers_str = '%0d'.join(identifiers)
153 else:
154 identifiers_str = identifiers
155
156 params = {
157 'identifiers': identifiers_str,
158 'species': species,
159 'required_score': required_score,
160 'network_flavor': network_flavor,
161 'add_nodes': add_nodes,
162 'caller_identity': caller_identity
163 }
164
165 url = f"{STRING_BASE_URL}/image/network?" + urllib.parse.urlencode(params)
166
167 try:
168 with urllib.request.urlopen(url) as response:
169 return response.read()
170 except urllib.error.HTTPError as e:
171 return f"Error: {e.code} - {e.reason}".encode()
172
173
174def string_interaction_partners(identifiers: Union[str, List[str]],
175 species: int = 9606,
176 required_score: int = 400,
177 limit: int = 10,
178 caller_identity: str = "claude_scientific_skills") -> str:
179 """
180 Get all interaction partners for protein(s).
181
182 Args:
183 identifiers: Protein identifier(s)
184 species: NCBI taxon ID (default: 9606 for human)
185 required_score: Confidence threshold 0-1000 (default: 400)
186 limit: Maximum number of partners to return (default: 10)
187 caller_identity: Application identifier for tracking
188
189 Returns:
190 str: TSV format with interaction partners
191
192 Example:
193 # Get top 20 interactors of TP53
194 partners = string_interaction_partners('TP53', limit=20, required_score=700)
195 """
196 if isinstance(identifiers, list):
197 identifiers_str = '%0d'.join(identifiers)
198 else:
199 identifiers_str = identifiers
200
201 params = {
202 'identifiers': identifiers_str,
203 'species': species,
204 'required_score': required_score,
205 'limit': limit,
206 'caller_identity': caller_identity
207 }
208
209 url = f"{STRING_BASE_URL}/tsv/interaction_partners?" + urllib.parse.urlencode(params)
210
211 try:
212 with urllib.request.urlopen(url) as response:
213 return response.read().decode('utf-8')
214 except urllib.error.HTTPError as e:
215 return f"Error: {e.code} - {e.reason}"
216
217
218def string_enrichment(identifiers: Union[str, List[str]],
219 species: int = 9606,
220 caller_identity: str = "claude_scientific_skills") -> str:
221 """
222 Perform functional enrichment analysis (Gene Ontology, KEGG, Pfam, etc.).
223
224 Args:
225 identifiers: List of protein identifiers
226 species: NCBI taxon ID (default: 9606 for human)
227 caller_identity: Application identifier for tracking
228
229 Returns:
230 str: TSV format with enrichment results
231
232 Example:
233 # Enrichment for a list of proteins
234 proteins = ['TP53', 'MDM2', 'ATM', 'CHEK2', 'BRCA1']
235 enrichment = string_enrichment(proteins, species=9606)
236 """
237 if isinstance(identifiers, list):
238 identifiers_str = '%0d'.join(identifiers)
239 else:
240 identifiers_str = identifiers
241
242 params = {
243 'identifiers': identifiers_str,
244 'species': species,
245 'caller_identity': caller_identity
246 }
247
248 url = f"{STRING_BASE_URL}/tsv/enrichment?" + urllib.parse.urlencode(params)
249
250 try:
251 with urllib.request.urlopen(url) as response:
252 return response.read().decode('utf-8')
253 except urllib.error.HTTPError as e:
254 return f"Error: {e.code} - {e.reason}"
255
256
257def string_ppi_enrichment(identifiers: Union[str, List[str]],
258 species: int = 9606,
259 required_score: int = 400,
260 caller_identity: str = "claude_scientific_skills") -> str:
261 """
262 Test if network has more interactions than expected by chance.
263
264 Args:
265 identifiers: List of protein identifiers
266 species: NCBI taxon ID (default: 9606 for human)
267 required_score: Confidence threshold 0-1000 (default: 400)
268 caller_identity: Application identifier for tracking
269
270 Returns:
271 str: JSON with PPI enrichment p-value
272
273 Example:
274 # Test if proteins are more connected than random
275 proteins = ['TP53', 'MDM2', 'ATM', 'CHEK2']
276 ppi_result = string_ppi_enrichment(proteins)
277 """
278 if isinstance(identifiers, list):
279 identifiers_str = '%0d'.join(identifiers)
280 else:
281 identifiers_str = identifiers
282
283 params = {
284 'identifiers': identifiers_str,
285 'species': species,
286 'required_score': required_score,
287 'caller_identity': caller_identity
288 }
289
290 url = f"{STRING_BASE_URL}/json/ppi_enrichment?" + urllib.parse.urlencode(params)
291
292 try:
293 with urllib.request.urlopen(url) as response:
294 return response.read().decode('utf-8')
295 except urllib.error.HTTPError as e:
296 return f"Error: {e.code} - {e.reason}"
297
298
299def string_homology(identifiers: Union[str, List[str]],
300 species: int = 9606,
301 caller_identity: str = "claude_scientific_skills") -> str:
302 """
303 Get homology/similarity scores between proteins.
304
305 Args:
306 identifiers: Protein identifier(s)
307 species: NCBI taxon ID (default: 9606 for human)
308 caller_identity: Application identifier for tracking
309
310 Returns:
311 str: TSV format with homology scores
312
313 Example:
314 # Get homology data
315 homology = string_homology(['TP53', 'TP63', 'TP73'])
316 """
317 if isinstance(identifiers, list):
318 identifiers_str = '%0d'.join(identifiers)
319 else:
320 identifiers_str = identifiers
321
322 params = {
323 'identifiers': identifiers_str,
324 'species': species,
325 'caller_identity': caller_identity
326 }
327
328 url = f"{STRING_BASE_URL}/tsv/homology?" + urllib.parse.urlencode(params)
329
330 try:
331 with urllib.request.urlopen(url) as response:
332 return response.read().decode('utf-8')
333 except urllib.error.HTTPError as e:
334 return f"Error: {e.code} - {e.reason}"
335
336
337def string_version() -> str:
338 """
339 Get current STRING database version.
340
341 Returns:
342 str: Version information
343
344 Example:
345 version = string_version()
346 """
347 url = f"{STRING_BASE_URL}/tsv/version"
348
349 try:
350 with urllib.request.urlopen(url) as response:
351 return response.read().decode('utf-8')
352 except urllib.error.HTTPError as e:
353 return f"Error: {e.code} - {e.reason}"
354
355
356if __name__ == "__main__":
357 # Example usage
358 print("STRING Version:")
359 print(string_version())
360 print()
361
362 print("Mapping protein names to STRING IDs:")
363 mapping = string_map_ids(['TP53', 'BRCA1'], species=9606)
364 print(mapping)
365 print()
366
367 print("Getting interaction network:")
368 network = string_network('TP53', species=9606, add_nodes=3)
369 print(network[:500] + "...")