def get_backward_pipes( self, pipe_or_node: Union[ZeroNode, ZeroPipe]) -> Iterator[ZeroPipe]: """ Get all pipes that go after the `pipe_or_node` instance. Example: <in> --p1--> N1 --p2--> N2 --p4--> <out> If N1 or p2 - target instance (`pipe_or_node`) then p1 - backward pipe :param pipe_or_node: specify target pipe or node :type pipe_or_node: Union[ZeroNode, ZeroPipe] :return: all pipes before the `pipe_or_node` :rtype: Iterator[ZeroPipe] """ reversed_pipes_map = self.get_pipes_map(reverse=True) if isinstance(pipe_or_node, ZeroPipe): node = pipe_or_node.node_a elif isinstance(pipe_or_node, ZeroNode): node = pipe_or_node else: raise ValueError("Bad 'pipe_or_node' argument type") if isinstance(node, str): return [] return flat_iter( list(p_dict.values()) for p_dict in reversed_pipes_map.get(node.id, {}).values() if p_dict)
def save(self: RegObjZT, save_dependency: bool = True, save_dependency_depth: int = 6, save_dependency_search_depth: int = 0, **kwargs) -> RegObjZT: """ Save current state to the repository. :param save_dependency: save related entities :type save_dependency: bool :param save_dependency_depth: depth of related entities recursion (-1 = infinity) :type save_dependency_depth: int :param save_dependency_search_depth: depth of searching in the fields values (like dict). :type save_dependency_depth: int """ normalized_attrs = self.prepare(self._attrs) setattr(self, "_attrs", normalized_attrs) def _converter(x): if isinstance(x, dict): return x.items() return x if save_dependency and save_dependency_depth != 0: for attr_name in self._attrs.keys(): attr_items = [getattr(self, attr_name, None)] items = filter( lambda x: isinstance(x, ZeroRegistrableObject), flat_iter( attr_items, depth=save_dependency_search_depth, converter=_converter, ), ) for item in items: item.save(save_dependency=save_dependency, save_dependency_depth=save_dependency_depth - 1, save_dependency_search_depth= save_dependency_search_depth, **kwargs) self.REPOSITORY.save(self.path, self, **kwargs) return self
def output_pipes(self) -> Iterator[ZeroPipe]: """ It returns `input pipes` Example: <in> --pipe1--> N --pipe2--> N **--pipe3-->** <out> **<--pipe4--** N **pipe3** and **pipe4** - output pipes :return: list of the output pipes :rtype: Iterable[ZeroPipe] """ reversed_pipes_map = self.get_pipes_map(reverse=True) return iter( flat_iter( list(p_dict.values()) for p_dict in reversed_pipes_map.get( ZeroNode.OUT, {}).values() if p_dict))
def input_pipes(self) -> Iterator[ZeroPipe]: """ It returns `input pipes` Example: <in> **--pipe1-->** N --pipe2--> N --pipe3--> <out> **pipe1** - input pipe :return: list of the input pipes :rtype: Iterable[ZeroPipe] """ pipes_map = self.get_pipes_map() return iter( flat_iter([ list(p_dict.values()) for p_dict in pipes_map.get(ZeroNode.IN, {}).values() if p_dict ]))
def _get_next(cls, node_id: str, session: "ZeroSession"): network = session.network if network.version not in _node_pipes: pipes_nodes = network.get_pipes_map()[node_id] _node_pipes[network.version] = list( flat_iter([ b_node_pipes.values() for b_node_pipes in pipes_nodes.values() ])) if session.version not in _cursors: _cursors[session.version] = 0 next_pipe_index = _cursors[session.version] next_pipe = _node_pipes[network.version][next_pipe_index] _cursors[session.version] = (_cursors[session.version] + 1) % len( _node_pipes[network.version]) return next_pipe
def add_pipes(self, *pipes: Union[Iterable[Union[ZeroPipe, str]], Union[ZeroPipe, str]]): """ It adds pipes to the ZeroNetwork instance :param pipes: list of args of the pipes (str or ZeroPipe instances) :type pipes: Iterable[Union[ZeroPipe, str] """ assert pipes, "`pipes` can't be empty" for pipe in flat_iter(pipes, depth=1): if isinstance(pipe, str): pipe = ZeroPipe.load(pipe) elif not isinstance(pipe, ZeroPipe): raise ValueError("'{}' is not PipeBase instance") if pipe.id in self.pipes_list: self.pipes_list.remove(pipe.id) self.pipes_list.append(pipe.id)