@@ 360,8 360,10 @@ class BetterCronTrigger(CronTrigger):
class InputEncoder(json.JSONEncoder):
def default(self, o):
- if getattr(o, '__json_encode__'):
+ if getattr(o, '__json_encode__', None):
return o.__json_encode__()
+ if isinstance(o, datetime):
+ return o.isoformat()
return super().default(o)
@@ 457,7 459,7 @@ def convert_io(spec, args):
typed = {}
for field in spec:
inp = _iobase.from_type(
- field['type'], field['name'], field['required'], field['choices']
+ field['type'], field['name'], field['required'], field['choices'], field['default']
)
val = inp.from_string(args)
if val is not None:
@@ 467,13 469,14 @@ def convert_io(spec, args):
def pack_io(spec, args):
+ "Prepare the args for a .prepare or .schedule api call"
if args is None and not len(spec):
return
raw = {}
for field in spec:
inp = _iobase.from_type(
- field['type'], field['name'], field['required'], field['choices']
+ field['type'], field['name'], field['required'], field['choices'], field['default']
)
val = inp.binary_encode(args)
if val is not None:
@@ 534,7 537,7 @@ def unpack_io(spec,
output.pop(fname, None)
continue
inp = _iobase.from_type(
- field['type'], fname, field['required'], field['choices']
+ field['type'], fname, field['required'], field['choices'], field['default']
)
val = inp.binary_decode(output)
if val is None:
@@ 555,7 558,7 @@ def unpack_iofiles_length(spec, packedby
continue
inp = _iobase.from_type(
- 'file', fname, field['required'], field['choices']
+ 'file', fname, field['required'], field['choices'], None
)
val = inp.binary_decode(output)
if val is None:
@@ 578,6 581,6 @@ def unpack_iofile(spec, packedbytes, nam
assert field['type'] == 'file'
inp = _iobase.from_type(
- 'file', fname, field['required'], field['choices']
+ 'file', fname, field['required'], field['choices'], None
)
return inp.binary_decode(output)
@@ 56,11 56,11 @@ def register_tasks():
@api.task(inputs=(
io.file('myfile.txt', required=True),
- io.number('weight'),
- io.datetime('birthdate'),
- io.boolean('happy'),
- io.moment('sometime'),
- io.string('name'),
+ io.number('weight', default=42),
+ io.datetime('birthdate', default=dt(2023, 1, 1, 12)),
+ io.boolean('happy', default=True),
+ io.moment('sometime', default='(date "2023-5-20")'),
+ io.string('name', default='Celeste'),
io.string('option', choices=('foo', 'bar')),
io.string('ignoreme'))
)
@@ 100,22 100,32 @@ def test_freeze_ops(engine, cleanup):
('cheesy', 'cheese', None),
('foo', 'default', None),
('happy_days', 'default', [
- {'choices': None, 'name': 'when', 'required': False, 'type': 'moment'}
+ {'choices': None, 'name': 'when', 'default': None,
+ 'required': False, 'type': 'moment'}
]),
('noinput', 'default', []),
('yummy', 'default', [
- {'choices': None, 'name': 'myfile.txt', 'required': True, 'type': 'file'},
- {'choices': None, 'name': 'weight', 'required': False, 'type': 'number'},
- {'choices': None, 'name': 'birthdate', 'required': False, 'type': 'datetime'},
- {'choices': None, 'name': 'happy', 'required': False, 'type': 'boolean'},
- {'choices': None, 'name': 'sometime', 'required': False, 'type': 'moment'},
- {'choices': None, 'name': 'name', 'required': False, 'type': 'string'},
- {'choices': ['foo', 'bar'], 'name': 'option', 'required': False, 'type': 'string'},
- {'choices': None, 'name': 'ignoreme', 'required': False, 'type': 'string'}
+ {'choices': None, 'default': None, 'name': 'myfile.txt',
+ 'required': True, 'type': 'file'},
+ {'choices': None, 'default': 42, 'name': 'weight',
+ 'required': False, 'type': 'number'},
+ {'choices': None, 'default': '2023-01-01T12:00:00', 'name': 'birthdate',
+ 'required': False, 'type': 'datetime'},
+ {'choices': None, 'default': True, 'name': 'happy',
+ 'required': False, 'type': 'boolean'},
+ {'choices': None, 'default': '(date "2023-5-20")', 'name': 'sometime',
+ 'required': False, 'type': 'moment'},
+ {'choices': None, 'default': 'Celeste', 'name': 'name',
+ 'required': False, 'type': 'string'},
+ {'choices': ['foo', 'bar'], 'default': None, 'name': 'option',
+ 'required': False, 'type': 'string'},
+ {'choices': None, 'default': None, 'name': 'ignoreme',
+ 'required': False, 'type': 'string'}
]),
('hammy', 'ham', None),
('nr', 'non-default', [
- {'choices': None, 'name': 'history', 'required': False, 'type': 'number'}
+ {'choices': None, 'default': None, 'name': 'history',
+ 'required': False, 'type': 'number'}
])
]
@@ 129,7 139,8 @@ def test_freeze_ops(engine, cleanup):
]
assert res == [
('hammy', 'ham', [
- {'choices': None, 'name': 'taste', 'required': False, 'type': 'string'}
+ {'choices': None, 'name': 'taste', 'default': None,
+ 'required': False, 'type': 'string'}
])
]
@@ 189,6 200,23 @@ def test_with_inputs(engine, cleanup):
'option': 'foo'
}
+ # test default values
+ args = {
+ 'myfile.txt': b'some file',
+ 'option': 'foo'
+ }
+ t = api.schedule(engine, 'yummy', args)
+ assert t.input == {
+ 'myfile.txt': b'some file',
+ 'weight': 42,
+ 'birthdate': dt(2023, 1, 1, 12),
+ 'happy': True,
+ 'sometime': dt(2023, 5, 20, 0, 0),
+ 'name': 'Celeste',
+ 'option': 'foo'
+ }
+
+
with pytest.raises(ValueError) as err:
api.schedule(engine, 'yummy', {'no-such-thing': 42})
assert err.value.args[0] == 'missing required input: `myfile.txt`'
@@ 388,16 416,20 @@ def test_prepare_with_inputs(engine, cle
unpacked = unpack_io(spec, inputdata)
assert unpacked == {
'birthdate': dt(1973, 5, 20, 0, 0),
+ 'happy': True,
'myfile.txt': b'some file',
'name': 'Babar',
'option': 'foo',
+ 'sometime': dt(2023, 5, 20, 0, 0),
'weight': 65
}
unpacked = unpack_io(spec, inputdata, nofiles=True)
assert unpacked == {
'weight': 65,
+ 'happy': True,
'birthdate': dt(1973, 5, 20, 0, 0),
'name': 'Babar',
+ 'sometime': dt(2023, 5, 20, 0, 0),
'option': 'foo'
}
@@ 415,12 447,14 @@ def test_prepare_with_inputs(engine, cle
(b'myfile.txt',
b'weight',
b'birthdate',
+ b'happy',
b'sometime',
b'name',
b'option',
b'some file',
b'65',
b'1973-05-20T09:00:00',
+ b'True',
b'(date "1973-5-20")',
b'Babar',
b'foo'),
@@ 430,11 464,15 @@ def test_prepare_with_inputs(engine, cle
(b'myfile.txt',
b'weight',
b'birthdate',
+ b'happy',
+ b'sometime',
b'name',
b'option',
b'some file',
b'65',
b'1973-05-20T00:00:00',
+ b'True',
+ b'(date "2023-5-20")',
b'Babar',
b'foo'),
None,