From c429262c2fc89e8babeb2968949f0c4d72e9a686 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Mon, 11 Dec 2023 20:44:51 +0100 Subject: [PATCH] Move edam data out of registry and into (web) app It's only used in API responses and the tool panels. We surely don't want to load edam data when loading the registry while setting metadata. --- lib/galaxy/app.py | 17 +++++++++++++++++ lib/galaxy/datatypes/registry.py | 12 ------------ lib/galaxy/managers/datatypes.py | 13 +++++++------ lib/galaxy/tool_util/edam_util.py | 4 +++- lib/galaxy/tool_util/toolbox/base.py | 7 +++++-- lib/galaxy/webapps/galaxy/api/datatypes.py | 10 ++++++---- 6 files changed, 38 insertions(+), 25 deletions(-) diff --git a/lib/galaxy/app.py b/lib/galaxy/app.py index 2753b87a076e..fdc8198d9e30 100644 --- a/lib/galaxy/app.py +++ b/lib/galaxy/app.py @@ -121,6 +121,10 @@ from galaxy.tool_util.deps import containers from galaxy.tool_util.deps.dependencies import AppInfo from galaxy.tool_util.deps.views import DependencyResolversView +from galaxy.tool_util.edam_util import ( + EdamDictType, + load_edam_tree, +) from galaxy.tool_util.verify.test_data import TestDataResolver from galaxy.tools.biotools import get_galaxy_biotools_metadata_source from galaxy.tools.cache import ToolCache @@ -688,6 +692,19 @@ def __init__(self, **kwargs) -> None: self.tool_shed_repository_cache = self._register_singleton(ToolShedRepositoryCache) # Watch various config files for immediate reload self.watchers = self._register_singleton(ConfigWatchers) + if self.is_webapp: + # Load edam data + edam_ontology_path = self.config.edam_toolbox_ontology_path + self.edam = self._register_singleton( + EdamDictType, + load_edam_tree( + None if not edam_ontology_path or not os.path.exists(edam_ontology_path) else edam_ontology_path, + "format_", + "data_", + "operation_", + "topic_", + ), + ) self._configure_toolbox() # Load Data Manager self.data_managers = self._register_singleton(DataManagers) # type: ignore[type-abstract] diff --git a/lib/galaxy/datatypes/registry.py b/lib/galaxy/datatypes/registry.py index 67135cf0ebae..03bbf579f211 100644 --- a/lib/galaxy/datatypes/registry.py +++ b/lib/galaxy/datatypes/registry.py @@ -46,21 +46,9 @@ class ConfigurationError(Exception): class Registry: def __init__(self, config=None): - edam_ontology_path = config.get("edam_toolbox_ontology_path", None) if config is not None else None - edam = {} - if edam_ontology_path: - edam = load_edam_tree( - None if not edam_ontology_path or not os.path.exists(edam_ontology_path) else edam_ontology_path, - "format_", - "data_", - "operation_", - "topic_", - ) - self.log = logging.getLogger(__name__) self.log.addHandler(logging.NullHandler()) self.config = config - self.edam = edam self.datatypes_by_extension = {} self.datatypes_by_suffix_inferences = {} self.mimetypes_by_extension = {} diff --git a/lib/galaxy/managers/datatypes.py b/lib/galaxy/managers/datatypes.py index 72dbbdb8f5a5..c1727afc00a6 100644 --- a/lib/galaxy/managers/datatypes.py +++ b/lib/galaxy/managers/datatypes.py @@ -16,6 +16,7 @@ ) from galaxy.datatypes.data import Data from galaxy.datatypes.registry import Registry +from galaxy.tool_util.edam_util import EdamDictType def view_index( @@ -90,10 +91,10 @@ def view_converters(datatypes_registry: Registry) -> DatatypeConverterList: return parse_obj_as(DatatypeConverterList, converters) -def _get_edam_details(datatypes_registry: Registry, edam_ids: Dict[str, str]) -> Dict[str, Dict]: +def _get_edam_details(edam: EdamDictType, edam_ids: Dict[str, str]) -> Dict[str, Dict]: details_dict = {} for format, edam_iri in edam_ids.items(): - edam_details = datatypes_registry.edam.get(edam_iri, {}) + edam_details = edam.get(edam_iri, {}) details_dict[format] = { "prefix_IRI": edam_iri, @@ -105,19 +106,19 @@ def _get_edam_details(datatypes_registry: Registry, edam_ids: Dict[str, str]) -> def view_edam_formats( - datatypes_registry: Registry, detailed: Optional[bool] = False + edam: EdamDictType, datatypes_registry: Registry, detailed: Optional[bool] = False ) -> Union[Dict[str, str], Dict[str, Dict[str, str]]]: if detailed: - return _get_edam_details(datatypes_registry, datatypes_registry.edam_formats) + return _get_edam_details(edam, datatypes_registry.edam_formats) else: return datatypes_registry.edam_formats def view_edam_data( - datatypes_registry: Registry, detailed: Optional[bool] = False + edam: EdamDictType, datatypes_registry: Registry, detailed: Optional[bool] = False ) -> Union[Dict[str, str], Dict[str, Dict[str, str]]]: if detailed: - return _get_edam_details(datatypes_registry, datatypes_registry.edam_data) + return _get_edam_details(edam, datatypes_registry.edam_data) else: return datatypes_registry.edam_data diff --git a/lib/galaxy/tool_util/edam_util.py b/lib/galaxy/tool_util/edam_util.py index 514a551a5c7a..89279c8b210c 100644 --- a/lib/galaxy/tool_util/edam_util.py +++ b/lib/galaxy/tool_util/edam_util.py @@ -15,8 +15,10 @@ ROOT_OPERATION = "operation_0004" ROOT_TOPIC = "topic_0003" +EdamDictType = Dict[str, Dict[str, str]] -def load_edam_tree(path: Optional[str] = None, *included_terms: str): + +def load_edam_tree(path: Optional[str] = None, *included_terms: str) -> EdamDictType: if path is not None: assert os.path.exists(path), f"Failed to load EDAM tabular data at [{path}] path does not exist." handle = open(path) diff --git a/lib/galaxy/tool_util/toolbox/base.py b/lib/galaxy/tool_util/toolbox/base.py index 264b96d26d60..e22967c3a345 100644 --- a/lib/galaxy/tool_util/toolbox/base.py +++ b/lib/galaxy/tool_util/toolbox/base.py @@ -189,6 +189,9 @@ def __init__( self._tool_tag_manager = self.tool_tag_manager() self._init_tools_from_configs(config_filenames) + if not self.app.is_webapp: + return + if self.app.name == "galaxy" and self._integrated_tool_panel_config_has_contents: self._load_tool_panel() @@ -223,7 +226,7 @@ def to_model(self) -> ToolPanelViewModel: for edam_view in listify(self.app.config.edam_panel_views): mode = EdamPanelMode[edam_view] - tool_panel_views_list.append(EdamToolPanelView(self.app.datatypes_registry.edam, mode=mode)) + tool_panel_views_list.append(EdamToolPanelView(self.app.edam, mode=mode)) if view_sources is not None: for definition in view_sources.get_definitions(): @@ -233,7 +236,7 @@ def to_model(self) -> ToolPanelViewModel: for tool_panel_view in tool_panel_views_list: self._tool_panel_views[tool_panel_view.to_model().id] = tool_panel_view - if self.app.name == "galaxy": + if self.app.name == "galaxy" and self.app.is_webapp: self._load_tool_panel_views() if save_integrated_tool_panel: self._save_integrated_tool_panel() diff --git a/lib/galaxy/webapps/galaxy/api/datatypes.py b/lib/galaxy/webapps/galaxy/api/datatypes.py index 7a35bc4b0a6a..43853e149fdd 100644 --- a/lib/galaxy/webapps/galaxy/api/datatypes.py +++ b/lib/galaxy/webapps/galaxy/api/datatypes.py @@ -26,6 +26,7 @@ view_mapping, view_sniffers, ) +from galaxy.tool_util.edam_util import EdamDictType from . import ( depends, Router, @@ -57,6 +58,7 @@ @router.cbv class FastAPIDatatypes: datatypes_registry: Registry = depends(Registry) + edam: EdamDictType = depends(EdamDictType) @router.get( "/api/datatypes", @@ -123,7 +125,7 @@ async def converters(self) -> DatatypeConverterList: ) async def edam_formats(self) -> Dict[str, str]: """Gets a map of datatypes and their corresponding EDAM formats.""" - return cast(Dict[str, str], view_edam_formats(self.datatypes_registry)) + return cast(Dict[str, str], view_edam_formats(self.edam, self.datatypes_registry)) @router.get( "/api/datatypes/edam_formats/detailed", @@ -134,7 +136,7 @@ async def edam_formats(self) -> Dict[str, str]: async def edam_formats_detailed(self): """Gets a map of datatypes and their corresponding EDAM formats. EDAM formats contain the EDAM iri, label, and definition.""" - return view_edam_formats(self.datatypes_registry, True) + return view_edam_formats(self.edam, self.datatypes_registry, True) @router.get( "/api/datatypes/edam_data", @@ -143,7 +145,7 @@ async def edam_formats_detailed(self): ) async def edam_data(self) -> Dict[str, str]: """Gets a map of datatypes and their corresponding EDAM data.""" - return cast(Dict[str, str], view_edam_data(self.datatypes_registry)) + return cast(Dict[str, str], view_edam_data(self.edam, self.datatypes_registry)) @router.get( "/api/datatypes/edam_data/detailed", @@ -154,4 +156,4 @@ async def edam_data(self) -> Dict[str, str]: async def edam_data_detailed(self): """Gets a map of datatypes and their corresponding EDAM data. EDAM data contains the EDAM iri, label, and definition.""" - return view_edam_data(self.datatypes_registry, True) + return view_edam_data(self.edam, self.datatypes_registry, True)