From 7385b4e9927534dd92dcef26aeaff124a7a7911f Mon Sep 17 00:00:00 2001 From: Martin Lange <martin.lange@ufz.de> Date: Sat, 29 Oct 2022 18:29:36 +0200 Subject: [PATCH] implement the info transfer --- src/finam/tools/connect_helper.py | 46 +++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/src/finam/tools/connect_helper.py b/src/finam/tools/connect_helper.py index efbb9d85..68e738ed 100644 --- a/src/finam/tools/connect_helper.py +++ b/src/finam/tools/connect_helper.py @@ -3,10 +3,15 @@ import logging from finam.interfaces import ComponentStatus, Loggable +from ..data.tools import Info from ..errors import FinamNoDataError from ..tools.log_helper import ErrorLogger +class MissingInfoError(Exception): + """Internal error type for handling missing infos for transfer rules""" + + class InfoSource: def __init__(self, name, *fields): self.name = name @@ -71,9 +76,6 @@ class ConnectHelper(Loggable): self._outputs = outputs self._cache = cache - self._in_info_rules = in_info_rules or {} - self._out_info_rules = in_info_rules or {} - with ErrorLogger(self.logger): for name in pull_data or []: if name not in self._inputs: @@ -93,12 +95,34 @@ class ConnectHelper(Loggable): name: False for name, out in self.outputs.items() if out.needs_push } + self._in_info_rules = in_info_rules or {} + self._out_info_rules = out_info_rules or {} self._check_info_rules() self._in_info_cache = {} self._out_info_cache = {} self._out_data_cache = {} + def _apply_rules(self, rules): + info = Info(time=None, grid=None) + for rule in rules: + if isinstance(rule, FromInput): + in_info = self.in_infos[rule.name] + if in_info is None: + raise MissingInfoError() + for field in rule.fields: + info.__setattr__(field, in_info.__getattr__(field)) + elif isinstance(rule, FromOutput): + out_info = self.out_infos[rule.name] + if out_info is None: + raise MissingInfoError() + for field in rule.fields: + info.__setattr__(field, out_info.__getattr__(field)) + elif isinstance(rule, FromValue): + info.__setattr__(field, rule.value) + + return info + def _check_info_rules(self): for name, rules in self._in_info_rules.items(): if name not in self._inputs: @@ -216,6 +240,22 @@ class ConnectHelper(Loggable): push_infos = {k: v for k, v in push_infos.items() if self.out_infos[k] is None} push_data = {k: v for k, v in push_data.items() if not self.data_pushed[k]} + for name, rules in self._in_info_rules.items(): + if self.in_infos[name] is None and name not in self._in_info_cache: + try: + info = self._apply_rules(rules) + exchange_infos[name] = info + except MissingInfoError: + pass + + for name, rules in self._out_info_rules.items(): + if self.out_infos[name] is None and name not in self._out_info_cache: + try: + info = self._apply_rules(rules) + push_infos[name] = info + except MissingInfoError: + pass + if self._cache: self._in_info_cache.update(exchange_infos) self._out_info_cache.update(push_infos) -- GitLab