azure-functions-durable 1.2.9__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 -781
  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 -32
  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 -336
  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 -27
  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.9.dist-info → azure_functions_durable-1.2.10.dist-info}/LICENSE +21 -21
  57. {azure_functions_durable-1.2.9.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. tests/models/test_DecoratorMetadata.py +135 -135
  60. tests/models/test_Decorators.py +107 -107
  61. tests/models/test_DurableOrchestrationBindings.py +68 -68
  62. tests/models/test_DurableOrchestrationClient.py +730 -730
  63. tests/models/test_DurableOrchestrationContext.py +102 -102
  64. tests/models/test_DurableOrchestrationStatus.py +59 -59
  65. tests/models/test_OrchestrationState.py +28 -28
  66. tests/models/test_RpcManagementOptions.py +79 -79
  67. tests/models/test_TokenSource.py +10 -10
  68. tests/orchestrator/models/OrchestrationInstance.py +18 -18
  69. tests/orchestrator/orchestrator_test_utils.py +130 -130
  70. tests/orchestrator/schemas/OrchetrationStateSchema.py +66 -66
  71. tests/orchestrator/test_call_http.py +235 -176
  72. tests/orchestrator/test_continue_as_new.py +67 -67
  73. tests/orchestrator/test_create_timer.py +126 -126
  74. tests/orchestrator/test_entity.py +395 -395
  75. tests/orchestrator/test_external_event.py +53 -53
  76. tests/orchestrator/test_fan_out_fan_in.py +175 -175
  77. tests/orchestrator/test_is_replaying_flag.py +101 -101
  78. tests/orchestrator/test_retries.py +308 -308
  79. tests/orchestrator/test_sequential_orchestrator.py +841 -841
  80. tests/orchestrator/test_sequential_orchestrator_custom_status.py +119 -119
  81. tests/orchestrator/test_sequential_orchestrator_with_retry.py +465 -465
  82. tests/orchestrator/test_serialization.py +30 -30
  83. tests/orchestrator/test_sub_orchestrator.py +95 -95
  84. tests/orchestrator/test_sub_orchestrator_with_retry.py +129 -129
  85. tests/orchestrator/test_task_any.py +60 -60
  86. tests/tasks/tasks_test_utils.py +17 -17
  87. tests/tasks/test_new_uuid.py +34 -34
  88. tests/test_utils/ContextBuilder.py +174 -174
  89. tests/test_utils/EntityContextBuilder.py +56 -56
  90. tests/test_utils/constants.py +1 -1
  91. tests/test_utils/json_utils.py +30 -30
  92. tests/test_utils/testClasses.py +56 -56
  93. tests/utils/__init__.py +1 -0
  94. tests/utils/test_entity_utils.py +24 -0
  95. azure_functions_durable-1.2.9.data/data/_manifest/bsi.json +0 -1
  96. azure_functions_durable-1.2.9.data/data/_manifest/manifest.cat +0 -0
  97. azure_functions_durable-1.2.9.data/data/_manifest/manifest.spdx.json +0 -11985
  98. azure_functions_durable-1.2.9.data/data/_manifest/manifest.spdx.json.sha256 +0 -1
  99. azure_functions_durable-1.2.9.dist-info/RECORD +0 -102
  100. {azure_functions_durable-1.2.9.dist-info → azure_functions_durable-1.2.10.dist-info}/WHEEL +0 -0
  101. {azure_functions_durable-1.2.9.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"]