azure-functions-durable 1.2.10__tar.gz → 1.3.1__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 (300) hide show
  1. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.github/workflows/durable_python_action.yml +2 -2
  2. azure-functions-durable-1.3.1/.github/workflows/validate.yml +60 -0
  3. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/CODEOWNERS +1 -1
  4. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/CONTRIBUTING.md +20 -6
  5. azure-functions-durable-1.3.1/PKG-INFO +54 -0
  6. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/decorators/durable_app.py +11 -0
  7. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/entity.py +7 -3
  8. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/DurableOrchestrationClient.py +33 -2
  9. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/DurableOrchestrationContext.py +46 -7
  10. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/ReplaySchema.py +1 -0
  11. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/Task.py +117 -3
  12. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/TaskOrchestrationExecutor.py +11 -5
  13. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/__init__.py +3 -1
  14. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/entities/OperationResult.py +18 -0
  15. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/utils/http_utils.py +14 -3
  16. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/utils/json_utils.py +40 -0
  17. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/orchestrator.py +2 -0
  18. azure-functions-durable-1.3.1/azure/durable_functions/testing/OrchestratorGeneratorWrapper.py +42 -0
  19. azure-functions-durable-1.3.1/azure/durable_functions/testing/__init__.py +6 -0
  20. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure-pipelines-release.yml +1 -1
  21. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure-pipelines.yml +2 -2
  22. azure-functions-durable-1.3.1/azure_functions_durable.egg-info/PKG-INFO +54 -0
  23. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure_functions_durable.egg-info/SOURCES.txt +16 -0
  24. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure_functions_durable.egg-info/requires.txt +3 -1
  25. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/eng/templates/build.yml +3 -3
  26. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/noxfile.py +4 -4
  27. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/requirements.txt +4 -2
  28. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/blueprint/requirements.txt +2 -1
  29. azure-functions-durable-1.3.1/samples-v2/blueprint/tests/readme.md +72 -0
  30. azure-functions-durable-1.3.1/samples-v2/blueprint/tests/test_my_orchestrator.py +35 -0
  31. azure-functions-durable-1.3.1/samples-v2/blueprint/tests/test_say_hello.py +4 -0
  32. azure-functions-durable-1.3.1/samples-v2/blueprint/tests/test_start_orchestrator.py +26 -0
  33. {azure-functions-durable-1.2.10/samples → azure-functions-durable-1.3.1/samples-v2}/fan_in_fan_out/requirements.txt +2 -1
  34. azure-functions-durable-1.3.1/samples-v2/fan_in_fan_out/tests/readme.md +72 -0
  35. azure-functions-durable-1.3.1/samples-v2/fan_in_fan_out/tests/test_E2_BackupSiteContent.py +52 -0
  36. azure-functions-durable-1.3.1/samples-v2/fan_in_fan_out/tests/test_E2_CopyFileToBlob.py +4 -0
  37. azure-functions-durable-1.3.1/samples-v2/fan_in_fan_out/tests/test_E2_GetFileList.py +4 -0
  38. azure-functions-durable-1.3.1/samples-v2/fan_in_fan_out/tests/test_HttpStart.py +27 -0
  39. azure-functions-durable-1.3.1/samples-v2/function_chaining/host.json +15 -0
  40. {azure-functions-durable-1.2.10/samples → azure-functions-durable-1.3.1/samples-v2}/function_chaining/requirements.txt +1 -0
  41. azure-functions-durable-1.3.1/samples-v2/function_chaining/tests/readme.md +72 -0
  42. azure-functions-durable-1.3.1/samples-v2/function_chaining/tests/test_http_start.py +27 -0
  43. azure-functions-durable-1.3.1/samples-v2/function_chaining/tests/test_my_orchestrator.py +37 -0
  44. azure-functions-durable-1.3.1/samples-v2/function_chaining/tests/test_say_hello.py +4 -0
  45. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/setup.py +5 -3
  46. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/test_DurableOrchestrationClient.py +1 -1
  47. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_entity.py +2 -0
  48. azure-functions-durable-1.3.1/tests/tasks/test_long_timers.py +70 -0
  49. azure-functions-durable-1.2.10/.github/workflows/validate.yml +0 -34
  50. azure-functions-durable-1.2.10/PKG-INFO +0 -51
  51. azure-functions-durable-1.2.10/azure_functions_durable.egg-info/PKG-INFO +0 -51
  52. azure-functions-durable-1.2.10/samples-v2/function_chaining/host.json +0 -25
  53. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.devcontainer/devcontainer.json +0 -0
  54. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.devcontainer/setup.sh +0 -0
  55. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.flake8 +0 -0
  56. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.github/ISSUE_TEMPLATE/----feature-request.md +0 -0
  57. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.github/ISSUE_TEMPLATE/---bug-report.md +0 -0
  58. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.github/policies/resourceManagement.yml +0 -0
  59. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.github/workflows/codeQL.yml +0 -0
  60. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.github/workflows/submodule-sync.yml +0 -0
  61. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.gitignore +0 -0
  62. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/CHANGELOG.md +0 -0
  63. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/LICENSE +0 -0
  64. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/MANIFEST.in +0 -0
  65. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/README.md +0 -0
  66. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/SECURITY.md +0 -0
  67. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/__init__.py +0 -0
  68. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/__init__.py +0 -0
  69. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/constants.py +0 -0
  70. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/decorators/__init__.py +0 -0
  71. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/decorators/metadata.py +0 -0
  72. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/DurableEntityContext.py +0 -0
  73. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/DurableHttpRequest.py +0 -0
  74. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/DurableOrchestrationBindings.py +0 -0
  75. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/DurableOrchestrationStatus.py +0 -0
  76. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/EntityStateResponse.py +0 -0
  77. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/FunctionContext.py +0 -0
  78. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/OrchestrationRuntimeStatus.py +0 -0
  79. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/OrchestratorState.py +0 -0
  80. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/PurgeHistoryResult.py +0 -0
  81. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/RetryOptions.py +0 -0
  82. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/RpcManagementOptions.py +0 -0
  83. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/TokenSource.py +0 -0
  84. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/Action.py +0 -0
  85. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/ActionType.py +0 -0
  86. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/CallActivityAction.py +0 -0
  87. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/CallActivityWithRetryAction.py +0 -0
  88. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/CallEntityAction.py +0 -0
  89. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/CallHttpAction.py +0 -0
  90. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/CallSubOrchestratorAction.py +0 -0
  91. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/CallSubOrchestratorWithRetryAction.py +0 -0
  92. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/CompoundAction.py +0 -0
  93. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/ContinueAsNewAction.py +0 -0
  94. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/CreateTimerAction.py +0 -0
  95. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/NoOpAction.py +0 -0
  96. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/SignalEntityAction.py +0 -0
  97. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/WaitForExternalEventAction.py +0 -0
  98. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/WhenAllAction.py +0 -0
  99. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/WhenAnyAction.py +0 -0
  100. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/__init__.py +0 -0
  101. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/entities/EntityState.py +0 -0
  102. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/entities/RequestMessage.py +0 -0
  103. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/entities/ResponseMessage.py +0 -0
  104. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/entities/Signal.py +0 -0
  105. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/entities/__init__.py +0 -0
  106. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/history/HistoryEvent.py +0 -0
  107. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/history/HistoryEventType.py +0 -0
  108. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/history/__init__.py +0 -0
  109. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/utils/__init__.py +0 -0
  110. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/utils/entity_utils.py +0 -0
  111. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure_functions_durable.egg-info/dependency_links.txt +0 -0
  112. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure_functions_durable.egg-info/top_level.txt +0 -0
  113. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/eng/ci/code-mirror.yml +0 -0
  114. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/eng/ci/official-build.yml +0 -0
  115. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/host.json +0 -0
  116. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/.funcignore +0 -0
  117. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/.gitignore +0 -0
  118. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/aml_durable_orchestrator/__init__.py +0 -0
  119. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/aml_durable_orchestrator/function.json +0 -0
  120. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/aml_pipeline/__init__.py +0 -0
  121. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/aml_pipeline/function.json +0 -0
  122. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/aml_poll_status/__init__.py +0 -0
  123. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/aml_poll_status/function.json +0 -0
  124. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/extensions.csproj +0 -0
  125. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/host.json +0 -0
  126. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/local.settings.json +0 -0
  127. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/proxies.json +0 -0
  128. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/requirements.txt +0 -0
  129. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/shared/__init__.py +0 -0
  130. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/shared/aml_helper.py +0 -0
  131. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/shared/auth_helper.py +0 -0
  132. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/.funcignore +0 -0
  133. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/.gitignore +0 -0
  134. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/Counter/__init__.py +0 -0
  135. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/Counter/function.json +0 -0
  136. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/DurableOrchestration/__init__.py +0 -0
  137. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/DurableOrchestration/function.json +0 -0
  138. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/DurableTrigger/__init__.py +0 -0
  139. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/DurableTrigger/function.json +0 -0
  140. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/README.md +0 -0
  141. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/RetrieveEntity/__init__.py +0 -0
  142. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/RetrieveEntity/function.json +0 -0
  143. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/host.json +0 -0
  144. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/local.settings.json +0 -0
  145. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/requirements.txt +0 -0
  146. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/.funcignore +0 -0
  147. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/.gitignore +0 -0
  148. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/E2_BackupSiteContent/__init__.py +0 -0
  149. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/E2_BackupSiteContent/function.json +0 -0
  150. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/E2_CopyFileToBlob/__init__.py +0 -0
  151. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/E2_CopyFileToBlob/function.json +0 -0
  152. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/E2_GetFileList/__init__.py +0 -0
  153. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/E2_GetFileList/function.json +0 -0
  154. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/HttpStart/__init__.py +0 -0
  155. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/HttpStart/function.json +0 -0
  156. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/README.md +0 -0
  157. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/host.json +0 -0
  158. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/local.settings.json +0 -0
  159. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/proxies.json +0 -0
  160. {azure-functions-durable-1.2.10/samples-v2 → azure-functions-durable-1.3.1/samples}/fan_in_fan_out/requirements.txt +0 -0
  161. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/.funcignore +0 -0
  162. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/.gitignore +0 -0
  163. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/E1_HelloSequence/__init__.py +0 -0
  164. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/E1_HelloSequence/function.json +0 -0
  165. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/E1_SayHello/__init__.py +0 -0
  166. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/E1_SayHello/function.json +0 -0
  167. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/HttpStart/__init__.py +0 -0
  168. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/HttpStart/function.json +0 -0
  169. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/README.md +0 -0
  170. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/host.json +0 -0
  171. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/local.settings.json +0 -0
  172. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/proxies.json +0 -0
  173. {azure-functions-durable-1.2.10/samples-v2 → azure-functions-durable-1.3.1/samples}/function_chaining/requirements.txt +0 -0
  174. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/.funcignore +0 -0
  175. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/.gitignore +0 -0
  176. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/DurableActivity/__init__.py +0 -0
  177. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/DurableActivity/function.json +0 -0
  178. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/DurableOrchestration/__init__.py +0 -0
  179. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/DurableOrchestration/function.json +0 -0
  180. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/DurableTrigger/__init__.py +0 -0
  181. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/DurableTrigger/function.json +0 -0
  182. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/README.md +0 -0
  183. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/host.json +0 -0
  184. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/local.settings.json +0 -0
  185. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/proxies.json +0 -0
  186. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/requirements.txt +0 -0
  187. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/.funcignore +0 -0
  188. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/.gitignore +0 -0
  189. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/E4_SMSPhoneVerification/__init__.py +0 -0
  190. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/E4_SMSPhoneVerification/function.json +0 -0
  191. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/HttpStart/__init__.py +0 -0
  192. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/HttpStart/function.json +0 -0
  193. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/README.md +0 -0
  194. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/SendSMSChallenge/__init__.py +0 -0
  195. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/SendSMSChallenge/function.json +0 -0
  196. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/host.json +0 -0
  197. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/local.settings.json +0 -0
  198. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/proxies.json +0 -0
  199. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/requirements.txt +0 -0
  200. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/.funcignore +0 -0
  201. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/.gitignore +0 -0
  202. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/E3_Monitor/__init__.py +0 -0
  203. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/E3_Monitor/function.json +0 -0
  204. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/E3_SendAlert/__init__.py +0 -0
  205. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/E3_SendAlert/function.json +0 -0
  206. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/E3_TooManyOpenIssues/__init__.py +0 -0
  207. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/E3_TooManyOpenIssues/function.json +0 -0
  208. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/HttpStart/__init__.py +0 -0
  209. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/HttpStart/function.json +0 -0
  210. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/README.md +0 -0
  211. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/host.json +0 -0
  212. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/local.settings.json +0 -0
  213. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/proxies.json +0 -0
  214. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/requirements.txt +0 -0
  215. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/.gitignore +0 -0
  216. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/DurableActivity/__init__.py +0 -0
  217. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/DurableActivity/function.json +0 -0
  218. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/DurableOrchestration/__init__.py +0 -0
  219. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/DurableOrchestration/function.json +0 -0
  220. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/DurableTrigger/__init__.py +0 -0
  221. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/DurableTrigger/function.json +0 -0
  222. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/README.md +0 -0
  223. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/host.json +0 -0
  224. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/local.settings.json +0 -0
  225. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/requirements.txt +0 -0
  226. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/shared_code/MyClasses.py +0 -0
  227. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/.funcignore +0 -0
  228. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/.gitignore +0 -0
  229. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/DurableFunctionsHttpStart/__init__.py +0 -0
  230. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/DurableFunctionsHttpStart/function.json +0 -0
  231. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/DurableOrchestrator/__init__.py +0 -0
  232. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/DurableOrchestrator/function.json +0 -0
  233. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/DurableSubOrchestrator/__init__.py +0 -0
  234. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/DurableSubOrchestrator/function.json +0 -0
  235. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/Hello/__init__.py +0 -0
  236. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/Hello/function.json +0 -0
  237. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/README.md +0 -0
  238. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/host.json +0 -0
  239. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/local.settings.json +0 -0
  240. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/proxies.json +0 -0
  241. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/requirements.txt +0 -0
  242. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/blueprint/.funcignore +0 -0
  243. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/blueprint/.gitignore +0 -0
  244. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/blueprint/durable_blueprints.py +0 -0
  245. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/blueprint/function_app.py +0 -0
  246. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/blueprint/host.json +0 -0
  247. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/fan_in_fan_out/.funcignore +0 -0
  248. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/fan_in_fan_out/.gitignore +0 -0
  249. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/fan_in_fan_out/README.md +0 -0
  250. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/fan_in_fan_out/function_app.py +0 -0
  251. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/fan_in_fan_out/host.json +0 -0
  252. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/fan_in_fan_out/proxies.json +0 -0
  253. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/function_chaining/.funcignore +0 -0
  254. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/function_chaining/.gitignore +0 -0
  255. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/function_chaining/README.md +0 -0
  256. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/function_chaining/function_app.py +0 -0
  257. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/function_chaining/proxies.json +0 -0
  258. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/scripts/sample_deploy.sh +0 -0
  259. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/setup.cfg +0 -0
  260. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/__init__.py +0 -0
  261. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/conftest.py +0 -0
  262. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/__init__.py +0 -0
  263. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/test_DecoratorMetadata.py +0 -0
  264. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/test_Decorators.py +0 -0
  265. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/test_DurableOrchestrationBindings.py +0 -0
  266. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/test_DurableOrchestrationContext.py +0 -0
  267. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/test_DurableOrchestrationStatus.py +0 -0
  268. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/test_OrchestrationState.py +0 -0
  269. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/test_RpcManagementOptions.py +0 -0
  270. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/test_TokenSource.py +0 -0
  271. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/__init__.py +0 -0
  272. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/models/OrchestrationInstance.py +0 -0
  273. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/orchestrator_test_utils.py +0 -0
  274. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/schemas/OrchetrationStateSchema.py +0 -0
  275. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_call_http.py +0 -0
  276. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_continue_as_new.py +0 -0
  277. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_create_timer.py +0 -0
  278. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_external_event.py +0 -0
  279. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_fan_out_fan_in.py +0 -0
  280. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_is_replaying_flag.py +0 -0
  281. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_retries.py +0 -0
  282. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_sequential_orchestrator.py +0 -0
  283. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_sequential_orchestrator_custom_status.py +0 -0
  284. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_sequential_orchestrator_with_retry.py +0 -0
  285. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_serialization.py +0 -0
  286. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_sub_orchestrator.py +0 -0
  287. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_sub_orchestrator_with_retry.py +0 -0
  288. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_task_any.py +0 -0
  289. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/tasks/__init__.py +0 -0
  290. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/tasks/tasks_test_utils.py +0 -0
  291. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/tasks/test_new_uuid.py +0 -0
  292. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/test_constants.py +0 -0
  293. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/test_utils/ContextBuilder.py +0 -0
  294. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/test_utils/EntityContextBuilder.py +0 -0
  295. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/test_utils/__init__.py +0 -0
  296. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/test_utils/constants.py +0 -0
  297. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/test_utils/json_utils.py +0 -0
  298. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/test_utils/testClasses.py +0 -0
  299. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/utils/__init__.py +0 -0
  300. {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/utils/test_entity_utils.py +0 -0
@@ -12,10 +12,10 @@ jobs:
12
12
 
13
13
  steps:
14
14
  - uses: actions/checkout@v1
15
- - name: Set up Python 3.6.x
15
+ - name: Set up Python 3.9.x
16
16
  uses: actions/setup-python@v1
17
17
  with:
18
- python-version: 3.6.x
18
+ python-version: 3.9.x
19
19
  - name: Install dependencies
20
20
  run: |
21
21
  python -m pip install --upgrade pip
@@ -0,0 +1,60 @@
1
+ name: Validate
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - dev
8
+ pull_request:
9
+ branches:
10
+ - main
11
+ - dev
12
+
13
+ jobs:
14
+ validate:
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - name: Checkout repository
18
+ uses: actions/checkout@v2
19
+
20
+ - name: Set up Python
21
+ uses: actions/setup-python@v2
22
+ with:
23
+ python-version: 3.9
24
+ - name: Install dependencies
25
+ run: |
26
+ python -m pip install --upgrade pip
27
+ pip install -r requirements.txt
28
+ - name: Run Linter
29
+ run: |
30
+ cd azure
31
+ flake8 . --count --show-source --statistics
32
+ - name: Run tests
33
+ run: |
34
+ pytest --ignore=samples-v2
35
+
36
+ test-samples:
37
+ strategy:
38
+ matrix:
39
+ app_name: [blueprint, fan_in_fan_out, function_chaining]
40
+ runs-on: ubuntu-latest
41
+ defaults:
42
+ run:
43
+ working-directory: ./samples-v2/${{ matrix.app_name }}
44
+ steps:
45
+ - name: Checkout repository
46
+ uses: actions/checkout@v2
47
+
48
+ - name: Set up Python
49
+ uses: actions/setup-python@v2
50
+ with:
51
+ python-version: 3.9
52
+ - name: Install dependencies
53
+ run: |
54
+ python -m pip install --upgrade pip
55
+ pip install -r requirements.txt
56
+ pip install -r ../../requirements.txt
57
+ pip install ../.. --no-cache-dir --upgrade --no-deps --force-reinstall
58
+ - name: Run tests
59
+ run: |
60
+ python -m pytest
@@ -9,4 +9,4 @@
9
9
  # For all file changes, github would automatically include the following people in the PRs.
10
10
  #
11
11
 
12
- * @davidmrdavid
12
+ * @nytian @cgillum @bachuv @andystaples
@@ -24,7 +24,7 @@ Thank you for taking the time to contribute to Durable Functions in [Python](htt
24
24
  - MacOS (or) Windows10 Ubuntu WSL
25
25
  - Language Runtimes
26
26
  - .NET Core 2.0
27
- - \>= Python 3.6.x
27
+ - \>= Python 3.9.x
28
28
 
29
29
  Note: Some ML libraries may not be compatible with newer Python versions. Make sure the library is compatible with the Python version.
30
30
 
@@ -123,16 +123,30 @@ pip install -e $REPOSITORY_ROOT/
123
123
  ```
124
124
  where REPOSITORY_ROOT is the root folder of the azure-functions-durable-python repository
125
125
 
126
- 7. Set breakpoints and click Run -> Start Debugging in VS Code. This should internally start the Azure Function using `func host start` command.
126
+ 7. Set breakpoints and click Run -> Start Debugging in VS Code. This should internally start the Azure Function using `func host start` command. If the breakpoints are not getting hit, check to make sure that you have set `justMyCode: false` in the function app's .vscode/launch.json.
127
+
128
+ ```
129
+ {
130
+ "version": "0.2.0",
131
+ "configurations": [
132
+ {
133
+ ...
134
+ "justMyCode": false
135
+ ...
136
+ }
137
+ ]
138
+ }
139
+ ```
127
140
 
128
141
  ### Debugging end-to-end
129
142
 
130
143
  If you want to debug into the Durable Task or any of the .NET bits, follow instructions below:
131
144
 
132
- 1. Open the Azure Storage Explorer and connect to the local storage emulator or the storage account you are using.
133
- 2. Make sure the Durable Python debugging is setup already and the debugger has started the `func` process.
134
- 3. In the VSCode editor for DurableTask, click Debug -> .NET Core Attach Process and search for `func host start` process and attach to it.
135
- 4. Add a breakpoint in both editors and continue debugging.
145
+ 1. If you would like to debug a custom local WebJobs extension package then create the custom package, place it in a local directory, and then run `func extensions install --package Microsoft.Azure.WebJobs.Extensions.DurableTask --version <VERSION>`. If you update the version while debugging and the new version doesn't get picked up, then try running `func extensions install` to get the new changes.
146
+ 2. Open the Azure Storage Explorer and connect to the local storage emulator or the storage account you are using.
147
+ 3. Make sure the Durable Python debugging is setup already and the debugger has started the `func` process.
148
+ 4. In the VSCode editor for DurableTask, click Debug -> .NET Core Attach Process, search for `func host start` process and attach to it. If you are using Visual Studio, click Debug -> Attach to Process, search for the `func` process and attach to it.
149
+ 5. Add a breakpoint in both editors and continue debugging.
136
150
 
137
151
  ## Testing changes locally (Windows)
138
152
 
@@ -0,0 +1,54 @@
1
+ Metadata-Version: 2.1
2
+ Name: azure-functions-durable
3
+ Version: 1.3.1
4
+ Summary: Durable Functions For Python
5
+ Home-page: https://github.com/Azure/azure-functions-durable-python
6
+ Author: Azure Functions team at Microsoft Corp.
7
+ Author-email: azurefunctions@microsoft.com
8
+ License: MIT
9
+ Keywords: azure functions azurefunctions python serverless workflows durablefunctions
10
+ Platform: UNKNOWN
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Operating System :: Microsoft :: Windows
15
+ Classifier: Operating System :: POSIX
16
+ Classifier: Operating System :: MacOS :: MacOS X
17
+ Classifier: Environment :: Web Environment
18
+ Classifier: Development Status :: 5 - Production/Stable
19
+ Requires-Python: >=3.9,<4
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+
23
+ |Branch|Status|
24
+ |---|---|
25
+ |main|[![Build Status](https://azfunc.visualstudio.com/Azure%20Functions/_apis/build/status/Azure.azure-functions-durable-python?branchName=main)](https://azfunc.visualstudio.com/Azure%20Functions/_build/latest?definitionId=58&branchName=main)|
26
+ |dev|[![Build Status](https://azfunc.visualstudio.com/Azure%20Functions/_apis/build/status/Azure.azure-functions-durable-python?branchName=dev)](https://azfunc.visualstudio.com/Azure%20Functions/_build/latest?definitionId=58&branchName=dev)|
27
+
28
+ # Durable Functions for Python
29
+
30
+ [Durable Functions](https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview) is an extension of [Azure Functions](https://docs.microsoft.com/en-us/azure/azure-functions/functions-overview) that lets you write stateful functions in a serverless compute environment. The extension lets you define stateful workflows by writing orchestrator functions and stateful entities by writing entity functions using the Azure Functions programming model. Behind the scenes, the extension manages state, checkpoints, and restarts for you, allowing you to focus on your business logic.
31
+
32
+ 🐍 Find us on PyPi [here](https://pypi.org/project/azure-functions-durable/) 🐍
33
+
34
+
35
+ You can find more information at the following links:
36
+
37
+ * [Azure Functions overview](https://docs.microsoft.com/en-us/azure/azure-functions/functions-overview)
38
+ * [Azure Functions Python developers guide](https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-python)
39
+ * [Durable Functions overview](https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview?tabs=python)
40
+ * [Core concepts and features overview](https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-types-features-overview).
41
+
42
+ > Durable Functions expects certain programming constraints to be followed. Please read the documentation linked above for more information.
43
+
44
+ ## Getting Started
45
+
46
+ Follow these instructions to get started with Durable Functions in Python:
47
+
48
+ **🚀 [Python Durable Functions quickstart](https://docs.microsoft.com/azure/azure-functions/durable/quickstart-python-vscode)**
49
+
50
+ ## Tooling
51
+
52
+ * Python Durable Functions requires [Azure Functions Core Tools](https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local) version 3.0.2630 or higher.
53
+
54
+
@@ -198,6 +198,17 @@ class Blueprint(TriggerApi, BindingApi, SettingsApi):
198
198
  # Invoke user code with rich DF Client binding
199
199
  return await user_code(*args, **kwargs)
200
200
 
201
+ # Todo: This feels awkward - however, there are two reasons that I can't naively implement
202
+ # this in the same way as entities and orchestrators:
203
+ # 1. We intentionally wrap this exported signature with @wraps, to preserve the original
204
+ # signature of the user code. This means that we can't just assign a new object to the
205
+ # fb._function._func, as that would overwrite the original signature.
206
+ # 2. I have not yet fully tested the behavior of overriding __call__ on an object with an
207
+ # async method.
208
+ # Here we lose type hinting and auto-documentation - not great. Need to find a better way
209
+ # to do this.
210
+ df_client_middleware.client_function = fb._function._func
211
+
201
212
  user_code_with_rich_client = df_client_middleware
202
213
  fb._function._func = user_code_with_rich_client
203
214
 
@@ -1,6 +1,6 @@
1
1
  from .models import DurableEntityContext
2
2
  from .models.entities import OperationResult, EntityState
3
- from datetime import datetime
3
+ from datetime import datetime, timezone
4
4
  from typing import Callable, Any, List, Dict
5
5
 
6
6
 
@@ -49,7 +49,7 @@ class Entity:
49
49
  for operation_data in batch:
50
50
  result: Any = None
51
51
  is_error: bool = False
52
- start_time: datetime = datetime.now()
52
+ start_time: datetime = datetime.now(timezone.utc)
53
53
 
54
54
  try:
55
55
  # populate context
@@ -74,6 +74,7 @@ class Entity:
74
74
  operation_result = OperationResult(
75
75
  is_error=is_error,
76
76
  duration=duration,
77
+ execution_start_time_ms=int(start_time.timestamp() * 1000),
77
78
  result=result
78
79
  )
79
80
  response.results.append(operation_result)
@@ -104,6 +105,9 @@ class Entity:
104
105
  context_body = context
105
106
  ctx, batch = DurableEntityContext.from_json(context_body)
106
107
  return Entity(fn).handle(ctx, batch)
108
+
109
+ handle.entity_function = fn
110
+
107
111
  return handle
108
112
 
109
113
  def _elapsed_milliseconds_since(self, start_time: datetime) -> int:
@@ -119,7 +123,7 @@ class Entity:
119
123
  int
120
124
  The time, in millseconds, from start_time to now
121
125
  """
122
- end_time = datetime.now()
126
+ end_time = datetime.now(timezone.utc)
123
127
  time_diff = end_time - start_time
124
128
  elapsed_time = int(time_diff.total_seconds() * 1000)
125
129
  return elapsed_time
@@ -4,6 +4,7 @@ from typing import List, Any, Optional, Dict, Union
4
4
  from time import time
5
5
  from asyncio import sleep
6
6
  from urllib.parse import urlparse, quote
7
+ from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
7
8
 
8
9
  import azure.functions as func
9
10
 
@@ -71,8 +72,13 @@ class DurableOrchestrationClient:
71
72
  request_url = self._get_start_new_url(
72
73
  instance_id=instance_id, orchestration_function_name=orchestration_function_name)
73
74
 
75
+ trace_parent, trace_state = DurableOrchestrationClient._get_current_activity_context()
76
+
74
77
  response: List[Any] = await self._post_async_request(
75
- request_url, self._get_json_input(client_input))
78
+ request_url,
79
+ self._get_json_input(client_input),
80
+ trace_parent,
81
+ trace_state)
76
82
 
77
83
  status_code: int = response[0]
78
84
  if status_code <= 202 and response[1]:
@@ -545,9 +551,14 @@ class DurableOrchestrationClient:
545
551
  entity_Id=entityId)
546
552
 
547
553
  request_url = options.to_url(self._orchestration_bindings.rpc_base_url)
554
+
555
+ trace_parent, trace_state = DurableOrchestrationClient._get_current_activity_context()
556
+
548
557
  response = await self._post_async_request(
549
558
  request_url,
550
- json.dumps(operation_input) if operation_input else None)
559
+ json.dumps(operation_input) if operation_input else None,
560
+ trace_parent,
561
+ trace_state)
551
562
 
552
563
  switch_statement = {
553
564
  202: lambda: None # signal accepted
@@ -779,3 +790,23 @@ class DurableOrchestrationClient:
779
790
  error_message = has_error_message()
780
791
  if error_message:
781
792
  raise Exception(error_message)
793
+
794
+ """Gets the current trace activity traceparent and tracestate
795
+
796
+ Returns
797
+ -------
798
+ tuple[str, str]
799
+ A tuple containing the (traceparent, tracestate)
800
+ """
801
+ @staticmethod
802
+ def _get_current_activity_context() -> tuple[str, str]:
803
+ carrier = {}
804
+
805
+ # Inject the current trace context into the carrier
806
+ TraceContextTextMapPropagator().inject(carrier)
807
+
808
+ # Extract the traceparent and optionally the tracestate
809
+ trace_parent = carrier.get("traceparent")
810
+ trace_state = carrier.get("tracestate")
811
+
812
+ return trace_parent, trace_state
@@ -1,7 +1,7 @@
1
1
  from collections import defaultdict
2
2
  from azure.durable_functions.models.actions.SignalEntityAction import SignalEntityAction
3
3
  from azure.durable_functions.models.actions.CallEntityAction import CallEntityAction
4
- from azure.durable_functions.models.Task import TaskBase, TimerTask
4
+ from azure.durable_functions.models.Task import LongTimerTask, TaskBase, TimerTask
5
5
  from azure.durable_functions.models.actions.CallHttpAction import CallHttpAction
6
6
  from azure.durable_functions.models.DurableHttpRequest import DurableHttpRequest
7
7
  from azure.durable_functions.models.actions.CallSubOrchestratorWithRetryAction import \
@@ -26,6 +26,8 @@ from typing import DefaultDict, List, Any, Dict, Optional, Tuple, Union, Callabl
26
26
  from uuid import UUID, uuid5, NAMESPACE_URL, NAMESPACE_OID
27
27
  from datetime import timezone
28
28
 
29
+ from azure.durable_functions.models.utils.json_utils import parse_timespan_attrib
30
+
29
31
  from .RetryOptions import RetryOptions
30
32
  from .FunctionContext import FunctionContext
31
33
  from .history import HistoryEvent, HistoryEventType
@@ -48,11 +50,22 @@ class DurableOrchestrationContext:
48
50
  # parameter names are as defined by JSON schema and do not conform to PEP8 naming conventions
49
51
  def __init__(self,
50
52
  history: List[Dict[Any, Any]], instanceId: str, isReplaying: bool,
51
- parentInstanceId: str, input: Any = None, upperSchemaVersion: int = 0, **kwargs):
53
+ parentInstanceId: str, input: Any = None, upperSchemaVersion: int = 0,
54
+ maximumShortTimerDuration: str = None,
55
+ longRunningTimerIntervalDuration: str = None, upperSchemaVersionNew: int = None,
56
+ **kwargs):
52
57
  self._histories: List[HistoryEvent] = [HistoryEvent(**he) for he in history]
53
58
  self._instance_id: str = instanceId
54
59
  self._is_replaying: bool = isReplaying
55
60
  self._parent_instance_id: str = parentInstanceId
61
+ self._maximum_short_timer_duration: datetime.timedelta = None
62
+ if maximumShortTimerDuration is not None:
63
+ max_short_duration = parse_timespan_attrib(maximumShortTimerDuration)
64
+ self._maximum_short_timer_duration = max_short_duration
65
+ self._long_timer_interval_duration: datetime.timedelta = None
66
+ if longRunningTimerIntervalDuration is not None:
67
+ long_interval_duration = parse_timespan_attrib(longRunningTimerIntervalDuration)
68
+ self._long_timer_interval_duration = long_interval_duration
56
69
  self._custom_status: Any = None
57
70
  self._new_uuid_counter: int = 0
58
71
  self._sub_orchestrator_counter: int = 0
@@ -66,6 +79,13 @@ class DurableOrchestrationContext:
66
79
  self._function_context: FunctionContext = FunctionContext(**kwargs)
67
80
  self._sequence_number = 0
68
81
  self._replay_schema = ReplaySchema(upperSchemaVersion)
82
+ if (upperSchemaVersionNew is not None
83
+ and upperSchemaVersionNew > self._replay_schema.value):
84
+ valid_schema_values = [enum_member.value for enum_member in ReplaySchema]
85
+ if upperSchemaVersionNew in valid_schema_values:
86
+ self._replay_schema = ReplaySchema(upperSchemaVersionNew)
87
+ else:
88
+ self._replay_schema = ReplaySchema(max(valid_schema_values))
69
89
 
70
90
  self._action_payload_v1: List[List[Action]] = []
71
91
  self._action_payload_v2: List[Action] = []
@@ -532,10 +552,10 @@ class DurableOrchestrationContext:
532
552
  The action to append
533
553
  """
534
554
  new_action: Union[List[Action], Action]
535
- if self._replay_schema is ReplaySchema.V2:
536
- new_action = action
537
- else:
555
+ if self._replay_schema is ReplaySchema.V1:
538
556
  new_action = [action]
557
+ else:
558
+ new_action = action
539
559
  self._add_to_actions(new_action)
540
560
  self._sequence_number += 1
541
561
 
@@ -580,6 +600,23 @@ class DurableOrchestrationContext:
580
600
  TaskBase
581
601
  A Durable Timer Task that schedules the timer to wake up the activity
582
602
  """
603
+ if self._replay_schema.value >= ReplaySchema.V3.value:
604
+ if not self._maximum_short_timer_duration or not self._long_timer_interval_duration:
605
+ raise Exception(
606
+ "A framework-internal error was detected: "
607
+ "replay schema version >= V3 is being used, "
608
+ "but one or more of the properties `maximumShortTimerDuration`"
609
+ "and `longRunningTimerIntervalDuration` are not defined. "
610
+ "This is likely an issue with the Durable Functions Extension. "
611
+ "Please report this bug here: "
612
+ "https://github.com/Azure/azure-functions-durable-python/issues\n"
613
+ f"maximumShortTimerDuration: {self._maximum_short_timer_duration}\n"
614
+ f"longRunningTimerIntervalDuration: {self._long_timer_interval_duration}"
615
+ )
616
+ if fire_at > self.current_utc_datetime + self._maximum_short_timer_duration:
617
+ action = CreateTimerAction(fire_at)
618
+ return LongTimerTask(None, action, self)
619
+
583
620
  action = CreateTimerAction(fire_at)
584
621
  task = self._generate_task(action, task_constructor=TimerTask)
585
622
  return task
@@ -656,7 +693,8 @@ class DurableOrchestrationContext:
656
693
 
657
694
  if self._replay_schema is ReplaySchema.V1 and isinstance(action_repr, list):
658
695
  self._action_payload_v1.append(action_repr)
659
- elif self._replay_schema is ReplaySchema.V2 and isinstance(action_repr, Action):
696
+ elif (self._replay_schema.value >= ReplaySchema.V2.value
697
+ and isinstance(action_repr, Action)):
660
698
  self._action_payload_v2.append(action_repr)
661
699
  else:
662
700
  raise Exception(f"DF-internal exception: ActionRepr of signature {type(action_repr)}"
@@ -684,7 +722,8 @@ class DurableOrchestrationContext:
684
722
  task.id = self._sequence_number
685
723
  self._sequence_number += 1
686
724
  self.open_tasks[task.id] = task
687
- elif task.id != -1:
725
+ elif task.id != -1 and self.open_tasks[task.id] != task:
726
+ # Case when returning task_any with multiple external events having the same ID
688
727
  self.open_tasks[task.id].append(task)
689
728
 
690
729
  if task.id in self.deferred_tasks:
@@ -1,3 +1,4 @@
1
+ from datetime import datetime
1
2
  from azure.durable_functions.models.actions.NoOpAction import NoOpAction
2
3
  from azure.durable_functions.models.actions.CompoundAction import CompoundAction
3
4
  from azure.durable_functions.models.RetryOptions import RetryOptions
@@ -170,7 +171,7 @@ class CompoundTask(TaskBase):
170
171
  child_actions.append(action_repr)
171
172
  if compound_action_constructor is None:
172
173
  self.action_repr = child_actions
173
- else: # replay_schema is ReplaySchema.V2
174
+ else: # replay_schema >= ReplaySchema.V2
174
175
  self.action_repr = compound_action_constructor(child_actions)
175
176
  self._first_error: Optional[Exception] = None
176
177
  self.pending_tasks: Set[TaskBase] = set(tasks)
@@ -292,7 +293,7 @@ class WhenAllTask(CompoundTask):
292
293
  The ReplaySchema, which determines the inner action payload representation
293
294
  """
294
295
  compound_action_constructor = None
295
- if replay_schema is ReplaySchema.V2:
296
+ if replay_schema.value >= ReplaySchema.V2.value:
296
297
  compound_action_constructor = WhenAllAction
297
298
  super().__init__(task, compound_action_constructor)
298
299
 
@@ -317,6 +318,119 @@ class WhenAllTask(CompoundTask):
317
318
  self.set_value(is_error=True, value=self._first_error)
318
319
 
319
320
 
321
+ class LongTimerTask(WhenAllTask):
322
+ """A Timer Task for intervals longer than supported by the storage backend."""
323
+
324
+ def __init__(self, id_, action: CreateTimerAction, orchestration_context):
325
+ """Initialize a LongTimerTask.
326
+
327
+ Parameters
328
+ ----------
329
+ id_ : int
330
+ An ID for the task
331
+ action : CreateTimerAction
332
+ The action this task represents
333
+ orchestration_context: DurableOrchestrationContext
334
+ The orchestration context this task was created in
335
+ """
336
+ current_time = orchestration_context.current_utc_datetime
337
+ final_fire_time = action.fire_at
338
+ duration_until_fire = final_fire_time - current_time
339
+
340
+ if duration_until_fire > orchestration_context._maximum_short_timer_duration:
341
+ next_fire_time = current_time + orchestration_context._long_timer_interval_duration
342
+ else:
343
+ next_fire_time = final_fire_time
344
+
345
+ next_timer_action = CreateTimerAction(next_fire_time)
346
+ next_timer_task = TimerTask(None, next_timer_action)
347
+ super().__init__([next_timer_task], orchestration_context._replay_schema)
348
+
349
+ self.id = id_
350
+ self.action = action
351
+ self._orchestration_context = orchestration_context
352
+ self._max_short_timer_duration = self._orchestration_context._maximum_short_timer_duration
353
+ self._long_timer_interval = self._orchestration_context._long_timer_interval_duration
354
+
355
+ def is_canceled(self) -> bool:
356
+ """Check if the LongTimer is cancelled.
357
+
358
+ Returns
359
+ -------
360
+ bool
361
+ Returns whether the timer has been cancelled or not
362
+ """
363
+ return self.action.is_cancelled
364
+
365
+ def cancel(self):
366
+ """Cancel a timer.
367
+
368
+ Raises
369
+ ------
370
+ ValueError
371
+ Raises an error if the task is already completed and an attempt is made to cancel it
372
+ """
373
+ if (self.result):
374
+ raise Exception("Cannot cancel a completed task.")
375
+ self.action.is_cancelled = True
376
+
377
+ def try_set_value(self, child: TimerTask):
378
+ """Transition this LongTimer Task to a terminal state and set its value.
379
+
380
+ If the LongTimer has not yet reached the designated completion time, starts a new
381
+ TimerTask for the next interval and does not close.
382
+
383
+ Parameters
384
+ ----------
385
+ child : TimerTask
386
+ A timer sub-task that just completed
387
+ """
388
+ current_time = self._orchestration_context.current_utc_datetime
389
+ final_fire_time = self.action.fire_at
390
+ if final_fire_time > current_time:
391
+ next_timer = self.get_next_timer_task(final_fire_time, current_time)
392
+ self.add_new_child(next_timer)
393
+ return super().try_set_value(child)
394
+
395
+ def get_next_timer_task(self, final_fire_time: datetime, current_time: datetime) -> TimerTask:
396
+ """Create a TimerTask to represent the next interval of the LongTimer.
397
+
398
+ Parameters
399
+ ----------
400
+ final_fire_time : datetime.datetime
401
+ The final firing time of the LongTimer
402
+ current_time : datetime.datetime
403
+ The current time
404
+
405
+ Returns
406
+ -------
407
+ TimerTask
408
+ A TimerTask representing the next interval of the LongTimer
409
+ """
410
+ duration_until_fire = final_fire_time - current_time
411
+ if duration_until_fire > self._max_short_timer_duration:
412
+ next_fire_time = current_time + self._long_timer_interval
413
+ else:
414
+ next_fire_time = final_fire_time
415
+ return TimerTask(None, CreateTimerAction(next_fire_time))
416
+
417
+ def add_new_child(self, child_timer: TimerTask):
418
+ """Add the TimerTask to this task's children.
419
+
420
+ Also register the TimerTask with the orchestration context.
421
+
422
+ Parameters
423
+ ----------
424
+ child_timer : TimerTask
425
+ The newly created TimerTask to add
426
+ """
427
+ child_timer.parent = self
428
+ self.pending_tasks.add(child_timer)
429
+ self._orchestration_context._add_to_open_tasks(child_timer)
430
+ self._orchestration_context._add_to_actions(child_timer.action_repr)
431
+ child_timer._set_is_scheduled(True)
432
+
433
+
320
434
  class WhenAnyTask(CompoundTask):
321
435
  """A Task representing `when_any` scenarios."""
322
436
 
@@ -331,7 +445,7 @@ class WhenAnyTask(CompoundTask):
331
445
  The ReplaySchema, which determines the inner action payload representation
332
446
  """
333
447
  compound_action_constructor = None
334
- if replay_schema is ReplaySchema.V2:
448
+ if replay_schema.value >= ReplaySchema.V2.value:
335
449
  compound_action_constructor = WhenAnyAction
336
450
  super().__init__(task, compound_action_constructor)
337
451
 
@@ -245,14 +245,14 @@ class TaskOrchestrationExecutor:
245
245
 
246
246
  self.current_task = new_task
247
247
  if not (new_task is None):
248
+ if not (self.current_task._is_scheduled):
249
+ # new task is received. it needs to be resolved to a value
250
+ self.context._add_to_actions(self.current_task.action_repr)
251
+ self._mark_as_scheduled(self.current_task)
248
252
  if not (new_task.state is TaskState.RUNNING):
249
253
  # user yielded the same task multiple times, continue executing code
250
254
  # until a new/not-previously-yielded task is encountered
251
255
  self.resume_user_code()
252
- elif not (self.current_task._is_scheduled):
253
- # new task is received. it needs to be resolved to a value
254
- self.context._add_to_actions(self.current_task.action_repr)
255
- self._mark_as_scheduled(self.current_task)
256
256
 
257
257
  def _mark_as_scheduled(self, task: TaskBase):
258
258
  if isinstance(task, CompoundTask):
@@ -286,12 +286,18 @@ class TaskOrchestrationExecutor:
286
286
  self.output = None
287
287
  self.exception = e
288
288
 
289
+ exception_str = None
290
+ if self.exception is not None:
291
+ exception_str = str(self.exception)
292
+ if not exception_str:
293
+ exception_str = str(type(self.exception))
294
+
289
295
  state = OrchestratorState(
290
296
  is_done=self.orchestration_invocation_succeeded,
291
297
  actions=self.context._actions,
292
298
  output=self.output,
293
299
  replay_schema=self.context._replay_schema,
294
- error=None if self.exception is None else str(self.exception),
300
+ error=exception_str,
295
301
  custom_status=self.context.custom_status
296
302
  )
297
303
 
@@ -9,6 +9,7 @@ from .RetryOptions import RetryOptions
9
9
  from .DurableHttpRequest import DurableHttpRequest
10
10
  from .TokenSource import ManagedIdentityTokenSource
11
11
  from .DurableEntityContext import DurableEntityContext
12
+ from .Task import TaskBase
12
13
 
13
14
  __all__ = [
14
15
  'DurableOrchestrationBindings',
@@ -20,5 +21,6 @@ __all__ = [
20
21
  'OrchestratorState',
21
22
  'OrchestrationRuntimeStatus',
22
23
  'PurgeHistoryResult',
23
- 'RetryOptions'
24
+ 'RetryOptions',
25
+ 'TaskBase'
24
26
  ]