tooluniverse 0.2.0__py3-none-any.whl → 1.0.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 (186) hide show
  1. tooluniverse/__init__.py +340 -4
  2. tooluniverse/admetai_tool.py +84 -0
  3. tooluniverse/agentic_tool.py +563 -0
  4. tooluniverse/alphafold_tool.py +96 -0
  5. tooluniverse/base_tool.py +129 -6
  6. tooluniverse/boltz_tool.py +207 -0
  7. tooluniverse/chem_tool.py +192 -0
  8. tooluniverse/compose_scripts/__init__.py +1 -0
  9. tooluniverse/compose_scripts/biomarker_discovery.py +293 -0
  10. tooluniverse/compose_scripts/comprehensive_drug_discovery.py +186 -0
  11. tooluniverse/compose_scripts/drug_safety_analyzer.py +89 -0
  12. tooluniverse/compose_scripts/literature_tool.py +34 -0
  13. tooluniverse/compose_scripts/output_summarizer.py +279 -0
  14. tooluniverse/compose_scripts/tool_description_optimizer.py +681 -0
  15. tooluniverse/compose_scripts/tool_discover.py +705 -0
  16. tooluniverse/compose_scripts/tool_graph_composer.py +448 -0
  17. tooluniverse/compose_tool.py +371 -0
  18. tooluniverse/ctg_tool.py +1002 -0
  19. tooluniverse/custom_tool.py +81 -0
  20. tooluniverse/dailymed_tool.py +108 -0
  21. tooluniverse/data/admetai_tools.json +155 -0
  22. tooluniverse/data/adverse_event_tools.json +108 -0
  23. tooluniverse/data/agentic_tools.json +1156 -0
  24. tooluniverse/data/alphafold_tools.json +87 -0
  25. tooluniverse/data/boltz_tools.json +9 -0
  26. tooluniverse/data/chembl_tools.json +16 -0
  27. tooluniverse/data/clinicaltrials_gov_tools.json +326 -0
  28. tooluniverse/data/compose_tools.json +202 -0
  29. tooluniverse/data/dailymed_tools.json +70 -0
  30. tooluniverse/data/dataset_tools.json +646 -0
  31. tooluniverse/data/disease_target_score_tools.json +712 -0
  32. tooluniverse/data/efo_tools.json +17 -0
  33. tooluniverse/data/embedding_tools.json +319 -0
  34. tooluniverse/data/enrichr_tools.json +31 -0
  35. tooluniverse/data/europe_pmc_tools.json +22 -0
  36. tooluniverse/data/expert_feedback_tools.json +10 -0
  37. tooluniverse/data/fda_drug_adverse_event_tools.json +491 -0
  38. tooluniverse/data/fda_drug_labeling_tools.json +1 -1
  39. tooluniverse/data/fda_drugs_with_brand_generic_names_for_tool.py +76929 -148860
  40. tooluniverse/data/finder_tools.json +209 -0
  41. tooluniverse/data/gene_ontology_tools.json +113 -0
  42. tooluniverse/data/gwas_tools.json +1082 -0
  43. tooluniverse/data/hpa_tools.json +333 -0
  44. tooluniverse/data/humanbase_tools.json +47 -0
  45. tooluniverse/data/idmap_tools.json +74 -0
  46. tooluniverse/data/mcp_client_tools_example.json +113 -0
  47. tooluniverse/data/mcpautoloadertool_defaults.json +28 -0
  48. tooluniverse/data/medlineplus_tools.json +141 -0
  49. tooluniverse/data/monarch_tools.json +1 -1
  50. tooluniverse/data/openalex_tools.json +36 -0
  51. tooluniverse/data/opentarget_tools.json +1 -1
  52. tooluniverse/data/output_summarization_tools.json +101 -0
  53. tooluniverse/data/packages/bioinformatics_core_tools.json +1756 -0
  54. tooluniverse/data/packages/categorized_tools.txt +206 -0
  55. tooluniverse/data/packages/cheminformatics_tools.json +347 -0
  56. tooluniverse/data/packages/earth_sciences_tools.json +74 -0
  57. tooluniverse/data/packages/genomics_tools.json +776 -0
  58. tooluniverse/data/packages/image_processing_tools.json +38 -0
  59. tooluniverse/data/packages/machine_learning_tools.json +789 -0
  60. tooluniverse/data/packages/neuroscience_tools.json +62 -0
  61. tooluniverse/data/packages/original_tools.txt +0 -0
  62. tooluniverse/data/packages/physics_astronomy_tools.json +62 -0
  63. tooluniverse/data/packages/scientific_computing_tools.json +560 -0
  64. tooluniverse/data/packages/single_cell_tools.json +453 -0
  65. tooluniverse/data/packages/structural_biology_tools.json +396 -0
  66. tooluniverse/data/packages/visualization_tools.json +399 -0
  67. tooluniverse/data/pubchem_tools.json +215 -0
  68. tooluniverse/data/pubtator_tools.json +68 -0
  69. tooluniverse/data/rcsb_pdb_tools.json +1332 -0
  70. tooluniverse/data/reactome_tools.json +19 -0
  71. tooluniverse/data/semantic_scholar_tools.json +26 -0
  72. tooluniverse/data/special_tools.json +2 -25
  73. tooluniverse/data/tool_composition_tools.json +88 -0
  74. tooluniverse/data/toolfinderkeyword_defaults.json +34 -0
  75. tooluniverse/data/txagent_client_tools.json +9 -0
  76. tooluniverse/data/uniprot_tools.json +211 -0
  77. tooluniverse/data/url_fetch_tools.json +94 -0
  78. tooluniverse/data/uspto_downloader_tools.json +9 -0
  79. tooluniverse/data/uspto_tools.json +811 -0
  80. tooluniverse/data/xml_tools.json +3275 -0
  81. tooluniverse/dataset_tool.py +296 -0
  82. tooluniverse/default_config.py +165 -0
  83. tooluniverse/efo_tool.py +42 -0
  84. tooluniverse/embedding_database.py +630 -0
  85. tooluniverse/embedding_sync.py +396 -0
  86. tooluniverse/enrichr_tool.py +266 -0
  87. tooluniverse/europe_pmc_tool.py +52 -0
  88. tooluniverse/execute_function.py +1775 -95
  89. tooluniverse/extended_hooks.py +444 -0
  90. tooluniverse/gene_ontology_tool.py +194 -0
  91. tooluniverse/graphql_tool.py +158 -36
  92. tooluniverse/gwas_tool.py +358 -0
  93. tooluniverse/hpa_tool.py +1645 -0
  94. tooluniverse/humanbase_tool.py +389 -0
  95. tooluniverse/logging_config.py +254 -0
  96. tooluniverse/mcp_client_tool.py +764 -0
  97. tooluniverse/mcp_integration.py +413 -0
  98. tooluniverse/mcp_tool_registry.py +925 -0
  99. tooluniverse/medlineplus_tool.py +337 -0
  100. tooluniverse/openalex_tool.py +228 -0
  101. tooluniverse/openfda_adv_tool.py +283 -0
  102. tooluniverse/openfda_tool.py +393 -160
  103. tooluniverse/output_hook.py +1122 -0
  104. tooluniverse/package_tool.py +195 -0
  105. tooluniverse/pubchem_tool.py +158 -0
  106. tooluniverse/pubtator_tool.py +168 -0
  107. tooluniverse/rcsb_pdb_tool.py +38 -0
  108. tooluniverse/reactome_tool.py +108 -0
  109. tooluniverse/remote/boltz/boltz_mcp_server.py +50 -0
  110. tooluniverse/remote/depmap_24q2/depmap_24q2_mcp_tool.py +442 -0
  111. tooluniverse/remote/expert_feedback/human_expert_mcp_tools.py +2013 -0
  112. tooluniverse/remote/expert_feedback/simple_test.py +23 -0
  113. tooluniverse/remote/expert_feedback/start_web_interface.py +188 -0
  114. tooluniverse/remote/expert_feedback/web_only_interface.py +0 -0
  115. tooluniverse/remote/immune_compass/compass_tool.py +327 -0
  116. tooluniverse/remote/pinnacle/pinnacle_tool.py +328 -0
  117. tooluniverse/remote/transcriptformer/transcriptformer_tool.py +586 -0
  118. tooluniverse/remote/uspto_downloader/uspto_downloader_mcp_server.py +61 -0
  119. tooluniverse/remote/uspto_downloader/uspto_downloader_tool.py +120 -0
  120. tooluniverse/remote_tool.py +99 -0
  121. tooluniverse/restful_tool.py +53 -30
  122. tooluniverse/scripts/generate_tool_graph.py +408 -0
  123. tooluniverse/scripts/visualize_tool_graph.py +829 -0
  124. tooluniverse/semantic_scholar_tool.py +62 -0
  125. tooluniverse/smcp.py +2452 -0
  126. tooluniverse/smcp_server.py +975 -0
  127. tooluniverse/test/mcp_server_test.py +0 -0
  128. tooluniverse/test/test_admetai_tool.py +370 -0
  129. tooluniverse/test/test_agentic_tool.py +129 -0
  130. tooluniverse/test/test_alphafold_tool.py +71 -0
  131. tooluniverse/test/test_chem_tool.py +37 -0
  132. tooluniverse/test/test_compose_lieraturereview.py +63 -0
  133. tooluniverse/test/test_compose_tool.py +448 -0
  134. tooluniverse/test/test_dailymed.py +69 -0
  135. tooluniverse/test/test_dataset_tool.py +200 -0
  136. tooluniverse/test/test_disease_target_score.py +56 -0
  137. tooluniverse/test/test_drugbank_filter_examples.py +179 -0
  138. tooluniverse/test/test_efo.py +31 -0
  139. tooluniverse/test/test_enrichr_tool.py +21 -0
  140. tooluniverse/test/test_europe_pmc_tool.py +20 -0
  141. tooluniverse/test/test_fda_adv.py +95 -0
  142. tooluniverse/test/test_fda_drug_labeling.py +91 -0
  143. tooluniverse/test/test_gene_ontology_tools.py +66 -0
  144. tooluniverse/test/test_gwas_tool.py +139 -0
  145. tooluniverse/test/test_hpa.py +625 -0
  146. tooluniverse/test/test_humanbase_tool.py +20 -0
  147. tooluniverse/test/test_idmap_tools.py +61 -0
  148. tooluniverse/test/test_mcp_server.py +211 -0
  149. tooluniverse/test/test_mcp_tool.py +247 -0
  150. tooluniverse/test/test_medlineplus.py +220 -0
  151. tooluniverse/test/test_openalex_tool.py +32 -0
  152. tooluniverse/test/test_opentargets.py +28 -0
  153. tooluniverse/test/test_pubchem_tool.py +116 -0
  154. tooluniverse/test/test_pubtator_tool.py +37 -0
  155. tooluniverse/test/test_rcsb_pdb_tool.py +86 -0
  156. tooluniverse/test/test_reactome.py +54 -0
  157. tooluniverse/test/test_semantic_scholar_tool.py +24 -0
  158. tooluniverse/test/test_software_tools.py +147 -0
  159. tooluniverse/test/test_tool_description_optimizer.py +49 -0
  160. tooluniverse/test/test_tool_finder.py +26 -0
  161. tooluniverse/test/test_tool_finder_llm.py +252 -0
  162. tooluniverse/test/test_tools_find.py +195 -0
  163. tooluniverse/test/test_uniprot_tools.py +74 -0
  164. tooluniverse/test/test_uspto_tool.py +72 -0
  165. tooluniverse/test/test_xml_tool.py +113 -0
  166. tooluniverse/tool_finder_embedding.py +267 -0
  167. tooluniverse/tool_finder_keyword.py +693 -0
  168. tooluniverse/tool_finder_llm.py +699 -0
  169. tooluniverse/tool_graph_web_ui.py +955 -0
  170. tooluniverse/tool_registry.py +416 -0
  171. tooluniverse/uniprot_tool.py +155 -0
  172. tooluniverse/url_tool.py +253 -0
  173. tooluniverse/uspto_tool.py +240 -0
  174. tooluniverse/utils.py +369 -41
  175. tooluniverse/xml_tool.py +369 -0
  176. tooluniverse-1.0.1.dist-info/METADATA +387 -0
  177. tooluniverse-1.0.1.dist-info/RECORD +182 -0
  178. tooluniverse-1.0.1.dist-info/entry_points.txt +9 -0
  179. tooluniverse/generate_mcp_tools.py +0 -113
  180. tooluniverse/mcp_server.py +0 -3340
  181. tooluniverse-0.2.0.dist-info/METADATA +0 -139
  182. tooluniverse-0.2.0.dist-info/RECORD +0 -21
  183. tooluniverse-0.2.0.dist-info/entry_points.txt +0 -4
  184. {tooluniverse-0.2.0.dist-info → tooluniverse-1.0.1.dist-info}/WHEEL +0 -0
  185. {tooluniverse-0.2.0.dist-info → tooluniverse-1.0.1.dist-info}/licenses/LICENSE +0 -0
  186. {tooluniverse-0.2.0.dist-info → tooluniverse-1.0.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,120 @@
1
+ import requests
2
+ import fitz
3
+ import easyocr
4
+ from io import BytesIO
5
+ from docx import Document
6
+ from PIL import Image
7
+ from .uspto_tool import USPTOOpenDataPortalTool
8
+ from .tool_registry import register_tool
9
+
10
+
11
+ @register_tool("USPTOPatentDocumentDownloader")
12
+ class USPTOPatentDocumentDownloader(USPTOOpenDataPortalTool):
13
+ """
14
+ Fetch and download the abstract (ABST), claims (CLM), and full application text (APP.TEXT)
15
+ PDFs for a given patent application number, following the one-time redirect flow.
16
+ """
17
+
18
+ def __init__(self, tool_config):
19
+ super().__init__(tool_config=tool_config)
20
+
21
+ def run(self, arguments):
22
+ def ocr_pdf_bytes(pdf_bytes, dpi=300):
23
+ print("Running OCR on PDF bytes...")
24
+ doc = fitz.open(stream=pdf_bytes, filetype="pdf")
25
+ pages_text = []
26
+
27
+ # Initialize EasyOCR reader once
28
+ reader = easyocr.Reader(["en"], gpu=True)
29
+
30
+ for page in doc:
31
+ # render the page to a PIL image at high resolution
32
+ pix = page.get_pixmap(dpi=dpi)
33
+ img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
34
+ img_bytes = BytesIO()
35
+ img.save(img_bytes, format="PNG")
36
+ img_bytes.seek(0)
37
+ results = reader.readtext(img_bytes.getvalue(), detail=0)
38
+ text = "\n".join(results)
39
+ pages_text.append(text.strip())
40
+
41
+ doc.close()
42
+ return "\n\n".join(pages_text)
43
+
44
+ metadata = super().run(arguments)
45
+ if isinstance(metadata, dict) and metadata.get("error"):
46
+ return metadata
47
+
48
+ desired = self.tool_config.get("document")
49
+
50
+ docs = metadata.get("documentBag", [])
51
+ if not docs:
52
+ return {"error": "No documents found."}
53
+
54
+ result = None
55
+ all_doc_codes = set()
56
+ for doc in docs:
57
+ code = doc.get("documentCode")
58
+ all_doc_codes.add(code)
59
+ if code != desired:
60
+ continue
61
+
62
+ plain_text = ""
63
+ pdf_opt = None
64
+ word_opt = None
65
+ for opt in doc.get("downloadOptionBag", []):
66
+ m = opt.get("mimeTypeIdentifier", "").upper()
67
+ if m == "PDF" and not pdf_opt:
68
+ pdf_opt = opt
69
+ elif m == "MS_WORD" and not word_opt:
70
+ word_opt = opt
71
+
72
+ if word_opt:
73
+ url = word_opt["downloadUrl"]
74
+ resp = requests.get(url, headers=self.headers, timeout=30)
75
+ resp.raise_for_status()
76
+ buf = BytesIO(resp.content)
77
+ docx = Document(buf)
78
+ plain_text = "\n\n".join(
79
+ p.text for p in docx.paragraphs if p.text.strip()
80
+ )
81
+
82
+ if not plain_text and pdf_opt:
83
+ url = pdf_opt["downloadUrl"]
84
+ resp = requests.get(url, headers=self.headers, timeout=30)
85
+ resp.raise_for_status()
86
+ pdf_bytes = resp.content
87
+ pdf_doc = fitz.open(stream=pdf_bytes, filetype="pdf")
88
+ for page in pdf_doc:
89
+ plain_text += page.get_text().strip()
90
+ pdf_doc.close()
91
+
92
+ if plain_text == "":
93
+ # If no text was extracted, try to extract text from images
94
+ plain_text = ocr_pdf_bytes(pdf_bytes)
95
+
96
+ if plain_text:
97
+ # if plain text is longer than current result, it is probably a better text extraction
98
+ if result is None or len(plain_text) > len(result):
99
+ result = plain_text
100
+
101
+ if result is None:
102
+ return {
103
+ "error": f"Could not parse document with code {desired}. The documents available for this patent are: {', '.join(all_doc_codes)}."
104
+ }
105
+ else:
106
+ # Return the plain text extracted from the PDF
107
+ return {"result": result}
108
+
109
+
110
+ # if __name__ == "__main__":
111
+ # # Example usage
112
+ # tool_config = {
113
+ # "name": "uspto_patent_document_downloader",
114
+ # "description": "Download patent documents and extract text.",
115
+ # "document": "ABST", # Specify the document type to download
116
+ # }
117
+ # downloader = USPTOPatentDocumentDownloader(tool_config)
118
+ # arguments = {"applicationNumberText": "19053071"} # Example application number
119
+ # result = downloader.run(arguments)
120
+ # print(result)
@@ -0,0 +1,99 @@
1
+ """
2
+ Remote Tool Implementation
3
+
4
+ This module provides a RemoteTool class that represents external MCP/SMCP tools
5
+ that are available for listing but cannot be executed locally. These tools are
6
+ stored as configuration records only.
7
+ """
8
+
9
+ from .base_tool import BaseTool
10
+ from .tool_registry import register_tool
11
+
12
+
13
+ @register_tool("RemoteTool")
14
+ class RemoteTool(BaseTool):
15
+ """
16
+ A placeholder tool class for external MCP/SMCP tools.
17
+
18
+ RemoteTool represents tools that are hosted on external MCP/SMCP servers
19
+ and are only available for discovery and listing purposes. These tools
20
+ cannot be executed locally through ToolUniverse but their configurations
21
+ are preserved for reference.
22
+
23
+ Attributes:
24
+ tool_config (dict): The tool configuration dictionary
25
+ remote_info (dict): Information about the remote server and tool
26
+ """
27
+
28
+ def __init__(self, tool_config=None):
29
+ """
30
+ Initialize the RemoteTool.
31
+
32
+ Args:
33
+ tool_config (dict, optional): Tool configuration dictionary
34
+ """
35
+ super().__init__(tool_config)
36
+ self.remote_info = tool_config.get("remote_info", {}) if tool_config else {}
37
+
38
+ def run(self, arguments=None):
39
+ """
40
+ Placeholder run method for remote tools.
41
+
42
+ Remote tools cannot be executed locally. This method always returns
43
+ an error message indicating that the tool is not available for local execution.
44
+
45
+ Args:
46
+ arguments (dict, optional): Tool arguments (ignored)
47
+
48
+ Returns:
49
+ dict: Error message indicating the tool is not available locally
50
+ """
51
+ server_type = self.remote_info.get("server_type", "Unknown")
52
+ original_type = self.remote_info.get("original_type", "Unknown")
53
+
54
+ return {
55
+ "error": "Remote tool not available for local execution",
56
+ "tool_name": (
57
+ self.tool_config.get("name", "Unknown")
58
+ if self.tool_config
59
+ else "Unknown"
60
+ ),
61
+ "tool_type": "RemoteTool",
62
+ "original_type": original_type,
63
+ "server_type": server_type,
64
+ "message": "This tool is hosted on an external MCP/SMCP server and cannot be executed locally. Please use the external server directly.",
65
+ "remote_info": self.remote_info,
66
+ }
67
+
68
+ def get_remote_info(self):
69
+ """
70
+ Get information about the remote server hosting this tool.
71
+
72
+ Returns:
73
+ dict: Remote server information including server type, URL, and original tool type
74
+ """
75
+ return self.remote_info.copy()
76
+
77
+ def is_available_locally(self):
78
+ """
79
+ Check if this tool is available for local execution.
80
+
81
+ Returns:
82
+ bool: Always False for RemoteTool instances
83
+ """
84
+ return False
85
+
86
+ def get_server_info(self):
87
+ """
88
+ Get server connection information for this remote tool.
89
+
90
+ Returns:
91
+ dict: Server connection details
92
+ """
93
+ return {
94
+ "server_type": self.remote_info.get("server_type"),
95
+ "server_url": self.remote_info.get("server_url"),
96
+ "transport": self.remote_info.get("transport"),
97
+ "mcp_tool_name": self.remote_info.get("mcp_tool_name"),
98
+ "source_directory": self.remote_info.get("source_directory"),
99
+ }
@@ -1,21 +1,21 @@
1
1
  from .graphql_tool import GraphQLTool
2
2
  import requests
3
3
  import copy
4
- import json
4
+ from .tool_registry import register_tool
5
+
5
6
 
6
7
  def execute_RESTful_query(endpoint_url, variables=None):
7
- response = requests.get(
8
- endpoint_url, params = variables)
8
+ response = requests.get(endpoint_url, params=variables)
9
9
  try:
10
10
  result = response.json()
11
11
 
12
12
  # Check if the response contains errors
13
- if 'error' in result:
14
- print("Invalid Query: ", result['error'])
13
+ if "error" in result:
14
+ print("Invalid Query: ", result["error"])
15
15
  return False
16
16
  else:
17
17
  return result
18
- except requests.exceptions.JSONDecodeError as e:
18
+ except requests.exceptions.JSONDecodeError:
19
19
  print("JSONDecodeError: Could not decode the response as JSON")
20
20
  return False
21
21
  except requests.exceptions.HTTPError as e:
@@ -23,19 +23,27 @@ def execute_RESTful_query(endpoint_url, variables=None):
23
23
  except Exception as e:
24
24
  print(f"An error occurred: {e}")
25
25
 
26
+
27
+ @register_tool("RESTfulTool")
26
28
  class RESTfulTool(GraphQLTool):
27
29
  def __init__(self, tool_config, endpoint_url):
28
30
  super().__init__(tool_config, endpoint_url)
29
31
 
30
32
  def run(self, arguments):
31
33
  arguments = copy.deepcopy(arguments)
32
- return execute_RESTful_query(endpoint_url=self.endpoint_url, variables=arguments)
34
+ return execute_RESTful_query(
35
+ endpoint_url=self.endpoint_url, variables=arguments
36
+ )
37
+
33
38
 
39
+ @register_tool("Monarch")
34
40
  class MonarchTool(RESTfulTool):
35
41
  def __init__(self, tool_config):
36
- endpoint_url = 'https://api.monarchinitiative.org/v3/api' + tool_config['tool_url']
42
+ endpoint_url = (
43
+ "https://api.monarchinitiative.org/v3/api" + tool_config["tool_url"]
44
+ )
37
45
  super().__init__(tool_config, endpoint_url)
38
-
46
+
39
47
  def run(self, arguments):
40
48
  arguments = copy.deepcopy(arguments)
41
49
  query_schema_runtime = copy.deepcopy(self.query_schema)
@@ -43,53 +51,68 @@ class MonarchTool(RESTfulTool):
43
51
  if key in arguments:
44
52
  query_schema_runtime[key] = arguments[key]
45
53
  if "url_key" in query_schema_runtime:
46
- url_key_name = query_schema_runtime['url_key']
47
- formatted_endpoint_url = self.endpoint_url.format(url_key = query_schema_runtime[url_key_name])
48
- del query_schema_runtime['url_key']
54
+ url_key_name = query_schema_runtime["url_key"]
55
+ formatted_endpoint_url = self.endpoint_url.format(
56
+ url_key=query_schema_runtime[url_key_name]
57
+ )
58
+ del query_schema_runtime["url_key"]
49
59
  else:
50
60
  formatted_endpoint_url = self.endpoint_url
51
61
  if isinstance(query_schema_runtime, dict):
52
62
  print(query_schema_runtime)
53
- if 'query' in query_schema_runtime:
54
- query_schema_runtime['q'] = query_schema_runtime['query'] # match with the api
55
- response = execute_RESTful_query(endpoint_url=formatted_endpoint_url, variables=query_schema_runtime)
56
- if 'facet_fields' in response:
57
- del response['facet_fields']
63
+ if "query" in query_schema_runtime:
64
+ query_schema_runtime["q"] = query_schema_runtime[
65
+ "query"
66
+ ] # match with the api
67
+ response = execute_RESTful_query(
68
+ endpoint_url=formatted_endpoint_url, variables=query_schema_runtime
69
+ )
70
+ if "facet_fields" in response:
71
+ del response["facet_fields"]
72
+
58
73
  def remove_empty_values(obj):
59
74
  if isinstance(obj, dict):
60
- return {k: remove_empty_values(v) for k, v in obj.items()
61
- if v not in [0, [], None]}
75
+ return {
76
+ k: remove_empty_values(v)
77
+ for k, v in obj.items()
78
+ if v not in [0, [], None]
79
+ }
62
80
  elif isinstance(obj, list):
63
81
  return [remove_empty_values(v) for v in obj if v not in [0, [], None]]
64
82
  else:
65
83
  return obj
84
+
66
85
  response = remove_empty_values(response)
67
86
  return response
68
87
 
88
+
89
+ @register_tool("MonarchDiseasesForMultiplePheno")
69
90
  class MonarchDiseasesForMultiplePhenoTool(MonarchTool):
70
91
  def __init__(self, tool_config):
71
92
  super().__init__(tool_config)
72
-
93
+
73
94
  def run(self, arguments):
74
95
  arguments = copy.deepcopy(arguments)
75
96
  query_schema_runtime = copy.deepcopy(self.query_schema)
76
97
  for key in query_schema_runtime:
77
- if (key!="HPO_ID_list") and (key in arguments):
98
+ if (key != "HPO_ID_list") and (key in arguments):
78
99
  query_schema_runtime[key] = arguments[key]
79
100
  all_diseases = []
80
- for HPOID in arguments['HPO_ID_list']:
101
+ for HPOID in arguments["HPO_ID_list"]:
81
102
  each_query_schema_runtime = copy.deepcopy(query_schema_runtime)
82
- each_query_schema_runtime['object'] = HPOID
83
- each_query_schema_runtime['limit'] = 500
84
- each_output = execute_RESTful_query(endpoint_url=self.endpoint_url, variables=each_query_schema_runtime)
85
- each_output = each_output['items']
86
- each_output_names = [disease['subject_label'] for disease in each_output]
103
+ each_query_schema_runtime["object"] = HPOID
104
+ each_query_schema_runtime["limit"] = 500
105
+ each_output = execute_RESTful_query(
106
+ endpoint_url=self.endpoint_url, variables=each_query_schema_runtime
107
+ )
108
+ each_output = each_output["items"]
109
+ each_output_names = [disease["subject_label"] for disease in each_output]
87
110
  all_diseases.append(each_output_names)
88
-
111
+
89
112
  intersection = set(all_diseases[0])
90
113
  for element in all_diseases[1:]:
91
114
  intersection &= set(element)
92
115
  intersection = list(intersection)
93
- if query_schema_runtime['limit'] < len(intersection):
94
- intersection = intersection[:query_schema_runtime['limit']]
116
+ if query_schema_runtime["limit"] < len(intersection):
117
+ intersection = intersection[: query_schema_runtime["limit"]]
95
118
  return intersection