def test_handle_constructing_graph_component(self):
        task1 = TaskSpec(component_ref=ComponentReference(name='comp 1'), arguments={'in1 1': 11})
        task2 = TaskSpec(component_ref=ComponentReference(name='comp 2'), arguments={'in2 1': 21, 'in2 2': TaskOutputArgument.construct(task_id='task 1', output_name='out1 1')})
        task3 = TaskSpec(component_ref=ComponentReference(name='comp 3'), arguments={'in3 1': TaskOutputArgument.construct(task_id='task 2', output_name='out2 1'), 'in3 2': GraphInputReference(input_name='graph in 1').as_argument()})

        graph_component1 = ComponentSpec(
            inputs=[
                InputSpec(name='graph in 1'),
                InputSpec(name='graph in 2'),
            ],
            outputs=[
                OutputSpec(name='graph out 1'),
                OutputSpec(name='graph out 2'),
            ],
            implementation=GraphImplementation(graph=GraphSpec(
                tasks={
                    'task 1': task1,
                    'task 2': task2,
                    'task 3': task3,
                },
                output_values={
                    'graph out 1': TaskOutputArgument.construct(task_id='task 3', output_name='out3 1'),
                    'graph out 2': TaskOutputArgument.construct(task_id='task 1', output_name='out1 2'),
                }
            ))
        )
示例#2
0
    def test_component_metadata(self):
        """Test component decorator metadata."""
        class MockContainerOp:
            def _set_metadata(self, component_meta):
                self._metadata = component_meta

        @component
        def componentA(
            a: {'ArtifactA': {
                'file_type': 'csv'
            }},
            b: Integer() = 12,
            c: {'ArtifactB': {
                'path_type': 'file',
                'file_type': 'tsv'
            }} = 'gs://hello/world'
        ) -> {
                'model': Integer()
        }:
            return MockContainerOp()

        containerOp = componentA(1, 2, c=3)

        golden_meta = ComponentSpec(name='ComponentA', inputs=[], outputs=[])
        golden_meta.inputs.append(
            InputSpec(name='a', type={'ArtifactA': {
                'file_type': 'csv'
            }}))
        golden_meta.inputs.append(
            InputSpec(name='b',
                      type={
                          'Integer': {
                              'openapi_schema_validator': {
                                  "type": "integer"
                              }
                          }
                      },
                      default="12",
                      optional=True))
        golden_meta.inputs.append(
            InputSpec(
                name='c',
                type={'ArtifactB': {
                    'path_type': 'file',
                    'file_type': 'tsv'
                }},
                default='gs://hello/world',
                optional=True))
        golden_meta.outputs.append(
            OutputSpec(name='model',
                       type={
                           'Integer': {
                               'openapi_schema_validator': {
                                   "type": "integer"
                               }
                           }
                       }))

        self.assertEqual(containerOp._metadata, golden_meta)
示例#3
0
    def test_extract_component_interface(self):
        from typing import NamedTuple

        def my_func(  # noqa: F722
            required_param,
            int_param: int = 42,
            float_param: float = 3.14,
            str_param: str = 'string',
            bool_param: bool = True,
            none_param=None,
            custom_type_param: 'Custom type' = None,
        ) -> NamedTuple(
                'DummyName',
            [
                #('required_param',), # All typing.NamedTuple fields must have types
                ('int_param', int),
                ('float_param', float),
                ('str_param', str),
                ('bool_param', bool),
                #('custom_type_param', 'Custom type'), #SyntaxError: Forward reference must be an expression -- got 'Custom type'
                ('custom_type_param', 'CustomType'),
            ]):
            '''Function docstring'''
            pass

        component_spec = comp._python_op._extract_component_interface(my_func)

        from kfp.components._structures import InputSpec, OutputSpec
        self.assertEqual(
            component_spec.inputs,
            [
                InputSpec(name='required_param'),
                InputSpec(name='int_param',
                          type='Integer',
                          default='42',
                          optional=True),
                InputSpec(name='float_param',
                          type='Float',
                          default='3.14',
                          optional=True),
                InputSpec(name='str_param',
                          type='String',
                          default='string',
                          optional=True),
                InputSpec(name='bool_param',
                          type='Boolean',
                          default='True',
                          optional=True),
                InputSpec(name='none_param',
                          optional=True),  # No default='None'
                InputSpec(name='custom_type_param',
                          type='Custom type',
                          optional=True),
            ])
        self.assertEqual(
            component_spec.outputs,
            [
                OutputSpec(name='int_param', type='Integer'),
                OutputSpec(name='float_param', type='Float'),
                OutputSpec(name='str_param', type='String'),
                OutputSpec(name='bool_param', type='Boolean'),
                #OutputSpec(name='custom_type_param', type='Custom type', default='None'),
                OutputSpec(name='custom_type_param', type='CustomType'),
            ])

        self.maxDiff = None
        self.assertDictEqual(
            component_spec.to_dict(),
            {
                'name':
                'My func',
                'description':
                'Function docstring\n',
                'inputs': [
                    {
                        'name': 'required_param'
                    },
                    {
                        'name': 'int_param',
                        'type': 'Integer',
                        'default': '42',
                        'optional': True
                    },
                    {
                        'name': 'float_param',
                        'type': 'Float',
                        'default': '3.14',
                        'optional': True
                    },
                    {
                        'name': 'str_param',
                        'type': 'String',
                        'default': 'string',
                        'optional': True
                    },
                    {
                        'name': 'bool_param',
                        'type': 'Boolean',
                        'default': 'True',
                        'optional': True
                    },
                    {
                        'name': 'none_param',
                        'optional': True
                    },  # No default='None'
                    {
                        'name': 'custom_type_param',
                        'type': 'Custom type',
                        'optional': True
                    },
                ],
                'outputs': [
                    {
                        'name': 'int_param',
                        'type': 'Integer'
                    },
                    {
                        'name': 'float_param',
                        'type': 'Float'
                    },
                    {
                        'name': 'str_param',
                        'type': 'String'
                    },
                    {
                        'name': 'bool_param',
                        'type': 'Boolean'
                    },
                    {
                        'name': 'custom_type_param',
                        'type': 'CustomType'
                    },
                ]
            })
 def test_to_dict(self):
     component_meta = ComponentSpec(
         name='foobar',
         description='foobar example',
         inputs=[
             InputSpec(name='input1',
                       description='input1 desc',
                       type={
                           'GCSPath': {
                               'bucket_type': 'directory',
                               'file_type': 'csv'
                           }
                       },
                       default='default1'),
             InputSpec(name='input2',
                       description='input2 desc',
                       type={
                           'TFModel': {
                               'input_data': 'tensor',
                               'version': '1.8.0'
                           }
                       },
                       default='default2'),
             InputSpec(name='input3',
                       description='input3 desc',
                       type='Integer',
                       default='default3'),
         ],
         outputs=[
             OutputSpec(
                 name='output1',
                 description='output1 desc',
                 type={'Schema': {
                     'file_type': 'tsv'
                 }},
             )
         ])
     golden_meta = {
         'name':
         'foobar',
         'description':
         'foobar example',
         'inputs': [{
             'name': 'input1',
             'description': 'input1 desc',
             'type': {
                 'GCSPath': {
                     'bucket_type': 'directory',
                     'file_type': 'csv'
                 }
             },
             'default': 'default1'
         }, {
             'name': 'input2',
             'description': 'input2 desc',
             'type': {
                 'TFModel': {
                     'input_data': 'tensor',
                     'version': '1.8.0'
                 }
             },
             'default': 'default2'
         }, {
             'name': 'input3',
             'description': 'input3 desc',
             'type': 'Integer',
             'default': 'default3'
         }],
         'outputs': [{
             'name': 'output1',
             'description': 'output1 desc',
             'type': {
                 'Schema': {
                     'file_type': 'tsv'
                 }
             },
         }]
     }
     self.assertEqual(component_meta.to_dict(), golden_meta)