dex-python-sdk 0.1.10__tar.gz → 0.1.11__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 (60) hide show
  1. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/PKG-INFO +1 -1
  2. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/_grpc_errors.py +52 -2
  3. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/pyproject.toml +1 -1
  4. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/LEGACY_NOTICES.md +0 -0
  5. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/LICENSE +0 -0
  6. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/README.md +0 -0
  7. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/__init__.py +0 -0
  8. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/_async_value_hydrator.py +0 -0
  9. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/_async_worker_dispatcher.py +0 -0
  10. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/_async_worker_service.py +0 -0
  11. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/_invocation_context.py +0 -0
  12. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/_native.pyi +0 -0
  13. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/_utils.py +0 -0
  14. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/_value_hydrator.py +0 -0
  15. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/_value_mapper.py +0 -0
  16. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/_worker_dispatcher.py +0 -0
  17. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/_worker_service.py +0 -0
  18. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/async_client.py +0 -0
  19. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/async_worker.py +0 -0
  20. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/attribute.py +0 -0
  21. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/blob_cache.py +0 -0
  22. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/channel.py +0 -0
  23. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/client.py +0 -0
  24. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/client_options.py +0 -0
  25. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/codec.py +0 -0
  26. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/condition.py +0 -0
  27. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/context.py +0 -0
  28. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/dexpb/__init__.py +0 -0
  29. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/dexpb/dex_pb2.py +0 -0
  30. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/dexpb/dex_pb2.pyi +0 -0
  31. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/dexpb/dex_pb2_grpc.py +0 -0
  32. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/flow.py +0 -0
  33. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/flow_config.py +0 -0
  34. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/flow_info.py +0 -0
  35. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/flow_options.py +0 -0
  36. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/flow_result.py +0 -0
  37. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/py.typed +0 -0
  38. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/runtime_errors.py +0 -0
  39. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/step.py +0 -0
  40. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/step_execution.py +0 -0
  41. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/subflow.py +0 -0
  42. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/timer.py +0 -0
  43. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/wait.py +0 -0
  44. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/worker.py +0 -0
  45. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/dex/worker_options.py +0 -0
  46. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/sdk-rust/Cargo.lock +0 -0
  47. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/sdk-rust/Cargo.toml +0 -0
  48. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/sdk-rust/crates/dex-blob-cache/Cargo.toml +0 -0
  49. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/sdk-rust/crates/dex-blob-cache/LICENSE +0 -0
  50. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/sdk-rust/crates/dex-blob-cache/src/config.rs +0 -0
  51. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/sdk-rust/crates/dex-blob-cache/src/entry.rs +0 -0
  52. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/sdk-rust/crates/dex-blob-cache/src/error.rs +0 -0
  53. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/sdk-rust/crates/dex-blob-cache/src/format.rs +0 -0
  54. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/sdk-rust/crates/dex-blob-cache/src/lib.rs +0 -0
  55. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/sdk-rust/crates/dex-blob-cache/src/policy.rs +0 -0
  56. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/sdk-rust/crates/dex-blob-cache/src/store.rs +0 -0
  57. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/sdk-rust/crates/dex-blob-cache/tests/blob_cache_integration.rs +0 -0
  58. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/sdk-rust/crates/dex-blob-cache-python/Cargo.toml +0 -0
  59. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/sdk-rust/crates/dex-blob-cache-python/LICENSE +0 -0
  60. {dex_python_sdk-0.1.10 → dex_python_sdk-0.1.11}/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.1.10
3
+ Version: 0.1.11
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
@@ -8,6 +8,8 @@
8
8
 
9
9
  from __future__ import annotations
10
10
 
11
+ import traceback
12
+ from dataclasses import dataclass
11
13
  from typing import Any, Literal, cast
12
14
 
13
15
  import grpc
@@ -29,6 +31,28 @@ from dex.runtime_errors import (
29
31
 
30
32
  FlowTargetRequirement = Literal["none", "existing", "active"]
31
33
 
34
+ MAX_WORKER_STACK_TRACE_BYTES = 16 * 1024
35
+ _STACK_TRACE_TRUNCATION_MARKER = b"\n... stack trace truncated by Dex Python SDK ..."
36
+
37
+
38
+ @dataclass(frozen=True)
39
+ class RetryAfterError(Exception):
40
+ """Requests a delay before the next retry while preserving the current failure."""
41
+
42
+ after_seconds: int
43
+ cause: BaseException
44
+
45
+ def __str__(self) -> str:
46
+ return str(self.cause)
47
+
48
+
49
+ def retry_after(after_seconds: int, cause: BaseException) -> RetryAfterError:
50
+ if cause is None:
51
+ raise ValueError("cause is required")
52
+ if after_seconds <= 0:
53
+ raise ValueError("after_seconds must be positive")
54
+ return RetryAfterError(after_seconds=after_seconds, cause=cause)
55
+
32
56
 
33
57
  def translate_rpc_error(
34
58
  error: grpc.RpcError,
@@ -118,11 +142,21 @@ async def async_abort_worker_error(
118
142
 
119
143
 
120
144
  def _worker_error_status(error: BaseException) -> status_pb2.Status:
121
- message = str(error) or type(error).__name__
145
+ retry_after_error: RetryAfterError | None = None
146
+ reported = error
147
+ if isinstance(error, RetryAfterError):
148
+ retry_after_error = error
149
+ reported = error.cause
150
+
151
+ message = str(reported) or type(reported).__name__
152
+ stack_trace_source = error if retry_after_error is not None else reported
122
153
  worker_error = pb.WorkerErrorResponse(
123
154
  detail=message,
124
- error_type=f"{type(error).__module__}.{type(error).__qualname__}",
155
+ error_type=f"{type(reported).__module__}.{type(reported).__qualname__}",
156
+ stack_trace=_worker_stack_trace(stack_trace_source),
125
157
  )
158
+ if retry_after_error is not None:
159
+ worker_error.retry_after_seconds = retry_after_error.after_seconds
126
160
  packed = any_pb2.Any()
127
161
  packed.Pack(worker_error)
128
162
  return status_pb2.Status(
@@ -132,6 +166,22 @@ def _worker_error_status(error: BaseException) -> status_pb2.Status:
132
166
  )
133
167
 
134
168
 
169
+ def _worker_stack_trace(error: BaseException) -> str:
170
+ if error.__traceback__ is None:
171
+ return ""
172
+ lines = traceback.format_exception(type(error), error, error.__traceback__)
173
+ encoded = "".join(lines).encode()
174
+ if len(encoded) <= MAX_WORKER_STACK_TRACE_BYTES:
175
+ return encoded.decode()
176
+ prefix_length = MAX_WORKER_STACK_TRACE_BYTES - len(_STACK_TRACE_TRUNCATION_MARKER)
177
+ while prefix_length > 0 and (encoded[prefix_length] & 0xC0) == 0x80:
178
+ prefix_length -= 1
179
+ return (
180
+ encoded[:prefix_length].decode(errors="replace")
181
+ + _STACK_TRACE_TRUNCATION_MARKER.decode()
182
+ )
183
+
184
+
135
185
  def _map_sub_status(value: int) -> ErrorSubStatus:
136
186
  statuses: dict[int, ErrorSubStatus] = {
137
187
  int(pb.ERROR_SUB_STATUS_UNCATEGORIZED): ErrorSubStatus.UNCATEGORIZED,
@@ -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.1.10"
4
+ version = "0.1.11"
5
5
  description = "Python SDK for the Dex workflow engine"
6
6
  authors = [{name = "Super Durable"}]
7
7
  readme = "README.md"
File without changes