def find_lhs(self) -> str: if self._lhs is not None: return self._lhs if self._instantiated_in is None or self._instantiated_in == "": raise _system_exceptions.FlyteSystemException(f"Object {self} does not have an _instantiated in") logger.debug(f"Looking for LHS for {self} from {self._instantiated_in}") m = _importlib.import_module(self._instantiated_in) for k in dir(m): try: if getattr(m, k) is self: logger.debug(f"Found LHS for {self}, {k}") self._lhs = k return k except ValueError as err: # Empty pandas dataframes behave weirdly here such that calling `m.df` raises: # ValueError: The truth value of a {type(self).__name__} is ambiguous. Use a.empty, a.bool(), a.item(), # a.any() or a.all() # Since dataframes aren't registrable entities to begin with we swallow any errors they raise and # continue looping through m. logger.warning("Caught ValueError {} while attempting to auto-assign name".format(err)) pass logger.error(f"Could not find LHS for {self} in {self._instantiated_in}") raise _system_exceptions.FlyteSystemException(f"Error looking for LHS in {self._instantiated_in}")
def promote_from_model( cls, base_model: _workflow_model.WorkflowNode, sub_workflows: Dict[id_models.Identifier, _workflow_model.WorkflowTemplate], node_launch_plans: Dict[id_models.Identifier, _launch_plan_model.LaunchPlanSpec], tasks: Dict[id_models.Identifier, _task_model.TaskTemplate], ) -> "FlyteWorkflowNode": from flytekit.remote import launch_plan as _launch_plan from flytekit.remote import workflow as _workflow if base_model.launchplan_ref is not None: return cls(flyte_launch_plan=_launch_plan.FlyteLaunchPlan. promote_from_model( base_model.launchplan_ref, node_launch_plans[ base_model.launchplan_ref])) elif base_model.sub_workflow_ref is not None: # the workflow templates for sub-workflows should have been included in the original response if base_model.reference in sub_workflows: return cls( flyte_workflow=_workflow.FlyteWorkflow.promote_from_model( sub_workflows[base_model.reference], sub_workflows=sub_workflows, node_launch_plans=node_launch_plans, tasks=tasks, )) raise _system_exceptions.FlyteSystemException( f"Subworkflow {base_model.reference} not found.") raise _system_exceptions.FlyteSystemException( "Bad workflow node model, neither subworkflow nor launchplan specified." )
def test_flyte_system_exception(): try: raise system.FlyteSystemException("bad") except Exception as e: assert str(e) == "bad" assert isinstance(type(e), base._FlyteCodedExceptionMetaclass) assert type(e).error_code == "SYSTEM:Unknown" assert isinstance(e, base.FlyteException)
def __init__( self, flyte_workflow: "flytekit.remote.workflow.FlyteWorkflow" = None, flyte_launch_plan: "flytekit.remote.launch_plan.FlyteLaunchPlan" = None, ): if flyte_workflow and flyte_launch_plan: raise _system_exceptions.FlyteSystemException( "FlyteWorkflowNode cannot be called with both a workflow and a launchplan specified, please pick " f"one. workflow: {flyte_workflow} launchPlan: {flyte_launch_plan}", ) self._flyte_workflow = flyte_workflow self._flyte_launch_plan = flyte_launch_plan super(FlyteWorkflowNode, self).__init__( launchplan_ref=self._flyte_launch_plan.id if self._flyte_launch_plan else None, sub_workflow_ref=self._flyte_workflow.id if self._flyte_workflow else None, )
def promote_from_model( cls, base_model: _workflow_model.TaskNode, tasks: Dict[id_models.Identifier, _task_model.TaskTemplate], ) -> "FlyteTaskNode": """ Takes the idl wrapper for a TaskNode and returns the hydrated Flytekit object for it by fetching it with the FlyteTask control plane. :param base_model: :param tasks: """ from flytekit.remote.task import FlyteTask if base_model.reference_id in tasks: task = tasks[base_model.reference_id] remote_logger.debug( f"Found existing task template for {task.id}, will not retrieve from Admin" ) flyte_task = FlyteTask.promote_from_model(task) return cls(flyte_task) raise _system_exceptions.FlyteSystemException( f"Task template {base_model.reference_id} not found.")
def promote_from_model( cls, model: _workflow_model.Node, sub_workflows: Optional[Dict[id_models.Identifier, _workflow_model.WorkflowTemplate]], node_launch_plans: Optional[Dict[id_models.Identifier, _launch_plan_model.LaunchPlanSpec]], tasks: Optional[Dict[id_models.Identifier, _task_model.TaskTemplate]], ) -> FlyteNode: node_model_id = model.id # TODO: Consider removing if id in {_constants.START_NODE_ID, _constants.END_NODE_ID}: remote_logger.warning( f"Should not call promote from model on a start node or end node {model}" ) return None flyte_task_node, flyte_workflow_node, flyte_branch_node = None, None, None if model.task_node is not None: flyte_task_node = _component_nodes.FlyteTaskNode.promote_from_model( model.task_node, tasks) elif model.workflow_node is not None: flyte_workflow_node = _component_nodes.FlyteWorkflowNode.promote_from_model( model.workflow_node, sub_workflows, node_launch_plans, tasks, ) elif model.branch_node is not None: flyte_branch_node = _component_nodes.FlyteBranchNode.promote_from_model( model.branch_node, sub_workflows, node_launch_plans, tasks) else: raise _system_exceptions.FlyteSystemException( f"Bad Node model, neither task nor workflow detected, node: {model}" ) # When WorkflowTemplate models (containing node models) are returned by Admin, they've been compiled with a # start node. In order to make the promoted FlyteWorkflow look the same, we strip the start-node text back out. # TODO: Consider removing for model_input in model.inputs: if (model_input.binding.promise is not None and model_input.binding.promise.node_id == _constants.START_NODE_ID): model_input.binding.promise._node_id = _constants.GLOBAL_INPUT_NODE_ID if flyte_task_node is not None: return cls( id=node_model_id, upstream_nodes= [], # set downstream, model doesn't contain this information bindings=model.inputs, metadata=model.metadata, flyte_task=flyte_task_node.flyte_task, ) elif flyte_workflow_node is not None: if flyte_workflow_node.flyte_workflow is not None: return cls( id=node_model_id, upstream_nodes= [], # set downstream, model doesn't contain this information bindings=model.inputs, metadata=model.metadata, flyte_workflow=flyte_workflow_node.flyte_workflow, ) elif flyte_workflow_node.flyte_launch_plan is not None: return cls( id=node_model_id, upstream_nodes= [], # set downstream, model doesn't contain this information bindings=model.inputs, metadata=model.metadata, flyte_launch_plan=flyte_workflow_node.flyte_launch_plan, ) raise _system_exceptions.FlyteSystemException( "Bad FlyteWorkflowNode model, both launch plan and workflow are None" ) elif flyte_branch_node is not None: return cls( id=node_model_id, upstream_nodes= [], # set downstream, model doesn't contain this information bindings=model.inputs, metadata=model.metadata, flyte_branch_node=flyte_branch_node, ) raise _system_exceptions.FlyteSystemException( "Bad FlyteNode model, both task and workflow nodes are empty")