def build_output(self, task): if self.output_factory is not None: try: return self.output_factory(task, self) except Exception: logger.exception( "Failed to created task output %s for %s : " " output_factory expected signature is '(Task, Parameter) -> Target(any structure) '", self, task, ) raise if ( not self.system and self.name not in ("task_band",) and task.task_in_memory_outputs ): return InMemoryTarget( path="memory://{value_type}:{task}.{p_name}".format( value_type=self.value_type, task=task.task_id, p_name=self.name ) ) # we separate into two functions , # as we want to be able to call build_target from output_factory implementation try: return self.build_target(task) except Exception as e: raise friendly_error.task_build.failed_to_build_output_target( self.name, task, e )
def parse_value(self, value, load_value=None, target_config=None): """ Parse an individual value from the input. probably this is the most important code in user value parsing :param str value: the value to parse. :return: the parsed value. """ from dbnd._core.utils.task_utils import to_targets from targets.inmemory_target import InMemoryTarget from targets.values.target_values import _TargetValueType if load_value is None: load_value = self.load_on_build value = self._interpolate_from_str(value) if value is None: return value if isinstance(value, six.string_types): # we are in the string mode # it's can be "serialized to string" or path value if load_value: # we can just load value from string if self.support_from_str: value = self.parse_from_str(value) value = self.normalize(value) return value # otherwise - the value is a path! target_kwargs = {} if target_config: target_kwargs["config"] = target_config return to_targets(json_utils.loads(value), from_string_kwargs=target_kwargs) from dbnd._core.task import Task from targets import Target if isinstance(value, Task): return to_targets(value) if isinstance(value, Target): return value # so we have a value that is obviously "Data" type, # we want to be able to supporet "load_value" behaviour if not load_value and not isinstance(self, _TargetValueType): return InMemoryTarget(value, value_type=self) value = self.normalize(value) return value
def parse_value(self, value, load_value=None, target_config=None): """ Parse an individual value from the input. probably this is the most important code in user value parsing :param str value: the value to parse. :return: the parsed value. """ from dbnd._core.utils.task_utils import to_targets from targets.inmemory_target import InMemoryTarget from targets.values.target_values import _TargetValueType from targets import Target if load_value is None: load_value = self.load_on_build value = self._interpolate_from_str(value) if value is None: return value if isinstance(value, six.string_types): # we are in the string mode # it's can be "serialized to string" or path value if load_value: # in case we have simple type -> just load/parse it if self.support_from_str: value = self.parse_from_str(value) value = self.normalize(value) return value # otherwise - the data is "Complex object" # our assumption is that it can not be loaded from string # the value is a path! target_kwargs = {} if target_config: target_kwargs["config"] = target_config # Check for glob path if _is_glob_path(value): from targets import target return target(value, config=target_config) """ it's possible that we have a list of targets, or just a single target (all targets should be loaded as single object). we need to support: 1. /some/path 2. /some/path,.... 3. ["/some_path",..] we will try to parse it as list, if we get list with one element (1) -> we can return it, otherwise we wrap it with MultiTarget """ from targets.values.structure import ListValueType # Parse into value type list list_of_targets = ListValueType().parse_from_str(value) # Apply all values from config list_of_targets = to_targets(list_of_targets, from_string_kwargs=target_kwargs) if len(list_of_targets) == 1: return list_of_targets[0] else: from targets.multi_target import MultiTarget return MultiTarget(list_of_targets) from dbnd._core.task import Task if isinstance(value, Task): return to_targets(value) if isinstance(value, Target): return value # so we have a value that is obviously "Data" type, # we want to be able to support "load_value" behaviour if not load_value and not isinstance(self, _TargetValueType): return InMemoryTarget(value, value_type=self) value = self.normalize(value) return value