tooluniverse 1.0.10__py3-none-any.whl → 1.0.11__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of tooluniverse might be problematic. Click here for more details.

Files changed (150) hide show
  1. tooluniverse/__init__.py +57 -1
  2. tooluniverse/blast_tool.py +132 -0
  3. tooluniverse/boltz_tool.py +2 -2
  4. tooluniverse/cbioportal_tool.py +42 -0
  5. tooluniverse/clinvar_tool.py +268 -74
  6. tooluniverse/compose_scripts/tool_discover.py +1941 -443
  7. tooluniverse/data/agentic_tools.json +0 -370
  8. tooluniverse/data/alphafold_tools.json +6 -6
  9. tooluniverse/data/blast_tools.json +112 -0
  10. tooluniverse/data/cbioportal_tools.json +87 -0
  11. tooluniverse/data/clinvar_tools.json +235 -0
  12. tooluniverse/data/compose_tools.json +0 -89
  13. tooluniverse/data/dbsnp_tools.json +275 -0
  14. tooluniverse/data/emdb_tools.json +61 -0
  15. tooluniverse/data/ensembl_tools.json +259 -0
  16. tooluniverse/data/file_download_tools.json +275 -0
  17. tooluniverse/data/geo_tools.json +200 -48
  18. tooluniverse/data/gnomad_tools.json +109 -0
  19. tooluniverse/data/gtopdb_tools.json +68 -0
  20. tooluniverse/data/gwas_tools.json +32 -0
  21. tooluniverse/data/interpro_tools.json +199 -0
  22. tooluniverse/data/jaspar_tools.json +70 -0
  23. tooluniverse/data/kegg_tools.json +356 -0
  24. tooluniverse/data/mpd_tools.json +87 -0
  25. tooluniverse/data/ols_tools.json +314 -0
  26. tooluniverse/data/package_discovery_tools.json +64 -0
  27. tooluniverse/data/packages/categorized_tools.txt +0 -1
  28. tooluniverse/data/packages/machine_learning_tools.json +0 -47
  29. tooluniverse/data/paleobiology_tools.json +91 -0
  30. tooluniverse/data/pride_tools.json +62 -0
  31. tooluniverse/data/pypi_package_inspector_tools.json +158 -0
  32. tooluniverse/data/python_executor_tools.json +341 -0
  33. tooluniverse/data/regulomedb_tools.json +50 -0
  34. tooluniverse/data/remap_tools.json +89 -0
  35. tooluniverse/data/screen_tools.json +89 -0
  36. tooluniverse/data/tool_discovery_agents.json +428 -0
  37. tooluniverse/data/tool_discovery_agents.json.backup +1343 -0
  38. tooluniverse/data/uniprot_tools.json +77 -0
  39. tooluniverse/data/web_search_tools.json +250 -0
  40. tooluniverse/data/worms_tools.json +55 -0
  41. tooluniverse/dbsnp_tool.py +196 -58
  42. tooluniverse/default_config.py +35 -2
  43. tooluniverse/emdb_tool.py +30 -0
  44. tooluniverse/ensembl_tool.py +140 -47
  45. tooluniverse/execute_function.py +74 -14
  46. tooluniverse/file_download_tool.py +269 -0
  47. tooluniverse/geo_tool.py +81 -28
  48. tooluniverse/gnomad_tool.py +100 -52
  49. tooluniverse/gtopdb_tool.py +41 -0
  50. tooluniverse/interpro_tool.py +72 -0
  51. tooluniverse/jaspar_tool.py +30 -0
  52. tooluniverse/kegg_tool.py +230 -0
  53. tooluniverse/mpd_tool.py +42 -0
  54. tooluniverse/ncbi_eutils_tool.py +96 -0
  55. tooluniverse/ols_tool.py +435 -0
  56. tooluniverse/package_discovery_tool.py +217 -0
  57. tooluniverse/paleobiology_tool.py +30 -0
  58. tooluniverse/pride_tool.py +30 -0
  59. tooluniverse/pypi_package_inspector_tool.py +593 -0
  60. tooluniverse/python_executor_tool.py +711 -0
  61. tooluniverse/regulomedb_tool.py +30 -0
  62. tooluniverse/remap_tool.py +44 -0
  63. tooluniverse/remote/depmap_24q2/depmap_24q2_mcp_tool.py +1 -1
  64. tooluniverse/screen_tool.py +44 -0
  65. tooluniverse/smcp_server.py +3 -3
  66. tooluniverse/tool_finder_embedding.py +3 -1
  67. tooluniverse/tool_finder_keyword.py +3 -1
  68. tooluniverse/tool_finder_llm.py +6 -2
  69. tooluniverse/tools/{UCSC_get_genes_by_region.py → BLAST_nucleotide_search.py} +22 -26
  70. tooluniverse/tools/BLAST_protein_search.py +63 -0
  71. tooluniverse/tools/ClinVar_search_variants.py +26 -15
  72. tooluniverse/tools/CodeQualityAnalyzer.py +3 -3
  73. tooluniverse/tools/EMDB_get_structure.py +46 -0
  74. tooluniverse/tools/GtoPdb_get_targets.py +52 -0
  75. tooluniverse/tools/InterPro_get_domain_details.py +46 -0
  76. tooluniverse/tools/InterPro_get_protein_domains.py +49 -0
  77. tooluniverse/tools/InterPro_search_domains.py +52 -0
  78. tooluniverse/tools/JASPAR_get_transcription_factors.py +52 -0
  79. tooluniverse/tools/MPD_get_phenotype_data.py +59 -0
  80. tooluniverse/tools/PRIDE_search_proteomics.py +52 -0
  81. tooluniverse/tools/PackageAnalyzer.py +55 -0
  82. tooluniverse/tools/Paleobiology_get_fossils.py +52 -0
  83. tooluniverse/tools/PyPIPackageInspector.py +59 -0
  84. tooluniverse/tools/ReMap_get_transcription_factor_binding.py +59 -0
  85. tooluniverse/tools/ReferenceInfoAnalyzer.py +55 -0
  86. tooluniverse/tools/RegulomeDB_query_variant.py +46 -0
  87. tooluniverse/tools/SCREEN_get_regulatory_elements.py +59 -0
  88. tooluniverse/tools/{ArgumentDescriptionOptimizer.py → TestResultsAnalyzer.py} +13 -13
  89. tooluniverse/tools/ToolDiscover.py +11 -11
  90. tooluniverse/tools/UniProt_id_mapping.py +63 -0
  91. tooluniverse/tools/UniProt_search.py +63 -0
  92. tooluniverse/tools/UnifiedToolGenerator.py +59 -0
  93. tooluniverse/tools/WoRMS_search_species.py +49 -0
  94. tooluniverse/tools/XMLToolOptimizer.py +55 -0
  95. tooluniverse/tools/__init__.py +119 -29
  96. tooluniverse/tools/alphafold_get_annotations.py +3 -3
  97. tooluniverse/tools/alphafold_get_prediction.py +3 -3
  98. tooluniverse/tools/alphafold_get_summary.py +3 -3
  99. tooluniverse/tools/cBioPortal_get_cancer_studies.py +46 -0
  100. tooluniverse/tools/cBioPortal_get_mutations.py +52 -0
  101. tooluniverse/tools/{gnomAD_query_variant.py → clinvar_get_clinical_significance.py} +8 -11
  102. tooluniverse/tools/clinvar_get_variant_details.py +49 -0
  103. tooluniverse/tools/dbSNP_get_variant_by_rsid.py +7 -7
  104. tooluniverse/tools/dbsnp_get_frequencies.py +46 -0
  105. tooluniverse/tools/dbsnp_search_by_gene.py +52 -0
  106. tooluniverse/tools/download_binary_file.py +66 -0
  107. tooluniverse/tools/download_file.py +71 -0
  108. tooluniverse/tools/download_text_content.py +55 -0
  109. tooluniverse/tools/dynamic_package_discovery.py +59 -0
  110. tooluniverse/tools/ensembl_get_sequence.py +52 -0
  111. tooluniverse/tools/{Ensembl_lookup_gene_by_symbol.py → ensembl_get_variants.py} +11 -11
  112. tooluniverse/tools/ensembl_lookup_gene.py +46 -0
  113. tooluniverse/tools/geo_get_dataset_info.py +46 -0
  114. tooluniverse/tools/geo_get_sample_info.py +46 -0
  115. tooluniverse/tools/geo_search_datasets.py +67 -0
  116. tooluniverse/tools/gnomad_get_gene_constraints.py +49 -0
  117. tooluniverse/tools/kegg_find_genes.py +52 -0
  118. tooluniverse/tools/kegg_get_gene_info.py +46 -0
  119. tooluniverse/tools/kegg_get_pathway_info.py +46 -0
  120. tooluniverse/tools/kegg_list_organisms.py +44 -0
  121. tooluniverse/tools/kegg_search_pathway.py +46 -0
  122. tooluniverse/tools/ols_find_similar_terms.py +63 -0
  123. tooluniverse/tools/{get_hyperopt_info.py → ols_get_ontology_info.py} +13 -10
  124. tooluniverse/tools/ols_get_term_ancestors.py +67 -0
  125. tooluniverse/tools/ols_get_term_children.py +67 -0
  126. tooluniverse/tools/{TestCaseGenerator.py → ols_get_term_info.py} +12 -9
  127. tooluniverse/tools/{CodeOptimizer.py → ols_search_ontologies.py} +22 -14
  128. tooluniverse/tools/ols_search_terms.py +71 -0
  129. tooluniverse/tools/python_code_executor.py +79 -0
  130. tooluniverse/tools/python_script_runner.py +79 -0
  131. tooluniverse/tools/web_api_documentation_search.py +63 -0
  132. tooluniverse/tools/web_search.py +71 -0
  133. tooluniverse/uniprot_tool.py +219 -16
  134. tooluniverse/url_tool.py +18 -0
  135. tooluniverse/utils.py +2 -2
  136. tooluniverse/web_search_tool.py +229 -0
  137. tooluniverse/worms_tool.py +64 -0
  138. {tooluniverse-1.0.10.dist-info → tooluniverse-1.0.11.dist-info}/METADATA +3 -2
  139. {tooluniverse-1.0.10.dist-info → tooluniverse-1.0.11.dist-info}/RECORD +143 -54
  140. tooluniverse/data/genomics_tools.json +0 -174
  141. tooluniverse/tools/ToolDescriptionOptimizer.py +0 -67
  142. tooluniverse/tools/ToolImplementationGenerator.py +0 -67
  143. tooluniverse/tools/ToolOptimizer.py +0 -59
  144. tooluniverse/tools/ToolSpecificationGenerator.py +0 -67
  145. tooluniverse/tools/ToolSpecificationOptimizer.py +0 -63
  146. tooluniverse/ucsc_tool.py +0 -60
  147. {tooluniverse-1.0.10.dist-info → tooluniverse-1.0.11.dist-info}/WHEEL +0 -0
  148. {tooluniverse-1.0.10.dist-info → tooluniverse-1.0.11.dist-info}/entry_points.txt +0 -0
  149. {tooluniverse-1.0.10.dist-info → tooluniverse-1.0.11.dist-info}/licenses/LICENSE +0 -0
  150. {tooluniverse-1.0.10.dist-info → tooluniverse-1.0.11.dist-info}/top_level.txt +0 -0
@@ -1,90 +1,284 @@
1
+ """
2
+ ClinVar REST API Tool
3
+
4
+ This tool provides access to the ClinVar database for clinical variant information,
5
+ disease associations, and clinical significance data.
6
+ """
7
+
1
8
  import requests
9
+ import time
10
+ from typing import Dict, Any, Optional
2
11
  from .base_tool import BaseTool
3
12
  from .tool_registry import register_tool
4
13
 
5
14
 
6
- @register_tool("ClinVarTool")
7
- class ClinVarTool(BaseTool):
8
- """
9
- Local tool wrapper for ClinVar via NCBI E-utilities.
10
- Uses esearch + esummary to fetch variant records.
11
- """
15
+ class ClinVarRESTTool(BaseTool):
16
+ """Base class for ClinVar REST API tools."""
12
17
 
13
18
  def __init__(self, tool_config):
14
19
  super().__init__(tool_config)
15
- self.base = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils"
20
+ self.base_url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils"
16
21
  self.session = requests.Session()
22
+ self.session.headers.update(
23
+ {"Accept": "application/json", "User-Agent": "ToolUniverse/1.0"}
24
+ )
25
+ self.timeout = 30
17
26
 
18
- def run(self, arguments):
19
- query = arguments.get("query")
20
- retmax = arguments.get("retmax", 5)
21
- if not query:
22
- return {"error": "Missing required parameter: query"}
27
+ def _make_request(
28
+ self, endpoint: str, params: Optional[Dict] = None, max_retries: int = 3
29
+ ) -> Dict[str, Any]:
30
+ """Make a request to the ClinVar API with automatic retry for rate limiting."""
31
+ url = f"{self.base_url}{endpoint}"
23
32
 
24
- # 1) esearch to get UIDs
25
- search_url = f"{self.base}/esearch.fcgi"
26
- search_params = {
27
- "db": "clinvar",
28
- "term": query,
29
- "retmode": "json",
30
- "retmax": retmax,
31
- }
32
- search_resp = self.session.get(search_url, params=search_params, timeout=20)
33
- search_resp.raise_for_status()
34
- search_data = search_resp.json()
35
- uids = search_data.get("esearchresult", {}).get("idlist", [])
36
- if not uids:
37
- return []
38
-
39
- # 2) esummary to get details
40
- summary_url = f"{self.base}/esummary.fcgi"
41
- summary_params = {
33
+ for attempt in range(max_retries + 1):
34
+ try:
35
+ response = self.session.get(url, params=params, timeout=self.timeout)
36
+
37
+ # Handle rate limiting (429 error)
38
+ if response.status_code == 429:
39
+ retry_after = response.headers.get("Retry-After")
40
+ if retry_after:
41
+ wait_time = int(retry_after)
42
+ else:
43
+ # Default exponential backoff: 1, 2, 4 seconds
44
+ wait_time = 2**attempt
45
+
46
+ if attempt < max_retries:
47
+ print(
48
+ f"Rate limited (429). Waiting {wait_time} seconds before retry {attempt + 1}/{max_retries}..."
49
+ )
50
+ time.sleep(wait_time)
51
+ continue
52
+ else:
53
+ return {
54
+ "status": "error",
55
+ "error": f"Rate limited after {max_retries} retries. Please wait before making more requests.",
56
+ "url": url,
57
+ "retry_after": retry_after,
58
+ }
59
+
60
+ response.raise_for_status()
61
+
62
+ # ClinVar API returns XML by default, but we can request JSON
63
+ if params and params.get("retmode") == "json":
64
+ data = response.json()
65
+ else:
66
+ # Parse XML response
67
+ data = response.text
68
+
69
+ return {
70
+ "status": "success",
71
+ "data": data,
72
+ "url": url,
73
+ "content_type": response.headers.get(
74
+ "content-type", "application/xml"
75
+ ),
76
+ "rate_limit_info": {
77
+ "limit": response.headers.get("X-RateLimit-Limit"),
78
+ "remaining": response.headers.get("X-RateLimit-Remaining"),
79
+ },
80
+ }
81
+
82
+ except requests.exceptions.RequestException as e:
83
+ if attempt < max_retries:
84
+ wait_time = 2**attempt
85
+ print(
86
+ f"Request failed: {str(e)}. Retrying in {wait_time} seconds..."
87
+ )
88
+ time.sleep(wait_time)
89
+ continue
90
+ else:
91
+ return {
92
+ "status": "error",
93
+ "error": f"ClinVar API request failed after {max_retries} retries: {str(e)}",
94
+ "url": url,
95
+ }
96
+
97
+ return {"status": "error", "error": "Maximum retries exceeded", "url": url}
98
+
99
+ def run(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
100
+ """Execute the tool with given arguments."""
101
+ return self._make_request(self.endpoint, arguments)
102
+
103
+
104
+ @register_tool("ClinVarSearchVariants")
105
+ class ClinVarSearchVariants(ClinVarRESTTool):
106
+ """Search for variants in ClinVar by gene or condition."""
107
+
108
+ def __init__(self, tool_config):
109
+ super().__init__(tool_config)
110
+ self.endpoint = "/esearch.fcgi"
111
+
112
+ def run(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
113
+ """Search variants by gene or condition."""
114
+ params = {
42
115
  "db": "clinvar",
43
- "id": ",".join(uids),
44
116
  "retmode": "json",
117
+ "retmax": arguments.get("max_results", 20),
45
118
  }
46
- summary_resp = self.session.get(summary_url, params=summary_params, timeout=30)
47
- summary_resp.raise_for_status()
48
- summary_data = summary_resp.json()
49
-
50
- results = []
51
- for uid in uids:
52
- record = summary_data.get("result", {}).get(uid, {})
53
- if not record:
54
- continue
55
-
56
- # Extract key fields
57
- variation_set = record.get("variation_set", [])
58
- gene = ""
59
- chr_name = ""
60
- start = None
61
- stop = None
62
- spdi = ""
63
- if variation_set:
64
- var = variation_set[0]
65
- gene = record.get("genes", [{}])[0].get("symbol", "")
66
- var_loc = var.get("variation_loc", [{}])[0]
67
- chr_name = var_loc.get("chr", "")
68
- start = var_loc.get("start")
69
- stop = var_loc.get("stop")
70
- spdi = var.get("canonical_spdi", "")
71
-
72
- clinical_sig = record.get("germline_classification", {}).get(
73
- "description", ""
74
- )
75
-
76
- results.append(
77
- {
78
- "uid": uid,
79
- "accession": record.get("accession", ""),
80
- "title": record.get("title", ""),
81
- "gene": gene,
82
- "chr": chr_name,
83
- "start": start,
84
- "stop": stop,
85
- "spdi": spdi,
86
- "clinical_significance": clinical_sig,
119
+
120
+ # Build search query
121
+ query_parts = []
122
+
123
+ if "gene" in arguments:
124
+ query_parts.append(f"{arguments['gene']}[gene]")
125
+
126
+ if "condition" in arguments:
127
+ query_parts.append(f"{arguments['condition']}[condition]")
128
+
129
+ if "variant_id" in arguments:
130
+ query_parts.append(f"{arguments['variant_id']}[variant_id]")
131
+
132
+ if not query_parts:
133
+ return {
134
+ "status": "error",
135
+ "error": "At least one search parameter is required",
136
+ }
137
+
138
+ params["term"] = " AND ".join(query_parts)
139
+
140
+ result = self._make_request(self.endpoint, params)
141
+
142
+ # Add search parameters to result and format data
143
+ if result.get("status") == "success":
144
+ result["search_params"] = {
145
+ "gene": arguments.get("gene"),
146
+ "condition": arguments.get("condition"),
147
+ "variant_id": arguments.get("variant_id"),
148
+ }
149
+
150
+ # Format search results for better usability
151
+ data = result.get("data", {})
152
+ if "esearchresult" in data:
153
+ esearch = data["esearchresult"]
154
+ formatted_results = {
155
+ "total_count": int(esearch.get("count", 0)),
156
+ "variant_ids": esearch.get("idlist", []),
157
+ "query_translation": esearch.get("querytranslation", ""),
158
+ "search_params": result["search_params"],
159
+ "summary": f"Found {esearch.get('count', 0)} variants matching the search criteria",
87
160
  }
88
- )
161
+ result["formatted_results"] = formatted_results
162
+
163
+ return result
164
+
165
+
166
+ @register_tool("ClinVarGetVariantDetails")
167
+ class ClinVarGetVariantDetails(ClinVarRESTTool):
168
+ """Get detailed variant information by ClinVar ID."""
169
+
170
+ def __init__(self, tool_config):
171
+ super().__init__(tool_config)
172
+ self.endpoint = "/esummary.fcgi"
173
+
174
+ def run(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
175
+ """Get variant details by ClinVar ID."""
176
+ variant_id = arguments.get("variant_id", "")
177
+ if not variant_id:
178
+ return {"status": "error", "error": "variant_id is required"}
179
+
180
+ params = {"db": "clinvar", "id": variant_id, "retmode": "json"}
181
+
182
+ result = self._make_request(self.endpoint, params)
183
+
184
+ # Add variant_id to result and format data
185
+ if result.get("status") == "success":
186
+ result["variant_id"] = variant_id
187
+
188
+ # Format the data for better usability
189
+ data = result.get("data", {})
190
+ if "result" in data and variant_id in data["result"]:
191
+ variant_data = data["result"][variant_id]
192
+
193
+ # Extract key information
194
+ formatted_data = {
195
+ "variant_id": variant_id,
196
+ "accession": variant_data.get("accession", ""),
197
+ "title": variant_data.get("title", ""),
198
+ "obj_type": variant_data.get("obj_type", ""),
199
+ "genes": [
200
+ gene.get("symbol", "") for gene in variant_data.get("genes", [])
201
+ ],
202
+ "clinical_significance": variant_data.get(
203
+ "germline_classification", {}
204
+ ).get("description", ""),
205
+ "review_status": variant_data.get(
206
+ "germline_classification", {}
207
+ ).get("review_status", ""),
208
+ "chromosome": variant_data.get("chr_sort", ""),
209
+ "location": variant_data.get("variation_set", [{}])[0]
210
+ .get("variation_loc", [{}])[0]
211
+ .get("band", ""),
212
+ "variation_name": variant_data.get("variation_set", [{}])[0].get(
213
+ "variation_name", ""
214
+ ),
215
+ "raw_data": variant_data, # Keep original data for advanced users
216
+ }
217
+
218
+ result["formatted_data"] = formatted_data
219
+
220
+ return result
221
+
222
+
223
+ @register_tool("ClinVarGetClinicalSignificance")
224
+ class ClinVarGetClinicalSignificance(ClinVarRESTTool):
225
+ """Get clinical significance information for variants."""
226
+
227
+ def __init__(self, tool_config):
228
+ super().__init__(tool_config)
229
+ self.endpoint = "/esummary.fcgi"
230
+
231
+ def run(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
232
+ """Get clinical significance by variant ID."""
233
+ variant_id = arguments.get("variant_id", "")
234
+ if not variant_id:
235
+ return {"status": "error", "error": "variant_id is required"}
236
+
237
+ params = {"db": "clinvar", "id": variant_id, "retmode": "json"}
238
+
239
+ result = self._make_request(self.endpoint, params)
240
+
241
+ # Add variant_id to result and format clinical significance data
242
+ if result.get("status") == "success":
243
+ result["variant_id"] = variant_id
244
+
245
+ # Format the clinical significance data
246
+ data = result.get("data", {})
247
+ if "result" in data and variant_id in data["result"]:
248
+ variant_data = data["result"][variant_id]
249
+
250
+ # Extract clinical significance information
251
+ germline_class = variant_data.get("germline_classification", {})
252
+ clinical_impact = variant_data.get("clinical_impact_classification", {})
253
+ oncogenicity = variant_data.get("oncogenicity_classification", {})
254
+
255
+ formatted_data = {
256
+ "variant_id": variant_id,
257
+ "germline_classification": {
258
+ "description": germline_class.get("description", ""),
259
+ "review_status": germline_class.get("review_status", ""),
260
+ "last_evaluated": germline_class.get("last_evaluated", ""),
261
+ "fda_recognized": germline_class.get(
262
+ "fda_recognized_database", ""
263
+ ),
264
+ "traits": [
265
+ trait.get("trait_name", "")
266
+ for trait in germline_class.get("trait_set", [])
267
+ ],
268
+ },
269
+ "clinical_impact": {
270
+ "description": clinical_impact.get("description", ""),
271
+ "review_status": clinical_impact.get("review_status", ""),
272
+ "last_evaluated": clinical_impact.get("last_evaluated", ""),
273
+ },
274
+ "oncogenicity": {
275
+ "description": oncogenicity.get("description", ""),
276
+ "review_status": oncogenicity.get("review_status", ""),
277
+ "last_evaluated": oncogenicity.get("last_evaluated", ""),
278
+ },
279
+ "raw_data": variant_data, # Keep original data for advanced users
280
+ }
281
+
282
+ result["formatted_data"] = formatted_data
89
283
 
90
- return results
284
+ return result