docs: def get_step_by(self, **kwargs):
          """
          Get the first step that matches all the passed named arguments.
  
          Has special argument index not present in the real step.
  
          Usage:
              config.get_step_by(name='not found')
              config.get_step_by(index=0)
              config.get_step_by(name="greeting", command='echo HELLO MORDOR')
  
          :param kwargs:
          :return: Step object or None
          :rtype: valohai_yaml.objs.Step|None
          """
          if not kwargs:
              return None
          for index, step in enumerate(self.steps.values()):
              extended_step = dict(step.serialize(), index=index)
              # check if kwargs is a subset of extended_step
              if all(item in extended_step.items() for item in kwargs.items()):
                  return step
          return None