Skip to content

Commit c9def48

Browse files
Optional flag for subtask submission (#29)
* Optional flag for subtask submission * Support job list query filter by task state * Fix comment * Updated test requests * Update CHANGELOG
1 parent 5590c3b commit c9def48

25 files changed

Lines changed: 357 additions & 258 deletions

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- `tilebox-workflows`: Added ability to mark tasks as optional. Optional tasks will not fail the job if they fail and
13+
tasks that depend on them will still execute even if they fail, allowing for a job to complete even if some tasks fail.
14+
- `tilebox-workflows`: Added a `task_states` parameter to `JobClient.query`, to allow filtering jobs by whether they
15+
contain tasks in one of the given state.
16+
1017
## [0.48.0] - 2026-01-29
1118

1219
### Added

tilebox-datasets/tests/test_timeseries.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@
2424
DeleteCollectionRequest,
2525
GetCollectionByNameRequest,
2626
ListCollectionsRequest,
27+
ListCollectionsResponse,
2728
)
2829
from tilebox.datasets.datasets.v1.collections_pb2_grpc import CollectionServiceStub
2930
from tilebox.datasets.datasets.v1.core_pb2 import Collection as CollectionMessage
3031
from tilebox.datasets.datasets.v1.core_pb2 import CollectionInfo as CollectionInfoMessage
31-
from tilebox.datasets.datasets.v1.core_pb2 import CollectionInfos as CollectionInfosMessage
3232
from tilebox.datasets.query.time_interval import (
3333
_EMPTY_TIME_INTERVAL,
3434
TimeInterval,
@@ -298,9 +298,9 @@ def DeleteCollection(self, req: DeleteCollectionRequest) -> None: # noqa: N802
298298
del self.collections[collection.collection.name]
299299
return
300300

301-
def ListCollections(self, req: ListCollectionsRequest) -> CollectionInfosMessage: # noqa: N802
301+
def ListCollections(self, req: ListCollectionsRequest) -> ListCollectionsResponse: # noqa: N802
302302
_ = req
303-
return CollectionInfosMessage(data=list(self.collections.values()))
303+
return ListCollectionsResponse(data=list(self.collections.values()), owned_collections=len(self.collections))
304304

305305

306306
class CollectionCRUDOperations(RuleBasedStateMachine):

tilebox-datasets/tilebox/datasets/buf/validate/validate_pb2.py

Lines changed: 82 additions & 67 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tilebox-datasets/tilebox/datasets/buf/validate/validate_pb2.pyi

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from google.protobuf import descriptor_pb2 as _descriptor_pb2
22
from google.protobuf import duration_pb2 as _duration_pb2
3+
from google.protobuf import field_mask_pb2 as _field_mask_pb2
34
from google.protobuf import timestamp_pb2 as _timestamp_pb2
45
from google.protobuf.internal import containers as _containers
56
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
@@ -48,12 +49,14 @@ class Rule(_message.Message):
4849
def __init__(self, id: _Optional[str] = ..., message: _Optional[str] = ..., expression: _Optional[str] = ...) -> None: ...
4950

5051
class MessageRules(_message.Message):
51-
__slots__ = ("cel", "oneof")
52+
__slots__ = ("cel_expression", "cel", "oneof")
53+
CEL_EXPRESSION_FIELD_NUMBER: _ClassVar[int]
5254
CEL_FIELD_NUMBER: _ClassVar[int]
5355
ONEOF_FIELD_NUMBER: _ClassVar[int]
56+
cel_expression: _containers.RepeatedScalarFieldContainer[str]
5457
cel: _containers.RepeatedCompositeFieldContainer[Rule]
5558
oneof: _containers.RepeatedCompositeFieldContainer[MessageOneofRule]
56-
def __init__(self, cel: _Optional[_Iterable[_Union[Rule, _Mapping]]] = ..., oneof: _Optional[_Iterable[_Union[MessageOneofRule, _Mapping]]] = ...) -> None: ...
59+
def __init__(self, cel_expression: _Optional[_Iterable[str]] = ..., cel: _Optional[_Iterable[_Union[Rule, _Mapping]]] = ..., oneof: _Optional[_Iterable[_Union[MessageOneofRule, _Mapping]]] = ...) -> None: ...
5760

5861
class MessageOneofRule(_message.Message):
5962
__slots__ = ("fields", "required")
@@ -70,7 +73,8 @@ class OneofRules(_message.Message):
7073
def __init__(self, required: bool = ...) -> None: ...
7174

7275
class FieldRules(_message.Message):
73-
__slots__ = ("cel", "required", "ignore", "float", "double", "int32", "int64", "uint32", "uint64", "sint32", "sint64", "fixed32", "fixed64", "sfixed32", "sfixed64", "bool", "string", "bytes", "enum", "repeated", "map", "any", "duration", "timestamp")
76+
__slots__ = ("cel_expression", "cel", "required", "ignore", "float", "double", "int32", "int64", "uint32", "uint64", "sint32", "sint64", "fixed32", "fixed64", "sfixed32", "sfixed64", "bool", "string", "bytes", "enum", "repeated", "map", "any", "duration", "field_mask", "timestamp")
77+
CEL_EXPRESSION_FIELD_NUMBER: _ClassVar[int]
7478
CEL_FIELD_NUMBER: _ClassVar[int]
7579
REQUIRED_FIELD_NUMBER: _ClassVar[int]
7680
IGNORE_FIELD_NUMBER: _ClassVar[int]
@@ -94,7 +98,9 @@ class FieldRules(_message.Message):
9498
MAP_FIELD_NUMBER: _ClassVar[int]
9599
ANY_FIELD_NUMBER: _ClassVar[int]
96100
DURATION_FIELD_NUMBER: _ClassVar[int]
101+
FIELD_MASK_FIELD_NUMBER: _ClassVar[int]
97102
TIMESTAMP_FIELD_NUMBER: _ClassVar[int]
103+
cel_expression: _containers.RepeatedScalarFieldContainer[str]
98104
cel: _containers.RepeatedCompositeFieldContainer[Rule]
99105
required: bool
100106
ignore: Ignore
@@ -118,8 +124,9 @@ class FieldRules(_message.Message):
118124
map: MapRules
119125
any: AnyRules
120126
duration: DurationRules
127+
field_mask: FieldMaskRules
121128
timestamp: TimestampRules
122-
def __init__(self, cel: _Optional[_Iterable[_Union[Rule, _Mapping]]] = ..., required: bool = ..., ignore: _Optional[_Union[Ignore, str]] = ..., float: _Optional[_Union[FloatRules, _Mapping]] = ..., double: _Optional[_Union[DoubleRules, _Mapping]] = ..., int32: _Optional[_Union[Int32Rules, _Mapping]] = ..., int64: _Optional[_Union[Int64Rules, _Mapping]] = ..., uint32: _Optional[_Union[UInt32Rules, _Mapping]] = ..., uint64: _Optional[_Union[UInt64Rules, _Mapping]] = ..., sint32: _Optional[_Union[SInt32Rules, _Mapping]] = ..., sint64: _Optional[_Union[SInt64Rules, _Mapping]] = ..., fixed32: _Optional[_Union[Fixed32Rules, _Mapping]] = ..., fixed64: _Optional[_Union[Fixed64Rules, _Mapping]] = ..., sfixed32: _Optional[_Union[SFixed32Rules, _Mapping]] = ..., sfixed64: _Optional[_Union[SFixed64Rules, _Mapping]] = ..., bool: _Optional[_Union[BoolRules, _Mapping]] = ..., string: _Optional[_Union[StringRules, _Mapping]] = ..., bytes: _Optional[_Union[BytesRules, _Mapping]] = ..., enum: _Optional[_Union[EnumRules, _Mapping]] = ..., repeated: _Optional[_Union[RepeatedRules, _Mapping]] = ..., map: _Optional[_Union[MapRules, _Mapping]] = ..., any: _Optional[_Union[AnyRules, _Mapping]] = ..., duration: _Optional[_Union[DurationRules, _Mapping]] = ..., timestamp: _Optional[_Union[TimestampRules, _Mapping]] = ...) -> None: ...
129+
def __init__(self, cel_expression: _Optional[_Iterable[str]] = ..., cel: _Optional[_Iterable[_Union[Rule, _Mapping]]] = ..., required: bool = ..., ignore: _Optional[_Union[Ignore, str]] = ..., float: _Optional[_Union[FloatRules, _Mapping]] = ..., double: _Optional[_Union[DoubleRules, _Mapping]] = ..., int32: _Optional[_Union[Int32Rules, _Mapping]] = ..., int64: _Optional[_Union[Int64Rules, _Mapping]] = ..., uint32: _Optional[_Union[UInt32Rules, _Mapping]] = ..., uint64: _Optional[_Union[UInt64Rules, _Mapping]] = ..., sint32: _Optional[_Union[SInt32Rules, _Mapping]] = ..., sint64: _Optional[_Union[SInt64Rules, _Mapping]] = ..., fixed32: _Optional[_Union[Fixed32Rules, _Mapping]] = ..., fixed64: _Optional[_Union[Fixed64Rules, _Mapping]] = ..., sfixed32: _Optional[_Union[SFixed32Rules, _Mapping]] = ..., sfixed64: _Optional[_Union[SFixed64Rules, _Mapping]] = ..., bool: _Optional[_Union[BoolRules, _Mapping]] = ..., string: _Optional[_Union[StringRules, _Mapping]] = ..., bytes: _Optional[_Union[BytesRules, _Mapping]] = ..., enum: _Optional[_Union[EnumRules, _Mapping]] = ..., repeated: _Optional[_Union[RepeatedRules, _Mapping]] = ..., map: _Optional[_Union[MapRules, _Mapping]] = ..., any: _Optional[_Union[AnyRules, _Mapping]] = ..., duration: _Optional[_Union[DurationRules, _Mapping]] = ..., field_mask: _Optional[_Union[FieldMaskRules, _Mapping]] = ..., timestamp: _Optional[_Union[TimestampRules, _Mapping]] = ...) -> None: ...
123130

124131
class PredefinedRules(_message.Message):
125132
__slots__ = ("cel",)
@@ -381,7 +388,7 @@ class BoolRules(_message.Message):
381388
def __init__(self, const: bool = ..., example: _Optional[_Iterable[bool]] = ...) -> None: ...
382389

383390
class StringRules(_message.Message):
384-
__slots__ = ("const", "len", "min_len", "max_len", "len_bytes", "min_bytes", "max_bytes", "pattern", "prefix", "suffix", "contains", "not_contains", "not_in", "email", "hostname", "ip", "ipv4", "ipv6", "uri", "uri_ref", "address", "uuid", "tuuid", "ip_with_prefixlen", "ipv4_with_prefixlen", "ipv6_with_prefixlen", "ip_prefix", "ipv4_prefix", "ipv6_prefix", "host_and_port", "well_known_regex", "strict", "example")
391+
__slots__ = ("const", "len", "min_len", "max_len", "len_bytes", "min_bytes", "max_bytes", "pattern", "prefix", "suffix", "contains", "not_contains", "not_in", "email", "hostname", "ip", "ipv4", "ipv6", "uri", "uri_ref", "address", "uuid", "tuuid", "ip_with_prefixlen", "ipv4_with_prefixlen", "ipv6_with_prefixlen", "ip_prefix", "ipv4_prefix", "ipv6_prefix", "host_and_port", "ulid", "well_known_regex", "strict", "example")
385392
Extensions: _python_message._ExtensionDict
386393
CONST_FIELD_NUMBER: _ClassVar[int]
387394
LEN_FIELD_NUMBER: _ClassVar[int]
@@ -414,6 +421,7 @@ class StringRules(_message.Message):
414421
IPV4_PREFIX_FIELD_NUMBER: _ClassVar[int]
415422
IPV6_PREFIX_FIELD_NUMBER: _ClassVar[int]
416423
HOST_AND_PORT_FIELD_NUMBER: _ClassVar[int]
424+
ULID_FIELD_NUMBER: _ClassVar[int]
417425
WELL_KNOWN_REGEX_FIELD_NUMBER: _ClassVar[int]
418426
STRICT_FIELD_NUMBER: _ClassVar[int]
419427
EXAMPLE_FIELD_NUMBER: _ClassVar[int]
@@ -447,13 +455,14 @@ class StringRules(_message.Message):
447455
ipv4_prefix: bool
448456
ipv6_prefix: bool
449457
host_and_port: bool
458+
ulid: bool
450459
well_known_regex: KnownRegex
451460
strict: bool
452461
example: _containers.RepeatedScalarFieldContainer[str]
453-
def __init__(self, const: _Optional[str] = ..., len: _Optional[int] = ..., min_len: _Optional[int] = ..., max_len: _Optional[int] = ..., len_bytes: _Optional[int] = ..., min_bytes: _Optional[int] = ..., max_bytes: _Optional[int] = ..., pattern: _Optional[str] = ..., prefix: _Optional[str] = ..., suffix: _Optional[str] = ..., contains: _Optional[str] = ..., not_contains: _Optional[str] = ..., not_in: _Optional[_Iterable[str]] = ..., email: bool = ..., hostname: bool = ..., ip: bool = ..., ipv4: bool = ..., ipv6: bool = ..., uri: bool = ..., uri_ref: bool = ..., address: bool = ..., uuid: bool = ..., tuuid: bool = ..., ip_with_prefixlen: bool = ..., ipv4_with_prefixlen: bool = ..., ipv6_with_prefixlen: bool = ..., ip_prefix: bool = ..., ipv4_prefix: bool = ..., ipv6_prefix: bool = ..., host_and_port: bool = ..., well_known_regex: _Optional[_Union[KnownRegex, str]] = ..., strict: bool = ..., example: _Optional[_Iterable[str]] = ..., **kwargs) -> None: ...
462+
def __init__(self, const: _Optional[str] = ..., len: _Optional[int] = ..., min_len: _Optional[int] = ..., max_len: _Optional[int] = ..., len_bytes: _Optional[int] = ..., min_bytes: _Optional[int] = ..., max_bytes: _Optional[int] = ..., pattern: _Optional[str] = ..., prefix: _Optional[str] = ..., suffix: _Optional[str] = ..., contains: _Optional[str] = ..., not_contains: _Optional[str] = ..., not_in: _Optional[_Iterable[str]] = ..., email: bool = ..., hostname: bool = ..., ip: bool = ..., ipv4: bool = ..., ipv6: bool = ..., uri: bool = ..., uri_ref: bool = ..., address: bool = ..., uuid: bool = ..., tuuid: bool = ..., ip_with_prefixlen: bool = ..., ipv4_with_prefixlen: bool = ..., ipv6_with_prefixlen: bool = ..., ip_prefix: bool = ..., ipv4_prefix: bool = ..., ipv6_prefix: bool = ..., host_and_port: bool = ..., ulid: bool = ..., well_known_regex: _Optional[_Union[KnownRegex, str]] = ..., strict: bool = ..., example: _Optional[_Iterable[str]] = ..., **kwargs) -> None: ...
454463

455464
class BytesRules(_message.Message):
456-
__slots__ = ("const", "len", "min_len", "max_len", "pattern", "prefix", "suffix", "contains", "not_in", "ip", "ipv4", "ipv6", "example")
465+
__slots__ = ("const", "len", "min_len", "max_len", "pattern", "prefix", "suffix", "contains", "not_in", "ip", "ipv4", "ipv6", "uuid", "example")
457466
Extensions: _python_message._ExtensionDict
458467
CONST_FIELD_NUMBER: _ClassVar[int]
459468
LEN_FIELD_NUMBER: _ClassVar[int]
@@ -468,6 +477,7 @@ class BytesRules(_message.Message):
468477
IP_FIELD_NUMBER: _ClassVar[int]
469478
IPV4_FIELD_NUMBER: _ClassVar[int]
470479
IPV6_FIELD_NUMBER: _ClassVar[int]
480+
UUID_FIELD_NUMBER: _ClassVar[int]
471481
EXAMPLE_FIELD_NUMBER: _ClassVar[int]
472482
const: bytes
473483
len: int
@@ -481,8 +491,9 @@ class BytesRules(_message.Message):
481491
ip: bool
482492
ipv4: bool
483493
ipv6: bool
494+
uuid: bool
484495
example: _containers.RepeatedScalarFieldContainer[bytes]
485-
def __init__(self, const: _Optional[bytes] = ..., len: _Optional[int] = ..., min_len: _Optional[int] = ..., max_len: _Optional[int] = ..., pattern: _Optional[str] = ..., prefix: _Optional[bytes] = ..., suffix: _Optional[bytes] = ..., contains: _Optional[bytes] = ..., not_in: _Optional[_Iterable[bytes]] = ..., ip: bool = ..., ipv4: bool = ..., ipv6: bool = ..., example: _Optional[_Iterable[bytes]] = ..., **kwargs) -> None: ...
496+
def __init__(self, const: _Optional[bytes] = ..., len: _Optional[int] = ..., min_len: _Optional[int] = ..., max_len: _Optional[int] = ..., pattern: _Optional[str] = ..., prefix: _Optional[bytes] = ..., suffix: _Optional[bytes] = ..., contains: _Optional[bytes] = ..., not_in: _Optional[_Iterable[bytes]] = ..., ip: bool = ..., ipv4: bool = ..., ipv6: bool = ..., uuid: bool = ..., example: _Optional[_Iterable[bytes]] = ..., **kwargs) -> None: ...
486497

487498
class EnumRules(_message.Message):
488499
__slots__ = ("const", "defined_only", "not_in", "example")
@@ -551,6 +562,18 @@ class DurationRules(_message.Message):
551562
example: _containers.RepeatedCompositeFieldContainer[_duration_pb2.Duration]
552563
def __init__(self, const: _Optional[_Union[_duration_pb2.Duration, _Mapping]] = ..., lt: _Optional[_Union[_duration_pb2.Duration, _Mapping]] = ..., lte: _Optional[_Union[_duration_pb2.Duration, _Mapping]] = ..., gt: _Optional[_Union[_duration_pb2.Duration, _Mapping]] = ..., gte: _Optional[_Union[_duration_pb2.Duration, _Mapping]] = ..., not_in: _Optional[_Iterable[_Union[_duration_pb2.Duration, _Mapping]]] = ..., example: _Optional[_Iterable[_Union[_duration_pb2.Duration, _Mapping]]] = ..., **kwargs) -> None: ...
553564

565+
class FieldMaskRules(_message.Message):
566+
__slots__ = ("const", "not_in", "example")
567+
Extensions: _python_message._ExtensionDict
568+
CONST_FIELD_NUMBER: _ClassVar[int]
569+
IN_FIELD_NUMBER: _ClassVar[int]
570+
NOT_IN_FIELD_NUMBER: _ClassVar[int]
571+
EXAMPLE_FIELD_NUMBER: _ClassVar[int]
572+
const: _field_mask_pb2.FieldMask
573+
not_in: _containers.RepeatedScalarFieldContainer[str]
574+
example: _containers.RepeatedCompositeFieldContainer[_field_mask_pb2.FieldMask]
575+
def __init__(self, const: _Optional[_Union[_field_mask_pb2.FieldMask, _Mapping]] = ..., not_in: _Optional[_Iterable[str]] = ..., example: _Optional[_Iterable[_Union[_field_mask_pb2.FieldMask, _Mapping]]] = ..., **kwargs) -> None: ...
576+
554577
class TimestampRules(_message.Message):
555578
__slots__ = ("const", "lt", "lte", "lt_now", "gt", "gte", "gt_now", "within", "example")
556579
Extensions: _python_message._ExtensionDict

0 commit comments

Comments
 (0)