durable-workflow 0.4.95__tar.gz → 0.4.96__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 (70) hide show
  1. {durable_workflow-0.4.95/src/durable_workflow.egg-info → durable_workflow-0.4.96}/PKG-INFO +1 -1
  2. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/pyproject.toml +1 -1
  3. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/client.py +13 -0
  4. {durable_workflow-0.4.95 → durable_workflow-0.4.96/src/durable_workflow.egg-info}/PKG-INFO +1 -1
  5. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_client.py +30 -1
  6. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_sync.py +22 -1
  7. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/LICENSE +0 -0
  8. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/README.md +0 -0
  9. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/setup.cfg +0 -0
  10. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/__init__.py +0 -0
  11. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/_avro.py +0 -0
  12. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/activity.py +0 -0
  13. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/auth_composition.py +0 -0
  14. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/errors.py +0 -0
  15. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/external_storage.py +0 -0
  16. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/external_task_input.py +0 -0
  17. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/external_task_result.py +0 -0
  18. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/history_bundle_verify.py +0 -0
  19. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/interceptors.py +0 -0
  20. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/invocable.py +0 -0
  21. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/metrics.py +0 -0
  22. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/nexus.py +0 -0
  23. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/py.typed +0 -0
  24. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/python_conformance.py +0 -0
  25. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/replay_conformance.py +0 -0
  26. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/replay_verify.py +0 -0
  27. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/retry_policy.py +0 -0
  28. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/serializer.py +0 -0
  29. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/sync.py +0 -0
  30. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/testing.py +0 -0
  31. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/worker.py +0 -0
  32. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/workflow.py +0 -0
  33. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow/workflow_updates_conformance.py +0 -0
  34. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow.egg-info/SOURCES.txt +0 -0
  35. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow.egg-info/dependency_links.txt +0 -0
  36. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow.egg-info/entry_points.txt +0 -0
  37. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow.egg-info/requires.txt +0 -0
  38. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/src/durable_workflow.egg-info/top_level.txt +0 -0
  39. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_activity_context.py +0 -0
  40. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_auth_composition.py +0 -0
  41. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_control_plane_parity_fixtures.py +0 -0
  42. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_errors.py +0 -0
  43. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_external_storage.py +0 -0
  44. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_external_task_input.py +0 -0
  45. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_external_task_result.py +0 -0
  46. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_golden_history_replay.py +0 -0
  47. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_history_bundle_verify.py +0 -0
  48. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_history_event_contract.py +0 -0
  49. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_invocable.py +0 -0
  50. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_metrics.py +0 -0
  51. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_order_processing_example.py +0 -0
  52. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_public_boundary_scanner.py +0 -0
  53. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_python_conformance.py +0 -0
  54. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_queries.py +0 -0
  55. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_readme_quickstart.py +0 -0
  56. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_release_docs_audit_workflow.py +0 -0
  57. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_replay.py +0 -0
  58. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_replay_conformance.py +0 -0
  59. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_replay_verify.py +0 -0
  60. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_retry_policy.py +0 -0
  61. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_schedules.py +0 -0
  62. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_serializer.py +0 -0
  63. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_signals.py +0 -0
  64. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_sleep.py +0 -0
  65. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_standalone_activity_client.py +0 -0
  66. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_testing_harness.py +0 -0
  67. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_updates.py +0 -0
  68. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_wait_condition.py +0 -0
  69. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_worker.py +0 -0
  70. {durable_workflow-0.4.95 → durable_workflow-0.4.96}/tests/test_workflow_updates_conformance.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: durable-workflow
3
- Version: 0.4.95
3
+ Version: 0.4.96
4
4
  Summary: Python SDK for the Durable Workflow server (language-neutral HTTP protocol)
5
5
  Author: Durable Workflow Contributors
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "durable-workflow"
7
- version = "0.4.95"
7
+ version = "0.4.96"
8
8
  description = "Python SDK for the Durable Workflow server (language-neutral HTTP protocol)"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -164,6 +164,8 @@ class WorkflowExecution:
164
164
  input: Any = None
165
165
  output: Any = None
166
166
  payload_codec: str | None = None
167
+ memo: dict[str, Any] | None = None
168
+ search_attributes: dict[str, Any] | None = None
167
169
 
168
170
 
169
171
  @dataclass
@@ -2386,6 +2388,10 @@ class Client:
2386
2388
  input=input_val,
2387
2389
  output=output_val,
2388
2390
  payload_codec=data.get("payload_codec"),
2391
+ memo=data.get("memo") if isinstance(data.get("memo"), dict) else None,
2392
+ search_attributes=(
2393
+ data.get("search_attributes") if isinstance(data.get("search_attributes"), dict) else None
2394
+ ),
2389
2395
  )
2390
2396
 
2391
2397
  async def list_workflows(
@@ -2425,6 +2431,13 @@ class Client:
2425
2431
  run_id=item.get("run_id"),
2426
2432
  workflow_type=item.get("workflow_type", ""),
2427
2433
  status=item.get("status"),
2434
+ namespace=item.get("namespace"),
2435
+ task_queue=item.get("task_queue"),
2436
+ payload_codec=item.get("payload_codec"),
2437
+ memo=item.get("memo") if isinstance(item.get("memo"), dict) else None,
2438
+ search_attributes=(
2439
+ item.get("search_attributes") if isinstance(item.get("search_attributes"), dict) else None
2440
+ ),
2428
2441
  )
2429
2442
  for item in items
2430
2443
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: durable-workflow
3
- Version: 0.4.95
3
+ Version: 0.4.96
4
4
  Summary: Python SDK for the Durable Workflow server (language-neutral HTTP protocol)
5
5
  Author: Durable Workflow Contributors
6
6
  License-Expression: MIT
@@ -464,6 +464,8 @@ class TestDescribeWorkflow:
464
464
  assert desc.status == response["status"]
465
465
  assert desc.payload_codec == response["payload_codec"]
466
466
  assert desc.input == response["input"]
467
+ assert desc.memo == response["memo"]
468
+ assert desc.search_attributes == response["search_attributes"]
467
469
 
468
470
  @pytest.mark.asyncio
469
471
  async def test_envelope_fields(self, client: Client) -> None:
@@ -1131,7 +1133,23 @@ class TestListWorkflows:
1131
1133
  async def test_list(self, client: Client) -> None:
1132
1134
  resp = _mock_response(200, {
1133
1135
  "workflows": [
1134
- {"workflow_id": "wf-1", "run_id": "r1", "workflow_type": "greeter", "status": "running"},
1136
+ {
1137
+ "workflow_id": "wf-1",
1138
+ "run_id": "r1",
1139
+ "workflow_type": "greeter",
1140
+ "status": "running",
1141
+ "namespace": "ns1",
1142
+ "task_queue": "q1",
1143
+ "payload_codec": "avro",
1144
+ "memo": {"source": "php-writer"},
1145
+ "search_attributes": {
1146
+ "customer_id": "cust-php-1",
1147
+ "order_total_cents": 9200,
1148
+ "discount_ratio": 0.125,
1149
+ "is_vip": True,
1150
+ "tags": ["urgent", "renewal"],
1151
+ },
1152
+ },
1135
1153
  {"workflow_id": "wf-2", "run_id": "r2", "workflow_type": "greeter", "status": "completed"},
1136
1154
  ],
1137
1155
  "next_page_token": "abc",
@@ -1141,6 +1159,17 @@ class TestListWorkflows:
1141
1159
  assert len(result.executions) == 2
1142
1160
  assert result.next_page_token == "abc"
1143
1161
  assert result.executions[0].workflow_id == "wf-1"
1162
+ assert result.executions[0].namespace == "ns1"
1163
+ assert result.executions[0].task_queue == "q1"
1164
+ assert result.executions[0].payload_codec == "avro"
1165
+ assert result.executions[0].memo == {"source": "php-writer"}
1166
+ assert result.executions[0].search_attributes == {
1167
+ "customer_id": "cust-php-1",
1168
+ "order_total_cents": 9200,
1169
+ "discount_ratio": 0.125,
1170
+ "is_vip": True,
1171
+ "tags": ["urgent", "renewal"],
1172
+ }
1144
1173
 
1145
1174
  @pytest.mark.asyncio
1146
1175
  async def test_list_request_matches_polyglot_fixture(self, client: Client) -> None:
@@ -156,11 +156,23 @@ class TestSyncClientDescribe:
156
156
  "run_id": "run-1",
157
157
  "workflow_type": "greeter",
158
158
  "status": "running",
159
+ "search_attributes": {
160
+ "customer_id": "cust-php-sync",
161
+ "order_total_cents": 6100,
162
+ "is_vip": False,
163
+ "tags": ["standard", "renewal"],
164
+ },
159
165
  },
160
166
  )
161
167
  with patch.object(client._async._http, "request", new_callable=AsyncMock, return_value=resp):
162
168
  desc = client.describe_workflow("wf-1")
163
169
  assert desc.status == "running"
170
+ assert desc.search_attributes == {
171
+ "customer_id": "cust-php-sync",
172
+ "order_total_cents": 6100,
173
+ "is_vip": False,
174
+ "tags": ["standard", "renewal"],
175
+ }
164
176
 
165
177
 
166
178
  class TestSyncClientSignal:
@@ -202,12 +214,21 @@ class TestSyncClientList:
202
214
  resp = _mock_response(
203
215
  200,
204
216
  {
205
- "workflows": [{"workflow_id": "wf-1", "run_id": "r1", "workflow_type": "g", "status": "running"}],
217
+ "workflows": [
218
+ {
219
+ "workflow_id": "wf-1",
220
+ "run_id": "r1",
221
+ "workflow_type": "g",
222
+ "status": "running",
223
+ "search_attributes": {"customer_id": "cust-php-sync"},
224
+ }
225
+ ],
206
226
  },
207
227
  )
208
228
  with patch.object(client._async._http, "request", new_callable=AsyncMock, return_value=resp):
209
229
  result = client.list_workflows(workflow_type="g")
210
230
  assert len(result.executions) == 1
231
+ assert result.executions[0].search_attributes == {"customer_id": "cust-php-sync"}
211
232
 
212
233
  def test_list_task_queues(self) -> None:
213
234
  client = Client("http://localhost:8080")