azure-functions-durable 1.2.8__py3-none-any.whl → 1.2.10__py3-none-any.whl

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 (101) hide show
  1. azure/durable_functions/__init__.py +81 -81
  2. azure/durable_functions/constants.py +9 -9
  3. azure/durable_functions/decorators/__init__.py +3 -3
  4. azure/durable_functions/decorators/durable_app.py +249 -249
  5. azure/durable_functions/decorators/metadata.py +109 -109
  6. azure/durable_functions/entity.py +125 -125
  7. azure/durable_functions/models/DurableEntityContext.py +201 -201
  8. azure/durable_functions/models/DurableHttpRequest.py +58 -58
  9. azure/durable_functions/models/DurableOrchestrationBindings.py +66 -66
  10. azure/durable_functions/models/DurableOrchestrationClient.py +781 -711
  11. azure/durable_functions/models/DurableOrchestrationContext.py +722 -707
  12. azure/durable_functions/models/DurableOrchestrationStatus.py +156 -156
  13. azure/durable_functions/models/EntityStateResponse.py +23 -23
  14. azure/durable_functions/models/FunctionContext.py +7 -7
  15. azure/durable_functions/models/OrchestrationRuntimeStatus.py +32 -29
  16. azure/durable_functions/models/OrchestratorState.py +117 -116
  17. azure/durable_functions/models/PurgeHistoryResult.py +33 -33
  18. azure/durable_functions/models/ReplaySchema.py +8 -8
  19. azure/durable_functions/models/RetryOptions.py +69 -69
  20. azure/durable_functions/models/RpcManagementOptions.py +86 -86
  21. azure/durable_functions/models/Task.py +426 -426
  22. azure/durable_functions/models/TaskOrchestrationExecutor.py +346 -333
  23. azure/durable_functions/models/TokenSource.py +56 -56
  24. azure/durable_functions/models/__init__.py +24 -24
  25. azure/durable_functions/models/actions/Action.py +23 -23
  26. azure/durable_functions/models/actions/ActionType.py +18 -18
  27. azure/durable_functions/models/actions/CallActivityAction.py +41 -41
  28. azure/durable_functions/models/actions/CallActivityWithRetryAction.py +45 -45
  29. azure/durable_functions/models/actions/CallEntityAction.py +46 -46
  30. azure/durable_functions/models/actions/CallHttpAction.py +35 -35
  31. azure/durable_functions/models/actions/CallSubOrchestratorAction.py +40 -40
  32. azure/durable_functions/models/actions/CallSubOrchestratorWithRetryAction.py +44 -44
  33. azure/durable_functions/models/actions/CompoundAction.py +35 -35
  34. azure/durable_functions/models/actions/ContinueAsNewAction.py +36 -36
  35. azure/durable_functions/models/actions/CreateTimerAction.py +48 -48
  36. azure/durable_functions/models/actions/NoOpAction.py +35 -35
  37. azure/durable_functions/models/actions/SignalEntityAction.py +47 -47
  38. azure/durable_functions/models/actions/WaitForExternalEventAction.py +63 -63
  39. azure/durable_functions/models/actions/WhenAllAction.py +14 -14
  40. azure/durable_functions/models/actions/WhenAnyAction.py +14 -14
  41. azure/durable_functions/models/actions/__init__.py +24 -24
  42. azure/durable_functions/models/entities/EntityState.py +74 -74
  43. azure/durable_functions/models/entities/OperationResult.py +76 -76
  44. azure/durable_functions/models/entities/RequestMessage.py +53 -53
  45. azure/durable_functions/models/entities/ResponseMessage.py +48 -48
  46. azure/durable_functions/models/entities/Signal.py +62 -62
  47. azure/durable_functions/models/entities/__init__.py +17 -17
  48. azure/durable_functions/models/history/HistoryEvent.py +92 -92
  49. azure/durable_functions/models/history/HistoryEventType.py +27 -25
  50. azure/durable_functions/models/history/__init__.py +8 -8
  51. azure/durable_functions/models/utils/__init__.py +7 -7
  52. azure/durable_functions/models/utils/entity_utils.py +103 -91
  53. azure/durable_functions/models/utils/http_utils.py +69 -69
  54. azure/durable_functions/models/utils/json_utils.py +56 -56
  55. azure/durable_functions/orchestrator.py +71 -71
  56. {azure_functions_durable-1.2.8.dist-info → azure_functions_durable-1.2.10.dist-info}/LICENSE +21 -21
  57. {azure_functions_durable-1.2.8.dist-info → azure_functions_durable-1.2.10.dist-info}/METADATA +58 -58
  58. azure_functions_durable-1.2.10.dist-info/RECORD +100 -0
  59. {azure_functions_durable-1.2.8.dist-info → azure_functions_durable-1.2.10.dist-info}/WHEEL +1 -1
  60. tests/models/test_DecoratorMetadata.py +135 -135
  61. tests/models/test_Decorators.py +107 -107
  62. tests/models/test_DurableOrchestrationBindings.py +68 -56
  63. tests/models/test_DurableOrchestrationClient.py +730 -612
  64. tests/models/test_DurableOrchestrationContext.py +102 -102
  65. tests/models/test_DurableOrchestrationStatus.py +59 -59
  66. tests/models/test_OrchestrationState.py +28 -28
  67. tests/models/test_RpcManagementOptions.py +79 -79
  68. tests/models/test_TokenSource.py +10 -10
  69. tests/orchestrator/models/OrchestrationInstance.py +18 -18
  70. tests/orchestrator/orchestrator_test_utils.py +130 -130
  71. tests/orchestrator/schemas/OrchetrationStateSchema.py +66 -66
  72. tests/orchestrator/test_call_http.py +235 -176
  73. tests/orchestrator/test_continue_as_new.py +67 -67
  74. tests/orchestrator/test_create_timer.py +126 -126
  75. tests/orchestrator/test_entity.py +395 -395
  76. tests/orchestrator/test_external_event.py +53 -53
  77. tests/orchestrator/test_fan_out_fan_in.py +175 -175
  78. tests/orchestrator/test_is_replaying_flag.py +101 -101
  79. tests/orchestrator/test_retries.py +308 -308
  80. tests/orchestrator/test_sequential_orchestrator.py +841 -801
  81. tests/orchestrator/test_sequential_orchestrator_custom_status.py +119 -119
  82. tests/orchestrator/test_sequential_orchestrator_with_retry.py +465 -465
  83. tests/orchestrator/test_serialization.py +30 -30
  84. tests/orchestrator/test_sub_orchestrator.py +95 -95
  85. tests/orchestrator/test_sub_orchestrator_with_retry.py +129 -129
  86. tests/orchestrator/test_task_any.py +60 -60
  87. tests/tasks/tasks_test_utils.py +17 -17
  88. tests/tasks/test_new_uuid.py +34 -34
  89. tests/test_utils/ContextBuilder.py +174 -174
  90. tests/test_utils/EntityContextBuilder.py +56 -56
  91. tests/test_utils/constants.py +1 -1
  92. tests/test_utils/json_utils.py +30 -30
  93. tests/test_utils/testClasses.py +56 -56
  94. tests/utils/__init__.py +1 -0
  95. tests/utils/test_entity_utils.py +24 -0
  96. azure_functions_durable-1.2.8.data/data/_manifest/bsi.json +0 -1
  97. azure_functions_durable-1.2.8.data/data/_manifest/manifest.cat +0 -0
  98. azure_functions_durable-1.2.8.data/data/_manifest/manifest.spdx.json +0 -12845
  99. azure_functions_durable-1.2.8.data/data/_manifest/manifest.spdx.json.sha256 +0 -1
  100. azure_functions_durable-1.2.8.dist-info/RECORD +0 -102
  101. {azure_functions_durable-1.2.8.dist-info → azure_functions_durable-1.2.10.dist-info}/top_level.txt +0 -0
@@ -1,127 +1,127 @@
1
- from azure.durable_functions.models.ReplaySchema import ReplaySchema
2
- from azure.durable_functions.models.actions.WhenAnyAction import WhenAnyAction
3
- from tests.test_utils.ContextBuilder import ContextBuilder
4
- from .orchestrator_test_utils \
5
- import get_orchestration_state_result, assert_orchestration_state_equals, assert_valid_schema
6
- from azure.durable_functions.models.actions.CreateTimerAction import CreateTimerAction
7
- from azure.durable_functions.models.OrchestratorState import OrchestratorState
8
- from azure.durable_functions.constants import DATETIME_STRING_FORMAT
9
- from datetime import datetime, timedelta, timezone
10
-
11
-
12
- def base_expected_state(output=None, replay_schema: ReplaySchema = ReplaySchema.V1) -> OrchestratorState:
13
- return OrchestratorState(is_done=False, actions=[], output=output, replay_schema=replay_schema)
14
-
15
- def add_timer_fired_events(context_builder: ContextBuilder, id_: int, timestamp: str):
16
- fire_at: str = context_builder.add_timer_created_event(id_, timestamp)
17
- context_builder.add_orchestrator_completed_event()
18
- context_builder.add_orchestrator_started_event()
19
- context_builder.add_timer_fired_event(id_=id_, fire_at=fire_at)
20
-
21
- def generator_function(context):
22
-
23
- # Create a timezone aware datetime object, just like a normal
24
- # call to `context.current_utc_datetime` would create
25
- timestamp = "2020-07-23T21:56:54.936700Z"
26
- fire_at = datetime.strptime(timestamp, DATETIME_STRING_FORMAT)
27
- fire_at = fire_at.replace(tzinfo=timezone.utc)
28
-
29
- yield context.create_timer(fire_at)
30
- return "Done!"
31
-
32
- def generator_function_timer_can_be_cancelled(context):
33
- time_limit1 = context.current_utc_datetime + timedelta(minutes=5)
34
- timer_task1 = context.create_timer(time_limit1)
35
-
36
- time_limit2 = context.current_utc_datetime + timedelta(minutes=10)
37
- timer_task2 = context.create_timer(time_limit2)
38
-
39
- winner = yield context.task_any([timer_task1, timer_task2])
40
- if winner == timer_task1:
41
- timer_task2.cancel()
42
- return "Done!"
43
- else:
44
- raise Exception("timer task 1 should complete before timer task 2")
45
-
46
- def add_timer_action(state: OrchestratorState, fire_at: datetime):
47
- action = CreateTimerAction(fire_at=fire_at)
48
- state._actions.append([action])
49
-
50
- def test_timers_comparison_with_relaxed_precision():
51
- """Test if that two `datetime` different but equivalent
52
- serializations of timer deadlines are found to be equivalent.
53
-
54
- The Durable Extension may sometimes drop redundant zeroes on
55
- a datetime object. For instance, the date
56
- 2020-07-23T21:56:54.936700Z
57
- may get transformed into
58
- 2020-07-23T21:56:54.9367Z
59
- This test ensures that dropping redundant zeroes does not affect
60
- our ability to recognize that a timer has been fired.
61
- """
62
-
63
- # equivalent to 2020-07-23T21:56:54.936700Z
64
- relaxed_timestamp = "2020-07-23T21:56:54.9367Z"
65
- fire_at = datetime.strptime(relaxed_timestamp, DATETIME_STRING_FORMAT)
66
-
67
- context_builder = ContextBuilder("relaxed precision")
68
- add_timer_fired_events(context_builder, 0, relaxed_timestamp)
69
-
70
- result = get_orchestration_state_result(
71
- context_builder, generator_function)
72
-
73
- expected_state = base_expected_state(output='Done!')
74
- add_timer_action(expected_state, fire_at)
75
-
76
- expected_state._is_done = True
77
- expected = expected_state.to_json()
78
-
79
- #assert_valid_schema(result)
80
- # TODO: getting the following error when validating the schema
81
- # "Additional properties are not allowed ('fireAt', 'isCanceled' were unexpected)">
82
- assert_orchestration_state_equals(expected, result)
83
-
84
- def test_timers_can_be_cancelled():
85
-
86
- context_builder = ContextBuilder("test_timers_can_be_cancelled")
87
- fire_at1 = context_builder.current_datetime + timedelta(minutes=5)
88
- fire_at2 = context_builder.current_datetime + timedelta(minutes=10)
89
- add_timer_fired_events(context_builder, 0, str(fire_at1))
90
- add_timer_fired_events(context_builder, 1, str(fire_at2))
91
-
92
- result = get_orchestration_state_result(
93
- context_builder, generator_function_timer_can_be_cancelled)
94
-
95
- expected_state = base_expected_state(output='Done!')
96
- expected_state._actions.append(
97
- [CreateTimerAction(fire_at=fire_at1), CreateTimerAction(fire_at=fire_at2, is_cancelled=True)])
98
-
99
- expected_state._is_done = True
100
- expected = expected_state.to_json()
101
-
102
- assert_orchestration_state_equals(expected, result)
103
- assert result["actions"][0][1]["isCanceled"]
104
-
105
- def test_timers_can_be_cancelled_replayV2():
106
-
107
- context_builder = ContextBuilder("test_timers_can_be_cancelled", replay_schema=ReplaySchema.V2)
108
- fire_at1 = context_builder.current_datetime + timedelta(minutes=5)
109
- fire_at2 = context_builder.current_datetime + timedelta(minutes=10)
110
- add_timer_fired_events(context_builder, 0, str(fire_at1))
111
- add_timer_fired_events(context_builder, 1, str(fire_at2))
112
-
113
- result = get_orchestration_state_result(
114
- context_builder, generator_function_timer_can_be_cancelled)
115
-
116
- expected_state = base_expected_state(output='Done!', replay_schema=ReplaySchema.V2)
117
- expected_state._actions = [
118
- [WhenAnyAction(
119
- [CreateTimerAction(fire_at=fire_at1), CreateTimerAction(fire_at=fire_at2, is_cancelled=True)]
120
- )]
121
- ]
122
-
123
- expected_state._is_done = True
124
- expected = expected_state.to_json()
125
-
126
- assert_orchestration_state_equals(expected, result)
1
+ from azure.durable_functions.models.ReplaySchema import ReplaySchema
2
+ from azure.durable_functions.models.actions.WhenAnyAction import WhenAnyAction
3
+ from tests.test_utils.ContextBuilder import ContextBuilder
4
+ from .orchestrator_test_utils \
5
+ import get_orchestration_state_result, assert_orchestration_state_equals, assert_valid_schema
6
+ from azure.durable_functions.models.actions.CreateTimerAction import CreateTimerAction
7
+ from azure.durable_functions.models.OrchestratorState import OrchestratorState
8
+ from azure.durable_functions.constants import DATETIME_STRING_FORMAT
9
+ from datetime import datetime, timedelta, timezone
10
+
11
+
12
+ def base_expected_state(output=None, replay_schema: ReplaySchema = ReplaySchema.V1) -> OrchestratorState:
13
+ return OrchestratorState(is_done=False, actions=[], output=output, replay_schema=replay_schema)
14
+
15
+ def add_timer_fired_events(context_builder: ContextBuilder, id_: int, timestamp: str):
16
+ fire_at: str = context_builder.add_timer_created_event(id_, timestamp)
17
+ context_builder.add_orchestrator_completed_event()
18
+ context_builder.add_orchestrator_started_event()
19
+ context_builder.add_timer_fired_event(id_=id_, fire_at=fire_at)
20
+
21
+ def generator_function(context):
22
+
23
+ # Create a timezone aware datetime object, just like a normal
24
+ # call to `context.current_utc_datetime` would create
25
+ timestamp = "2020-07-23T21:56:54.936700Z"
26
+ fire_at = datetime.strptime(timestamp, DATETIME_STRING_FORMAT)
27
+ fire_at = fire_at.replace(tzinfo=timezone.utc)
28
+
29
+ yield context.create_timer(fire_at)
30
+ return "Done!"
31
+
32
+ def generator_function_timer_can_be_cancelled(context):
33
+ time_limit1 = context.current_utc_datetime + timedelta(minutes=5)
34
+ timer_task1 = context.create_timer(time_limit1)
35
+
36
+ time_limit2 = context.current_utc_datetime + timedelta(minutes=10)
37
+ timer_task2 = context.create_timer(time_limit2)
38
+
39
+ winner = yield context.task_any([timer_task1, timer_task2])
40
+ if winner == timer_task1:
41
+ timer_task2.cancel()
42
+ return "Done!"
43
+ else:
44
+ raise Exception("timer task 1 should complete before timer task 2")
45
+
46
+ def add_timer_action(state: OrchestratorState, fire_at: datetime):
47
+ action = CreateTimerAction(fire_at=fire_at)
48
+ state._actions.append([action])
49
+
50
+ def test_timers_comparison_with_relaxed_precision():
51
+ """Test if that two `datetime` different but equivalent
52
+ serializations of timer deadlines are found to be equivalent.
53
+
54
+ The Durable Extension may sometimes drop redundant zeroes on
55
+ a datetime object. For instance, the date
56
+ 2020-07-23T21:56:54.936700Z
57
+ may get transformed into
58
+ 2020-07-23T21:56:54.9367Z
59
+ This test ensures that dropping redundant zeroes does not affect
60
+ our ability to recognize that a timer has been fired.
61
+ """
62
+
63
+ # equivalent to 2020-07-23T21:56:54.936700Z
64
+ relaxed_timestamp = "2020-07-23T21:56:54.9367Z"
65
+ fire_at = datetime.strptime(relaxed_timestamp, DATETIME_STRING_FORMAT)
66
+
67
+ context_builder = ContextBuilder("relaxed precision")
68
+ add_timer_fired_events(context_builder, 0, relaxed_timestamp)
69
+
70
+ result = get_orchestration_state_result(
71
+ context_builder, generator_function)
72
+
73
+ expected_state = base_expected_state(output='Done!')
74
+ add_timer_action(expected_state, fire_at)
75
+
76
+ expected_state._is_done = True
77
+ expected = expected_state.to_json()
78
+
79
+ #assert_valid_schema(result)
80
+ # TODO: getting the following error when validating the schema
81
+ # "Additional properties are not allowed ('fireAt', 'isCanceled' were unexpected)">
82
+ assert_orchestration_state_equals(expected, result)
83
+
84
+ def test_timers_can_be_cancelled():
85
+
86
+ context_builder = ContextBuilder("test_timers_can_be_cancelled")
87
+ fire_at1 = context_builder.current_datetime + timedelta(minutes=5)
88
+ fire_at2 = context_builder.current_datetime + timedelta(minutes=10)
89
+ add_timer_fired_events(context_builder, 0, str(fire_at1))
90
+ add_timer_fired_events(context_builder, 1, str(fire_at2))
91
+
92
+ result = get_orchestration_state_result(
93
+ context_builder, generator_function_timer_can_be_cancelled)
94
+
95
+ expected_state = base_expected_state(output='Done!')
96
+ expected_state._actions.append(
97
+ [CreateTimerAction(fire_at=fire_at1), CreateTimerAction(fire_at=fire_at2, is_cancelled=True)])
98
+
99
+ expected_state._is_done = True
100
+ expected = expected_state.to_json()
101
+
102
+ assert_orchestration_state_equals(expected, result)
103
+ assert result["actions"][0][1]["isCanceled"]
104
+
105
+ def test_timers_can_be_cancelled_replayV2():
106
+
107
+ context_builder = ContextBuilder("test_timers_can_be_cancelled", replay_schema=ReplaySchema.V2)
108
+ fire_at1 = context_builder.current_datetime + timedelta(minutes=5)
109
+ fire_at2 = context_builder.current_datetime + timedelta(minutes=10)
110
+ add_timer_fired_events(context_builder, 0, str(fire_at1))
111
+ add_timer_fired_events(context_builder, 1, str(fire_at2))
112
+
113
+ result = get_orchestration_state_result(
114
+ context_builder, generator_function_timer_can_be_cancelled)
115
+
116
+ expected_state = base_expected_state(output='Done!', replay_schema=ReplaySchema.V2)
117
+ expected_state._actions = [
118
+ [WhenAnyAction(
119
+ [CreateTimerAction(fire_at=fire_at1), CreateTimerAction(fire_at=fire_at2, is_cancelled=True)]
120
+ )]
121
+ ]
122
+
123
+ expected_state._is_done = True
124
+ expected = expected_state.to_json()
125
+
126
+ assert_orchestration_state_equals(expected, result)
127
127
  assert result["actions"][0][0]['compoundActions'][1]["isCanceled"]