class_docstr: Main class from which all Flows should inherit.
  
  Attributes
  ----------
  index
  input
code: def _set_constants(self, graph, kwargs):
      from metaflow.decorators import (
          flow_decorators,
      )  # To prevent circular dependency
  
      # Persist values for parameters and other constants (class level variables)
      # only once. This method is called before persist_constants is called to
      # persist all values set using setattr
      seen = set()
      for var, param in self._get_parameters():
          norm = param.name.lower()
          if norm in seen:
              raise MetaflowException(
                  "Parameter *%s* is specified twice. "
                  "Note that parameter names are "
                  "case-insensitive." % param.name
              )
          seen.add(norm)
      seen.clear()
      self._success = True
  
      parameters_info = []
      for var, param in self._get_parameters():
          seen.add(var)
          val = kwargs[param.name.replace("-", "_").lower()]
          # Support for delayed evaluation of parameters.
          if isinstance(val, DelayedEvaluationParameter):
              val = val()
          val = (
              val.split(param.separator)
              if val and param.separator
              else val
          )
          setattr(self, var, val)
          parameters_info.append(
              {"name": var, "type": param.__class__.__name__}
          )
  
      # Do the same for class variables which will be forced constant as modifications
      # to them don't propagate well since we create a new process for each step and
      # re-read the flow file
      constants_info = []
      for var in dir(self.__class__):
          if (
              var[0] == "_"
              or var in self._NON_PARAMETERS
              or var in seen
          ):
              continue
          val = getattr(self.__class__, var)
          if isinstance(
              val, (MethodType, FunctionType, property, type)
          ):
              continue
          constants_info.append(
              {"name": var, "type": type(val).__name__}
          )
          setattr(self, var, val)
  
      # We store the DAG information as an artifact called _graph_info
      steps_info, graph_structure = graph.output_steps()
  
      graph_info = {
          "file": os.path.basename(os.path.abspath(sys.argv[0])),
          "parameters": parameters_info,
          "constants": constants_info,
          "steps": steps_info,
          "graph_structure": graph_structure,
          "doc": graph.doc,
          "decorators": [
              {
                  "name": deco.name,
                  "attributes": deco.attributes,
                  "statically_defined": deco.statically_defined,
              }
              for deco in flow_decorators()
              if not deco.name.startswith("_")
          ],
      }
      self._graph_info = graph_info
  
imports: import inspect
  import os
  import sys
  import traceback
  from itertools import islice
  from types import FunctionType, MethodType
  from typing import Any, Callable, List, Optional, Tuple
  from .None import cmd_with_io
  from .parameters import DelayedEvaluationParameter, Parameter
  from .exception import MetaflowException, MissingInMergeArtifactsException, UnhandledInMergeArtifactsException
  from .graph import FlowGraph
  from .unbounded_foreach import UnboundedForeachInput
  from .datastore.inputs import Inputs
label_desc: Use image node_id 3 for calling the FlowSpec obj's underlying member method code with example usage: obj._set_constants(graph, kwargs) without return types