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.
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.github/workflows/durable_python_action.yml +2 -2
- azure-functions-durable-1.3.1/.github/workflows/validate.yml +60 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/CODEOWNERS +1 -1
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/CONTRIBUTING.md +20 -6
- azure-functions-durable-1.3.1/PKG-INFO +54 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/decorators/durable_app.py +11 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/entity.py +7 -3
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/DurableOrchestrationClient.py +33 -2
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/DurableOrchestrationContext.py +46 -7
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/ReplaySchema.py +1 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/Task.py +117 -3
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/TaskOrchestrationExecutor.py +11 -5
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/__init__.py +3 -1
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/entities/OperationResult.py +18 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/utils/http_utils.py +14 -3
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/utils/json_utils.py +40 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/orchestrator.py +2 -0
- azure-functions-durable-1.3.1/azure/durable_functions/testing/OrchestratorGeneratorWrapper.py +42 -0
- azure-functions-durable-1.3.1/azure/durable_functions/testing/__init__.py +6 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure-pipelines-release.yml +1 -1
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure-pipelines.yml +2 -2
- azure-functions-durable-1.3.1/azure_functions_durable.egg-info/PKG-INFO +54 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure_functions_durable.egg-info/SOURCES.txt +16 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure_functions_durable.egg-info/requires.txt +3 -1
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/eng/templates/build.yml +3 -3
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/noxfile.py +4 -4
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/requirements.txt +4 -2
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/blueprint/requirements.txt +2 -1
- azure-functions-durable-1.3.1/samples-v2/blueprint/tests/readme.md +72 -0
- azure-functions-durable-1.3.1/samples-v2/blueprint/tests/test_my_orchestrator.py +35 -0
- azure-functions-durable-1.3.1/samples-v2/blueprint/tests/test_say_hello.py +4 -0
- azure-functions-durable-1.3.1/samples-v2/blueprint/tests/test_start_orchestrator.py +26 -0
- {azure-functions-durable-1.2.10/samples → azure-functions-durable-1.3.1/samples-v2}/fan_in_fan_out/requirements.txt +2 -1
- azure-functions-durable-1.3.1/samples-v2/fan_in_fan_out/tests/readme.md +72 -0
- azure-functions-durable-1.3.1/samples-v2/fan_in_fan_out/tests/test_E2_BackupSiteContent.py +52 -0
- azure-functions-durable-1.3.1/samples-v2/fan_in_fan_out/tests/test_E2_CopyFileToBlob.py +4 -0
- azure-functions-durable-1.3.1/samples-v2/fan_in_fan_out/tests/test_E2_GetFileList.py +4 -0
- azure-functions-durable-1.3.1/samples-v2/fan_in_fan_out/tests/test_HttpStart.py +27 -0
- azure-functions-durable-1.3.1/samples-v2/function_chaining/host.json +15 -0
- {azure-functions-durable-1.2.10/samples → azure-functions-durable-1.3.1/samples-v2}/function_chaining/requirements.txt +1 -0
- azure-functions-durable-1.3.1/samples-v2/function_chaining/tests/readme.md +72 -0
- azure-functions-durable-1.3.1/samples-v2/function_chaining/tests/test_http_start.py +27 -0
- azure-functions-durable-1.3.1/samples-v2/function_chaining/tests/test_my_orchestrator.py +37 -0
- azure-functions-durable-1.3.1/samples-v2/function_chaining/tests/test_say_hello.py +4 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/setup.py +5 -3
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/test_DurableOrchestrationClient.py +1 -1
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_entity.py +2 -0
- azure-functions-durable-1.3.1/tests/tasks/test_long_timers.py +70 -0
- azure-functions-durable-1.2.10/.github/workflows/validate.yml +0 -34
- azure-functions-durable-1.2.10/PKG-INFO +0 -51
- azure-functions-durable-1.2.10/azure_functions_durable.egg-info/PKG-INFO +0 -51
- azure-functions-durable-1.2.10/samples-v2/function_chaining/host.json +0 -25
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.devcontainer/devcontainer.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.devcontainer/setup.sh +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.flake8 +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.github/ISSUE_TEMPLATE/----feature-request.md +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.github/ISSUE_TEMPLATE/---bug-report.md +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.github/policies/resourceManagement.yml +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.github/workflows/codeQL.yml +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.github/workflows/submodule-sync.yml +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/.gitignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/CHANGELOG.md +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/LICENSE +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/MANIFEST.in +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/README.md +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/SECURITY.md +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/constants.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/decorators/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/decorators/metadata.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/DurableEntityContext.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/DurableHttpRequest.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/DurableOrchestrationBindings.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/DurableOrchestrationStatus.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/EntityStateResponse.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/FunctionContext.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/OrchestrationRuntimeStatus.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/OrchestratorState.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/PurgeHistoryResult.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/RetryOptions.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/RpcManagementOptions.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/TokenSource.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/Action.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/ActionType.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/CallActivityAction.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/CallActivityWithRetryAction.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/CallEntityAction.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/CallHttpAction.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/CallSubOrchestratorAction.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/CallSubOrchestratorWithRetryAction.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/CompoundAction.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/ContinueAsNewAction.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/CreateTimerAction.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/NoOpAction.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/SignalEntityAction.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/WaitForExternalEventAction.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/WhenAllAction.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/WhenAnyAction.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/actions/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/entities/EntityState.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/entities/RequestMessage.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/entities/ResponseMessage.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/entities/Signal.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/entities/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/history/HistoryEvent.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/history/HistoryEventType.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/history/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/utils/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/models/utils/entity_utils.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure_functions_durable.egg-info/dependency_links.txt +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure_functions_durable.egg-info/top_level.txt +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/eng/ci/code-mirror.yml +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/eng/ci/official-build.yml +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/host.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/.funcignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/.gitignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/aml_durable_orchestrator/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/aml_durable_orchestrator/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/aml_pipeline/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/aml_pipeline/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/aml_poll_status/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/aml_poll_status/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/extensions.csproj +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/host.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/local.settings.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/proxies.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/requirements.txt +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/shared/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/shared/aml_helper.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/aml_monitoring/shared/auth_helper.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/.funcignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/.gitignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/Counter/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/Counter/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/DurableOrchestration/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/DurableOrchestration/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/DurableTrigger/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/DurableTrigger/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/README.md +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/RetrieveEntity/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/RetrieveEntity/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/host.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/local.settings.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/counter_entity/requirements.txt +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/.funcignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/.gitignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/E2_BackupSiteContent/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/E2_BackupSiteContent/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/E2_CopyFileToBlob/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/E2_CopyFileToBlob/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/E2_GetFileList/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/E2_GetFileList/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/HttpStart/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/HttpStart/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/README.md +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/host.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/local.settings.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/fan_in_fan_out/proxies.json +0 -0
- {azure-functions-durable-1.2.10/samples-v2 → azure-functions-durable-1.3.1/samples}/fan_in_fan_out/requirements.txt +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/.funcignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/.gitignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/E1_HelloSequence/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/E1_HelloSequence/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/E1_SayHello/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/E1_SayHello/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/HttpStart/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/HttpStart/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/README.md +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/host.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/local.settings.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining/proxies.json +0 -0
- {azure-functions-durable-1.2.10/samples-v2 → azure-functions-durable-1.3.1/samples}/function_chaining/requirements.txt +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/.funcignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/.gitignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/DurableActivity/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/DurableActivity/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/DurableOrchestration/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/DurableOrchestration/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/DurableTrigger/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/DurableTrigger/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/README.md +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/host.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/local.settings.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/proxies.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/function_chaining_custom_status/requirements.txt +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/.funcignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/.gitignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/E4_SMSPhoneVerification/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/E4_SMSPhoneVerification/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/HttpStart/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/HttpStart/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/README.md +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/SendSMSChallenge/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/SendSMSChallenge/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/host.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/local.settings.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/proxies.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/human_interaction/requirements.txt +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/.funcignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/.gitignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/E3_Monitor/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/E3_Monitor/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/E3_SendAlert/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/E3_SendAlert/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/E3_TooManyOpenIssues/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/E3_TooManyOpenIssues/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/HttpStart/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/HttpStart/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/README.md +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/host.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/local.settings.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/proxies.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/monitor/requirements.txt +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/.gitignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/DurableActivity/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/DurableActivity/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/DurableOrchestration/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/DurableOrchestration/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/DurableTrigger/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/DurableTrigger/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/README.md +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/host.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/local.settings.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/requirements.txt +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/serialize_arguments/shared_code/MyClasses.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/.funcignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/.gitignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/DurableFunctionsHttpStart/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/DurableFunctionsHttpStart/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/DurableOrchestrator/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/DurableOrchestrator/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/DurableSubOrchestrator/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/DurableSubOrchestrator/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/Hello/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/Hello/function.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/README.md +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/host.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/local.settings.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/proxies.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples/simple_sub_orchestration/requirements.txt +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/blueprint/.funcignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/blueprint/.gitignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/blueprint/durable_blueprints.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/blueprint/function_app.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/blueprint/host.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/fan_in_fan_out/.funcignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/fan_in_fan_out/.gitignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/fan_in_fan_out/README.md +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/fan_in_fan_out/function_app.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/fan_in_fan_out/host.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/fan_in_fan_out/proxies.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/function_chaining/.funcignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/function_chaining/.gitignore +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/function_chaining/README.md +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/function_chaining/function_app.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/samples-v2/function_chaining/proxies.json +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/scripts/sample_deploy.sh +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/setup.cfg +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/conftest.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/test_DecoratorMetadata.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/test_Decorators.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/test_DurableOrchestrationBindings.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/test_DurableOrchestrationContext.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/test_DurableOrchestrationStatus.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/test_OrchestrationState.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/test_RpcManagementOptions.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/models/test_TokenSource.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/models/OrchestrationInstance.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/orchestrator_test_utils.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/schemas/OrchetrationStateSchema.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_call_http.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_continue_as_new.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_create_timer.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_external_event.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_fan_out_fan_in.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_is_replaying_flag.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_retries.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_sequential_orchestrator.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_sequential_orchestrator_custom_status.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_sequential_orchestrator_with_retry.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_serialization.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_sub_orchestrator.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_sub_orchestrator_with_retry.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/orchestrator/test_task_any.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/tasks/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/tasks/tasks_test_utils.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/tasks/test_new_uuid.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/test_constants.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/test_utils/ContextBuilder.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/test_utils/EntityContextBuilder.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/test_utils/__init__.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/test_utils/constants.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/test_utils/json_utils.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/test_utils/testClasses.py +0 -0
- {azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/tests/utils/__init__.py +0 -0
- {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.
|
|
15
|
+
- name: Set up Python 3.9.x
|
|
16
16
|
uses: actions/setup-python@v1
|
|
17
17
|
with:
|
|
18
|
-
python-version: 3.
|
|
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
|
|
@@ -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.
|
|
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.
|
|
133
|
-
2.
|
|
134
|
-
3.
|
|
135
|
-
4.
|
|
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|[](https://azfunc.visualstudio.com/Azure%20Functions/_build/latest?definitionId=58&branchName=main)|
|
|
26
|
+
|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
|
|
{azure-functions-durable-1.2.10 → azure-functions-durable-1.3.1}/azure/durable_functions/entity.py
RENAMED
|
@@ -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,
|
|
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,
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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=
|
|
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
|
]
|