durable-workflow 0.4.45__tar.gz → 0.4.46__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.
- {durable_workflow-0.4.45/src/durable_workflow.egg-info → durable_workflow-0.4.46}/PKG-INFO +1 -1
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/pyproject.toml +1 -1
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/worker.py +38 -6
- {durable_workflow-0.4.45 → durable_workflow-0.4.46/src/durable_workflow.egg-info}/PKG-INFO +1 -1
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_worker.py +113 -14
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/LICENSE +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/README.md +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/setup.cfg +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/__init__.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/_avro.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/activity.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/auth_composition.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/client.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/errors.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/external_storage.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/external_task_input.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/external_task_result.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/history_bundle_verify.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/interceptors.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/invocable.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/metrics.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/py.typed +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/replay_verify.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/retry_policy.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/serializer.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/sync.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/testing.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/workflow.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow.egg-info/SOURCES.txt +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow.egg-info/dependency_links.txt +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow.egg-info/entry_points.txt +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow.egg-info/requires.txt +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow.egg-info/top_level.txt +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_activity_context.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_auth_composition.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_client.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_control_plane_parity_fixtures.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_errors.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_external_storage.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_external_task_input.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_external_task_result.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_golden_history_replay.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_history_bundle_verify.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_history_event_contract.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_invocable.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_metrics.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_order_processing_example.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_public_boundary_scanner.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_queries.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_readme_quickstart.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_replay.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_replay_verify.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_retry_policy.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_schedules.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_serializer.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_signals.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_sleep.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_standalone_activity_client.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_sync.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_testing_harness.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_updates.py +0 -0
- {durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_wait_condition.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "durable-workflow"
|
|
7
|
-
version = "0.4.
|
|
7
|
+
version = "0.4.46"
|
|
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"
|
|
@@ -45,7 +45,15 @@ from .client import (
|
|
|
45
45
|
Client,
|
|
46
46
|
WorkflowExecution,
|
|
47
47
|
)
|
|
48
|
-
from .errors import
|
|
48
|
+
from .errors import (
|
|
49
|
+
ActivityCancelled,
|
|
50
|
+
AvroNotInstalledError,
|
|
51
|
+
DurableWorkflowError,
|
|
52
|
+
InvalidArgument,
|
|
53
|
+
NonRetryableError,
|
|
54
|
+
QueryFailed,
|
|
55
|
+
ServerError,
|
|
56
|
+
)
|
|
49
57
|
from .external_storage import ExternalPayloadCache, ExternalStorageDriver
|
|
50
58
|
from .interceptors import (
|
|
51
59
|
ActivityInterceptorContext,
|
|
@@ -74,6 +82,15 @@ _QUERY_TASK_FINAL_REJECTION_REASONS = {
|
|
|
74
82
|
"query_task_not_leased",
|
|
75
83
|
"query_task_timed_out",
|
|
76
84
|
}
|
|
85
|
+
_WORKFLOW_TASK_COMPLETION_AMBIGUOUS_REJECTION_REASONS = {
|
|
86
|
+
"lease_expired",
|
|
87
|
+
"lease_owner_mismatch",
|
|
88
|
+
"run_already_closed",
|
|
89
|
+
"run_closed",
|
|
90
|
+
"task_not_found",
|
|
91
|
+
"task_not_leased",
|
|
92
|
+
"workflow_task_attempt_mismatch",
|
|
93
|
+
}
|
|
77
94
|
_WORKER_WORKFLOW_FINGERPRINTS: dict[tuple[str, str], str] = {}
|
|
78
95
|
|
|
79
96
|
|
|
@@ -111,6 +128,19 @@ def _is_final_query_task_rejection(error: BaseException) -> bool:
|
|
|
111
128
|
)
|
|
112
129
|
|
|
113
130
|
|
|
131
|
+
def _should_fail_workflow_task_after_completion_error(error: BaseException) -> bool:
|
|
132
|
+
if isinstance(error, InvalidArgument):
|
|
133
|
+
return True
|
|
134
|
+
|
|
135
|
+
if isinstance(error, ServerError):
|
|
136
|
+
if error.status >= 500 or error.status == 429:
|
|
137
|
+
return False
|
|
138
|
+
|
|
139
|
+
return error.reason() not in _WORKFLOW_TASK_COMPLETION_AMBIGUOUS_REJECTION_REASONS
|
|
140
|
+
|
|
141
|
+
return isinstance(error, DurableWorkflowError)
|
|
142
|
+
|
|
143
|
+
|
|
114
144
|
def _signal_arguments_envelope_from_export(
|
|
115
145
|
signal: Mapping[str, Any],
|
|
116
146
|
*,
|
|
@@ -775,8 +805,9 @@ class Worker:
|
|
|
775
805
|
)
|
|
776
806
|
except Exception as e:
|
|
777
807
|
log.warning("failed to complete workflow update task %s: %s", task_id, e)
|
|
778
|
-
|
|
779
|
-
|
|
808
|
+
if _should_fail_workflow_task_after_completion_error(e):
|
|
809
|
+
await self._report_workflow_task_after_completion_error(task_id, attempt, e)
|
|
810
|
+
return None
|
|
780
811
|
return [command]
|
|
781
812
|
|
|
782
813
|
try:
|
|
@@ -849,11 +880,12 @@ class Worker:
|
|
|
849
880
|
)
|
|
850
881
|
except Exception as e:
|
|
851
882
|
log.warning("failed to complete workflow task %s: %s", task_id, e)
|
|
852
|
-
|
|
853
|
-
|
|
883
|
+
if _should_fail_workflow_task_after_completion_error(e):
|
|
884
|
+
await self._report_workflow_task_after_completion_error(task_id, attempt, e)
|
|
885
|
+
return None
|
|
854
886
|
return commands
|
|
855
887
|
|
|
856
|
-
async def
|
|
888
|
+
async def _report_workflow_task_after_completion_error(
|
|
857
889
|
self,
|
|
858
890
|
task_id: str,
|
|
859
891
|
attempt: int,
|
|
@@ -22,7 +22,7 @@ from durable_workflow.client import (
|
|
|
22
22
|
Client,
|
|
23
23
|
WorkflowExecution,
|
|
24
24
|
)
|
|
25
|
-
from durable_workflow.errors import ServerError
|
|
25
|
+
from durable_workflow.errors import InvalidArgument, ServerError, Unauthorized, WorkflowNotFound
|
|
26
26
|
from durable_workflow.interceptors import (
|
|
27
27
|
ActivityHandler,
|
|
28
28
|
ActivityInterceptorContext,
|
|
@@ -32,7 +32,7 @@ from durable_workflow.interceptors import (
|
|
|
32
32
|
WorkflowTaskHandler,
|
|
33
33
|
WorkflowTaskInterceptorContext,
|
|
34
34
|
)
|
|
35
|
-
from durable_workflow.worker import Worker
|
|
35
|
+
from durable_workflow.worker import Worker, _should_fail_workflow_task_after_completion_error
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
@workflow.defn(name="test-wf")
|
|
@@ -185,6 +185,28 @@ def compatible_cluster_info(**overrides: object) -> dict[str, object]:
|
|
|
185
185
|
return info
|
|
186
186
|
|
|
187
187
|
|
|
188
|
+
class TestWorkflowTaskCompletionErrorClassification:
|
|
189
|
+
@pytest.mark.parametrize(
|
|
190
|
+
("error", "should_fail"),
|
|
191
|
+
[
|
|
192
|
+
(TimeoutError("completion timed out"), False),
|
|
193
|
+
(RuntimeError("connection reset"), False),
|
|
194
|
+
(ServerError(409, {"reason": "lease_expired"}), False),
|
|
195
|
+
(ServerError(409, {"reason": "workflow_task_attempt_mismatch"}), False),
|
|
196
|
+
(ServerError(429, {"reason": "rate_limited"}), False),
|
|
197
|
+
(ServerError(503, {"reason": "server_busy"}), False),
|
|
198
|
+
(ServerError(409, {"reason": "invalid_commands"}), True),
|
|
199
|
+
(InvalidArgument("invalid command payload"), True),
|
|
200
|
+
(Unauthorized("missing bearer token"), True),
|
|
201
|
+
(WorkflowNotFound("wf-missing"), True),
|
|
202
|
+
],
|
|
203
|
+
)
|
|
204
|
+
def test_classifies_definite_and_ambiguous_completion_errors(
|
|
205
|
+
self, error: BaseException, should_fail: bool
|
|
206
|
+
) -> None:
|
|
207
|
+
assert _should_fail_workflow_task_after_completion_error(error) is should_fail
|
|
208
|
+
|
|
209
|
+
|
|
188
210
|
class TestWorkerRegistration:
|
|
189
211
|
@pytest.mark.asyncio
|
|
190
212
|
async def test_register(self, mock_client: AsyncMock) -> None:
|
|
@@ -502,7 +524,7 @@ class TestWorkflowTaskExecution:
|
|
|
502
524
|
assert serializer.decode(commands[0]["arguments"]["blob"], codec="json") == ["hello"]
|
|
503
525
|
|
|
504
526
|
@pytest.mark.asyncio
|
|
505
|
-
async def
|
|
527
|
+
async def test_workflow_task_ambiguous_completion_error_preserves_commands(
|
|
506
528
|
self, mock_client: AsyncMock
|
|
507
529
|
) -> None:
|
|
508
530
|
mock_client.complete_workflow_task.side_effect = TimeoutError("completion timed out")
|
|
@@ -518,15 +540,96 @@ class TestWorkflowTaskExecution:
|
|
|
518
540
|
|
|
519
541
|
result = await worker._run_workflow_task(task)
|
|
520
542
|
|
|
543
|
+
assert result is not None
|
|
544
|
+
assert result[0]["type"] == "schedule_activity"
|
|
545
|
+
mock_client.complete_workflow_task.assert_awaited_once()
|
|
546
|
+
mock_client.fail_workflow_task.assert_not_called()
|
|
547
|
+
|
|
548
|
+
@pytest.mark.asyncio
|
|
549
|
+
async def test_workflow_task_definite_completion_rejection_fails_task(
|
|
550
|
+
self, mock_client: AsyncMock
|
|
551
|
+
) -> None:
|
|
552
|
+
mock_client.complete_workflow_task.side_effect = ServerError(409, {"reason": "invalid_commands"})
|
|
553
|
+
worker = Worker(mock_client, task_queue="q1", workflows=[TestWorkflow], activities=[])
|
|
554
|
+
task = {
|
|
555
|
+
"task_id": "t-complete-invalid",
|
|
556
|
+
"workflow_type": "test-wf",
|
|
557
|
+
"workflow_task_attempt": 2,
|
|
558
|
+
"history_events": [],
|
|
559
|
+
"arguments": '["hello"]',
|
|
560
|
+
"payload_codec": "json",
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
result = await worker._run_workflow_task(task)
|
|
564
|
+
|
|
565
|
+
assert result is None
|
|
566
|
+
mock_client.fail_workflow_task.assert_awaited_once()
|
|
567
|
+
call_kwargs = mock_client.fail_workflow_task.await_args.kwargs
|
|
568
|
+
assert call_kwargs["task_id"] == "t-complete-invalid"
|
|
569
|
+
assert call_kwargs["workflow_task_attempt"] == 2
|
|
570
|
+
assert call_kwargs["lease_owner"] == worker.worker_id
|
|
571
|
+
assert call_kwargs["failure_type"] == "ServerError"
|
|
572
|
+
assert "invalid_commands" in call_kwargs["message"]
|
|
573
|
+
|
|
574
|
+
@pytest.mark.parametrize(
|
|
575
|
+
("completion_error", "failure_type", "message_fragment"),
|
|
576
|
+
[
|
|
577
|
+
(Unauthorized("missing bearer token"), "Unauthorized", "missing bearer token"),
|
|
578
|
+
(WorkflowNotFound("wf-typed-missing"), "WorkflowNotFound", "wf-typed-missing"),
|
|
579
|
+
],
|
|
580
|
+
)
|
|
581
|
+
@pytest.mark.asyncio
|
|
582
|
+
async def test_workflow_task_typed_completion_rejection_fails_task(
|
|
583
|
+
self,
|
|
584
|
+
mock_client: AsyncMock,
|
|
585
|
+
completion_error: Exception,
|
|
586
|
+
failure_type: str,
|
|
587
|
+
message_fragment: str,
|
|
588
|
+
) -> None:
|
|
589
|
+
mock_client.complete_workflow_task.side_effect = completion_error
|
|
590
|
+
worker = Worker(mock_client, task_queue="q1", workflows=[TestWorkflow], activities=[])
|
|
591
|
+
task = {
|
|
592
|
+
"task_id": "t-complete-typed-rejection",
|
|
593
|
+
"workflow_type": "test-wf",
|
|
594
|
+
"workflow_task_attempt": 2,
|
|
595
|
+
"history_events": [],
|
|
596
|
+
"arguments": '["hello"]',
|
|
597
|
+
"payload_codec": "json",
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
result = await worker._run_workflow_task(task)
|
|
601
|
+
|
|
521
602
|
assert result is None
|
|
522
603
|
mock_client.complete_workflow_task.assert_awaited_once()
|
|
523
604
|
mock_client.fail_workflow_task.assert_awaited_once()
|
|
524
605
|
call_kwargs = mock_client.fail_workflow_task.await_args.kwargs
|
|
525
|
-
assert call_kwargs["task_id"] == "t-complete-
|
|
606
|
+
assert call_kwargs["task_id"] == "t-complete-typed-rejection"
|
|
526
607
|
assert call_kwargs["workflow_task_attempt"] == 2
|
|
527
608
|
assert call_kwargs["lease_owner"] == worker.worker_id
|
|
528
|
-
assert call_kwargs["failure_type"] ==
|
|
529
|
-
assert
|
|
609
|
+
assert call_kwargs["failure_type"] == failure_type
|
|
610
|
+
assert message_fragment in call_kwargs["message"]
|
|
611
|
+
|
|
612
|
+
@pytest.mark.asyncio
|
|
613
|
+
async def test_workflow_task_definite_completion_rejection_stays_failed_when_report_fails(
|
|
614
|
+
self, mock_client: AsyncMock
|
|
615
|
+
) -> None:
|
|
616
|
+
mock_client.complete_workflow_task.side_effect = ServerError(409, {"reason": "invalid_commands"})
|
|
617
|
+
mock_client.fail_workflow_task.side_effect = RuntimeError("failure report unavailable")
|
|
618
|
+
worker = Worker(mock_client, task_queue="q1", workflows=[TestWorkflow], activities=[])
|
|
619
|
+
task = {
|
|
620
|
+
"task_id": "t-complete-invalid-report-fails",
|
|
621
|
+
"workflow_type": "test-wf",
|
|
622
|
+
"workflow_task_attempt": 2,
|
|
623
|
+
"history_events": [],
|
|
624
|
+
"arguments": '["hello"]',
|
|
625
|
+
"payload_codec": "json",
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
result = await worker._run_workflow_task(task)
|
|
629
|
+
|
|
630
|
+
assert result is None
|
|
631
|
+
mock_client.complete_workflow_task.assert_awaited_once()
|
|
632
|
+
mock_client.fail_workflow_task.assert_awaited_once()
|
|
530
633
|
|
|
531
634
|
@pytest.mark.asyncio
|
|
532
635
|
async def test_workflow_command_payload_warning_uses_client_policy(
|
|
@@ -701,7 +804,7 @@ class TestWorkflowTaskExecution:
|
|
|
701
804
|
mock_client.fail_workflow_task.assert_not_called()
|
|
702
805
|
|
|
703
806
|
@pytest.mark.asyncio
|
|
704
|
-
async def
|
|
807
|
+
async def test_update_task_ambiguous_completion_error_preserves_command(
|
|
705
808
|
self, mock_client: AsyncMock
|
|
706
809
|
) -> None:
|
|
707
810
|
mock_client.complete_workflow_task.side_effect = TimeoutError("update completion timed out")
|
|
@@ -729,14 +832,10 @@ class TestWorkflowTaskExecution:
|
|
|
729
832
|
|
|
730
833
|
result = await worker._run_workflow_task(task)
|
|
731
834
|
|
|
732
|
-
assert result is None
|
|
835
|
+
assert result is not None
|
|
836
|
+
assert result[0]["type"] == "complete_update"
|
|
733
837
|
mock_client.complete_workflow_task.assert_awaited_once()
|
|
734
|
-
mock_client.fail_workflow_task.
|
|
735
|
-
call_kwargs = mock_client.fail_workflow_task.await_args.kwargs
|
|
736
|
-
assert call_kwargs["task_id"] == "t-update-timeout"
|
|
737
|
-
assert call_kwargs["workflow_task_attempt"] == 3
|
|
738
|
-
assert call_kwargs["failure_type"] == "TimeoutError"
|
|
739
|
-
assert "update completion timed out" in call_kwargs["message"]
|
|
838
|
+
mock_client.fail_workflow_task.assert_not_called()
|
|
740
839
|
|
|
741
840
|
@pytest.mark.asyncio
|
|
742
841
|
async def test_query_task_executes_registered_query(self, mock_client: AsyncMock) -> None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/auth_composition.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/external_storage.py
RENAMED
|
File without changes
|
{durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/external_task_input.py
RENAMED
|
File without changes
|
{durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/external_task_result.py
RENAMED
|
File without changes
|
{durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow/history_bundle_verify.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow.egg-info/requires.txt
RENAMED
|
File without changes
|
{durable_workflow-0.4.45 → durable_workflow-0.4.46}/src/durable_workflow.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_control_plane_parity_fixtures.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-0.4.45 → durable_workflow-0.4.46}/tests/test_standalone_activity_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|