def test_incomplete_params(self): config_dict = { "inputs": [ {"name": "param1", "type": types.INT}, {"name": "param2", "type": types.INT}, ], "run": {"kind": V1RunKind.JOB, "container": {"image": "test"}}, } config = V1Component.from_dict(config_dict) with self.assertRaises(ValidationError): ops_params.validate_params( params={"param1": {"value": 1}}, inputs=config.inputs, outputs=config.outputs, is_template=False, ) config_dict = { "outputs": [ {"name": "param1", "type": types.INT, "value": 12, "isOptional": True}, {"name": "param2", "type": types.INT}, ], "run": {"kind": V1RunKind.JOB, "container": {"image": "test"}}, } config = V1Component.from_dict(config_dict) ops_params.validate_params( params={"param1": {"value": 1}}, inputs=config.inputs, outputs=config.outputs, is_template=False, )
def test_extra_params(self): # inputs config_dict = { "inputs": [{"name": "param1", "type": types.INT}], "run": {"kind": V1RunKind.JOB, "container": {"image": "test"}}, } config = V1Component.from_dict(config_dict) with self.assertRaises(ValidationError): ops_params.validate_params( params={"param1": {"value": 1}, "param2": {"value": 2}}, inputs=config.inputs, outputs=config.outputs, is_template=False, ) # outputs config_dict = { "outputs": [{"name": "param1", "type": types.INT}], "run": {"kind": V1RunKind.JOB, "container": {"image": "test"}}, } config = V1Component.from_dict(config_dict) with self.assertRaises(ValidationError): ops_params.validate_params( params={"param1": {"value": 1}, "param2": {"value": 2}}, inputs=config.inputs, outputs=config.outputs, is_template=False, )
def test_passing_params_declarations_raises(self): config_dict = { "params": {"foo": {"value": "bar"}}, "declarations": {"foo": "bar"}, } with self.assertRaises(ValidationError): V1Component.from_dict(config_dict)
def test_required_input_no_param_only_validated_on_run(self): # Inputs config_dict = { "inputs": [ {"name": "param1", "type": types.STR}, {"name": "param10", "type": types.PATH}, ], "run": {"kind": V1RunKind.JOB, "container": {"image": "test"}}, } config = V1Component.from_dict(config_dict) with self.assertRaises(ValidationError): ops_params.validate_params( params={"param1": {"value": "text"}}, inputs=config.inputs, outputs=config.outputs, is_template=False, ) # Outputs config_dict = { "outputs": [ {"name": "param1", "type": types.STR}, {"name": "param10", "type": types.PATH}, ], "run": {"kind": V1RunKind.JOB, "container": {"image": "test"}}, } config = V1Component.from_dict(config_dict) ops_params.validate_params( params={"param1": {"value": "text"}}, inputs=config.inputs, outputs=config.outputs, is_template=False, ) # IO config_dict = { "inputs": [{"name": "param1", "type": types.STR}], "outputs": [{"name": "param10", "type": types.PATH}], "run": {"kind": V1RunKind.JOB, "container": {"image": "test"}}, } config = V1Component.from_dict(config_dict) ops_params.validate_params( params={"param1": {"value": "text"}}, inputs=config.inputs, outputs=config.outputs, is_template=False, )
def test_component_actions_and_hooks(self): config_dict = { "kind": "component", "actions": [ { "hubRef": "ref1" }, { "hubRef": "ref2", "label": "customLabel", "many": True }, ], "hooks": [ { "trigger": "succeeded", "connection": "connection1" }, { "connection": "connection1", "hubRef": "ref2" }, ], "run": { "kind": V1RunKind.JOB, "container": { "image": "test" } }, } config = V1Component.from_dict(config_dict) assert config.to_dict() == config_dict
def test_job_refs_params(self): config_dict = { "inputs": [ { "name": "param1", "type": types.INT }, { "name": "param9", "type": types.FLOAT }, ], "run": { "kind": V1RunKind.JOB, "container": { "image": "test" } }, } params = { "param1": { "ref": "job.A", "value": "outputs.foo" }, "param9": { "value": 13.1 }, } config = V1Component.from_dict(config_dict) # Validation outside the context of a pipeline with self.assertRaises(ValidationError): ops_params.validate_params(params=params, inputs=config.inputs, outputs=None, is_template=False)
def test_component_base_attrs(self): config_dict = { "concurrency": "foo", "run": {"kind": V1RunKind.JOB, "container": {"image": "test"}}, } with self.assertRaises(ValidationError): V1Component.from_dict(config_dict) config_dict = { "concurrency": 2, "run": {"kind": V1RunKind.JOB, "container": {"image": "test"}}, } with self.assertRaises(ValidationError): V1Component.from_dict(config_dict) config_dict = { "kind": "component", "matrix": { "concurrency": 2, "kind": "mapping", "values": [{"a": 1}, {"a": 1}], }, "run": {"kind": V1RunKind.JOB, "container": {"image": "test"}}, } with self.assertRaises(ValidationError): V1Component.from_dict(config_dict) config_dict = { "kind": "component", "matrix": { "concurrency": 2, "kind": "mapping", "values": [{"a": 1}, {"a": 1}], }, "schedule": { "kind": "datetime", "startAt": local_datetime(now()).isoformat(), }, "termination": {"timeout": 1000}, "run": {"kind": V1RunKind.JOB, "container": {"image": "test"}}, } with self.assertRaises(ValidationError): V1Component.from_dict(config_dict) config_dict = { "kind": "component", "termination": {"timeout": 1000}, "run": {"kind": V1RunKind.JOB, "container": {"image": "test"}}, } config = V1Component.from_dict(config_dict) assert config.to_dict() == config_dict
def get_full_operation_with_component(self): operation = self.get_full_operation() config_dict = { "inputs": [{"name": "param1", "type": types.INT}], "run": {"kind": V1RunKind.JOB, "container": {"image": "test"}}, } operation.component = V1Component.from_dict(config_dict) return operation
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, ), ), )
def test_param_validation_with_outputs(self): config_dict = { "outputs": [ {"name": "param1", "type": types.STR}, {"name": "param2", "type": types.INT}, {"name": "param3", "type": types.FLOAT}, {"name": "param4", "type": types.BOOL}, {"name": "param5", "type": types.DICT}, {"name": "param6", "type": types.LIST}, {"name": "param7", "type": types.GCS}, {"name": "param8", "type": types.S3}, {"name": "param9", "type": types.WASB}, {"name": "param10", "type": types.PATH}, {"name": "param11", "type": types.METRIC}, {"name": "param12", "type": types.METADATA}, {"name": "param13", "type": types.METADATA}, {"name": "param14", "type": types.METADATA}, ], "run": {"kind": V1RunKind.JOB, "container": {"image": "test"}}, } component = V1Component.from_dict(config_dict) params = { "param1": {"value": "text"}, "param2": {"value": 12}, "param3": {"value": 13.3}, "param4": {"value": False}, "param5": {"value": {"foo": "bar"}}, "param6": {"value": [1, 3, 45, 5]}, "param7": {"value": "gs://bucket/path/to/blob/"}, "param8": {"value": "s3://test/this/is/bad/key.txt"}, "param9": {"value": "wasbs://[email protected]/"}, "param10": {"value": "/foo/bar"}, "param11": {"value": 124.4}, "param12": {"value": {"foo": 124.4}}, "param13": {"value": {"foo": "bar"}}, "param14": {"value": {"foo": ["foo", 124.4]}}, } validated_params = ops_params.validate_params( params=params, inputs=None, outputs=component.outputs, is_template=False ) assert params == {p.name: {"value": p.param.value} for p in validated_params} # Passing missing params params.pop("param1") params.pop("param2") validated_params = ops_params.validate_params( params=params, inputs=None, outputs=component.outputs, is_template=False ) params["param1"] = {"value": None} params["param2"] = {"value": None} assert params == {p.name: {"value": p.param.value} for p in validated_params}
def test_apply_context_raises_with_required_inputs(self): content = { "version": 1.1, "kind": "component", "inputs": [ {"name": "lr", "type": types.FLOAT}, {"name": "num_steps", "type": types.INT}, ], "run": { "kind": V1RunKind.JOB, "container": { "name": "polyaxon-main", "image": "test/test:latest", "command": "train", }, }, } component_config = V1Component.read(content) assert component_config.to_dict() == content content = { "version": 1.1, "kind": "compiled_operation", "inputs": [ {"name": "lr", "type": types.FLOAT}, {"name": "num_steps", "type": types.INT}, ], "run": { "kind": V1RunKind.JOB, "container": { "name": "polyaxon-main", "image": "test/test:latest", "command": "train", }, }, } run_config = V1CompiledOperation.read(content) # Raise because required inputs are not met with self.assertRaises(ValidationError): CompiledOperationSpecification.apply_operation_contexts(run_config) # Validation for template should pass validated_params = run_config.validate_params() assert {"lr": None, "num_steps": None} == { p.name: p.param.value for p in validated_params } # Validation for non template should raise with self.assertRaises(ValidationError): run_config.validate_params(is_template=False)
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, ), ), )
def test_component_template(self): config_dict = { "kind": "component", "hooks": [ {"trigger": "succeeded", "connection": "connection1", "hubRef": "ref2"}, {"connection": "connection1", "hubRef": "ref2"}, ], "run": {"kind": V1RunKind.JOB, "container": {"image": "test"}}, "template": { "description": "This is a template, check the fields", "fields": ["actions[1].hubRef", "hooks[0].trigger"], }, } config = V1Component.from_dict(config_dict) assert config.to_dict() == config_dict
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(), ), ), )
def test_experiment_and_job_refs_params(self): config_dict = { "inputs": [ {"name": "param1", "type": types.INT}, {"name": "param2", "type": types.FLOAT}, {"name": "param9", "type": types.WASB}, {"name": "param11", "type": types.METRIC}, ], "run": {"kind": V1RunKind.JOB, "container": {"image": "test"}}, } op = V1Component.from_dict(config_dict) params = { "param1": { "ref": "runs.64332180bfce46eba80a65caf73c5396", "value": "outputs.foo", }, "param2": { "ref": "runs.0de53b5bf8b04a219d12a39c6b92bcce", "value": "outputs.foo", }, "param9": {"value": "wasbs://[email protected]/"}, "param11": { "ref": "runs.fcc462d764104eb698d3cca509f34154", "value": "outputs.accuracy", }, } validated_params = ops_params.validate_params( params=params, inputs=op.inputs, outputs=None, is_template=False ) assert {p.name: p.param.to_dict() for p in validated_params} == { "param1": { "ref": "runs.64332180bfce46eba80a65caf73c5396", "value": "outputs.foo", }, "param2": { "ref": "runs.0de53b5bf8b04a219d12a39c6b92bcce", "value": "outputs.foo", }, "param9": {"value": "wasbs://[email protected]/"}, "param11": { "ref": "runs.fcc462d764104eb698d3cca509f34154", "value": "outputs.accuracy", }, }
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(), ), ), )
def test_refs_pipeline(self): run_config = V1CompiledOperation.read( [ os.path.abspath("tests/fixtures/pipelines/ref_pipeline.yml"), {"kind": "compiled_operation"}, ] ) with patch("polyaxon.config_reader.spec.ConfigSpec.read") as config_read: config_read.return_value = V1Component( kind="component", version="1.05", inputs=[V1IO(name="str-input", iotype="str")], run=V1Job(container=V1Container(name="test")), ).to_dict() compiled_op = CompiledOperationSpecification.apply_context(run_config) assert compiled_op.run is not None assert len(compiled_op.run.operations) == 2 assert compiled_op.run.operations[0].name == "ref-path-op" assert compiled_op.run.operations[1].name == "ref-url-op"
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), ), ), )
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), ), ), )
def test_spec_without_io_and_params_raises(self): content = { "version": 1.1, "kind": "component", "run": { "kind": V1RunKind.JOB, "container": { "name": "polyaxon-main", "image": "test/test:latest", "command": "train", }, }, } config = V1Component.read(content) assert config.to_dict() == content content = { "version": 1.1, "kind": "compiled_operation", "run": { "kind": V1RunKind.JOB, "container": { "name": "polyaxon-main", "image": "test/test:latest", "command": "train", }, }, } config = V1CompiledOperation.read(content) config = CompiledOperationSpecification.apply_operation_contexts( config) assert config.to_dict() == content # Add params content["params"] = {"lr": 0.1} with self.assertRaises(ValidationError): V1CompiledOperation.read(content)
def test_apply_context_passes_with_required_inputs_and_params(self): content = { "version": 1.1, "kind": "component", "inputs": [ { "name": "lr", "type": types.FLOAT }, { "name": "num_steps", "type": types.INT }, ], "run": { "kind": V1RunKind.JOB, "container": { "name": "polyaxon-main", "image": "test/test:latest", "command": "train", }, }, } component_config = V1Component.read(content) assert component_config.to_dict() == content content = { "version": 1.1, "kind": "compiled_operation", "inputs": [ { "name": "lr", "type": types.FLOAT }, { "name": "num_steps", "type": types.INT }, ], "run": { "kind": V1RunKind.JOB, "container": { "name": "polyaxon-main", "image": "test/test:latest", "command": "train", }, }, } run_config = V1CompiledOperation.read(content) # no params with self.assertRaises(ValidationError): CompiledOperationSpecification.apply_operation_contexts(run_config) params = { "lr": V1Param(value=0.1), "num_steps": V1Param.from_dict({"value": 100}), } assert run_config.inputs[0].value is None assert run_config.inputs[1].value is None validated_params = run_config.validate_params(params=params) run_config.apply_params(params=params) assert {k: v.to_dict() for k, v in params.items() } == {p.name: p.param.to_dict() for p in validated_params} assert run_config.inputs[0].value == 0.1 assert run_config.inputs[1].value == 100 run_config = CompiledOperationSpecification.apply_operation_contexts( run_config) updated_content = { "version": 1.1, "kind": "compiled_operation", "inputs": [ { "name": "lr", "type": types.FLOAT, "isOptional": True, "value": 0.1 }, { "name": "num_steps", "type": types.INT, "isOptional": True, "value": 100, }, ], "run": { "kind": V1RunKind.JOB, "container": { "name": "polyaxon-main", "image": "test/test:latest", "command": "train", }, }, } assert run_config.to_dict() == updated_content updated_content["run"]["container"]["resources"] = { "requests": { "gpu": 1, "tpu": 1 }, "limits": { "gpu": 1, "tpu": 1 }, } run_config = V1CompiledOperation.read(updated_content) assert (run_config.run.container.resources == updated_content["run"] ["container"]["resources"])
async def notify_run( namespace: str, owner: str, project: str, run_uuid: str, run_name: str, condition: V1StatusCondition, connections: List[str], ): spawner = AsyncSpawner(namespace=namespace) await spawner.k8s_manager.setup() for connection in connections: connection_type = settings.AGENT_CONFIG.notification_connections_by_names.get( connection ) if not connection_type: logger.warning( "Could not create notification using connection {}, " "the connection was not found or not set correctly.".format( connection_type ) ) continue operation = V1Operation( params={ "kind": connection_type.kind, "owner": owner, "project": project, "run_uuid": run_uuid, "run_name": run_name, "condition": ujson.dumps(condition.to_dict()), }, 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(), ), ), ) compiled_operation = OperationSpecification.compile_operation(operation) resource = compiler.make( owner_name=owner, project_name=project, project_uuid=project, run_uuid=run_uuid, run_name=run_name, run_path=run_uuid, compiled_operation=compiled_operation, params=operation.params, ) await spawner.create( run_uuid=run_uuid, run_kind=compiled_operation.get_run_kind(), resource=resource, )
def test_param_validation_with_mismatched_outputs(self): config_dict = { "outputs": [{ "name": "param1", "type": types.INT }], "run": { "kind": V1RunKind.JOB, "container": { "image": "test" } }, } config = V1Component.from_dict(config_dict) # Passing correct param ops_params.validate_params( params={"param1": { "value": 1 }}, inputs=config.inputs, outputs=config.outputs, is_template=False, ) # Passing wrong type with self.assertRaises(ValidationError): ops_params.validate_params( params={"param1": { "value": "text" }}, inputs=config.inputs, outputs=config.outputs, is_template=False, ) with self.assertRaises(ValidationError): ops_params.validate_params( params={"param1": { "value": 12.1 }}, inputs=config.inputs, outputs=config.outputs, is_template=False, ) with self.assertRaises(ValidationError): ops_params.validate_params( params={"param1": { "value": { "foo": "bar" } }}, inputs=config.inputs, outputs=config.outputs, is_template=False, ) with self.assertRaises(ValidationError): ops_params.validate_params( params={"param1": { "value": "gs://bucket/path/to/blob/" }}, inputs=config.inputs, outputs=config.outputs, is_template=False, ) config_dict = { "outputs": [{ "name": "param2", "type": types.STR }], "run": { "kind": V1RunKind.JOB, "container": { "image": "test" } }, } config = V1Component.from_dict(config_dict) # Passing correct param ops_params.validate_params( params={"param2": { "value": "text" }}, inputs=config.inputs, outputs=config.outputs, is_template=False, ) # Passing wrong type with self.assertRaises(ValidationError): ops_params.validate_params( params={"param2": { "value": 1 }}, inputs=config.inputs, outputs=config.outputs, is_template=False, ) with self.assertRaises(ValidationError): ops_params.validate_params( params={"param2": { "value": False }}, inputs=config.inputs, outputs=config.outputs, is_template=False, ) with self.assertRaises(ValidationError): ops_params.validate_params( params={"param2": { "value": { "foo": "bar" } }}, inputs=config.inputs, outputs=config.outputs, is_template=False, ) with self.assertRaises(ValidationError): ops_params.validate_params( params={"param2": { "value": ["gs://bucket/path/to/blob/"] }}, inputs=config.inputs, outputs=config.outputs, is_template=False, ) config_dict = { "outputs": [{ "name": "param7", "type": types.WASB }], "run": { "kind": V1RunKind.JOB, "container": { "image": "test" } }, } config = V1Component.from_dict(config_dict) # Passing correct param ops_params.validate_params( params={ "param7": { "value": "wasbs://[email protected]/" } }, inputs=config.inputs, outputs=config.outputs, is_template=False, ) # Passing wrong param with self.assertRaises(ValidationError): ops_params.validate_params( params={"param7": { "value": "gs://bucket/path/to/blob/" }}, inputs=config.inputs, outputs=config.outputs, is_template=False, ) with self.assertRaises(ValidationError): ops_params.validate_params( params={"param7": { "value": "s3://test/this/is/bad/key.txt" }}, inputs=config.inputs, outputs=config.outputs, is_template=False, ) with self.assertRaises(ValidationError): ops_params.validate_params( params={"param7": { "value": 1 }}, inputs=config.inputs, outputs=config.outputs, is_template=False, )
def test_passing_wrong_params(self): config_dict = {"params": {"foo": "bar"}} with self.assertRaises(ValidationError): V1Component.from_dict(config_dict)
V1IO(name="accuracy", type=types.FLOAT), ] job = V1Job( init=[ V1Init(git=V1GitType( url="https://github.com/polyaxon/polyaxon-quick-start")) ], container=V1Container( image="polyaxon/polyaxon-quick-start", working_dir="{{ globals.artifacts_path }}", command=["python3", "polyaxon-quick-start/model.py"], args=[ "--conv1_size={{ conv1_size }}", "--conv2_size={{ conv2_size }}", "--dropout={{ dropout }}", "--hidden1_size={{ hidden1_size }}", "--optimizer={{ optimizer }}", "--conv_activation={{ conv_activation }}", "--dense_activation={{ dense_activation }}", "--learning_rate={{ learning_rate }}", "--epochs={{ epochs }}" ]), ) component = V1Component( name="typed-experiment", description="experiment with inputs", tags=["examples"], inputs=inputs, outputs=outputs, run=job, )