docs: def start(self, pipeline, return_task=True, countdown=None, eta=None):
      """Starts a pipeline.
  
      Args:
        pipeline: Pipeline instance to run.
        return_task: When True, do not submit the task to start the pipeline
          but instead return it for someone else to enqueue.
        countdown: Time in seconds into the future that this Task should execute.
          Defaults to zero.
        eta: A datetime.datetime specifying the absolute time at which the task
          should be executed. Must not be specified if 'countdown' is specified.
          This may be timezone-aware or timezone-naive. If None, defaults to now.
          For pull tasks, no worker will be able to lease this task before the
          time indicated by eta.
  
      Returns:
        The task to start this pipeline if return_task was True.
  
      Raises:
        PipelineExistsError if the pipeline with the given ID already exists.
      """
      # Adjust all pipeline output keys for this Pipeline to be children of
      # the _PipelineRecord, that way we can write them all and submit in a
      # single transaction.
      for name, slot in pipeline.outputs._output_dict.iteritems():
        slot.key = db.Key.from_path(
            *slot.key.to_path(), **dict(parent=pipeline._pipeline_key))
  
      _, output_slots, params_text, params_blob = _generate_args(
          pipeline, pipeline.outputs, self.queue_name, self.base_path)
  
      @db.transactional(propagation=db.INDEPENDENT)
      def txn():
        pipeline_record = db.get(pipeline._pipeline_key)
        if pipeline_record is not None:
          raise PipelineExistsError(
              'Pipeline with idempotence key "%s" already exists; params=%s' %
              (pipeline._pipeline_key.name(),
               _short_repr(pipeline_record.params)))
  
        entities_to_put = []
        for name, slot in pipeline.outputs._output_dict.iteritems():
          entities_to_put.append(_SlotRecord(
              key=slot.key,
              root_pipeline=pipeline._pipeline_key))
  
        entities_to_put.append(_PipelineRecord(
            key=pipeline._pipeline_key,
            root_pipeline=pipeline._pipeline_key,
            is_root_pipeline=True,
            # Bug in DB means we need to use the storage name here,
            # not the local property name.
            params=params_text,
            params_blob=params_blob,
            start_time=self._gettime(),
            class_path=pipeline._class_path,
            max_attempts=pipeline.max_attempts))
  
        entities_to_put.extend(_PipelineContext._create_barrier_entities(
            pipeline._pipeline_key,
            pipeline._pipeline_key,
            _BarrierRecord.FINALIZE,
            output_slots))
  
        db.put(entities_to_put)
  
        task = taskqueue.Task(
            url=self.pipeline_handler_path,
            params=dict(pipeline_key=pipeline._pipeline_key),
            headers={'X-Ae-Pipeline-Key': pipeline._pipeline_key},
            target=pipeline.target,
            countdown=countdown,
            eta=eta)
        if return_task:
          return task
        task.add(queue_name=self.queue_name, transactional=True)
  
      task = txn()
      # Immediately mark the output slots as existing so they can be filled
      # by asynchronous pipelines or used in test mode.
      for output_slot in pipeline.outputs._output_dict.itervalues():
        output_slot._exists = True
      return task