Source code for aws_resource_search.searcher_finder

# -*- coding: utf-8 -*-

"""
All AWS resource searchers are defined as variables in the
``aws_resource_search.res.${service}.py`` module. We don't want to import them
manually in the code; instead, we need a lazy-loading mechanism to import them
programmatically based on the resource type.
"""

import typing as T
import json
import importlib
import dataclasses

from .paths import path_searchers_json
from .searcher_metadata import SearcherMetadata

if T.TYPE_CHECKING:  # pragma: no cover
    from .base_searcher import T_SEARCHER


[docs]@dataclasses.dataclass class SearcherFinder: """ This is a helper class to access the implemented searcher metadata, and also import the per-aws-resource-type searcher object. """ sm_meta_mapper: T.Dict[str, SearcherMetadata] = dataclasses.field(init=False) searcher_cache: T.Dict[str, "T_SEARCHER"] = dataclasses.field(default_factory=dict)
[docs] def reload(self): """ Reload the lookup data from ``aws_resource_search/searchers.json``. """ data = json.loads(path_searchers_json.read_text()) self.sm_meta_mapper = { id: SearcherMetadata( id=id, desc=dct["desc"], ngram=dct["ngram"], module=dct["module"], var=dct["var"], ) for id, dct in data.items() }
def __post_init__(self): self.reload()
[docs] def all_resource_types(self) -> T.List[str]: """ Return all resource types. """ return list(self.sm_meta_mapper.keys())
[docs] def is_valid_resource_type(self, resource_type: str) -> bool: """ Check if the resource type is supported. """ return resource_type in self.sm_meta_mapper
[docs] def import_searcher(self, resource_type: str) -> "T_SEARCHER": """ Import the searcher object by resource type, it uses cache to avoid loading the same module multiple times. """ if self.is_valid_resource_type(resource_type): if resource_type not in self.searcher_cache: mod = searcher_finder.sm_meta_mapper[resource_type].module var = searcher_finder.sm_meta_mapper[resource_type].var module = importlib.import_module(f"aws_resource_search.res.{mod}") self.searcher_cache[resource_type] = getattr(module, var) return self.searcher_cache[resource_type] else: raise ValueError(f"Invalid resource type: {resource_type}")
searcher_finder = SearcherFinder() # singleton object