예제 #1
0
    def from_v1_component_spec(
            cls,
            v1_component_spec: v1_structures.ComponentSpec) -> 'ComponentSpec':
        """Converts V1 ComponentSpec to V2 ComponentSpec.

        Args:
            v1_component_spec: The V1 ComponentSpec.

        Returns:
            Component spec in the form of V2 ComponentSpec.

        Raises:
            ValueError: If implementation is not found.
            TypeError: if any argument is neither a str nor Dict.
        """
        component_dict = v1_component_spec.to_dict()
        if component_dict.get('implementation') is None:
            raise ValueError('Implementation field not found')
        if 'container' not in component_dict.get('implementation'):
            raise NotImplementedError

        def _transform_arg(
                arg: Union[str, Dict[str, str]]) -> ValidCommandArgs:
            if isinstance(arg, str):
                return arg
            if 'inputValue' in arg:
                return InputValuePlaceholder(
                    input_name=utils.sanitize_input_name(arg['inputValue']))
            if 'inputPath' in arg:
                return InputPathPlaceholder(
                    input_name=utils.sanitize_input_name(arg['inputPath']))
            if 'inputUri' in arg:
                return InputUriPlaceholder(
                    input_name=utils.sanitize_input_name(arg['inputUri']))
            if 'outputPath' in arg:
                return OutputPathPlaceholder(
                    output_name=utils.sanitize_input_name(arg['outputPath']))
            if 'outputUri' in arg:
                return OutputUriPlaceholder(
                    output_name=utils.sanitize_input_name(arg['outputUri']))
            if 'if' in arg:
                if_placeholder_values = arg['if']
                if_placeholder_values_then = list(
                    if_placeholder_values['then'])
                try:
                    if_placeholder_values_else = list(
                        if_placeholder_values['else'])
                except KeyError:
                    if_placeholder_values_else = []

                IfPresentPlaceholderStructure.update_forward_refs()
                return IfPresentPlaceholder(
                    if_structure=IfPresentPlaceholderStructure(
                        input_name=utils.sanitize_input_name(
                            if_placeholder_values['cond']['isPresent']),
                        then=list(
                            _transform_arg(val)
                            for val in if_placeholder_values_then),
                        otherwise=list(
                            _transform_arg(val)
                            for val in if_placeholder_values_else)))
            if 'concat' in arg:
                ConcatPlaceholder.update_forward_refs()

                return ConcatPlaceholder(concat=list(
                    _transform_arg(val) for val in arg['concat']))
            raise ValueError(
                f'Unexpected command/argument type: "{arg}" of type "{type(arg)}".'
            )

        implementation = component_dict['implementation']['container']
        implementation['commands'] = [
            _transform_arg(command)
            for command in implementation.pop('command', [])
        ]
        implementation['arguments'] = [
            _transform_arg(command)
            for command in implementation.pop('args', [])
        ]
        implementation['env'] = {
            key: _transform_arg(command)
            for key, command in implementation.pop('env', {}).items()
        }

        container_spec = ContainerSpec(image=implementation['image'])

        # Workaround for https://github.com/samuelcolvin/pydantic/issues/2079
        def _copy_model(obj):
            if isinstance(obj, BaseModel):
                return obj.copy(deep=True)
            return obj

        # Must assign these after the constructor call, otherwise it won't work.
        if implementation['commands']:
            container_spec.commands = [
                _copy_model(cmd) for cmd in implementation['commands']
            ]
        if implementation['arguments']:
            container_spec.arguments = [
                _copy_model(arg) for arg in implementation['arguments']
            ]
        if implementation['env']:
            container_spec.env = {
                k: _copy_model(v)
                for k, v in implementation['env']
            }

        return ComponentSpec(
            name=component_dict.get('name', 'name'),
            description=component_dict.get('description'),
            implementation=Implementation(container=container_spec),
            inputs={
                utils.sanitize_input_name(spec['name']):
                InputSpec(type=spec.get('type', 'Artifact'),
                          default=spec.get('default', None))
                for spec in component_dict.get('inputs', [])
            },
            outputs={
                utils.sanitize_input_name(spec['name']):
                OutputSpec(type=spec.get('type', 'Artifact'))
                for spec in component_dict.get('outputs', [])
            })
예제 #2
0
 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)