Repository: kubeflow/pipelines

Issue:
The KFP preloaded XGboost sample is broken and out-dated. 
**TL;DR: The preload XGBoost sample is currently broken. 
Proposing we remove this sample from KFP preload and from sample test until we got a chance to refresh the sample.**

------------
The direct cause was that it used the Dataproc 1.2 image which is based on Python 2.7, and pip 21.0 dropped support for Python 2.7.
The symptom is that `dataproc_create_cluster` fails on initialization. 
![image](https://user-images.githubusercontent.com/2043310/106823995-bbcd6780-6636-11eb-8169-92d7a338e048.png)
and the specific error is mentioned [here](https://github.com/kubeflow/pipelines/issues/5007#issuecomment-769637030).

https://github.com/kubeflow/pipelines/pull/5062 made an attempted fix by upgrading to Dataproc 1.5 image. It fixed the Dataproc cluster creation issue, but we hit [an error](https://github.com/kubeflow/pipelines/issues/5007#issuecomment-770182313) later at the Trainer step.

We were advised that newer versions of Dataproc images likely don't have XGBoost library preinstalled, as there's now [an initialization action that goes through extra steps to install XGBoost libraries](https://github.com/GoogleCloudDataproc/initialization-actions/tree/master/rapids).

Following that route, I tried installing the default XGBoost version using the rapids script, then hit the error as follows:
```
21/02/03 18:34:20 INFO org.spark_project.jetty.util.log: Logging initialized @3037ms
21/02/03 18:34:20 INFO org.spark_project.jetty.server.Server: jetty-9.3.z-SNAPSHOT, build timestamp: unknown, git hash: unknown
21/02/03 18:34:20 INFO org.spark_project.jetty.server.Server: Started @3169ms
21/02/03 18:34:20 INFO org.spark_project.jetty.server.AbstractConnector: Started ServerConnector@4159e81b{HTTP/1.1,[http/1.1]}{0.0.0.0:37489}
21/02/03 18:34:20 INFO org.apache.hadoop.yarn.client.RMProxy: Connecting to ResourceManager at xgb-bdd8f29b-fb13-4ec2-abcf-38b3699e7ca3-m/10.128.0.101:8032
21/02/03 18:34:21 INFO org.apache.hadoop.yarn.client.AHSProxy: Connecting to Application History server at xgb-bdd8f29b-fb13-4ec2-abcf-38b3699e7ca3-m/10.128.0.101:10200
21/02/03 18:34:21 INFO org.apache.hadoop.conf.Configuration: resource-types.xml not found
21/02/03 18:34:21 INFO org.apache.hadoop.yarn.util.resource.ResourceUtils: Unable to find 'resource-types.xml'.
21/02/03 18:34:21 INFO org.apache.hadoop.yarn.util.resource.ResourceUtils: Adding resource type - name = memory-mb, units = Mi, type = COUNTABLE
21/02/03 18:34:21 INFO org.apache.hadoop.yarn.util.resource.ResourceUtils: Adding resource type - name = vcores, units = , type = COUNTABLE
21/02/03 18:34:23 INFO org.apache.hadoop.yarn.client.api.impl.YarnClientImpl: Submitted application application_1612377093662_0003
21/02/03 18:34:30 INFO org.apache.hadoop.mapreduce.lib.input.FileInputFormat: Total input files to process : 1
21/02/03 18:34:30 INFO org.apache.hadoop.mapreduce.lib.input.FileInputFormat: Total input files to process : 1
21/02/03 18:34:30 INFO org.apache.hadoop.mapreduce.lib.input.CombineFileInputFormat: DEBUG: Terminated node allocation with : CompletedNodes: 1, size left: 0
21/02/03 18:34:36 INFO org.apache.hadoop.mapreduce.lib.input.FileInputFormat: Total input files to process : 1
21/02/03 18:34:36 INFO org.apache.hadoop.mapreduce.lib.input.FileInputFormat: Total input files to process : 1
21/02/03 18:34:36 INFO org.apache.hadoop.mapreduce.lib.input.CombineFileInputFormat: DEBUG: Terminated node allocation with : CompletedNodes: 1, size left: 0
Exception in thread "main" java.lang.NoSuchMethodError: ml.dmlc.xgboost4j.scala.spark.XGBoost$.trainWithDataFrame$default$5()Lml/dmlc/xgboost4j/scala/ObjectiveTrait;
	at ml.dmlc.xgboost4j.scala.example.spark.XGBoostTrainer$.main(XGBoostTrainer.scala:120)
	at ml.dmlc.xgboost4j.scala.example.spark.XGBoostTrainer.main(XGBoostTrainer.scala)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.spark.deploy.JavaMainApplication.start(SparkApplication.scala:52)
	at org.apache.spark.deploy.SparkSubmit.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:845)
	at org.apache.spark.deploy.SparkSubmit.doRunMain$1(SparkSubmit.scala:161)
	at org.apache.spark.deploy.SparkSubmit.submit(SparkSubmit.scala:184)
	at org.apache.spark.deploy.SparkSubmit.doSubmit(SparkSubmit.scala:86)
	at org.apache.spark.deploy.SparkSubmit$$anon$2.doSubmit(SparkSubmit.scala:920)
	at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:929)
	at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
21/02/03 18:34:39 INFO org.spark_project.jetty.server.AbstractConnector: Stopped Spark@4159e81b{HTTP/1.1,[http/1.1]}{0.0.0.0:0}
Job output is complete
```

I then realized that the sample is based on the code from the deprecated component path, which was deleted by https://github.com/kubeflow/pipelines/pull/5045.

Specifically, the not found method from the above error was used here:  
https://github.com/kubeflow/pipelines/blob/32ce8d8f90bfc8f89a2a3c347ad906f99ba776a8/components/deprecated/dataproc/train/src/XGBoostTrainer.scala#L121

And `trainWithDataFrame` only [exists in XGBoost 0.72](https://xgboost.readthedocs.io/en/release_0.72/jvm/scaladocs/xgboost4j-spark/index.html#ml.dmlc.xgboost4j.scala.spark.XGBoost$@trainWithDataFrame(trainingData:org.apache.spark.sql.Dataset[_],params:Map[String,Any],round:Int,nWorkers:Int,obj:ml.dmlc.xgboost4j.scala.ObjectiveTrait,eval:ml.dmlc.xgboost4j.scala.EvalTrait,useExternalMemory:Boolean,missing:Float,featureCol:String,labelCol:String):ml.dmlc.xgboost4j.scala.spark.XGBoostModel), but not seen from any versions beyond. 

XGBoost 0.72 is too old and not even available from https://repo1.maven.org/maven2/com/nvidia/, which is [used by rapids to download XGBoost](https://github.com/GoogleCloudDataproc/initialization-actions/blob/8980d37d16ae580ad1d3eba7a40da59da52ff175/rapids/rapids.sh#L90).

At this point, I feel like we'd rather invest to rewrite the XGBoost sample using the latest XGBoost library than patching the existing one if we do think it's worth demoing running a XGBoost-on-Dataproc pipeline. 
Util we have the sample working, I propose we remove it from the KFP preloaded pipelines and sample-tests.


Discussion:
> Util we have the sample working, I propose we remove it from the KFP preloaded pipelines and sample-tests.

Completely agree with this!
The sample is a nice to have, although it's more important get KFP releases healthy and running.

Resolving patch:
diff --git a/samples/core/train_until_good/train_until_good.py b/samples/core/train_until_good/train_until_good.py
--- a/samples/core/train_until_good/train_until_good.py
+++ b/samples/core/train_until_good/train_until_good.py
@@ -67,6 +67,7 @@ def train_until_low_error(starting_model, training_data, true_values):
 
 
 # The main pipleine trains the initial model and then gradually trains the model some more until the model evaluation metrics are good enough.
+@kfp.dsl.pipeline()
 def train_until_good_pipeline():
     # Preparing the training data
     training_data = chicago_taxi_dataset_op(


Test patch:
diff --git a/frontend/src/pages/GettingStarted.test.tsx b/frontend/src/pages/GettingStarted.test.tsx
--- a/frontend/src/pages/GettingStarted.test.tsx
+++ b/frontend/src/pages/GettingStarted.test.tsx
@@ -46,181 +46,7 @@ describe('GettingStarted page', () => {
 
   it('initially renders documentation', () => {
     const { container } = render(<GettingStarted {...generateProps()} />);
-    expect(container).toMatchInlineSnapshot(`
-      <div>
-        <div
-          class="page kfp-start-page"
-        >
-          <div>
-            <br />
-            <h2
-              id="build-your-own-pipeline-with"
-            >
-              Build your own pipeline with
-            </h2>
-            <ul>
-              <li>
-                TensorFlow Extended (TFX) 
-                <a
-                  class="link"
-                  href="https://www.tensorflow.org/tfx/guide"
-                  rel="noopener"
-                  target="_blank"
-                >
-                  SDK
-                </a>
-                 with end-to-end ML Pipeline Template (
-                <a
-                  class="link"
-                  href="https://console.cloud.google.com/mlengine/notebooks/deploy-notebook?q=download_url%3Dhttps%253A%252F%252Fraw.githubusercontent.com%252Ftensorflow%252Ftfx%252Fmaster%252Fdocs%252Ftutorials%252Ftfx%252Ftemplate.ipynb"
-                  rel="noopener"
-                  target="_blank"
-                >
-                  Open TF 2.1 Notebook
-                </a>
-                )
-              </li>
-              <li>
-                Kubeflow Pipelines 
-                <a
-                  class="link"
-                  href="https://www.kubeflow.org/docs/pipelines/sdk/"
-                  rel="noopener"
-                  target="_blank"
-                >
-                  SDK
-                </a>
-              </li>
-            </ul>
-            <br />
-            <h2
-              id="demonstrations-and-tutorials"
-            >
-              Demonstrations and Tutorials
-            </h2>
-            <p>
-              This section contains demo and tutorial pipelines.
-            </p>
-            <p>
-              <strong>
-                Demos
-              </strong>
-               - Try an end-to-end demonstration pipeline.
-            </p>
-            <ul>
-              <li>
-                <a
-                  class="link"
-                  href="#/pipelines"
-                >
-                  TFX pipeline demo with Keras
-                </a>
-                 
-                <ul>
-                  <li>
-                    Classification pipeline based on Keras. 
-                    <a
-                      class="link"
-                      href="https://github.com/kubeflow/pipelines/tree/master/samples/core/iris"
-                      rel="noopener"
-                      target="_blank"
-                    >
-                      source code
-                    </a>
-                  </li>
-                </ul>
-              </li>
-              <li>
-                <a
-                  class="link"
-                  href="#/pipelines"
-                >
-                  TFX pipeline demo with Estimator
-                </a>
-                 
-                <ul>
-                  <li>
-                    Classification pipeline with model analysis, based on a public BigQuery dataset of taxicab trips. 
-                    <a
-                      class="link"
-                      href="https://github.com/kubeflow/pipelines/tree/master/samples/core/parameterized_tfx_oss"
-                      rel="noopener"
-                      target="_blank"
-                    >
-                      source code
-                    </a>
-                  </li>
-                </ul>
-              </li>
-            </ul>
-            <br />
-            <p>
-              <strong>
-                Tutorials
-              </strong>
-               - Learn pipeline concepts by following a tutorial.
-            </p>
-            <ul>
-              <li>
-                <a
-                  class="link"
-                  href="#/pipelines"
-                >
-                  Data passing in python components
-                </a>
-                 
-                <ul>
-                  <li>
-                    Shows how to pass data between python components. 
-                    <a
-                      class="link"
-                      href="https://github.com/kubeflow/pipelines/tree/master/samples/tutorials/Data%20passing%20in%20python%20components"
-                      rel="noopener"
-                      target="_blank"
-                    >
-                      source code
-                    </a>
-                  </li>
-                </ul>
-              </li>
-              <li>
-                <a
-                  class="link"
-                  href="#/pipelines"
-                >
-                  DSL - Control structures
-                </a>
-                 
-                <ul>
-                  <li>
-                    Shows how to use conditional execution and exit handlers. 
-                    <a
-                      class="link"
-                      href="https://github.com/kubeflow/pipelines/tree/master/samples/tutorials/DSL%20-%20Control%20structures"
-                      rel="noopener"
-                      target="_blank"
-                    >
-                      source code
-                    </a>
-                  </li>
-                </ul>
-              </li>
-            </ul>
-            <p>
-              Want to learn more? 
-              <a
-                class="link"
-                href="https://www.kubeflow.org/docs/pipelines/tutorials/"
-                rel="noopener"
-                target="_blank"
-              >
-                Learn from sample and tutorial pipelines.
-              </a>
-            </p>
-          </div>
-        </div>
-      </div>
-    `);
+    expect(container).toMatchSnapshot();
   });
 
   it('renders documentation with pipeline deep link after querying demo pipelines', async () => {
@@ -235,34 +61,7 @@ describe('GettingStarted page', () => {
     const { container } = render(<GettingStarted {...generateProps()} />);
     const base = container.innerHTML;
     await TestUtils.flushPromises();
-    expect(pipelineListSpy.mock.calls).toMatchInlineSnapshot(`
-      Array [
-        Array [
-          undefined,
-          10,
-          undefined,
-          "%7B%22predicates%22%3A%5B%7B%22key%22%3A%22name%22%2C%22op%22%3A%22EQUALS%22%2C%22string_value%22%3A%22%5BDemo%5D%20TFX%20-%20Taxi%20tip%20prediction%20model%20trainer%22%7D%5D%7D",
-        ],
-        Array [
-          undefined,
-          10,
-          undefined,
-          "%7B%22predicates%22%3A%5B%7B%22key%22%3A%22name%22%2C%22op%22%3A%22EQUALS%22%2C%22string_value%22%3A%22%5BDemo%5D%20TFX%20-%20Iris%20classification%20pipeline%22%7D%5D%7D",
-        ],
-        Array [
-          undefined,
-          10,
-          undefined,
-          "%7B%22predicates%22%3A%5B%7B%22key%22%3A%22name%22%2C%22op%22%3A%22EQUALS%22%2C%22string_value%22%3A%22%5BTutorial%5D%20Data%20passing%20in%20python%20components%22%7D%5D%7D",
-        ],
-        Array [
-          undefined,
-          10,
-          undefined,
-          "%7B%22predicates%22%3A%5B%7B%22key%22%3A%22name%22%2C%22op%22%3A%22EQUALS%22%2C%22string_value%22%3A%22%5BTutorial%5D%20DSL%20-%20Control%20structures%22%7D%5D%7D",
-        ],
-      ]
-    `);
+    expect(pipelineListSpy.mock.calls).toMatchSnapshot();
     expect(diffHTML({ base, update: container.innerHTML })).toMatchInlineSnapshot(`
       Snapshot Diff:
       - Expected
@@ -275,7 +74,7 @@ describe('GettingStarted page', () => {
             <ul>
               <li>
       -         <a href="#/pipelines" class="link">TFX pipeline demo with Keras</a>
-      +         <a href="#/pipelines/details/pipeline-id-2?" class="link"
+      +         <a href="#/pipelines/details/pipeline-id-3?" class="link"
       +           >TFX pipeline demo with Keras</a
       +         >
                 <ul>
@@ -290,7 +89,7 @@ describe('GettingStarted page', () => {
               </li>
               <li>
       -         <a href="#/pipelines" class="link">TFX pipeline demo with Estimator</a>
-      +         <a href="#/pipelines/details/pipeline-id-1?" class="link"
+      +         <a href="#/pipelines/details/pipeline-id-2?" class="link"
       +           >TFX pipeline demo with Estimator</a
       +         >
                 <ul>
@@ -298,6 +97,21 @@ describe('GettingStarted page', () => {
                     Classification pipeline with model analysis, based on a public
                     BigQuery dataset of taxicab trips.
                     <a
+      @@ --- --- @@
+                    >
+                  </li>
+                </ul>
+              </li>
+              <li>
+      -         <a href="#/pipelines" class="link">XGBoost Pipeline demo</a>
+      +         <a href="#/pipelines/details/pipeline-id-1?" class="link"
+      +           >XGBoost Pipeline demo</a
+      +         >
+                <ul>
+                  <li>
+                    An example of end-to-end iterative XGBoost model training.
+                    <a
+                      href="https://github.com/kubeflow/pipelines/tree/master/samples/core/train_until_good"
       @@ --- --- @@
               <strong>Tutorials</strong> - Learn pipeline concepts by following a
               tutorial.
@@ -305,7 +119,7 @@ describe('GettingStarted page', () => {
             <ul>
               <li>
       -         <a href="#/pipelines" class="link">Data passing in python components</a>
-      +         <a href="#/pipelines/details/pipeline-id-3?" class="link"
+      +         <a href="#/pipelines/details/pipeline-id-4?" class="link"
       +           >Data passing in python components</a
       +         >
                 <ul>
@@ -313,21 +127,6 @@ describe('GettingStarted page', () => {
                     Shows how to pass data between python components.
                     <a
                       href="https://github.com/kubeflow/pipelines/tree/master/samples/tutorials/Data%20passing%20in%20python%20components"
-      @@ --- --- @@
-                    >
-                  </li>
-                </ul>
-              </li>
-              <li>
-      -         <a href="#/pipelines" class="link">DSL - Control structures</a>
-      +         <a href="#/pipelines/details/pipeline-id-4?" class="link"
-      +           >DSL - Control structures</a
-      +         >
-                <ul>
-                  <li>
-                    Shows how to use conditional execution and exit handlers.
-                    <a
-                      href="https://github.com/kubeflow/pipelines/tree/master/samples/tutorials/DSL%20-%20Control%20structures"
     `);
   });
 
@@ -360,20 +159,20 @@ describe('GettingStarted page', () => {
       + Received
 
       @@ --- --- @@
-                    >
-                  </li>
-                </ul>
-              </li>
+              <strong>Tutorials</strong> - Learn pipeline concepts by following a
+              tutorial.
+            </p>
+            <ul>
               <li>
-      -         <a href="#/pipelines" class="link">DSL - Control structures</a>
+      -         <a href="#/pipelines" class="link">Data passing in python components</a>
       +         <a href="#/pipelines/details/pipeline-id-4?" class="link"
-      +           >DSL - Control structures</a
+      +           >Data passing in python components</a
       +         >
                 <ul>
                   <li>
-                    Shows how to use conditional execution and exit handlers.
+                    Shows how to pass data between python components.
                     <a
-                      href="https://github.com/kubeflow/pipelines/tree/master/samples/tutorials/DSL%20-%20Control%20structures"
+                      href="https://github.com/kubeflow/pipelines/tree/master/samples/tutorials/Data%20passing%20in%20python%20components"
     `);
   });
 });
diff --git a/frontend/src/pages/__snapshots__/GettingStarted.test.tsx.snap b/frontend/src/pages/__snapshots__/GettingStarted.test.tsx.snap
new file mode 100644
--- /dev/null
+++ b/frontend/src/pages/__snapshots__/GettingStarted.test.tsx.snap
@@ -0,0 +1,230 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`GettingStarted page initially renders documentation 1`] = `
+<div>
+  <div
+    class="page kfp-start-page"
+  >
+    <div>
+      <br />
+      <h2
+        id="build-your-own-pipeline-with"
+      >
+        Build your own pipeline with
+      </h2>
+      <ul>
+        <li>
+          TensorFlow Extended (TFX) 
+          <a
+            class="link"
+            href="https://www.tensorflow.org/tfx/guide"
+            rel="noopener"
+            target="_blank"
+          >
+            SDK
+          </a>
+           with end-to-end ML Pipeline Template (
+          <a
+            class="link"
+            href="https://console.cloud.google.com/mlengine/notebooks/deploy-notebook?q=download_url%3Dhttps%253A%252F%252Fraw.githubusercontent.com%252Ftensorflow%252Ftfx%252Fmaster%252Fdocs%252Ftutorials%252Ftfx%252Ftemplate.ipynb"
+            rel="noopener"
+            target="_blank"
+          >
+            Open TF 2.1 Notebook
+          </a>
+          )
+        </li>
+        <li>
+          Kubeflow Pipelines 
+          <a
+            class="link"
+            href="https://www.kubeflow.org/docs/pipelines/sdk/"
+            rel="noopener"
+            target="_blank"
+          >
+            SDK
+          </a>
+        </li>
+      </ul>
+      <br />
+      <h2
+        id="demonstrations-and-tutorials"
+      >
+        Demonstrations and Tutorials
+      </h2>
+      <p>
+        This section contains demo and tutorial pipelines.
+      </p>
+      <p>
+        <strong>
+          Demos
+        </strong>
+         - Try an end-to-end demonstration pipeline.
+      </p>
+      <ul>
+        <li>
+          <a
+            class="link"
+            href="#/pipelines"
+          >
+            TFX pipeline demo with Keras
+          </a>
+           
+          <ul>
+            <li>
+              Classification pipeline based on Keras. 
+              <a
+                class="link"
+                href="https://github.com/kubeflow/pipelines/tree/master/samples/core/iris"
+                rel="noopener"
+                target="_blank"
+              >
+                source code
+              </a>
+            </li>
+          </ul>
+        </li>
+        <li>
+          <a
+            class="link"
+            href="#/pipelines"
+          >
+            TFX pipeline demo with Estimator
+          </a>
+           
+          <ul>
+            <li>
+              Classification pipeline with model analysis, based on a public BigQuery dataset of taxicab trips. 
+              <a
+                class="link"
+                href="https://github.com/kubeflow/pipelines/tree/master/samples/core/parameterized_tfx_oss"
+                rel="noopener"
+                target="_blank"
+              >
+                source code
+              </a>
+            </li>
+          </ul>
+        </li>
+        <li>
+          <a
+            class="link"
+            href="#/pipelines"
+          >
+            XGBoost Pipeline demo
+          </a>
+           
+          <ul>
+            <li>
+              An example of end-to-end iterative XGBoost model training. 
+              <a
+                class="link"
+                href="https://github.com/kubeflow/pipelines/tree/master/samples/core/train_until_good"
+                rel="noopener"
+                target="_blank"
+              >
+                source code
+              </a>
+            </li>
+          </ul>
+        </li>
+      </ul>
+      <br />
+      <p>
+        <strong>
+          Tutorials
+        </strong>
+         - Learn pipeline concepts by following a tutorial.
+      </p>
+      <ul>
+        <li>
+          <a
+            class="link"
+            href="#/pipelines"
+          >
+            Data passing in python components
+          </a>
+           
+          <ul>
+            <li>
+              Shows how to pass data between python components. 
+              <a
+                class="link"
+                href="https://github.com/kubeflow/pipelines/tree/master/samples/tutorials/Data%20passing%20in%20python%20components"
+                rel="noopener"
+                target="_blank"
+              >
+                source code
+              </a>
+            </li>
+          </ul>
+        </li>
+        <li>
+          <a
+            class="link"
+            href="undefined"
+            rel="noopener"
+            target="_blank"
+          >
+            DSL - Control structures
+          </a>
+           
+          <ul>
+            <li>
+              Shows how to use conditional execution and exit handlers. 
+              <a
+                class="link"
+                href="https://github.com/kubeflow/pipelines/tree/master/samples/tutorials/DSL%20-%20Control%20structures"
+                rel="noopener"
+                target="_blank"
+              >
+                source code
+              </a>
+            </li>
+          </ul>
+        </li>
+      </ul>
+      <p>
+        Want to learn more? 
+        <a
+          class="link"
+          href="https://www.kubeflow.org/docs/pipelines/tutorials/"
+          rel="noopener"
+          target="_blank"
+        >
+          Learn from sample and tutorial pipelines.
+        </a>
+      </p>
+    </div>
+  </div>
+</div>
+`;
+
+exports[`GettingStarted page renders documentation with pipeline deep link after querying demo pipelines 1`] = `
+Array [
+  Array [
+    undefined,
+    10,
+    undefined,
+    "%7B%22predicates%22%3A%5B%7B%22key%22%3A%22name%22%2C%22op%22%3A%22EQUALS%22%2C%22string_value%22%3A%22%5BDemo%5D%20XGBoost%20-%20Iterative%20model%20training%22%7D%5D%7D",
+  ],
+  Array [
+    undefined,
+    10,
+    undefined,
+    "%7B%22predicates%22%3A%5B%7B%22key%22%3A%22name%22%2C%22op%22%3A%22EQUALS%22%2C%22string_value%22%3A%22%5BDemo%5D%20TFX%20-%20Taxi%20tip%20prediction%20model%20trainer%22%7D%5D%7D",
+  ],
+  Array [
+    undefined,
+    10,
+    undefined,
+    "%7B%22predicates%22%3A%5B%7B%22key%22%3A%22name%22%2C%22op%22%3A%22EQUALS%22%2C%22string_value%22%3A%22%5BDemo%5D%20TFX%20-%20Iris%20classification%20pipeline%22%7D%5D%7D",
+  ],
+  Array [
+    undefined,
+    10,
+    undefined,
+    "%7B%22predicates%22%3A%5B%7B%22key%22%3A%22name%22%2C%22op%22%3A%22EQUALS%22%2C%22string_value%22%3A%22%5BTutorial%5D%20Data%20passing%20in%20python%20components%22%7D%5D%7D",
+  ],
+]
+`;