Skip to content

Commit

Permalink
chore(sdk): make kfp v2 hermetic (kubeflow#7428)
Browse files Browse the repository at this point in the history
* move v1 files to v2

* format with yapf

* remove unused imports

* clean up

* update copyright

* move imports to module top level

* apply some pylint changes

* loosen pylintrc

* remove v2_yaml_utils.py
  • Loading branch information
connor-mccarthy authored and abaland committed May 29, 2022
1 parent f7b7a00 commit 94eaa87
Show file tree
Hide file tree
Showing 7 changed files with 1,318 additions and 29 deletions.
15 changes: 6 additions & 9 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ confidence=
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
# TODO(numerology): enable missing-module-docstring after finish the effort.
disable=missing-module-docstring, unspecified-encoding
disable=missing-module-docstring, unspecified-encoding, missing-function-docstring


[REPORTS]
Expand Down Expand Up @@ -99,10 +99,6 @@ evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / stateme

[BASIC]

# Good variable names which should always be accepted, separated by a comma
# s3 is whitelisted for its special meaning.
good-names=i,j,k,f,ex,Run,_,s3

# Bad variable names which should always be refused, separated by a comma
bad-names=foo,bar,baz,toto,tutu,tata

Expand All @@ -117,9 +113,6 @@ include-naming-hint=no
# to this list to register other decorators that produce valid properties.
property-classes=abc.abstractproperty

# Regular expression matching correct variable names
variable-rgx=[a-z_][a-z0-9_]{2,30}$

# Naming hint for variable names
variable-name-hint=[a-z_][a-z0-9_]{2,30}$

Expand Down Expand Up @@ -185,6 +178,7 @@ no-docstring-rgx=^test_
# ones are exempt.
docstring-min-length=-1

disable=invalid-name

[ELIF]

Expand Down Expand Up @@ -296,6 +290,7 @@ generated-members=set_shape,np.float32
# produce valid context managers.
contextmanager-decorators=contextlib.contextmanager

disable=redefined-builtin

[VARIABLES]

Expand All @@ -318,6 +313,8 @@ callbacks=cb_,_cb
# builtins.
redefining-builtins-modules=six.moves,future.builtins

disable=unused-argument


[CLASSES]

Expand All @@ -332,7 +329,7 @@ valid-metaclass-classmethod-first-arg=mcs

# List of member names, which should be excluded from the protected access
# warning.
exclude-protected=_asdict,_fields,_replace,_source,_make
disable=protected-access


[DESIGN]
Expand Down
8 changes: 4 additions & 4 deletions sdk/python/kfp/components/structures.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2021 The Kubeflow Authors
# Copyright 2021-2022 The Kubeflow Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -21,8 +21,8 @@
import pydantic
import yaml
from kfp.components import utils
from kfp.deprecated.components import _components
from kfp.deprecated.components import structures as v1_structures
from kfp.components import v1_components
from kfp.components import v1_structures


class BaseModel(pydantic.BaseModel):
Expand Down Expand Up @@ -587,7 +587,7 @@ def load_from_component_yaml(cls, component_yaml: str) -> 'ComponentSpec':
try:
return ComponentSpec.parse_obj(json_component)
except (pydantic.ValidationError, AttributeError):
v1_component = _components._load_component_spec_from_component_text(
v1_component = v1_components._load_component_spec_from_component_text(
component_yaml)
return cls.from_v1_component_spec(v1_component)

Expand Down
14 changes: 7 additions & 7 deletions sdk/python/kfp/components/types/type_utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2020 The Kubeflow Authors
# Copyright 2020-2022 The Kubeflow Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -12,17 +12,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""Utilities for component I/O type mapping."""
import json
import inspect
import re
import warnings
from typing import Dict, List, Optional, Type, Union
from typing import List, Optional, Type, Union

from kfp.deprecated.components import structures
from kfp.pipeline_spec import pipeline_spec_pb2
import kfp
from kfp.components import task_final_status
from kfp.components import v1_structures
from kfp.components.types import artifact_types
from kfp.components.types import type_annotations
from kfp.pipeline_spec import pipeline_spec_pb2

PARAMETER_TYPES = Union[str, int, float, bool, dict, list]

Expand Down Expand Up @@ -179,7 +179,7 @@ def get_parameter_type_field_name(type_name: Optional[str]) -> str:

def get_input_artifact_type_schema(
input_name: str,
inputs: List[structures.InputSpec],
inputs: List[v1_structures.InputSpec],
) -> Optional[str]:
"""Find the input artifact type by input name.
Expand Down Expand Up @@ -249,7 +249,7 @@ def verify_type_compatibility(
error_text = error_message_prefix + (
'Argument type "{}" is incompatible with the input type "{}"'
).format(str(given_type), str(expected_type))
import kfp.deprecated as kfp

if kfp.TYPE_CHECK:
raise InconsistentTypeException(error_text)
else:
Expand Down
17 changes: 8 additions & 9 deletions sdk/python/kfp/components/types/type_utils_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2020 The Kubeflow Authors
# Copyright 2020-2022 The Kubeflow Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -11,16 +11,15 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import sys
import unittest
from typing import Any, Dict, List, Union

from absl.testing import parameterized
from kfp.deprecated.components import structures
from kfp.pipeline_spec import pipeline_spec_pb2 as pb
from kfp.components.types import artifact_types, type_utils
from kfp.components import v1_structures
from kfp.components.types import artifact_types
from kfp.components.types import type_utils
from kfp.components.types.type_utils import InconsistentTypeException
from kfp.pipeline_spec import pipeline_spec_pb2 as pb

_PARAMETER_TYPES = [
'String',
Expand Down Expand Up @@ -302,9 +301,9 @@ def test_get_parameter_type_invalid(self):

def test_get_input_artifact_type_schema(self):
input_specs = [
structures.InputSpec(name='input1', type='String'),
structures.InputSpec(name='input2', type='Model'),
structures.InputSpec(name='input3', type=None),
v1_structures.InputSpec(name='input1', type='String'),
v1_structures.InputSpec(name='input2', type='Model'),
v1_structures.InputSpec(name='input3', type=None),
]
# input not found.
with self.assertRaises(AssertionError) as cm:
Expand Down
44 changes: 44 additions & 0 deletions sdk/python/kfp/components/v1_components.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Copyright 2018-2022 The Kubeflow Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import hashlib
import warnings

import yaml
from kfp.components import v1_structures


def _load_component_spec_from_component_text(
text) -> v1_structures.ComponentSpec:
component_dict = yaml.safe_load(text)
component_spec = v1_structures.ComponentSpec.from_dict(component_dict)

if isinstance(component_spec.implementation,
v1_structures.ContainerImplementation) and (
component_spec.implementation.container.command is None):
warnings.warn(
'Container component must specify command to be compatible with KFP '
'v2 compatible mode and emissary executor, which will be the default'
' executor for KFP v2.'
'https://www.kubeflow.org/docs/components/pipelines/installation/choose-executor/',
category=FutureWarning,
)

# Calculating hash digest for the component
data = text if isinstance(text, bytes) else text.encode('utf-8')
data = data.replace(b'\r\n', b'\n') # Normalizing line endings
digest = hashlib.sha256(data).hexdigest()
component_spec._digest = digest

return component_spec
Loading

0 comments on commit 94eaa87

Please sign in to comment.