code: def _evaluate_op_node(
      ctx: _Context, node_id: str, data: Mapping[str, _Data]
  ) -> _Data:
      """A functional interface for `InputNode`."""
      op_node = ctx.input_graph.nodes[node_id].op_node
      args = [_unwrap_arg(v, data) for v in op_node.args]
      kwargs = {
          k: _unwrap_arg(v, data) for k, v in op_node.kwargs.items()
      }
      try:
          op_type = ops.get_by_name(op_node.op_type)
      except KeyError as e:
          try:
              # Currently ResolverStrategy is stored as a class path.
              op_type = ops.get_by_class_path(op_node.op_type)
          except ValueError:
              raise exceptions.InternalError(
                  f"nodes[{node_id}] has unknown op_type {op_node.op_type}."
              ) from e
      if issubclass(op_type, resolver_op.ResolverOp):
          op: resolver_op.ResolverOp = op_type.create(**kwargs)
          op.set_context(
              resolver_op.Context(store=ctx.mlmd_handle.store)
          )
          return op.apply(*args)
      elif issubclass(op_type, resolver.ResolverStrategy):
          if len(args) != 1:
              raise exceptions.FailedPreconditionError(
                  f"Invalid number of {op_type} arguments: {args!r}"
              )
          arg = args[0]
          if not typing_utils.is_artifact_multimap(arg):
              raise exceptions.FailedPreconditionError(
                  f"Invalid {op_type} argument: {arg!r}"
              )
          strategy: resolver.ResolverStrategy = op_type(**kwargs)
          result = strategy.resolve_artifacts(
              ctx.mlmd_handle.store, arg
          )
          if result is None:
              raise exceptions.InputResolutionError(
                  f"{strategy} returned None."
              )
          return result
      else:
          raise exceptions.InternalError(f"Unknown op_type {op_type}.")
  
imports: import collections
  import dataclasses
  import functools
  from typing import Union, Sequence, Mapping, Tuple, List, Iterable, Callable
  from tfx import types
  from tfx.dsl.components.common import resolver
  from tfx.dsl.input_resolution import resolver_op
  from tfx.dsl.input_resolution.ops import ops
  from tfx.orchestration import data_types_utils
  from tfx.orchestration import metadata
  from tfx.orchestration.portable.input_resolution import exceptions
  from tfx.proto.orchestration import pipeline_pb2
  from tfx.utils import topsort
  from tfx.utils import typing_utils
label_desc: Use image node_id 3 for calling a global function with example usage: _evaluate_op_node(ctx, node_id, data) and returns: op, result