dex-python-sdk 0.3.1__tar.gz → 0.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/PKG-INFO +24 -1
  2. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/README.md +23 -0
  3. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/__init__.py +2 -1
  4. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/_invocation_context.py +10 -0
  5. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/context.py +23 -0
  6. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/pyproject.toml +1 -1
  7. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/LEGACY_NOTICES.md +0 -0
  8. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/LICENSE +0 -0
  9. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/_async_value_hydrator.py +0 -0
  10. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/_async_worker_dispatcher.py +0 -0
  11. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/_async_worker_service.py +0 -0
  12. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/_grpc_errors.py +0 -0
  13. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/_native.pyi +0 -0
  14. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/_utils.py +0 -0
  15. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/_value_hydrator.py +0 -0
  16. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/_value_mapper.py +0 -0
  17. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/_worker_dispatcher.py +0 -0
  18. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/_worker_service.py +0 -0
  19. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/async_client.py +0 -0
  20. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/async_worker.py +0 -0
  21. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/attribute.py +0 -0
  22. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/blob_cache.py +0 -0
  23. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/channel.py +0 -0
  24. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/client.py +0 -0
  25. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/client_options.py +0 -0
  26. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/codec.py +0 -0
  27. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/condition.py +0 -0
  28. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/dexpb/__init__.py +0 -0
  29. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/dexpb/dex_pb2.py +0 -0
  30. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/dexpb/dex_pb2.pyi +0 -0
  31. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/dexpb/dex_pb2_grpc.py +0 -0
  32. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/flow.py +0 -0
  33. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/flow_config.py +0 -0
  34. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/flow_info.py +0 -0
  35. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/flow_options.py +0 -0
  36. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/flow_result.py +0 -0
  37. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/py.typed +0 -0
  38. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/runtime_errors.py +0 -0
  39. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/step.py +0 -0
  40. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/step_execution.py +0 -0
  41. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/stream.py +0 -0
  42. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/subflow.py +0 -0
  43. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/timer.py +0 -0
  44. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/wait.py +0 -0
  45. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/worker.py +0 -0
  46. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/dex/worker_options.py +0 -0
  47. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/sdk-rust/Cargo.lock +0 -0
  48. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/sdk-rust/Cargo.toml +0 -0
  49. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/sdk-rust/crates/dex-blob-cache/Cargo.toml +0 -0
  50. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/sdk-rust/crates/dex-blob-cache/LICENSE +0 -0
  51. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/sdk-rust/crates/dex-blob-cache/src/config.rs +0 -0
  52. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/sdk-rust/crates/dex-blob-cache/src/entry.rs +0 -0
  53. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/sdk-rust/crates/dex-blob-cache/src/error.rs +0 -0
  54. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/sdk-rust/crates/dex-blob-cache/src/format.rs +0 -0
  55. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/sdk-rust/crates/dex-blob-cache/src/lib.rs +0 -0
  56. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/sdk-rust/crates/dex-blob-cache/src/policy.rs +0 -0
  57. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/sdk-rust/crates/dex-blob-cache/src/store.rs +0 -0
  58. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/sdk-rust/crates/dex-blob-cache/tests/blob_cache_integration.rs +0 -0
  59. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/sdk-rust/crates/dex-blob-cache-python/Cargo.toml +0 -0
  60. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/sdk-rust/crates/dex-blob-cache-python/LICENSE +0 -0
  61. {dex_python_sdk-0.3.1 → dex_python_sdk-0.3.2}/sdk-rust/crates/dex-blob-cache-python/src/lib.rs +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dex-python-sdk
3
- Version: 0.3.1
3
+ Version: 0.3.2
4
4
  Requires-Dist: grpcio>=1.83.0
5
5
  Requires-Dist: grpcio-status>=1.83.0
6
6
  Requires-Dist: protobuf>=7.35.1
@@ -59,6 +59,29 @@ atomic commit and Channel deletion validation. Attribute locks add isolation
59
59
  only among cooperating Steps and RPCs using the same lock. Write-only publish
60
60
  and delete operations do not require loading.
61
61
 
62
+ ## Step and timeout-handler state loading
63
+
64
+ `StepOptions` provides the same five selections independently for `wait_for` and
65
+ `execute`: all AttributeMap instances, exact AttributeMap instances, Channels,
66
+ all ChannelMap instances, and exact ChannelMap instances. The methods receive
67
+ independent snapshots. Execute reads after the winning Wait consumes messages;
68
+ retries of one logical method call reuse its first snapshot.
69
+
70
+ `FlowTimeoutHandlerOptions` provides Execute-style timeouts, heartbeat detection,
71
+ retry, durability, Attribute locks, and the same state selections. Set it on
72
+ `StartFlowOptions` or `SubFlowOptions` only for a positive timeout using `HANDLER`.
73
+ Exhausted retries may proceed to a registered `Step[None]`; read the final
74
+ failure from `Context.recovery_error`.
75
+
76
+ ```python
77
+ class TimeoutRecoveryStep(Step[None]):
78
+ def execute(self, context: Context, input: None) -> StepDecision:
79
+ failure = context.recovery_error
80
+ if failure is None:
81
+ return force_fail("timeout recovery has no failure")
82
+ return force_fail(failure.detail)
83
+ ```
84
+
62
85
  Python SDK for [Dex workflow engine](https://github.com/superdurable/dex)
63
86
 
64
87
  ## New user contracts
@@ -43,6 +43,29 @@ atomic commit and Channel deletion validation. Attribute locks add isolation
43
43
  only among cooperating Steps and RPCs using the same lock. Write-only publish
44
44
  and delete operations do not require loading.
45
45
 
46
+ ## Step and timeout-handler state loading
47
+
48
+ `StepOptions` provides the same five selections independently for `wait_for` and
49
+ `execute`: all AttributeMap instances, exact AttributeMap instances, Channels,
50
+ all ChannelMap instances, and exact ChannelMap instances. The methods receive
51
+ independent snapshots. Execute reads after the winning Wait consumes messages;
52
+ retries of one logical method call reuse its first snapshot.
53
+
54
+ `FlowTimeoutHandlerOptions` provides Execute-style timeouts, heartbeat detection,
55
+ retry, durability, Attribute locks, and the same state selections. Set it on
56
+ `StartFlowOptions` or `SubFlowOptions` only for a positive timeout using `HANDLER`.
57
+ Exhausted retries may proceed to a registered `Step[None]`; read the final
58
+ failure from `Context.recovery_error`.
59
+
60
+ ```python
61
+ class TimeoutRecoveryStep(Step[None]):
62
+ def execute(self, context: Context, input: None) -> StepDecision:
63
+ failure = context.recovery_error
64
+ if failure is None:
65
+ return force_fail("timeout recovery has no failure")
66
+ return force_fail(failure.detail)
67
+ ```
68
+
46
69
  Python SDK for [Dex workflow engine](https://github.com/superdurable/dex)
47
70
 
48
71
  ## New user contracts
@@ -36,7 +36,7 @@ from dex.codec import (
36
36
  WireKind,
37
37
  )
38
38
  from dex.condition import ConditionCombination
39
- from dex.context import AsyncContext, Context
39
+ from dex.context import AsyncContext, Context, RecoveryErrorInfo
40
40
  from dex.flow import Flow, PersistenceSchema, Registry, RPCResult, rpc
41
41
  from dex.flow_config import ActiveStepSearchMode, FlowConfig
42
42
  from dex.flow_info import (
@@ -163,6 +163,7 @@ __all__ = [
163
163
  "LongPollTimeoutError",
164
164
  "PersistenceSchema",
165
165
  "RPCResult",
166
+ "RecoveryErrorInfo",
166
167
  "RetryAfterError",
167
168
  "RpcLockConflictError",
168
169
  "Registry",
@@ -17,6 +17,7 @@ from dex._value_mapper import ValueMapper
17
17
  from dex.attribute import Attribute, AttributeMap, _apply_attribute_store_sync
18
18
  from dex.channel import Channel, ChannelMap, ChannelMessage
19
19
  from dex.codec import Codec
20
+ from dex.context import RecoveryErrorInfo
20
21
  from dex.dexpb import dex_pb2 as pb
21
22
  from dex.flow import Registry, _RegisteredFlow
22
23
  from dex.flow_result import FlowResult, flow_result_from_proto
@@ -116,6 +117,15 @@ class InvocationContext:
116
117
  def from_step_execution_id(self) -> str:
117
118
  return self._metadata.from_step_execution_id
118
119
 
120
+ @property
121
+ def recovery_error(self) -> RecoveryErrorInfo | None:
122
+ if not self._metadata.HasField("recovery_error"):
123
+ return None
124
+ return RecoveryErrorInfo(
125
+ detail=self._metadata.recovery_error.detail,
126
+ error_type=self._metadata.recovery_error.error_type,
127
+ )
128
+
119
129
  @property
120
130
  def attempt(self) -> int:
121
131
  return self._metadata.attempt
@@ -10,6 +10,7 @@
10
10
 
11
11
  from __future__ import annotations
12
12
 
13
+ from dataclasses import dataclass
13
14
  from typing import TYPE_CHECKING, Any, Protocol, Sequence, TypeVar
14
15
 
15
16
  if TYPE_CHECKING:
@@ -27,6 +28,19 @@ if TYPE_CHECKING:
27
28
  ValueT = TypeVar("ValueT")
28
29
 
29
30
 
31
+ @dataclass(frozen=True)
32
+ class RecoveryErrorInfo:
33
+ """Describe the final failure that selected a recovery path.
34
+
35
+ Attributes:
36
+ detail: Failure message supplied by the Worker or backend.
37
+ error_type: Original Worker error type or backend failure type.
38
+ """
39
+
40
+ detail: str
41
+ error_type: str
42
+
43
+
30
44
  class Context(Protocol):
31
45
  """Expose execution metadata and decision-local Step operations.
32
46
 
@@ -72,6 +86,15 @@ class Context(Protocol):
72
86
  """
73
87
  ...
74
88
 
89
+ @property
90
+ def recovery_error(self) -> RecoveryErrorInfo | None:
91
+ """Return the final failure that selected this recovery path.
92
+
93
+ Returns:
94
+ Recovery information, or ``None`` outside a recovery path.
95
+ """
96
+ ...
97
+
75
98
  @property
76
99
  def attempt(self) -> int:
77
100
  """Return the one-based handler retry attempt.
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "dex-python-sdk"
3
3
  # Publish uses tag sdk-python/v*; CI stamps this for release builds.
4
- version = "0.3.1"
4
+ version = "0.3.2"
5
5
  description = "Python SDK for the Dex workflow engine"
6
6
  authors = [{name = "Super Durable"}]
7
7
  readme = "README.md"
File without changes