diff --git a/clearml/automation/job.py b/clearml/automation/job.py index b6fd9f52..d7353f64 100644 --- a/clearml/automation/job.py +++ b/clearml/automation/job.py @@ -1,4 +1,5 @@ import hashlib +import warnings from datetime import datetime from logging import getLogger from time import time, sleep @@ -11,7 +12,7 @@ from ..backend_api.services import tasks as tasks_service logger = getLogger('clearml.automation.job') -class TrainsJob(object): +class ClearmlJob(object): def __init__( self, base_task_id, # type: str @@ -58,10 +59,19 @@ class TrainsJob(object): params.update(parameter_override) self.task.set_parameters(params) self.task_parameter_override = dict(**parameter_override) + if task_overrides: - # todo: make sure it works + sections = {} + # set values inside the Task + for k, v in task_overrides.items(): + # noinspection PyProtectedMember + self.task._set_task_property(k, v, raise_on_error=False, log_on_error=True) + section = k.split('.')[0] + sections[section] = getattr(self.task.data, section, None) + # store back Task parameters into backend # noinspection PyProtectedMember - self.task._edit(**task_overrides) + self.task._edit(**sections) + self.task_started = False self._worker = None @@ -298,6 +308,15 @@ class TrainsJob(object): return False +class TrainsJob(ClearmlJob): + + def __init__(self, **kwargs): + super(TrainsJob, self).__init__(**kwargs) + warnings.warn( + "Use clearml.automation.ClearmlJob", + DeprecationWarning, + ) + # noinspection PyMethodMayBeStatic, PyUnusedLocal class _JobStub(object): """ diff --git a/clearml/backend_interface/task/access.py b/clearml/backend_interface/task/access.py index 0f63ebf2..c9ebd96c 100644 --- a/clearml/backend_interface/task/access.py +++ b/clearml/backend_interface/task/access.py @@ -18,24 +18,32 @@ class AccessMixin(object): obj = self.data props = prop_path.split('.') for i in range(len(props)): - if not hasattr(obj, props[i]): + if not hasattr(obj, props[i]) and (not isinstance(obj, dict) or props[i] not in obj): msg = 'Task has no %s section defined' % '.'.join(props[:i + 1]) if log_on_error: self.log.info(msg) if raise_on_error: raise ValueError(msg) return default - obj = getattr(obj, props[i], None) + + if isinstance(obj, dict): + obj = obj.get(props[i]) + else: + obj = getattr(obj, props[i], None) + return obj def _set_task_property(self, prop_path, value, raise_on_error=True, log_on_error=True): props = prop_path.split('.') if len(props) > 1: - obj = self._get_task_property('.'.join(props[:-1]), raise_on_error=raise_on_error, - log_on_error=log_on_error) + obj = self._get_task_property( + '.'.join(props[:-1]), raise_on_error=raise_on_error, log_on_error=log_on_error) else: obj = self.data - setattr(obj, props[-1], value) + if not hasattr(obj, props[-1]) and isinstance(obj, dict): + obj[props[-1]] = value + else: + setattr(obj, props[-1], value) def save_exec_model_design_file(self, filename='model_design.txt', use_cache=False): """ Save execution model design to file """