chore(sdk): Support loading v1 yaml with {executorInput: } placeholder (#7870)
* Support {executorInput: } placeholder * merge * use single quotes for consistency
This commit is contained in:
parent
e3fc7cd365
commit
f84b51e72d
|
@ -21,6 +21,7 @@ import warnings
|
|||
from typing import Callable, List, Optional, Tuple
|
||||
|
||||
import docstring_parser
|
||||
from kfp.components import placeholders
|
||||
from kfp.components import python_component
|
||||
from kfp.components import structures
|
||||
from kfp.components.types import artifact_types
|
||||
|
@ -310,9 +311,6 @@ def extract_component_interface(func: Callable) -> structures.ComponentSpec:
|
|||
return component_spec
|
||||
|
||||
|
||||
EXECUTOR_INPUT_PLACEHOLDER = "{{$}}"
|
||||
|
||||
|
||||
def _get_command_and_args_for_lightweight_component(
|
||||
func: Callable) -> Tuple[List[str], List[str]]:
|
||||
imports_source = [
|
||||
|
@ -344,7 +342,7 @@ def _get_command_and_args_for_lightweight_component(
|
|||
|
||||
args = [
|
||||
'--executor_input',
|
||||
EXECUTOR_INPUT_PLACEHOLDER,
|
||||
placeholders.ExecutorInputPlaceholder().to_placeholder_string(),
|
||||
'--function_to_execute',
|
||||
func.__name__,
|
||||
]
|
||||
|
@ -362,7 +360,7 @@ def _get_command_and_args_for_containerized_component(
|
|||
|
||||
args = [
|
||||
'--executor_input',
|
||||
EXECUTOR_INPUT_PLACEHOLDER,
|
||||
placeholders.ExecutorInputPlaceholder().to_placeholder_string(),
|
||||
'--function_to_execute',
|
||||
function_name,
|
||||
]
|
||||
|
|
|
@ -146,6 +146,16 @@ class RegexPlaceholderSerializationMixin(Placeholder):
|
|||
return self._TO_PLACEHOLDER.format(**self.to_dict())
|
||||
|
||||
|
||||
class ExecutorInputPlaceholder(base_model.BaseModel,
|
||||
RegexPlaceholderSerializationMixin):
|
||||
"""Class that represents executor input placeholder."""
|
||||
_TO_PLACEHOLDER = '{{$}}'
|
||||
_FROM_PLACEHOLDER = re.compile(r'\{\{\$\}\}')
|
||||
|
||||
def to_placeholder_string(self) -> str:
|
||||
return self._TO_PLACEHOLDER
|
||||
|
||||
|
||||
class InputValuePlaceholder(base_model.BaseModel,
|
||||
RegexPlaceholderSerializationMixin):
|
||||
"""Class that holds an input value placeholder.
|
||||
|
@ -236,10 +246,11 @@ class OutputUriPlaceholder(base_model.BaseModel,
|
|||
)
|
||||
|
||||
|
||||
CommandLineElement = Union[str, InputValuePlaceholder, InputPathPlaceholder,
|
||||
InputUriPlaceholder, OutputParameterPlaceholder,
|
||||
OutputPathPlaceholder, OutputUriPlaceholder,
|
||||
'IfPresentPlaceholder', 'ConcatPlaceholder']
|
||||
CommandLineElement = Union[str, ExecutorInputPlaceholder, InputValuePlaceholder,
|
||||
InputPathPlaceholder, InputUriPlaceholder,
|
||||
OutputParameterPlaceholder, OutputPathPlaceholder,
|
||||
OutputUriPlaceholder, 'IfPresentPlaceholder',
|
||||
'ConcatPlaceholder']
|
||||
|
||||
|
||||
class ConcatPlaceholder(base_model.BaseModel, Placeholder):
|
||||
|
|
|
@ -20,6 +20,21 @@ from kfp.components import placeholders
|
|||
from kfp.components import structures
|
||||
|
||||
|
||||
class TestExecutorInputPlaceholder(parameterized.TestCase):
|
||||
|
||||
@parameterized.parameters([
|
||||
('{{$}}', placeholders.ExecutorInputPlaceholder()),
|
||||
])
|
||||
def test_to_from_placeholder(
|
||||
self, placeholder_string: str,
|
||||
placeholder_obj: placeholders.ExecutorInputPlaceholder):
|
||||
self.assertEqual(
|
||||
placeholders.ExecutorInputPlaceholder.from_placeholder_string(
|
||||
placeholder_string), placeholder_obj)
|
||||
self.assertEqual(placeholder_obj.to_placeholder_string(),
|
||||
placeholder_string)
|
||||
|
||||
|
||||
class TestInputValuePlaceholder(parameterized.TestCase):
|
||||
|
||||
@parameterized.parameters([
|
||||
|
|
|
@ -412,6 +412,9 @@ def convert_str_or_dict_to_placeholder(
|
|||
convert_str_or_dict_to_placeholder(e) for e in element['concat']
|
||||
])
|
||||
|
||||
elif first_key == 'executorInput':
|
||||
return placeholders.ExecutorInputPlaceholder()
|
||||
|
||||
else:
|
||||
raise TypeError(
|
||||
f'Unexpected command/argument type: "{element}" of type "{type(element)}".'
|
||||
|
@ -459,7 +462,8 @@ def _check_valid_placeholder_reference(
|
|||
for placeholder in placeholder.items:
|
||||
_check_valid_placeholder_reference(valid_inputs, valid_outputs,
|
||||
placeholder)
|
||||
elif not isinstance(placeholder, str):
|
||||
elif not isinstance(placeholder, placeholders.ExecutorInputPlaceholder
|
||||
) and not isinstance(placeholder, str):
|
||||
raise TypeError(
|
||||
f'Unexpected argument "{placeholder}" of type {type(placeholder)}.')
|
||||
|
||||
|
|
|
@ -145,6 +145,43 @@ COMPONENT_SPEC_NESTED_PLACEHOLDER = structures.ComponentSpec(
|
|||
inputs={'input_prefix': structures.InputSpec(type='String')},
|
||||
)
|
||||
|
||||
V1_YAML_EXECUTOR_INPUT_PLACEHOLDER = textwrap.dedent("""\
|
||||
name: component_executor_input
|
||||
inputs:
|
||||
- {name: input, type: String}
|
||||
implementation:
|
||||
container:
|
||||
image: alpine
|
||||
command:
|
||||
- python
|
||||
- -m
|
||||
- kfp.containers.entrypoint
|
||||
args:
|
||||
- --executor_input
|
||||
- {executorInput: null}
|
||||
- --function_name
|
||||
- test_function
|
||||
""")
|
||||
|
||||
COMPONENT_SPEC_EXECUTOR_INPUT_PLACEHOLDER = structures.ComponentSpec(
|
||||
name='component_executor_input',
|
||||
implementation=structures.Implementation(
|
||||
container=structures.ContainerSpec(
|
||||
image='alpine',
|
||||
command=[
|
||||
'python',
|
||||
'-m',
|
||||
'kfp.containers.entrypoint',
|
||||
],
|
||||
args=[
|
||||
'--executor_input',
|
||||
placeholders.ExecutorInputPlaceholder(),
|
||||
'--function_name',
|
||||
'test_function',
|
||||
])),
|
||||
inputs={'input': structures.InputSpec(type='String')},
|
||||
)
|
||||
|
||||
|
||||
class StructuresTest(parameterized.TestCase):
|
||||
|
||||
|
@ -315,6 +352,10 @@ sdkVersion: kfp-2.0.0-alpha.2
|
|||
'yaml': V1_YAML_NESTED_PLACEHOLDER,
|
||||
'expected_component': COMPONENT_SPEC_NESTED_PLACEHOLDER
|
||||
},
|
||||
{
|
||||
'yaml': V1_YAML_EXECUTOR_INPUT_PLACEHOLDER,
|
||||
'expected_component': COMPONENT_SPEC_EXECUTOR_INPUT_PLACEHOLDER
|
||||
},
|
||||
)
|
||||
def test_component_spec_placeholder_load_from_v2_component_yaml(
|
||||
self, yaml, expected_component):
|
||||
|
|
Loading…
Reference in New Issue