import logging from typing import Dict from service.async_task_manager import io_task from service.tasks.analytics.modules import get_am logger = logging.getLogger(__name__) class Chart: def __init__(self, chart_conf): self.conf = chart_conf self._data_retrieval_task = None self.am = None def prepare_data(self, recalculate=False, use_cache=True): """Fires off data retrieval in another thread""" if self._data_retrieval_task is None: self._data_retrieval_task = self._get_analytics_data( recalculate=recalculate, use_cache=use_cache ) return self @io_task def _get_analytics_data(self, recalculate=False, use_cache=True, **kwargs): self.am = get_am(self.conf) return self.am.get_result(recalculate=recalculate, use_cache=use_cache) def json_for_appsync(self) -> Dict[str, str]: self.prepare_data() try: return self.fill_json_template() except Exception as e: logger.exception(e) raise RuntimeError( f"Analytics data retrieval failed for {self.conf['type']} '{self.conf['label']}': " f"{', '.join(str(a) for a in e.args)}" ) def fill_json_template(self): """Filling json template with info from self.conf and data from retrieval_task""" return { "id": self.conf["id"], "type": self.conf["type"], "label": self.conf["label"], "description": self.conf.get("description"), "options": self.conf.get("options", {}), "data": self.map_module_result(), } def map_module_result(self, **kwargs): """Format the query result and make the proper labels for records""" am_data = self._data_retrieval_task.wait_for_result() am_map = self.am.get_output_map() data_map = { d: am_map[s].idx for d, s in self.conf["output_maps"]["data"].items() } return [ {dest: data[source] for dest, source in data_map.items()} for data in am_data ] def recalculate(self): return self.prepare_data(recalculate=True) def wait_for_done(self): if self._data_retrieval_task: try: self._data_retrieval_task.wait_for_result() return True except Exception as e: logger.exception(e) return False @classmethod def get_series(cls, chart_conf, available_fields_list, schema, kwargs): return [chart_conf]