class AddThree(specs.Task): __inputs__ = specs.PortList([ {'name': 'a', 'type': 'number', 'format': 'number'} ]) __outputs__ = specs.PortList([ {'name': 'b', 'type': 'number', 'format': 'number'} ]) def __init__(self, spec=None, **kw): super(AddThree, self).__init__(spec, **kw) self.mode = 'python' self.script = 'b = a + 3'
class Multiply(specs.Task): __inputs__ = specs.PortList([ {'name': 'in1', 'type': 'number', 'format': 'number'}, {'name': 'in2', 'type': 'number', 'format': 'number'} ]) __outputs__ = specs.PortList([ {'name': 'out', 'type': 'number', 'format': 'number'} ]) def __init__(self, spec=None, **kw): super(Multiply, self).__init__(spec, **kw) self.mode = 'python' self.script = 'out = in1 * in2'
def test_class_level_set_of_inputs_outputs(self): """Test task input/output attributes are set from class vars""" class TempTask(specs.Task): __inputs__ = specs.PortList(self.inputs) __outputs__ = specs.PortList(self.outputs) t = specs.Task(self.spec) self.assertEquals( set(t.keys()), {'inputs', 'outputs', 'mode', 'script'}) self.assertEquals(t['inputs'], specs.PortList()) self.assertEquals(t['outputs'], specs.PortList()) t2 = TempTask(self.spec) self.assertEquals(t2['inputs'], self.inputs) self.assertEquals(t2['outputs'], self.outputs)
def test_read_only_attributes(self): """Raise exception if task input/output are assigned""" class TempTask(specs.Task): __inputs__ = specs.PortList(self.inputs) __outputs__ = specs.PortList(self.outputs) # Test if passed in in spec dict with self.assertRaises(specs.ReadOnlyAttributeException): spec = self.spec.copy() spec['inputs'] = specs.PortList() TempTask(spec) with self.assertRaises(specs.ReadOnlyAttributeException): spec = self.spec.copy() spec['outputs'] = specs.PortList() TempTask(spec) # Test if assigned after instatiation t = TempTask(self.spec) with self.assertRaises(specs.ReadOnlyAttributeException): t['inputs'] = specs.PortList() with self.assertRaises(specs.ReadOnlyAttributeException): t['outputs'] = specs.PortList() with self.assertRaises(specs.ReadOnlyAttributeException): t.inputs = specs.PortList() with self.assertRaises(specs.ReadOnlyAttributeException): t.outputs = specs.PortList()
def spec_class_generator(class_type, spec): """Generate a generic Task style class from a Spec style dict. For example: >>> from girder_worker.core.specs.utils import spec_class_generator >>> spec = { ... "inputs": [ ... {"name": "a", ... "type": "number", ... "format": "number"}], ... "outputs": [ ... {"name": "b", ... "type": "number", ... "format": "number"}], ... "mode": "python", ... "script": "b = a + 3"} # Define the class >>> spec_class_generator("addThree", spec) <class 'abc.addThree'> # Set a variable to hold the class >>> addThree = spec_class_generator("addThree", spec) # Instantiate the class >>> dict(addThree()) # doctest: +NORMALIZE_WHITESPACE {'inputs': [{"format": "number", "name": "a", "type": "number"}], 'script': 'b = a + 3', 'mode': 'python', 'outputs': [{"format": "number", "name": "b", "type": "number"}]} """ # Decorator that adds 'script' and 'mode' keywords from # the spec to the kw argument passed to the decorated function def add_spec_to_kw(func): def wrapped_f(self, _spec=None, **kwargs): for k in ['script', 'mode', 'steps', 'connections']: if k not in kwargs.keys(): try: kwargs[k] = spec[k] except KeyError: pass func(self, _spec, **kwargs) return wrapped_f # __init__ function used for the class @add_spec_to_kw def __init__(self, spec, **kw): specs.Task.__init__(self, spec, **kw) for k, v in kw.items(): self[k] = v return __init__ # Define __inputs__ and __outputs__ variables on the class. cls_vars = { '__inputs__': specs.PortList(spec['inputs']), '__outputs__': specs.PortList(spec['outputs']), '__init__': __init__} return type(class_type, (specs.Task,), cls_vars)
class TempTask(specs.Task): __inputs__ = specs.PortList(self.inputs) __outputs__ = specs.PortList(self.outputs)