Repository: kubeflow/pipelines

Issue:
Running into TypeError exception with `batch_predict` component
### What steps did you take:
I am using batch_predict component to schedule prediction job on AI platform. I was referring to steps here. https://github.com/kubeflow/pipelines/tree/master/components/gcp/ml_engine/batch_predict
- I downloaded the component from https://raw.githubusercontent.com/kubeflow/pipelines/1.0.0/components/gcp/ml_engine/batch_predict/component.yaml. 
- loaded the component with `ml_op = load_component_from_file(<local-path>)`
- created pipeline component with `ml_op(<attributes-mentioned-below>)`
- scheduled the pipeline on kubeflow

Job Parameters:

```
prediction_input: {'runtimeVersion': '2.1'}
project_id: <gcs-project>
region: <region-name>
model_path: <gcs-path>
input_paths: [<list-of-input-paths>]
input_data_format: TF_RECORD_GZIP
output_path: <gcs-path>
output_data_format: JSON
```

### What happened:

Running into type error while generating the job_id.

Issue:

It is raising an exception while generating id to schedule the job. This line is failing https://github.com/kubeflow/pipelines/blob/1.0.0/components/gcp/container/component_sdk/python/kfp_component/google/common/_utils.py#L44 with this error `TypeError: expected string or buffer`. I am not passing any job_id and job_id_prefix. It is using the default values for generating the name.

Error trace:

```
INFO:root:Start KFP context with ID: 858b3ff01cdeed5c0b0b7fd9d2655641.
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/runpy.py", line 174, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/local/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/ml/kfp_component/launcher/__main__.py", line 45, in <module>
    main()
  File "/ml/kfp_component/launcher/__main__.py", line 42, in main
    launch(args.file_or_module, args.args)
  File "kfp_component/launcher/launcher.py", line 45, in launch
    return fire.Fire(module, command=args, name=module.__name__)
  File "/usr/local/lib/python2.7/site-packages/fire/core.py", line 127, in Fire
    component_trace = _Fire(component, args, context, name)
  File "/usr/local/lib/python2.7/site-packages/fire/core.py", line 366, in _Fire
    component, remaining_args)
  File "/usr/local/lib/python2.7/site-packages/fire/core.py", line 542, in _CallCallable
    result = fn(*varargs, **kwargs)
  File "kfp_component/google/ml_engine/_batch_predict.py", line 70, in batch_predict
    create_job(project_id, job, job_id_prefix, wait_interval)
  File "kfp_component/google/ml_engine/_create_job.py", line 48, in create_job
    return CreateJobOp(project_id, job, job_id_prefix, job_id, wait_interval
  File "kfp_component/google/ml_engine/_create_job.py", line 63, in execute_and_wait
    self._set_job_id(ctx.context_id())
  File "kfp_component/google/ml_engine/_create_job.py", line 74, in _set_job_id
    job_id = gcp_common.normalize_name(job_id)
  File "kfp_component/google/common/_utils.py", line 45, in normalize_name
    invalid_char_placeholder, name)
  File "/usr/local/lib/python2.7/re.py", line 155, in sub
    return _compile(pattern, flags).sub(repl, string, count)
TypeError: expected string or buffer

```

### What did you expect to happen:

I was expecting the component to schedule the job with auto generated job id.

### Environment:
<!-- Please fill in those that seem relevant. -->

How did you deploy Kubeflow Pipelines (KFP)?
- I used Kustomize to deploy standalone kubeflow pipeline manifests on GKE.

<!-- If you are not sure, here's [an introduction of all options](https://www.kubeflow.org/docs/pipelines/installation/overview/). -->

KFP version: <!-- If you are not sure, build commit shows on bottom of KFP UI left sidenav. -->
1.0.0

KFP SDK version: <!-- Please attach the output of this shell command: $pip list | grep kfp -->
kfp==0.5.1

### Anything else you would like to add:
[Miscellaneous information that will assist in solving the issue.]

/kind bug
<!-- Please include labels by uncommenting them to help us better triage issues, choose from the following -->
<!--
// /area frontend
 /area backend
// /area sdk
// /area testing
 /area engprod
-->



Discussion:
Thank you fr your bug report.
I've found the issue:
It was introduced in https://github.com/kubeflow/pipelines/pull/3850 . That PR has added a new parameter in the middle of the the `create_job` function signature which can cause breaking changes as the parameter ordering changes.

Resolving patch:
diff --git a/components/gcp/container/component_sdk/python/kfp_component/google/ml_engine/_batch_predict.py b/components/gcp/container/component_sdk/python/kfp_component/google/ml_engine/_batch_predict.py
--- a/components/gcp/container/component_sdk/python/kfp_component/google/ml_engine/_batch_predict.py
+++ b/components/gcp/container/component_sdk/python/kfp_component/google/ml_engine/_batch_predict.py
@@ -67,7 +67,13 @@ def batch_predict(project_id, model_path, input_paths, input_data_format,
     job = {
         'predictionInput': prediction_input
     }
-    create_job(project_id, job, job_id_prefix, wait_interval, job_id_output_path=job_id_output_path)
+    create_job(
+        project_id=project_id,
+        job=job,
+        job_id_prefix=job_id_prefix,
+        wait_interval=wait_interval,
+        job_id_output_path=job_id_output_path,
+    )
     
 def _is_model_name(name):
     return re.match(r'/projects/[^/]+/models/[^/]+$', name)
diff --git a/components/gcp/container/component_sdk/python/kfp_component/google/ml_engine/_train.py b/components/gcp/container/component_sdk/python/kfp_component/google/ml_engine/_train.py
--- a/components/gcp/container/component_sdk/python/kfp_component/google/ml_engine/_train.py
+++ b/components/gcp/container/component_sdk/python/kfp_component/google/ml_engine/_train.py
@@ -82,4 +82,11 @@ def train(project_id, job_id_output_path, python_module=None, package_uris=None,
     job = {
         'trainingInput': training_input
     }
-    return create_job(project_id, job, job_id_prefix, job_id, wait_interval, job_id_output_path=job_id_output_path)
\ No newline at end of file
+    return create_job(
+        project_id=project_id,
+        job=job,
+        job_id_prefix=job_id_prefix,
+        job_id=job_id,
+        wait_interval=wait_interval,
+        job_id_output_path=job_id_output_path,
+    )
\ No newline at end of file


Test patch:
diff --git a/components/gcp/container/component_sdk/python/tests/google/ml_engine/test__train.py b/components/gcp/container/component_sdk/python/tests/google/ml_engine/test__train.py
--- a/components/gcp/container/component_sdk/python/tests/google/ml_engine/test__train.py
+++ b/components/gcp/container/component_sdk/python/tests/google/ml_engine/test__train.py
@@ -39,7 +39,7 @@ def test_train_succeed(self, mock_create_job):
             job_id_output_path='/tmp/kfp/output/ml_engine/job_id.txt',
         )
         
-        mock_create_job.assert_called_with('proj-1', {
+        mock_create_job.assert_called_with(project_id='proj-1', job={
             'trainingInput': {
                 'pythonModule': 'mock.module',
                 'packageUris': ['gs://test/package'],
@@ -55,4 +55,4 @@ def test_train_succeed(self, mock_create_job):
                     'imageUri': 'debian:latest'
                 }
             }
-        }, 'job-', 'job-1', 30, job_id_output_path='/tmp/kfp/output/ml_engine/job_id.txt')
+        }, job_id_prefix='job-', job_id='job-1', wait_interval=30, job_id_output_path='/tmp/kfp/output/ml_engine/job_id.txt')