# Buggy code
def create_run_from_pipeline_func(
    self,
    pipeline_func: Callable,
    arguments: Mapping[str, str],
    run_name=None,
    experiment_name=None,
    pipeline_conf: kfp.dsl.PipelineConf = None,
    namespace=None,
):
    """Runs pipeline on KFP-enabled Kubernetes cluster.
    This command compiles the pipeline function, creates or gets an experiment and submits the pipeline for execution.

    Args:
      pipeline_func: A function that describes a pipeline by calling components and composing them into execution graph.
      arguments: Arguments to the pipeline function provided as a dict.
      run_name: Optional. Name of the run to be shown in the UI.
      experiment_name: Optional. Name of the experiment to add the run to.
      namespace: kubernetes namespace where the pipeline runs are created.
        For single user deployment, leave it as None;
        For multi user, input a namespace where the user is authorized
    """
    # TODO: Check arguments against the pipeline function
    pipeline_name = pipeline_func.__name__
    run_name = run_name or pipeline_name + " " + datetime.now().strftime(
        "%Y-%m-%d %H-%M-%S"
    )
    with tempfile.TemporaryDirectory() as tmpdir:
        pipeline_package_path = os.path.join(tmpdir, "pipeline.yaml")
        compiler.Compiler().compile(
            pipeline_func, pipeline_package_path, pipeline_conf=pipeline_conf
        )
        return self.create_run_from_pipeline_package(
            pipeline_package_path, arguments, run_name, experiment_name, namespace
        )


# Traceback (AttributeError)
AttributeError
Traceback (most recent call last)
<ipython-input-8-8ebf2be6196c> in <module>
1 client = kfp.Client(host='2c688415e5fe965e-dot-us-central2.pipelines.googleusercontent.com')
----> 2 client.wait_for_run_completion(run_id=run_result.run_id, timeout=36000)

~/Library/Python/3.7/lib/python/site-packages/kfp/_client.py in wait_for_run_completion(self, run_id, timeout)
597     while status is None or status.lower() not in ['succeeded', 'failed', 'skipped', 'error']:
598       get_run_response = self._run_api.get_run(run_id=run_id)
--> 599       status = get_run_response.run.status
600       elapsed_time = (datetime.now() - start_time).seconds
601       logging.info('Waiting for the job to complete...')

AttributeError: 'NoneType' object has no attribute 'status'

# Fixed code
def create_run_from_pipeline_func(
    self,
    pipeline_func: Callable,
    arguments: Mapping[str, str],
    run_name=None,
    experiment_name=None,
    pipeline_conf: kfp.dsl.PipelineConf = None,
    namespace=None,
):
    """Runs pipeline on KFP-enabled Kubernetes cluster.
    This command compiles the pipeline function, creates or gets an experiment and submits the pipeline for execution.

    Args:
      pipeline_func: A function that describes a pipeline by calling components and composing them into execution graph.
      arguments: Arguments to the pipeline function provided as a dict.
      run_name: Optional. Name of the run to be shown in the UI.
      experiment_name: Optional. Name of the experiment to add the run to.
      namespace: kubernetes namespace where the pipeline runs are created.
        For single user deployment, leave it as None;
        For multi user, input a namespace where the user is authorized
    """
    # TODO: Check arguments against the pipeline function
    pipeline_name = pipeline_func.__name__
    run_name = run_name or pipeline_name + " " + datetime.datetime.now().strftime(
        "%Y-%m-%d %H-%M-%S"
    )
    with tempfile.TemporaryDirectory() as tmpdir:
        pipeline_package_path = os.path.join(tmpdir, "pipeline.yaml")
        compiler.Compiler().compile(
            pipeline_func, pipeline_package_path, pipeline_conf=pipeline_conf
        )
        return self.create_run_from_pipeline_package(
            pipeline_package_path, arguments, run_name, experiment_name, namespace
        )