tooluniverse 1.0.10__py3-none-any.whl → 1.0.11.1__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 (151) 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 +78 -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.py +10 -2
  66. tooluniverse/smcp_server.py +3 -3
  67. tooluniverse/tool_finder_embedding.py +3 -1
  68. tooluniverse/tool_finder_keyword.py +3 -1
  69. tooluniverse/tool_finder_llm.py +6 -2
  70. tooluniverse/tools/{UCSC_get_genes_by_region.py → BLAST_nucleotide_search.py} +22 -26
  71. tooluniverse/tools/BLAST_protein_search.py +63 -0
  72. tooluniverse/tools/ClinVar_search_variants.py +26 -15
  73. tooluniverse/tools/CodeQualityAnalyzer.py +3 -3
  74. tooluniverse/tools/EMDB_get_structure.py +46 -0
  75. tooluniverse/tools/GtoPdb_get_targets.py +52 -0
  76. tooluniverse/tools/InterPro_get_domain_details.py +46 -0
  77. tooluniverse/tools/InterPro_get_protein_domains.py +49 -0
  78. tooluniverse/tools/InterPro_search_domains.py +52 -0
  79. tooluniverse/tools/JASPAR_get_transcription_factors.py +52 -0
  80. tooluniverse/tools/MPD_get_phenotype_data.py +59 -0
  81. tooluniverse/tools/PRIDE_search_proteomics.py +52 -0
  82. tooluniverse/tools/PackageAnalyzer.py +55 -0
  83. tooluniverse/tools/Paleobiology_get_fossils.py +52 -0
  84. tooluniverse/tools/PyPIPackageInspector.py +59 -0
  85. tooluniverse/tools/ReMap_get_transcription_factor_binding.py +59 -0
  86. tooluniverse/tools/ReferenceInfoAnalyzer.py +55 -0
  87. tooluniverse/tools/RegulomeDB_query_variant.py +46 -0
  88. tooluniverse/tools/SCREEN_get_regulatory_elements.py +59 -0
  89. tooluniverse/tools/{ArgumentDescriptionOptimizer.py → TestResultsAnalyzer.py} +13 -13
  90. tooluniverse/tools/ToolDiscover.py +11 -11
  91. tooluniverse/tools/UniProt_id_mapping.py +63 -0
  92. tooluniverse/tools/UniProt_search.py +63 -0
  93. tooluniverse/tools/UnifiedToolGenerator.py +59 -0
  94. tooluniverse/tools/WoRMS_search_species.py +49 -0
  95. tooluniverse/tools/XMLToolOptimizer.py +55 -0
  96. tooluniverse/tools/__init__.py +119 -29
  97. tooluniverse/tools/alphafold_get_annotations.py +3 -3
  98. tooluniverse/tools/alphafold_get_prediction.py +3 -3
  99. tooluniverse/tools/alphafold_get_summary.py +3 -3
  100. tooluniverse/tools/cBioPortal_get_cancer_studies.py +46 -0
  101. tooluniverse/tools/cBioPortal_get_mutations.py +52 -0
  102. tooluniverse/tools/{gnomAD_query_variant.py → clinvar_get_clinical_significance.py} +8 -11
  103. tooluniverse/tools/clinvar_get_variant_details.py +49 -0
  104. tooluniverse/tools/dbSNP_get_variant_by_rsid.py +7 -7
  105. tooluniverse/tools/dbsnp_get_frequencies.py +46 -0
  106. tooluniverse/tools/dbsnp_search_by_gene.py +52 -0
  107. tooluniverse/tools/download_binary_file.py +66 -0
  108. tooluniverse/tools/download_file.py +71 -0
  109. tooluniverse/tools/download_text_content.py +55 -0
  110. tooluniverse/tools/dynamic_package_discovery.py +59 -0
  111. tooluniverse/tools/ensembl_get_sequence.py +52 -0
  112. tooluniverse/tools/{Ensembl_lookup_gene_by_symbol.py → ensembl_get_variants.py} +11 -11
  113. tooluniverse/tools/ensembl_lookup_gene.py +46 -0
  114. tooluniverse/tools/geo_get_dataset_info.py +46 -0
  115. tooluniverse/tools/geo_get_sample_info.py +46 -0
  116. tooluniverse/tools/geo_search_datasets.py +67 -0
  117. tooluniverse/tools/gnomad_get_gene_constraints.py +49 -0
  118. tooluniverse/tools/kegg_find_genes.py +52 -0
  119. tooluniverse/tools/kegg_get_gene_info.py +46 -0
  120. tooluniverse/tools/kegg_get_pathway_info.py +46 -0
  121. tooluniverse/tools/kegg_list_organisms.py +44 -0
  122. tooluniverse/tools/kegg_search_pathway.py +46 -0
  123. tooluniverse/tools/ols_find_similar_terms.py +63 -0
  124. tooluniverse/tools/{get_hyperopt_info.py → ols_get_ontology_info.py} +13 -10
  125. tooluniverse/tools/ols_get_term_ancestors.py +67 -0
  126. tooluniverse/tools/ols_get_term_children.py +67 -0
  127. tooluniverse/tools/{TestCaseGenerator.py → ols_get_term_info.py} +12 -9
  128. tooluniverse/tools/{CodeOptimizer.py → ols_search_ontologies.py} +22 -14
  129. tooluniverse/tools/ols_search_terms.py +71 -0
  130. tooluniverse/tools/python_code_executor.py +79 -0
  131. tooluniverse/tools/python_script_runner.py +79 -0
  132. tooluniverse/tools/web_api_documentation_search.py +63 -0
  133. tooluniverse/tools/web_search.py +71 -0
  134. tooluniverse/uniprot_tool.py +219 -16
  135. tooluniverse/url_tool.py +18 -0
  136. tooluniverse/utils.py +2 -2
  137. tooluniverse/web_search_tool.py +229 -0
  138. tooluniverse/worms_tool.py +64 -0
  139. {tooluniverse-1.0.10.dist-info → tooluniverse-1.0.11.1.dist-info}/METADATA +3 -2
  140. {tooluniverse-1.0.10.dist-info → tooluniverse-1.0.11.1.dist-info}/RECORD +144 -55
  141. tooluniverse/data/genomics_tools.json +0 -174
  142. tooluniverse/tools/ToolDescriptionOptimizer.py +0 -67
  143. tooluniverse/tools/ToolImplementationGenerator.py +0 -67
  144. tooluniverse/tools/ToolOptimizer.py +0 -59
  145. tooluniverse/tools/ToolSpecificationGenerator.py +0 -67
  146. tooluniverse/tools/ToolSpecificationOptimizer.py +0 -63
  147. tooluniverse/ucsc_tool.py +0 -60
  148. {tooluniverse-1.0.10.dist-info → tooluniverse-1.0.11.1.dist-info}/WHEEL +0 -0
  149. {tooluniverse-1.0.10.dist-info → tooluniverse-1.0.11.1.dist-info}/entry_points.txt +0 -0
  150. {tooluniverse-1.0.10.dist-info → tooluniverse-1.0.11.1.dist-info}/licenses/LICENSE +0 -0
  151. {tooluniverse-1.0.10.dist-info → tooluniverse-1.0.11.1.dist-info}/top_level.txt +0 -0
tooluniverse/__init__.py CHANGED
@@ -174,9 +174,26 @@ MCPAutoLoaderTool: Any
174
174
  ADMETAITool: Any
175
175
  AlphaFoldRESTTool: Any
176
176
  ComposeTool: Any
177
+ PythonCodeExecutor: Any
178
+ PythonScriptRunner: Any
177
179
  CellosaurusSearchTool: Any
178
180
  CellosaurusQueryConverterTool: Any
179
181
  CellosaurusGetCellLineInfoTool: Any
182
+ # New database tools
183
+ InterProRESTTool: Any
184
+ NCBIBlastTool: Any
185
+ CBioPortalRESTTool: Any
186
+ RegulomeDBRESTTool: Any
187
+ JASPARRESTTool: Any
188
+ ReMapRESTTool: Any
189
+ SCREENRESTTool: Any
190
+ PRIDERESTTool: Any
191
+ EMDBRESTTool: Any
192
+ GtoPdbRESTTool: Any
193
+ MPDRESTTool: Any
194
+ WoRMSRESTTool: Any
195
+ PaleobiologyRESTTool: Any
196
+ OLSTool: Any
180
197
  if not _LIGHT_IMPORT and not LAZY_LOADING_ENABLED:
181
198
  # Import all tool classes immediately (old behavior) with warning suppression # noqa: E501
182
199
  with warnings.catch_warnings():
@@ -185,7 +202,6 @@ if not _LIGHT_IMPORT and not LAZY_LOADING_ENABLED:
185
202
  warnings.filterwarnings("ignore", category=UserWarning)
186
203
  warnings.filterwarnings("ignore", category=FutureWarning)
187
204
  # Suppress specific third-party warnings
188
- warnings.filterwarnings("ignore", category=UserWarning, module="hyperopt")
189
205
  warnings.filterwarnings(
190
206
  "ignore", category=DeprecationWarning, module="pkg_resources"
191
207
  )
@@ -213,6 +229,10 @@ if not _LIGHT_IMPORT and not LAZY_LOADING_ENABLED:
213
229
  )
214
230
  from .chem_tool import ChEMBLTool
215
231
  from .compose_tool import ComposeTool
232
+ from .python_executor_tool import (
233
+ PythonCodeExecutor,
234
+ PythonScriptRunner,
235
+ )
216
236
  from .europe_pmc_tool import EuropePMCTool
217
237
  from .semantic_scholar_tool import SemanticScholarTool
218
238
  from .pubtator_tool import PubTatorTool
@@ -235,6 +255,12 @@ if not _LIGHT_IMPORT and not LAZY_LOADING_ENABLED:
235
255
  from .embedding_database import EmbeddingDatabase
236
256
  from .embedding_sync import EmbeddingSync
237
257
  from .rcsb_pdb_tool import RCSBTool
258
+ from .web_search_tool import (
259
+ WebSearchTool,
260
+ WebAPIDocumentationSearchTool,
261
+ )
262
+ from .package_discovery_tool import DynamicPackageDiscovery
263
+ from .pypi_package_inspector_tool import PyPIPackageInspector
238
264
  from .gwas_tool import (
239
265
  GWASAssociationSearch,
240
266
  GWASStudySearch,
@@ -264,6 +290,14 @@ if not _LIGHT_IMPORT and not LAZY_LOADING_ENABLED:
264
290
  CellosaurusQueryConverterTool,
265
291
  CellosaurusGetCellLineInfoTool,
266
292
  )
293
+ from .ols_tool import OLSTool
294
+
295
+ # New database tools
296
+ from .clinvar_tool import (
297
+ ClinVarSearchVariants,
298
+ ClinVarGetVariantDetails,
299
+ ClinVarGetClinicalSignificance,
300
+ )
267
301
 
268
302
  # Literature search tools
269
303
  from .arxiv_tool import ArXivTool
@@ -310,6 +344,8 @@ else:
310
344
  )
311
345
  ChEMBLTool = _LazyImportProxy("chem_tool", "ChEMBLTool")
312
346
  ComposeTool = _LazyImportProxy("compose_tool", "ComposeTool")
347
+ PythonCodeExecutor = _LazyImportProxy("python_executor_tool", "PythonCodeExecutor")
348
+ PythonScriptRunner = _LazyImportProxy("python_executor_tool", "PythonScriptRunner")
313
349
  EuropePMCTool = _LazyImportProxy("europe_pmc_tool", "EuropePMCTool")
314
350
  SemanticScholarTool = _LazyImportProxy(
315
351
  "semantic_scholar_tool", "SemanticScholarTool"
@@ -368,6 +404,7 @@ else:
368
404
  CellosaurusGetCellLineInfoTool = _LazyImportProxy(
369
405
  "cellosaurus_tool", "CellosaurusGetCellLineInfoTool"
370
406
  )
407
+ OLSTool = _LazyImportProxy("ols_tool", "OLSTool")
371
408
  # Literature search tools
372
409
  ArXivTool = _LazyImportProxy("arxiv_tool", "ArXivTool")
373
410
  CrossrefTool = _LazyImportProxy("crossref_tool", "CrossrefTool")
@@ -381,6 +418,16 @@ else:
381
418
  CoreTool = _LazyImportProxy("core_tool", "CoreTool")
382
419
  PMCTool = _LazyImportProxy("pmc_tool", "PMCTool")
383
420
  ZenodoTool = _LazyImportProxy("zenodo_tool", "ZenodoTool")
421
+ WebSearchTool = _LazyImportProxy("web_search_tool", "WebSearchTool")
422
+ WebAPIDocumentationSearchTool = _LazyImportProxy(
423
+ "web_search_tool", "WebAPIDocumentationSearchTool"
424
+ )
425
+ DynamicPackageDiscovery = _LazyImportProxy(
426
+ "package_discovery_tool", "DynamicPackageDiscovery"
427
+ )
428
+ PyPIPackageInspector = _LazyImportProxy(
429
+ "pypi_package_inspector_tool", "PyPIPackageInspector"
430
+ )
384
431
 
385
432
  __all__ = [
386
433
  "__version__",
@@ -456,6 +503,7 @@ __all__ = [
456
503
  "CellosaurusSearchTool",
457
504
  "CellosaurusQueryConverterTool",
458
505
  "CellosaurusGetCellLineInfoTool",
506
+ "OLSTool",
459
507
  # Literature search tools
460
508
  "ArXivTool",
461
509
  "CrossrefTool",
@@ -469,4 +517,12 @@ __all__ = [
469
517
  "CoreTool",
470
518
  "PMCTool",
471
519
  "ZenodoTool",
520
+ "WebSearchTool",
521
+ "WebAPIDocumentationSearchTool",
522
+ "DynamicPackageDiscovery",
523
+ "PyPIPackageInspector",
524
+ # ClinVar tools
525
+ "ClinVarSearchVariants",
526
+ "ClinVarGetVariantDetails",
527
+ "ClinVarGetClinicalSignificance",
472
528
  ]
@@ -0,0 +1,132 @@
1
+ from typing import Any, Dict
2
+ from Bio.Blast import NCBIWWW, NCBIXML
3
+ from Bio.Seq import Seq
4
+ from .base_tool import BaseTool
5
+ from .tool_registry import register_tool
6
+
7
+
8
+ @register_tool("NCBIBlastTool")
9
+ class NCBIBlastTool(BaseTool):
10
+ def __init__(self, tool_config: Dict):
11
+ super().__init__(tool_config)
12
+ self.timeout = 300 # BLAST can take a long time
13
+ self.max_wait_time = 600 # Maximum wait time for results
14
+
15
+ def _parse_blast_results(self, blast_xml: str) -> Dict[str, Any]:
16
+ """Parse BLAST XML results into structured data"""
17
+ try:
18
+ from io import StringIO
19
+
20
+ blast_record = NCBIXML.read(StringIO(blast_xml))
21
+
22
+ results = {
23
+ "query_id": blast_record.query_id,
24
+ "query_length": blast_record.query_length,
25
+ "database": blast_record.database,
26
+ "algorithm": blast_record.application,
27
+ "alignments": [],
28
+ }
29
+
30
+ for alignment in blast_record.alignments:
31
+ alignment_data = {
32
+ "hit_id": getattr(alignment, "hit_id", "unknown"),
33
+ "hit_def": getattr(alignment, "hit_def", "unknown"),
34
+ "hit_length": getattr(alignment, "hit_length", 0),
35
+ "hsps": [],
36
+ }
37
+
38
+ for hsp in alignment.hsps:
39
+ hsp_data = {
40
+ "score": getattr(hsp, "score", 0),
41
+ "bits": getattr(hsp, "bits", 0),
42
+ "expect": getattr(hsp, "expect", 0),
43
+ "identities": getattr(hsp, "identities", 0),
44
+ "positives": getattr(hsp, "positives", 0),
45
+ "gaps": getattr(hsp, "gaps", 0),
46
+ "align_length": getattr(hsp, "align_length", 0),
47
+ "query_start": getattr(hsp, "query_start", 0),
48
+ "query_end": getattr(hsp, "query_end", 0),
49
+ "hit_start": getattr(hsp, "hit_start", 0),
50
+ "hit_end": getattr(hsp, "hit_end", 0),
51
+ "query": getattr(hsp, "query", ""),
52
+ "match": getattr(hsp, "match", ""),
53
+ "sbjct": getattr(hsp, "sbjct", ""),
54
+ }
55
+ alignment_data["hsps"].append(hsp_data)
56
+
57
+ results["alignments"].append(alignment_data)
58
+
59
+ return results
60
+
61
+ except Exception as e:
62
+ return {
63
+ "error": f"Failed to parse BLAST results: {str(e)}",
64
+ "raw_xml": (
65
+ blast_xml[:1000] + "..." if len(blast_xml) > 1000 else blast_xml
66
+ ),
67
+ }
68
+
69
+ def run(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
70
+ """Execute BLAST search using NCBI Web service"""
71
+ try:
72
+ sequence = arguments.get("sequence", "")
73
+ blast_type = arguments.get("blast_type", "blastn")
74
+ database = arguments.get("database", "nt")
75
+ expect = arguments.get("expect", 10.0)
76
+ hitlist_size = arguments.get("hitlist_size", 50)
77
+
78
+ if not sequence:
79
+ return {
80
+ "status": "error",
81
+ "error": "Missing required parameter: sequence",
82
+ }
83
+
84
+ # Validate sequence
85
+ try:
86
+ seq_obj = Seq(sequence)
87
+ if len(seq_obj) < 10:
88
+ return {
89
+ "status": "error",
90
+ "error": "Sequence too short (minimum 10 nucleotides)",
91
+ }
92
+ except Exception as e:
93
+ return {
94
+ "status": "error",
95
+ "error": f"Invalid sequence format: {str(e)}",
96
+ }
97
+
98
+ # Perform BLAST search
99
+ result_handle = NCBIWWW.qblast(
100
+ blast_type,
101
+ database,
102
+ sequence,
103
+ expect=expect,
104
+ hitlist_size=hitlist_size,
105
+ format_type="XML",
106
+ )
107
+
108
+ # Read results
109
+ blast_xml = result_handle.read()
110
+ result_handle.close()
111
+
112
+ # Parse results
113
+ parsed_results = self._parse_blast_results(blast_xml)
114
+
115
+ if "error" in parsed_results:
116
+ return {
117
+ "status": "error",
118
+ "error": parsed_results["error"],
119
+ "raw_data": parsed_results.get("raw_xml", ""),
120
+ }
121
+
122
+ return {
123
+ "status": "success",
124
+ "data": parsed_results,
125
+ "query_sequence": sequence,
126
+ "blast_type": blast_type,
127
+ "database": database,
128
+ "hit_count": len(parsed_results["alignments"]),
129
+ }
130
+
131
+ except Exception as e:
132
+ return {"status": "error", "error": f"BLAST search failed: {str(e)}"}
@@ -170,7 +170,7 @@ class Boltz2DockingTool(BaseTool):
170
170
  prediction_folder, f"{input_filename}_model_0.cif"
171
171
  )
172
172
  if os.path.exists(structure_file):
173
- with open(structure_file, "r") as f:
173
+ with open(structure_file, "r", encoding="utf-8") as f:
174
174
  results["predicted_structure"] = f.read()
175
175
  results["structure_format"] = "cif"
176
176
  else:
@@ -183,7 +183,7 @@ class Boltz2DockingTool(BaseTool):
183
183
  prediction_folder, f"affinity_{input_filename}.json"
184
184
  )
185
185
  if os.path.exists(affinity_file):
186
- with open(affinity_file, "r") as f:
186
+ with open(affinity_file, "r", encoding="utf-8") as f:
187
187
  results["affinity_prediction"] = json.load(f)
188
188
  else:
189
189
  results["affinity_error"] = f"Missing {os.path.basename(affinity_file)}"
@@ -0,0 +1,42 @@
1
+ import requests
2
+ from typing import Any, Dict
3
+ from .base_tool import BaseTool
4
+ from .tool_registry import register_tool
5
+
6
+
7
+ @register_tool("CBioPortalRESTTool")
8
+ class CBioPortalRESTTool(BaseTool):
9
+ def __init__(self, tool_config: Dict):
10
+ super().__init__(tool_config)
11
+ self.base_url = "https://www.cbioportal.org/api"
12
+ self.session = requests.Session()
13
+ self.session.headers.update(
14
+ {"Accept": "application/json", "User-Agent": "ToolUniverse/1.0"}
15
+ )
16
+ self.timeout = 30
17
+
18
+ def _build_url(self, args: Dict[str, Any]) -> str:
19
+ url = self.tool_config["fields"]["endpoint"]
20
+ for k, v in args.items():
21
+ url = url.replace(f"{{{k}}}", str(v))
22
+ return url
23
+
24
+ def run(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
25
+ try:
26
+ url = self._build_url(arguments)
27
+ response = self.session.get(url, timeout=self.timeout)
28
+ response.raise_for_status()
29
+ data = response.json()
30
+
31
+ return {
32
+ "status": "success",
33
+ "data": data,
34
+ "url": url,
35
+ "count": len(data) if isinstance(data, list) else 1,
36
+ }
37
+ except Exception as e:
38
+ return {
39
+ "status": "error",
40
+ "error": f"cBioPortal API error: {str(e)}",
41
+ "url": url,
42
+ }