Esempio n. 1
0
def resume_run(
    run: BaseRun,
    user_id: int = None,
    name: str = None,
    description: str = None,
    content: str = None,
    readme: str = None,
    tags: List[str] = None,
) -> BaseRun:
    op_spec = V1Operation.read(run.raw_content)
    compiled_operation, instance = operations.init_run(
        project_id=run.project_id,
        user_id=user_id or run.user_id,
        name=name or run.name,
        description=description or run.description,
        readme=readme or run.readme,
        op_spec=op_spec,
        tags=tags or run.tags,
        override=content,
    )

    run.user_id = instance.user_id
    run.name = instance.name
    run.description = instance.description
    run.readme = instance.readme
    run.content = instance.content
    run.raw_content = instance.raw_content
    run.tags = instance.tags
    run.save()
    new_run_status(
        run,
        condition=V1StatusCondition.get_condition(type=V1Statuses.RESUMING,
                                                  status=True),
    )
    return run
Esempio n. 2
0
def get_ops_from_suggestions(
    content: str,
    compiled_operation: V1CompiledOperation,
    suggestions: List[Dict],
) -> List[V1Operation]:
    ops = []
    for suggestion in suggestions:
        params = {
            k: V1Param(value=Parser.parse_expression(v, {}))
            for (k, v) in suggestion.items()
        }
        op_spec = V1Operation.read(content)
        op_spec.matrix = None
        op_spec.conditions = None
        op_spec.schedule = None
        op_spec.events = None
        op_spec.dependencies = None
        op_spec.trigger = None
        op_spec.skip_on_upstream_skip = None
        op_spec.cache = compiled_operation.cache
        op_spec.queue = compiled_operation.queue
        op_spec.params = params
        op_spec.component.inputs = compiled_operation.inputs
        op_spec.component.outputs = compiled_operation.outputs
        op_spec.component.contexts = compiled_operation.contexts
        ops.append(op_spec)

    return ops
Esempio n. 3
0
    def test_patch_pre_merge_full_values_with_empty_preset(self):
        operation = self.get_full_operation()
        tmp_operation = self.get_full_operation()
        result = tmp_operation.patch(V1Operation(is_preset=True),
                                     strategy=V1PatchStrategy.PRE_MERGE)
        assert result.to_dict() == operation.to_dict()

        tmp_operation = self.get_full_operation()
        preset = self.get_empty_preset()
        result = tmp_operation.patch(preset,
                                     strategy=V1PatchStrategy.PRE_MERGE)
        result_dict = result.to_dict()
        # Since there's no component to validate the runPatch section it stays the same
        assert result_dict == operation.to_dict()

        operation = self.get_full_operation_with_component()
        tmp_operation = self.get_full_operation_with_component()
        preset = self.get_empty_preset()
        result = tmp_operation.patch(preset,
                                     strategy=V1PatchStrategy.PRE_MERGE)
        result_dict = result.to_dict()
        assert result_dict["runPatch"]["container"].pop(
            "name") == MAIN_JOB_CONTAINER
        # Run patch was validated and merged
        assert result_dict == operation.to_dict()
Esempio n. 4
0
def clone_run(
    run: BaseRun,
    cloning_kind: str,
    user_id: int = None,
    name: str = None,
    description: str = None,
    content: str = None,
    readme: str = None,
    tags: List[int] = None,
) -> BaseRun:
    op_spec = V1Operation.read(run.raw_content)
    compiled_operation, instance = operations.init_run(
        project_id=run.project_id,
        user_id=user_id or run.user_id,
        name=name or run.name,
        description=description or run.description,
        readme=readme or run.readme,
        op_spec=op_spec,
        original_id=run.id,
        original_uuid=run.uuid.hex,
        cloning_kind=cloning_kind,
        tags=tags or run.tags,
        override=content,
        override_post=True,
    )
    instance.save()
    return instance
Esempio n. 5
0
def collect_references(config: V1Operation, path_context: str = None):
    if config.has_component_reference:
        return config
    elif config.has_hub_reference:
        component = ConfigSpec.get_from(config.hub_ref, "hub").read()
    elif config.has_url_reference:
        component = ConfigSpec.get_from(config.url_ref, "url").read()
    elif config.has_path_reference:
        path_ref = config.path_ref
        if path_context:
            path_ref = os.path.join(
                os.path.dirname(os.path.abspath(path_context)), path_ref)
        component = ConfigSpec.get_from(path_ref).read()
    else:
        raise PolyaxonfileError("Operation found without component")

    component = get_specification(data=component)
    if component.kind != kinds.COMPONENT:
        if config.has_url_reference:
            ref_type = "Url ref"
            ref = config.url_ref
        else:
            ref_type = "Path ref"
            ref = config.path_ref
        raise PolyaxonfileError(
            "the reference ({}) `{}` is of kind `{}`, it should be a `{}`".
            format(ref, ref_type, component.kind, kinds.COMPONENT))
    config.component = component
    if component.is_dag_run:
        component.run.collect_components()
    return config
Esempio n. 6
0
    def test_patch_replace_full_values_with_empty_preset(self):
        operation = self.get_full_operation()
        tmp_operation = self.get_full_operation()
        result = tmp_operation.patch(
            V1Operation(is_preset=True), strategy=V1PatchStrategy.REPLACE
        )
        assert result.to_dict() == operation.to_dict()

        tmp_operation = self.get_full_operation()
        preset = self.get_empty_preset()
        result = tmp_operation.patch(preset, strategy=V1PatchStrategy.REPLACE)
        result_dict = result.to_dict()
        assert result_dict.pop("hubRef") == operation.hub_ref
        assert result_dict.pop("name") == operation.name
        assert result_dict.pop("trigger") == operation.trigger
        assert result_dict.pop("conditions") == operation.conditions
        assert result_dict.pop("skipOnUpstreamSkip") == operation.skip_on_upstream_skip
        assert result_dict.pop("schedule") == operation.schedule.to_dict()
        assert result_dict.pop("conditions", None) is None
        assert result_dict.pop("matrix") == operation.matrix.to_dict()
        assert result_dict.pop("cache") == operation.cache.to_dict()
        assert result_dict.pop("plugins") == operation.plugins.to_dict()
        assert result_dict.pop("termination") == operation.termination.to_dict()
        expected = preset.to_dict()
        expected.pop("isPreset")
        expected.pop("cache")
        expected.pop("plugins")
        expected.pop("termination")
        assert result_dict == expected
Esempio n. 7
0
def get_ops_from_suggestions(
    content: str,
    compiled_operation: V1CompiledOperation,
    suggestions: List[Dict],
) -> List[V1Operation]:
    def has_param(k: str):
        if not compiled_operation.matrix:
            return None
        return not compiled_operation.matrix.has_param(k)

    op_content = V1Operation.read(content)
    for suggestion in suggestions:
        params = {
            k: V1Param(value=Parser.parse_expression(v, {}),
                       context_only=has_param(k))
            for (k, v) in suggestion.items()
        }
        op_spec = copy.deepcopy(op_content)
        op_spec.matrix = None
        op_spec.conditions = None
        op_spec.schedule = None
        op_spec.events = None
        op_spec.dependencies = None
        op_spec.trigger = None
        op_spec.skip_on_upstream_skip = None
        op_spec.cache = compiled_operation.cache
        op_spec.queue = compiled_operation.queue
        op_spec.params = params
        op_spec.component.inputs = compiled_operation.inputs
        op_spec.component.outputs = compiled_operation.outputs
        op_spec.component.contexts = compiled_operation.contexts
        yield op_spec
    def test_op_specification(self):
        config_dict = {
            "version": 1.1,
            "kind": "operation",
            "name": "foo",
            "description": "a description",
            "tags": ["value"],
            "params": {"param1": {"value": "foo"}, "param2": {"value": "bar"}},
            "trigger": "all_succeeded",
            "component": {
                "name": "build-template",
                "tags": ["kaniko"],
                "run": {
                    "kind": V1RunKind.JOB,
                    "container": {"image": "test"},
                    "init": [
                        {
                            "container": {
                                "name": "polyaxon-init",
                                "image": "foo",
                                "args": "dev",
                            }
                        }
                    ],
                    "sidecars": [{"name": "foo", "image": "foo", "args": "dev"}],
                },
            },
        }
        op_config = V1Operation.read(values=config_dict)

        run_config = OperationSpecification.compile_operation(op_config)
        assert run_config.name == "foo"
        assert run_config.description == "a description"
        assert run_config.tags == ["kaniko", "value"]
        assert [
            {
                "container": {
                    "name": i.container.name,
                    "image": i.container.image,
                    "args": i.container.args,
                }
            }
            for i in run_config.run.init
        ] == [{"container": {"name": "polyaxon-init", "image": "foo", "args": "dev"}}]

        env = {
            "runPatch": {
                "container": {
                    "resources": {
                        "requests": {"gpu": 1, "tpu": 1},
                        "limits": {"gpu": 1, "tpu": 1},
                    }
                }
            }
        }
        run_config = OperationSpecification.compile_operation(op_config, env)
        assert (
            run_config.run.container.resources
            == env["runPatch"]["container"]["resources"]
        )
Esempio n. 9
0
    def test_op_specification_with_override_info(self):
        config_dict = {
            "version": 1.1,
            "kind": "operation",
            "name": "foo",
            "description": "a description",
            "tags": ["value"],
            "params": {"param1": {"value": "foo"}, "param2": {"value": "bar"}},
            "trigger": "all_succeeded",
            "component": {
                "name": "build-template",
                "tags": ["kaniko"],
                "run": {
                    "kind": V1RunKind.JOB,
                    "init": [
                        {
                            "connection": "foo",
                            "container": {
                                "name": "polyaxon-init",
                                "args": "--branch=dev",
                            },
                        }
                    ],
                    "container": {"name": "polyaxon-main", "image": "test"},
                },
            },
        }
        op_config = V1Operation.read(values=config_dict)
        assert op_config.name == "foo"
        assert op_config.description == "a description"
        assert op_config.tags == ["value"]

        run_config = OperationSpecification.compile_operation(op_config)
        assert run_config.name == "foo"
        assert run_config.description == "a description"
        assert run_config.tags == ["value"]
        assert [i.to_light_dict() for i in run_config.run.init] == [
            {
                "connection": "foo",
                "container": {"name": "polyaxon-init", "args": "--branch=dev"},
            }
        ]

        env = {
            "run": {
                "container": {
                    "resources": {
                        "requests": {"gpu": 1, "tpu": 1},
                        "limits": {"gpu": 1, "tpu": 1},
                    }
                }
            }
        }
        run_config = OperationSpecification.compile_operation(op_config, env)
        assert (
            run_config.run.container.resources == env["run"]["container"]["resources"]
        )
Esempio n. 10
0
    def create(
        self,
        name: str = None,
        description: str = None,
        tags: Union[str, Sequence[str]] = None,
        content: Union[str, Dict, V1Operation] = None,
    ):
        """Creates a new run based on the data passed.

        N.B. Create methods are only useful if you want to create a run programmatically,
        if you run a component/operation from the CLI/UI an instance will be created automatically.

        This is a generic create function, you can check other methods for creating runs:
          * from yaml: `create_from_polyaxonfile`
          * from url: `create_from_url`
          * from hub: `create_from_hub`

        > Note that if you don't pass `content`, the creation will pass,
        and the run will be marked as non-managed.

        [Run API](/docs/api/#operation/CreateRun)

        Args:
            name: str, optional, it will override the name in the operation if provided.
            description: str, optional,
                it will override the description in the operation if provided.
            tags: str or List[str], optional, list of tags,
                it will override the tags in the operation if provided.
            content: str or Dict or V1Operation, optional.

        Returns:
            V1Run, run instance from the response.
        """
        is_managed = True
        if not content:
            is_managed = False
        elif not isinstance(content, (str, Mapping, V1Operation)):
            raise PolyaxonClientException(
                "Received an invalid content: {}".format(content)
            )
        if content:
            if isinstance(content, Mapping):
                content = V1Operation.from_dict(content)
            content = (
                content if isinstance(content, str) else content.to_dict(dump=True)
            )
        data = polyaxon_sdk.V1OperationBody(
            name=name,
            description=description,
            tags=tags,
            content=content,
            is_managed=is_managed,
        )
        self._create(data=data, async_req=False)
        self._post_create()
        return self.run_data
Esempio n. 11
0
 def generate_run_data(cls,
                       config: V1Operation,
                       override=None,
                       override_post=True):
     op_config = config.to_light_dict()
     name = None
     if config.component:
         name = config.component.get_name()
     component_config = op_config.pop("component", {})
     if name:
         component_config["name"] = name
     values = [
         {
             "version": config.version
         },
         component_config,
         {
             "kind": kinds.COMPILED_OPERATION
         },
     ]
     op_override = {}
     for field in [
             cls.NAME,
             cls.DESCRIPTION,
             cls.TAGS,
             cls.PROFILE,
             cls.QUEUE,
             cls.CACHE,
             cls.PLUGINS,
             cls.TERMINATION,
             cls.PARALLEL,
             cls.SCHEDULE,
             cls.DEPENDENCIES,
             cls.TRIGGER,
             cls.CONDITIONS,
             cls.SKIP_ON_UPSTREAM_SKIP,
             cls.HUB_REF,
     ]:
         override_field = op_config.get(field)
         if override_field:
             op_override[field] = override_field
     # Patch run
     run_patch = op_config.get(cls.RUN_PATCH)
     if run_patch:
         op_override[cls.RUN] = run_patch
     if override_post:
         if op_override:
             values.append(op_override)
         if override:
             values.append(override)
     else:
         if override:
             values.append(override)
         if op_override:
             values.append(op_override)
     return values
Esempio n. 12
0
def get_tuner(
    name: str,
    container: V1Container,
    matrix: V1Matrix,
    search: V1ParamSearch,
    iteration: int,
    bracket_iteration: int = None,
) -> V1Operation:
    params = {
        "matrix": V1Param(value=matrix.to_dict()),
        "search": V1Param(value=search.to_dict()),
        "iteration": V1Param(value=iteration),
    }
    inputs = [
        V1IO(name="matrix", iotype=types.DICT, is_list=False,
             is_optional=True),
        V1IO(name="search", iotype=types.DICT, is_list=False,
             is_optional=True),
        V1IO(name="iteration",
             iotype=types.INT,
             is_list=False,
             is_optional=True),
    ]
    if bracket_iteration is not None:
        params["bracket_iteration"] = V1Param(value=bracket_iteration)
        inputs.append(
            V1IO(
                name="bracket_iteration",
                iotype=types.INT,
                is_list=False,
                is_optional=True,
            ))
    return V1Operation(
        params=params,
        component=V1Component(
            name=name,
            plugins=V1Plugins(
                auth=True,
                collect_logs=True,
                collect_artifacts=True,
                collect_resources=False,
                sync_statuses=False,
            ),
            inputs=inputs,
            outputs=[
                V1IO(
                    name="suggestions",
                    iotype=types.DICT,
                    is_list=True,
                    is_optional=False,
                ),
            ],
            run=V1Tuner(container=container, ),
        ),
    )
Esempio n. 13
0
    def test_patch_isnull_full_values_with_empty_preset(self):
        operation = self.get_full_operation()
        tmp_operation = self.get_full_operation()
        result = tmp_operation.patch(V1Operation(is_preset=True),
                                     strategy=V1PatchStrategy.ISNULL)
        assert result.to_dict() == operation.to_dict()

        tmp_operation = self.get_full_operation()
        preset = self.get_empty_preset()
        result = tmp_operation.patch(preset, strategy=V1PatchStrategy.ISNULL)
        assert result.to_dict() == operation.to_dict()
Esempio n. 14
0
    def compile_operation(cls,
                          config: V1Operation,
                          override: Dict = None) -> V1CompiledOperation:
        if override:
            preset = OperationSpecification.read(override, is_preset=True)
            config = config.patch(preset, preset.patch_strategy)
        # Patch run
        component = config.component  # type: V1Component
        if config.run_patch:
            component.run = component.run.patch(
                validate_run_patch(config.run_patch, component.run.kind),
                strategy=config.patch_strategy,
            )
        # Gather contexts io
        config_params = config.params or {}
        contexts = [
            V1IO(name=p) for p in config_params
            if config_params[p].context_only
        ]
        patch_compiled = V1CompiledOperation(
            name=config.name,
            description=config.description,
            contexts=contexts,
            tags=config.tags,
            presets=config.presets,
            queue=config.queue,
            cache=config.cache,
            hooks=config.hooks,
            actions=config.actions,
            events=config.events,
            plugins=config.plugins,
            termination=config.termination,
            matrix=config.matrix,
            schedule=config.schedule,
            dependencies=config.dependencies,
            trigger=config.trigger,
            conditions=config.conditions,
            skip_on_upstream_skip=config.skip_on_upstream_skip,
        )

        values = [
            {
                cls.VERSION: config.version
            },
            component.to_dict(),
            {
                cls.KIND: kinds.COMPILED_OPERATION
            },
        ]
        compiled = V1CompiledOperation.read(
            values)  # type: V1CompiledOperation
        return compiled.patch(patch_compiled, strategy=config.patch_strategy)
Esempio n. 15
0
def collect_references(config: V1Operation):
    if config.has_component_reference or config.has_hub_reference:
        return config
    elif config.has_url_reference:
        component = ConfigSpec.get_from(config.url_ref, "url").read()
    elif config.has_path_reference:
        component = ConfigSpec.get_from(config.path_ref).read()
    else:
        raise PolyaxonfileError("Operation found without component")

    component = get_specification(data=component)
    config.component = component
    return config
Esempio n. 16
0
    def create(
        self,
        name: str = None,
        description: str = None,
        tags: Union[str, Sequence[str]] = None,
        content: Union[str, Dict, V1Operation] = None,
    ):
        """Creates a new run based on the data passed.

        This is a generic create function, you can check other methods for creating runs:
          * from yaml
          * from hub
          * from url

        Note that if you don't pass data, the creation will pass,
        and the run will be marked as non-managed.

        [Run API](/docs/api/#operation/CreateRun)

        Args:
            name: str, optional, name
                note it will override the name in the operation if available.
            description: str, optional, description
                note it will override the description in the operation if available.
            tags: str or List[str], optional, list of tags,
                note it will override the tags in the operation if available.
            content: str or Dict or V1Operation, optional.

        Returns:
            V1Run, run instance from the response.
        """
        is_managed = True
        if not content:
            is_managed = False
        elif not isinstance(content, (str, Mapping, V1Operation)):
            raise PolyaxonClientException(
                "Received an invalid content: {}".format(content))
        if content:
            if isinstance(content, Mapping):
                content = V1Operation.from_dict(content)
            content = (content if isinstance(content, str) else
                       content.to_dict(dump=True))
        data = polyaxon_sdk.V1OperationBody(
            name=name,
            description=description,
            tags=tags,
            content=content,
            is_managed=is_managed,
        )
        self._create(data=data, async_req=False)
        self._post_create()
Esempio n. 17
0
def get_tuner(
    name: str,
    container: V1Container,
    matrix: V1Matrix,
    configs: List[Dict],
    metrics: List[float],
    iteration: int,
) -> V1Operation:
    return V1Operation(
        params={
            "configs": V1Param(value=configs),
            "metrics": V1Param(value=metrics),
            "matrix": V1Param(value=matrix),
            "iteration": V1Param(value=iteration),
        },
        termination=V1Termination(max_retries=3),
        component=V1Component(
            name=name,
            plugins=V1Plugins(
                auth=True,
                collect_logs=False,
                collect_artifacts=False,
                collect_resources=False,
                sync_statuses=True,
            ),
            inputs=[
                V1IO(name="configs",
                     iotype=types.DICT,
                     is_list=True,
                     is_optional=False),
                V1IO(name="metrics",
                     iotype=types.FLOAT,
                     is_list=True,
                     is_optional=False),
                V1IO(name="iteration",
                     iotype=types.INT,
                     is_list=True,
                     is_optional=True),
            ],
            outputs=[
                V1IO(
                    name="suggestions",
                    iotype=types.DICT,
                    is_list=True,
                    is_optional=False,
                ),
            ],
            run=V1Tuner(container=container, ),
        ),
    )
Esempio n. 18
0
    def test_patch_isnull_empty_values_with_full_preset(self):
        operation = self.get_empty_operation()
        tmp_operation = self.get_empty_operation()
        result = tmp_operation.patch(V1Operation(is_preset=True),
                                     strategy=V1PatchStrategy.ISNULL)
        assert result.to_dict() == operation.to_dict()

        tmp_operation = self.get_empty_operation()
        preset = self.get_empty_preset()
        result = tmp_operation.patch(preset, strategy=V1PatchStrategy.ISNULL)
        result_dict = result.to_dict()
        assert result_dict.pop("hubRef") == operation.hub_ref
        expected = preset.to_dict()
        expected.pop("isPreset")
        assert result_dict == expected
Esempio n. 19
0
def clone_run(
    run: BaseRun,
    cloning_kind: str,
    user_id: int = None,
    name: str = None,
    description: str = None,
    content: str = None,
    readme: str = None,
    tags: List[int] = None,
    supported_kinds: Set[str] = None,
    **kwargs,
) -> BaseRun:
    op_spec = V1Operation.read(run.raw_content)
    meta_info = kwargs.pop("meta_info", {}) or {}
    original_meta_info = run.meta_info or {}
    original_uuid = run.uuid.hex
    upload_artifacts = original_meta_info.get(META_UPLOAD_ARTIFACTS)
    if upload_artifacts:
        meta_info[META_UPLOAD_ARTIFACTS] = upload_artifacts
    if cloning_kind == V1CloningKind.COPY and META_COPY_ARTIFACTS not in meta_info:
        # Handle default copy mode
        meta_info[META_COPY_ARTIFACTS] = V1ArtifactsType(
            dirs=[original_uuid]).to_dict()
    if META_COPY_ARTIFACTS not in meta_info and upload_artifacts:
        # Handle default copy mode
        meta_info[META_COPY_ARTIFACTS] = V1ArtifactsType(
            dirs=["{}/{}".format(original_uuid, upload_artifacts)]).to_dict()

    compiled_operation, instance = operations.init_run(
        project_id=run.project_id,
        user_id=user_id or run.user_id,
        name=name or run.name,
        description=description or run.description,
        readme=readme or run.readme,
        op_spec=op_spec,
        original_id=run.id,
        original_uuid=original_uuid,
        cloning_kind=cloning_kind,
        tags=tags or run.tags,
        override=content,
        supported_kinds=supported_kinds,
        meta_info=meta_info,
        **kwargs,
    )
    instance.save()
    return instance
Esempio n. 20
0
def get_op_from_schedule(
    content: str,
    compiled_operation: V1CompiledOperation,
) -> V1Operation:
    op_spec = V1Operation.read(content)
    op_spec.conditions = None
    op_spec.schedule = None
    op_spec.events = None
    op_spec.dependencies = None
    op_spec.trigger = None
    op_spec.skip_on_upstream_skip = None
    op_spec.cache = compiled_operation.cache
    op_spec.queue = compiled_operation.queue
    op_spec.component.inputs = compiled_operation.inputs
    op_spec.component.outputs = compiled_operation.outputs
    op_spec.component.contexts = compiled_operation.contexts
    return op_spec
Esempio n. 21
0
    def test_op_specification_with_nocache(self):
        config_dict = {
            "version": 1.1,
            "kind": "operation",
            "name": "foo",
            "description": "a description",
            "tags": ["value"],
            "cache": {"disable": True, "ttl": 12},
            "params": {"param1": {"value": "foo"}, "param2": {"value": "bar"}},
            "trigger": "all_succeeded",
            "component": {
                "name": "build-template",
                "tags": ["kaniko"],
                "run": {
                    "kind": V1RunKind.JOB,
                    "container": {"name": "polyaxon-main", "image": "test"},
                    "init": [{"connection": "some-connection"}],
                },
            },
        }
        op_config = V1Operation.read(values=config_dict)

        run_config = OperationSpecification.compile_operation(op_config)
        assert run_config.name == "foo"
        assert run_config.description == "a description"
        assert run_config.tags == ["kaniko", "value"]
        assert run_config.cache.to_dict() == {"disable": True, "ttl": 12}
        assert [i.to_light_dict() for i in run_config.run.init] == [
            {"connection": "some-connection"}
        ]

        env = {
            "runPatch": {
                "container": {
                    "resources": {
                        "requests": {"gpu": 1, "tpu": 1},
                        "limits": {"gpu": 1, "tpu": 1},
                    }
                }
            }
        }
        run_config = OperationSpecification.compile_operation(op_config, env)
        assert (
            run_config.run.container.resources
            == env["runPatch"]["container"]["resources"]
        )
Esempio n. 22
0
def get_ops_from_suggestions(
    content: str, compiled_operation: V1CompiledOperation, suggestions: List[Dict]
) -> List[V1Operation]:
    ops = []
    for suggestion in suggestions:
        params = {
            k: V1Param(value=Parser.parse_expression(v, {}))
            for (k, v) in suggestion.items()
        }
        op_spec = V1Operation.read(content)
        op_spec.matrix = None  # remove matrix
        op_spec.params = params
        op_spec.component.inputs = compiled_operation.inputs
        op_spec.component.outputs = compiled_operation.outputs
        ops.append(op_spec)

    return ops
Esempio n. 23
0
def get_notifier_operation(
    connection: str,
    backend: str,
    owner: str,
    project: str,
    run_uuid: str,
    run_name: str,
    condition: Union[str, Dict],
) -> V1Operation:
    return V1Operation(
        params={
            "backend": V1Param(value=backend),
            "owner": V1Param(value=owner),
            "project": V1Param(value=project),
            "uuid": V1Param(value=run_uuid),
            "name": V1Param(value=run_name),
            "condition": V1Param(value=condition),
        },
        termination=V1Termination(max_retries=3),
        component=V1Component(
            name="notifier",
            plugins=V1Plugins(
                auth=False,
                collect_logs=False,
                collect_artifacts=False,
                collect_resources=False,
                auto_resume=False,
                sync_statuses=False,
                external_host=True,
            ),
            inputs=[
                V1IO(name="backend", type=types.STR, is_optional=False),
                V1IO(name="owner", type=types.STR, is_optional=False),
                V1IO(name="project", type=types.STR, is_optional=False),
                V1IO(name="uuid", type=types.STR, is_optional=False),
                V1IO(name="name", type=types.STR, is_optional=True),
                V1IO(name="condition", type=types.DICT, is_optional=True),
                V1IO(name="connection", type=types.STR, is_optional=True),
            ],
            run=V1NotifierJob(
                connections=[connection],
                container=get_default_notification_container(),
            ),
        ),
    )
Esempio n. 24
0
def get_notifier_operation(
    connection: str,
    kind: str,
    owner: str,
    project: str,
    run_uuid: str,
    run_name: str,
    condition: str,
) -> V1Operation:
    return V1Operation(
        params={
            "kind": V1Param(value=kind),
            "owner": V1Param(value=owner),
            "project": V1Param(value=project),
            "run_uuid": V1Param(value=run_uuid),
            "run_name": V1Param(value=run_name),
            "condition": V1Param(value=condition),
        },
        termination=V1Termination(max_retries=3),
        component=V1Component(
            name="slack-notification",
            plugins=V1Plugins(
                auth=False,
                collect_logs=False,
                collect_artifacts=False,
                collect_resources=False,
                sync_statuses=False,
            ),
            inputs=[
                V1IO(name="kind", iotype=types.STR, is_optional=False),
                V1IO(name="owner", iotype=types.STR, is_optional=False),
                V1IO(name="project", iotype=types.STR, is_optional=False),
                V1IO(name="run_uuid", iotype=types.STR, is_optional=False),
                V1IO(name="run_name", iotype=types.STR, is_optional=True),
                V1IO(name="condition", iotype=types.STR, is_optional=True),
                V1IO(name="connection", iotype=types.STR, is_optional=True),
            ],
            run=V1Notifier(
                connections=[connection],
                container=get_default_notification_container(),
            ),
        ),
    )
Esempio n. 25
0
    def test_patch_post_merge_full_values_with_empty_preset(self):
        operation = self.get_full_operation()
        tmp_operation = self.get_full_operation()
        result = tmp_operation.patch(V1Operation(is_preset=True),
                                     strategy=V1PatchStrategy.POST_MERGE)
        assert result.to_dict() == operation.to_dict()

        tmp_operation = self.get_full_operation()
        preset = self.get_empty_preset()
        result = tmp_operation.patch(preset,
                                     strategy=V1PatchStrategy.POST_MERGE)
        result_dict = result.to_dict()
        assert result_dict["description"] == ""
        result_dict["description"] = self.DEFAULT_STR_VALUE
        assert result_dict["queue"] == ""
        result_dict["queue"] = "{}/{}".format(self.DEFAULT_STR_VALUE,
                                              self.DEFAULT_STR_VALUE)
        result_dict["presets"] = [self.DEFAULT_STR_VALUE]
        # Since there's no component to validate the runPatch section it stays the same
        assert result_dict == operation.to_dict()

        operation = self.get_full_operation_with_component()
        tmp_operation = self.get_full_operation_with_component()
        preset = self.get_empty_preset()
        result = tmp_operation.patch(preset,
                                     strategy=V1PatchStrategy.POST_MERGE)
        result_dict = result.to_dict()
        assert result_dict["description"] == ""
        result_dict["description"] = self.DEFAULT_STR_VALUE
        assert result_dict["queue"] == ""
        result_dict["queue"] = "{}/{}".format(self.DEFAULT_STR_VALUE,
                                              self.DEFAULT_STR_VALUE)
        # Run patch was validated and merged
        assert result_dict["runPatch"]["environment"][
            "serviceAccountName"] == ""
        result_dict["runPatch"]["environment"][
            "serviceAccountName"] = operation.run_patch["environment"][
                "serviceAccountName"]
        assert result_dict["runPatch"]["container"].pop(
            "name") == MAIN_JOB_CONTAINER
        assert result_dict == operation.to_dict()
Esempio n. 26
0
def get_cleaner_operation(connection: V1ConnectionType, run_uuid: str,
                          run_kind: str) -> V1Operation:
    return V1Operation(
        termination=V1Termination(max_retries=1),
        component=V1Component(
            name="cleaner",
            plugins=V1Plugins(
                auth=False,
                collect_logs=False,
                collect_artifacts=False,
                collect_resources=False,
                auto_resume=False,
                sync_statuses=False,
            ),
            run=V1CleanerJob(
                connections=[connection.name],
                container=get_default_cleaner_container(
                    connection, run_uuid, run_kind),
            ),
        ),
    )
Esempio n. 27
0
def get_batch_cleaner_operation(
    connection: V1ConnectionType,
    paths: List[str],
) -> V1Operation:
    return V1Operation(
        termination=V1Termination(max_retries=1),
        component=V1Component(
            name="cleaner",
            plugins=V1Plugins(
                auth=False,
                collect_logs=False,
                collect_artifacts=False,
                collect_resources=False,
                auto_resume=False,
                sync_statuses=False,
            ),
            run=V1CleanerJob(
                connections=[connection.name],
                container=get_batch_cleaner_container(connection, paths),
            ),
        ),
    )
Esempio n. 28
0
 def set_spec(spec: V1Operation, **kwargs) -> Tuple[V1Operation, Dict]:
     kwargs["raw_content"] = spec.to_dict(dump=True)
     return spec, kwargs
Esempio n. 29
0
    def init_run(
        self,
        project_id: int,
        user_id: int,
        op_spec: V1Operation = None,
        compiled_operation: V1CompiledOperation = None,
        name: str = None,
        description: str = None,
        tags: str = None,
        override: Union[str, Dict] = None,
        override_post: bool = True,
        params: Dict = None,
        readme: str = None,
        original_id: int = None,
        cloning_kind: str = None,
        **kwargs,
    ) -> Tuple[V1CompiledOperation, BaseRun]:
        content = None
        raw_content = None
        if op_spec:
            op_spec = self.set_spec(op_spec)
            raw_content = op_spec.to_dict(dump=True)
        if op_spec:
            if not compiled_operation or override:
                compiled_operation = OperationSpecification.compile_operation(
                    op_spec, override=override, override_post=override_post)
            params = op_spec.params

        params = params or {}
        inputs = {p: pv.value for p, pv in params.items() if pv.is_literal}
        params = {p: pv.to_dict() for p, pv in params.items()}
        kind = None
        meta_info = {}
        if compiled_operation:
            content = compiled_operation.to_dict(dump=True)
            name = name or compiled_operation.name
            description = description or compiled_operation.description
            tags = tags or compiled_operation.tags
            kind, meta_kind = self.get_kind(compiled_operation)
            kind, meta_info = self.get_meta_info(compiled_operation, kind,
                                                 meta_kind)
        instance = get_run_model()(
            project_id=project_id,
            user_id=user_id,
            name=name,
            description=description,
            tags=tags,
            readme=readme,
            raw_content=raw_content,
            content=content,
            params=params,
            inputs=inputs,
            kind=kind,
            meta_info=meta_info,
            original_id=original_id,
            cloning_kind=cloning_kind,
            status_conditions=[
                V1StatusCondition.get_condition(
                    type=V1Statuses.CREATED,
                    status="True",
                    reason="PolyaxonRunCreated",
                    message="Run is created",
                ).to_dict()
            ],
            **self.sanitize_kwargs(**kwargs),
        )
        return compiled_operation, instance
Esempio n. 30
0
    def compile_operation(cls,
                          config: V1Operation,
                          override: Dict = None) -> V1CompiledOperation:
        if override:
            preset = OperationSpecification.read(override, is_preset=True)
            config = config.patch(preset, preset.patch_strategy)
        # Patch run
        component = config.component  # type: V1Component
        if config.run_patch:
            component.run = component.run.patch(
                validate_run_patch(config.run_patch, component.run.kind),
                strategy=config.patch_strategy,
            )

        contexts = []

        def get_context_io(c_name: str, c_io: V1Param, is_list=None):
            if not c_io.context_only:
                return

            contexts.append(
                V1IO(
                    name=c_name,
                    to_init=c_io.to_init,
                    connection=c_io.connection,
                    is_list=is_list,
                ))

        # Collect contexts io form params
        for p in config.params or {}:
            get_context_io(c_name=p, c_io=config.params[p])

        # Collect contexts io form joins
        for j in config.joins or []:
            for p in j.params or {}:
                get_context_io(c_name=p, c_io=j.params[p], is_list=True)

        patch_compiled = V1CompiledOperation(
            name=config.name,
            description=config.description,
            contexts=contexts,
            tags=config.tags,
            presets=config.presets,
            queue=config.queue,
            cache=config.cache,
            hooks=config.hooks,
            events=config.events,
            plugins=config.plugins,
            termination=config.termination,
            matrix=config.matrix,
            joins=config.joins,
            schedule=config.schedule,
            dependencies=config.dependencies,
            trigger=config.trigger,
            conditions=config.conditions,
            skip_on_upstream_skip=config.skip_on_upstream_skip,
        )

        values = [
            {
                cls.VERSION: config.version
            },
            component.to_dict(),
            {
                cls.KIND: kinds.COMPILED_OPERATION
            },
        ]
        compiled = V1CompiledOperation.read(
            values)  # type: V1CompiledOperation
        return compiled.patch(patch_compiled, strategy=config.patch_strategy)