azure-functions-durable 1.2.9__py3-none-any.whl → 1.3.0__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 (104) 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 +260 -249
  5. azure/durable_functions/decorators/metadata.py +109 -109
  6. azure/durable_functions/entity.py +129 -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 +812 -781
  11. azure/durable_functions/models/DurableOrchestrationContext.py +761 -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 +9 -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 +540 -426
  22. azure/durable_functions/models/TaskOrchestrationExecutor.py +352 -336
  23. azure/durable_functions/models/TokenSource.py +56 -56
  24. azure/durable_functions/models/__init__.py +26 -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 +94 -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 +80 -69
  54. azure/durable_functions/models/utils/json_utils.py +96 -56
  55. azure/durable_functions/orchestrator.py +73 -71
  56. azure/durable_functions/testing/OrchestratorGeneratorWrapper.py +42 -0
  57. azure/durable_functions/testing/__init__.py +6 -0
  58. {azure_functions_durable-1.2.9.dist-info → azure_functions_durable-1.3.0.dist-info}/LICENSE +21 -21
  59. {azure_functions_durable-1.2.9.dist-info → azure_functions_durable-1.3.0.dist-info}/METADATA +59 -58
  60. azure_functions_durable-1.3.0.dist-info/RECORD +103 -0
  61. {azure_functions_durable-1.2.9.dist-info → azure_functions_durable-1.3.0.dist-info}/WHEEL +1 -1
  62. tests/models/test_DecoratorMetadata.py +135 -135
  63. tests/models/test_Decorators.py +107 -107
  64. tests/models/test_DurableOrchestrationBindings.py +68 -68
  65. tests/models/test_DurableOrchestrationClient.py +730 -730
  66. tests/models/test_DurableOrchestrationContext.py +102 -102
  67. tests/models/test_DurableOrchestrationStatus.py +59 -59
  68. tests/models/test_OrchestrationState.py +28 -28
  69. tests/models/test_RpcManagementOptions.py +79 -79
  70. tests/models/test_TokenSource.py +10 -10
  71. tests/orchestrator/models/OrchestrationInstance.py +18 -18
  72. tests/orchestrator/orchestrator_test_utils.py +130 -130
  73. tests/orchestrator/schemas/OrchetrationStateSchema.py +66 -66
  74. tests/orchestrator/test_call_http.py +235 -176
  75. tests/orchestrator/test_continue_as_new.py +67 -67
  76. tests/orchestrator/test_create_timer.py +126 -126
  77. tests/orchestrator/test_entity.py +397 -395
  78. tests/orchestrator/test_external_event.py +53 -53
  79. tests/orchestrator/test_fan_out_fan_in.py +175 -175
  80. tests/orchestrator/test_is_replaying_flag.py +101 -101
  81. tests/orchestrator/test_retries.py +308 -308
  82. tests/orchestrator/test_sequential_orchestrator.py +841 -841
  83. tests/orchestrator/test_sequential_orchestrator_custom_status.py +119 -119
  84. tests/orchestrator/test_sequential_orchestrator_with_retry.py +465 -465
  85. tests/orchestrator/test_serialization.py +30 -30
  86. tests/orchestrator/test_sub_orchestrator.py +95 -95
  87. tests/orchestrator/test_sub_orchestrator_with_retry.py +129 -129
  88. tests/orchestrator/test_task_any.py +60 -60
  89. tests/tasks/tasks_test_utils.py +17 -17
  90. tests/tasks/test_long_timers.py +70 -0
  91. tests/tasks/test_new_uuid.py +34 -34
  92. tests/test_utils/ContextBuilder.py +174 -174
  93. tests/test_utils/EntityContextBuilder.py +56 -56
  94. tests/test_utils/constants.py +1 -1
  95. tests/test_utils/json_utils.py +30 -30
  96. tests/test_utils/testClasses.py +56 -56
  97. tests/utils/__init__.py +1 -0
  98. tests/utils/test_entity_utils.py +24 -0
  99. azure_functions_durable-1.2.9.data/data/_manifest/bsi.json +0 -1
  100. azure_functions_durable-1.2.9.data/data/_manifest/manifest.cat +0 -0
  101. azure_functions_durable-1.2.9.data/data/_manifest/manifest.spdx.json +0 -11985
  102. azure_functions_durable-1.2.9.data/data/_manifest/manifest.spdx.json.sha256 +0 -1
  103. azure_functions_durable-1.2.9.dist-info/RECORD +0 -102
  104. {azure_functions_durable-1.2.9.dist-info → azure_functions_durable-1.3.0.dist-info}/top_level.txt +0 -0
@@ -1,130 +1,130 @@
1
- import json
2
- from typing import Callable, Iterator, Any, Dict, List
3
- from jsonschema import validate
4
-
5
- from azure.durable_functions.models import DurableOrchestrationContext, DurableEntityContext
6
- from azure.durable_functions.orchestrator import Orchestrator
7
- from azure.durable_functions.entity import Entity
8
- from .schemas.OrchetrationStateSchema import schema
9
-
10
-
11
- def assert_orchestration_state_equals(expected, result):
12
- """Ensure that the observable OrchestratorState matches the expected result.
13
- """
14
- assert_attribute_equal(expected, result, "isDone")
15
- assert_attribute_equal(expected, result, "schemaVersion")
16
- assert_actions_are_equal(expected, result)
17
- assert_attribute_equal(expected, result, "output")
18
- assert_attribute_equal(expected, result, "error")
19
- assert_attribute_equal(expected, result, "customStatus")
20
-
21
- def assert_entity_state_equals(expected, result):
22
- """Ensure the that the observable EntityState json matches the expected result.
23
- """
24
- assert_attribute_equal(expected, result,"entityExists")
25
- assert "results" in result
26
- observed_results = result["results"]
27
- expected_results = expected["results"]
28
- assert_results_are_equal(expected_results, observed_results)
29
- assert_attribute_equal(expected, result, "entityState")
30
- assert_attribute_equal(expected, result, "signals")
31
-
32
- def assert_results_are_equal(expected: Dict[str, Any], result: Dict[str, Any]) -> bool:
33
- for (payload_expected, payload_result) in zip(expected, result):
34
- assert_attribute_equal(payload_expected, payload_result, "result")
35
- assert_attribute_equal(payload_expected, payload_result, "isError")
36
-
37
- def assert_attribute_equal(expected, result, attribute):
38
- if attribute in expected:
39
- assert result.get(attribute) == expected.get(attribute)
40
- else:
41
- assert attribute not in result
42
-
43
-
44
- def assert_actions_are_equal(expected, result):
45
- expected_actions = expected.get("actions")
46
- result_actions = result.get("actions")
47
- assert len(expected_actions) == len(result_actions)
48
- for index in range(len(expected_actions)):
49
- assert len(expected_actions[index]) == len(result_actions[index])
50
- for action_index in range(len(expected_actions[index])):
51
- expected_action = expected_actions[index][action_index]
52
- result_action = result_actions[index][action_index]
53
- assert_action_is_equal(expected_action, result_action)
54
-
55
-
56
- def assert_action_is_equal(expected_action, result_action):
57
- assert_attribute_equal(expected_action, result_action, "functionName")
58
- assert_attribute_equal(expected_action, result_action, "input")
59
- assert_attribute_equal(expected_action, result_action, "actionType")
60
-
61
-
62
- def get_orchestration_state_result(
63
- context_builder,
64
- user_code: Callable[[DurableOrchestrationContext], Iterator[Any]],
65
- uses_pystein=False):
66
- context_as_string = context_builder.to_json_string()
67
- result_of_handle = None
68
- if uses_pystein:
69
- result_of_handle = user_code._function._func(context_as_string)
70
- else:
71
- orchestrator = Orchestrator(user_code)
72
- result_of_handle = orchestrator.handle(
73
- DurableOrchestrationContext.from_json(context_as_string))
74
- result = json.loads(result_of_handle)
75
- return result
76
-
77
- def get_entity_state_result(
78
- context_builder: DurableEntityContext,
79
- user_code: Callable[[DurableEntityContext], Any],
80
- uses_pystein=False
81
- ) -> Dict[str, Any]:
82
- """Simulate the result of running the entity function with the provided context and batch.
83
-
84
- Parameters
85
- ----------
86
- context_builder: DurableEntityContext
87
- A mocked entity context
88
- user_code: Callable[[DurableEntityContext], Any]
89
- A function implementing an entity
90
-
91
- Returns:
92
- -------
93
- Dict[str, Any]:
94
- JSON-response of the entity
95
- """
96
- # The durable-extension automatically wraps the data within a 'self' key
97
- context_as_string = context_builder.to_json_string()
98
- entity = Entity(user_code)
99
- result_of_handle = None
100
- if uses_pystein:
101
- result_of_handle = user_code._function._func(context_as_string)
102
- else:
103
- context, batch = DurableEntityContext.from_json(context_as_string)
104
- result_of_handle = entity.handle(context, batch)
105
- result = json.loads(result_of_handle)
106
- return result
107
-
108
- def get_orchestration_property(
109
- context_builder,
110
- activity_func: Callable[[DurableOrchestrationContext], Iterator[Any]],
111
- prop: str):
112
- context_as_string = context_builder.to_json_string()
113
- orchestrator = Orchestrator(activity_func)
114
- result_of_handle = orchestrator.handle(
115
- DurableOrchestrationContext.from_json(context_as_string))
116
- result = getattr(orchestrator, prop)
117
- return result
118
-
119
-
120
- def assert_valid_schema(orchestration_state):
121
- validation_results = validate(instance=orchestration_state, schema=schema)
122
- assert validation_results is None
123
-
124
-
125
- def assert_dict_are_equal(expected: Dict[Any, Any], result: Dict[Any, Any]):
126
- assert len(expected.keys()) == len(result.keys())
127
- for key in expected.keys():
128
- assert expected[key] == result[key]
129
- for key in result.keys():
130
- assert result[key] == expected[key]
1
+ import json
2
+ from typing import Callable, Iterator, Any, Dict, List
3
+ from jsonschema import validate
4
+
5
+ from azure.durable_functions.models import DurableOrchestrationContext, DurableEntityContext
6
+ from azure.durable_functions.orchestrator import Orchestrator
7
+ from azure.durable_functions.entity import Entity
8
+ from .schemas.OrchetrationStateSchema import schema
9
+
10
+
11
+ def assert_orchestration_state_equals(expected, result):
12
+ """Ensure that the observable OrchestratorState matches the expected result.
13
+ """
14
+ assert_attribute_equal(expected, result, "isDone")
15
+ assert_attribute_equal(expected, result, "schemaVersion")
16
+ assert_actions_are_equal(expected, result)
17
+ assert_attribute_equal(expected, result, "output")
18
+ assert_attribute_equal(expected, result, "error")
19
+ assert_attribute_equal(expected, result, "customStatus")
20
+
21
+ def assert_entity_state_equals(expected, result):
22
+ """Ensure the that the observable EntityState json matches the expected result.
23
+ """
24
+ assert_attribute_equal(expected, result,"entityExists")
25
+ assert "results" in result
26
+ observed_results = result["results"]
27
+ expected_results = expected["results"]
28
+ assert_results_are_equal(expected_results, observed_results)
29
+ assert_attribute_equal(expected, result, "entityState")
30
+ assert_attribute_equal(expected, result, "signals")
31
+
32
+ def assert_results_are_equal(expected: Dict[str, Any], result: Dict[str, Any]) -> bool:
33
+ for (payload_expected, payload_result) in zip(expected, result):
34
+ assert_attribute_equal(payload_expected, payload_result, "result")
35
+ assert_attribute_equal(payload_expected, payload_result, "isError")
36
+
37
+ def assert_attribute_equal(expected, result, attribute):
38
+ if attribute in expected:
39
+ assert result.get(attribute) == expected.get(attribute)
40
+ else:
41
+ assert attribute not in result
42
+
43
+
44
+ def assert_actions_are_equal(expected, result):
45
+ expected_actions = expected.get("actions")
46
+ result_actions = result.get("actions")
47
+ assert len(expected_actions) == len(result_actions)
48
+ for index in range(len(expected_actions)):
49
+ assert len(expected_actions[index]) == len(result_actions[index])
50
+ for action_index in range(len(expected_actions[index])):
51
+ expected_action = expected_actions[index][action_index]
52
+ result_action = result_actions[index][action_index]
53
+ assert_action_is_equal(expected_action, result_action)
54
+
55
+
56
+ def assert_action_is_equal(expected_action, result_action):
57
+ assert_attribute_equal(expected_action, result_action, "functionName")
58
+ assert_attribute_equal(expected_action, result_action, "input")
59
+ assert_attribute_equal(expected_action, result_action, "actionType")
60
+
61
+
62
+ def get_orchestration_state_result(
63
+ context_builder,
64
+ user_code: Callable[[DurableOrchestrationContext], Iterator[Any]],
65
+ uses_pystein=False):
66
+ context_as_string = context_builder.to_json_string()
67
+ result_of_handle = None
68
+ if uses_pystein:
69
+ result_of_handle = user_code._function._func(context_as_string)
70
+ else:
71
+ orchestrator = Orchestrator(user_code)
72
+ result_of_handle = orchestrator.handle(
73
+ DurableOrchestrationContext.from_json(context_as_string))
74
+ result = json.loads(result_of_handle)
75
+ return result
76
+
77
+ def get_entity_state_result(
78
+ context_builder: DurableEntityContext,
79
+ user_code: Callable[[DurableEntityContext], Any],
80
+ uses_pystein=False
81
+ ) -> Dict[str, Any]:
82
+ """Simulate the result of running the entity function with the provided context and batch.
83
+
84
+ Parameters
85
+ ----------
86
+ context_builder: DurableEntityContext
87
+ A mocked entity context
88
+ user_code: Callable[[DurableEntityContext], Any]
89
+ A function implementing an entity
90
+
91
+ Returns:
92
+ -------
93
+ Dict[str, Any]:
94
+ JSON-response of the entity
95
+ """
96
+ # The durable-extension automatically wraps the data within a 'self' key
97
+ context_as_string = context_builder.to_json_string()
98
+ entity = Entity(user_code)
99
+ result_of_handle = None
100
+ if uses_pystein:
101
+ result_of_handle = user_code._function._func(context_as_string)
102
+ else:
103
+ context, batch = DurableEntityContext.from_json(context_as_string)
104
+ result_of_handle = entity.handle(context, batch)
105
+ result = json.loads(result_of_handle)
106
+ return result
107
+
108
+ def get_orchestration_property(
109
+ context_builder,
110
+ activity_func: Callable[[DurableOrchestrationContext], Iterator[Any]],
111
+ prop: str):
112
+ context_as_string = context_builder.to_json_string()
113
+ orchestrator = Orchestrator(activity_func)
114
+ result_of_handle = orchestrator.handle(
115
+ DurableOrchestrationContext.from_json(context_as_string))
116
+ result = getattr(orchestrator, prop)
117
+ return result
118
+
119
+
120
+ def assert_valid_schema(orchestration_state):
121
+ validation_results = validate(instance=orchestration_state, schema=schema)
122
+ assert validation_results is None
123
+
124
+
125
+ def assert_dict_are_equal(expected: Dict[Any, Any], result: Dict[Any, Any]):
126
+ assert len(expected.keys()) == len(result.keys())
127
+ for key in expected.keys():
128
+ assert expected[key] == result[key]
129
+ for key in result.keys():
130
+ assert result[key] == expected[key]
@@ -1,66 +1,66 @@
1
- schema = {
2
- "$schema": "http://json-schema.org/draft-07/schema#",
3
- "type": "object",
4
- "properties": {
5
- "isDone": {"type": "boolean"},
6
- "output": {},
7
- "error": {"type": "string"},
8
- "customStatus": {
9
- "anyOf": [
10
- {
11
- "type": "object",
12
- },{
13
- "type": "string",
14
- }] },
15
- "actions": {
16
- "type": "array",
17
- "items": {
18
- "type": "array",
19
- "items": {
20
- "type": "object",
21
- "properties": {
22
- "functionName": {"type": "string"},
23
- "actionType": {"type": "number"},
24
- "input": {},
25
- "retryOptions": {
26
- "type": "object",
27
- "properties": {
28
- "firstRetryIntervalInMilliseconds": {
29
- "type": "number",
30
- "minimum": 1},
31
- "maxNumberOfAttempts": {"type": "number"}
32
- },
33
- "required":
34
- ["firstRetryIntervalInMilliseconds", "maxNumberOfAttempts"],
35
- "additionalProperties": False
36
- },
37
- "httpRequest": {
38
- "type": "object",
39
- "properties": {
40
- "method": {"type": "string"},
41
- "uri": {"type": "string"},
42
- "content": {},
43
- "headers": {},
44
- "tokenSource": {
45
- "type": "object",
46
- "properties": {
47
- "resource": {"type": "string"}
48
- },
49
- "required": ["resource"],
50
- "additionalProperties": False
51
- }
52
- },
53
- "required":
54
- ["method", "uri"],
55
- "additionalProperties": False
56
- }
57
- },
58
- "required": ["actionType"],
59
- "additionalProperties": False
60
- }
61
- }
62
- }
63
- },
64
- "required": ["isDone"],
65
- "additionalProperties": False
66
- }
1
+ schema = {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "properties": {
5
+ "isDone": {"type": "boolean"},
6
+ "output": {},
7
+ "error": {"type": "string"},
8
+ "customStatus": {
9
+ "anyOf": [
10
+ {
11
+ "type": "object",
12
+ },{
13
+ "type": "string",
14
+ }] },
15
+ "actions": {
16
+ "type": "array",
17
+ "items": {
18
+ "type": "array",
19
+ "items": {
20
+ "type": "object",
21
+ "properties": {
22
+ "functionName": {"type": "string"},
23
+ "actionType": {"type": "number"},
24
+ "input": {},
25
+ "retryOptions": {
26
+ "type": "object",
27
+ "properties": {
28
+ "firstRetryIntervalInMilliseconds": {
29
+ "type": "number",
30
+ "minimum": 1},
31
+ "maxNumberOfAttempts": {"type": "number"}
32
+ },
33
+ "required":
34
+ ["firstRetryIntervalInMilliseconds", "maxNumberOfAttempts"],
35
+ "additionalProperties": False
36
+ },
37
+ "httpRequest": {
38
+ "type": "object",
39
+ "properties": {
40
+ "method": {"type": "string"},
41
+ "uri": {"type": "string"},
42
+ "content": {},
43
+ "headers": {},
44
+ "tokenSource": {
45
+ "type": "object",
46
+ "properties": {
47
+ "resource": {"type": "string"}
48
+ },
49
+ "required": ["resource"],
50
+ "additionalProperties": False
51
+ }
52
+ },
53
+ "required":
54
+ ["method", "uri"],
55
+ "additionalProperties": False
56
+ }
57
+ },
58
+ "required": ["actionType"],
59
+ "additionalProperties": False
60
+ }
61
+ }
62
+ }
63
+ },
64
+ "required": ["isDone"],
65
+ "additionalProperties": False
66
+ }