Skip to content

Consume new version of Durable Python SDK. #61

Open

Description

@greenie-msft

Activity

  1. changed the title [-]Cosume new version of Durable Python SDK.[/-] [+]Consume new version of Durable Python SDK.[/+] on Aug 3, 2026
  2. added this to the GA milestone on Aug 3, 2026
  3. ahmedmuhsin commented on Aug 18, 2026

    @ahmedmuhsin
    Contributor

    I've started on this. Branch is python/azure-functions-durable-2x, not pushed yet.

    What shipped upstream

    azure-functions-durable 2.0.0b2 is a ground-up rewrite that now lives in microsoft/durabletask-python, built on the durabletask gRPC runtime rather than the classic Durable Functions extension protocol. It pulls in durabletask 1.9.0 and azure-functions 2.3.0b3.

    Verified against the real package, not the docs

    • azure.durable_functions.models is gone. That removes TaskBase, CompoundTask, TaskState and NoOpAction, which our _orchestration.py was built on top of.
    • mcp_tool_trigger still exists in azure-functions 2.3.0b3 with a compatible signature, so sample 08 is fine. This was my main worry going in.
    • entity_trigger accepts a class-based DurableEntity, so the Functions host can register the same entity class the standalone worker already uses.
    • The preview extension bundle is reachable and has versions through 4.46.0, so [4.*, 5.0.0) resolves.

    Why this is a net simplification

    If you take the native path, a two-argument orchestrator receives a real durabletask.task.OrchestrationContext. That is the exact type agent-framework-durabletask already targets, so most of the Azure Functions adapter layer becomes redundant.

    I deleted _orchestration.py, _workflow_af_context.py and _entities.py, plus two test files that were duplicating coverage the durabletask package already has. AzureFunctionsAgentExecutor was a line for line duplicate of OrchestrationAgentExecutor, and AgentTask was a duplicate of DurableAgentTask. I also pulled the configured-entity factory into the durabletask package so both hosts register the same implementation.

    Worth being honest that _app.py stays big. Its HTTP routing, status endpoints and MCP wiring are not duplicated with durabletask and do not get simpler.

    Current state

    durabletask is ruff clean, pyright clean, 413 tests passing. azurefunctions is ruff clean with 247 tests passing and 8 pyright errors left, covered below.

    Workspace split

    2.x requires Python 3.13. uv resolves a workspace to a single lock over the intersection of its members, so keeping both packages in one workspace pulled agent-framework-durabletask up to 3.13 too, which broke three of the four legs in the 3.10 to 3.13 matrix in python-merge-tests.yml.

    durabletask has zero references to azure.durable_functions and no technical reason to require 3.13, so dropping three Python versions for its users would have been a real regression. I split the workspace instead. packages/azurefunctions is now a standalone uv project with its own lockfile.

    What's left

    1. Migrate the remaining deprecated client calls (get_status, raise_event, read_entity_state). Pyright strict treats them as errors so CI will not pass without it. The catch is that the native status enum renders COMPLETED where the compat wrapper renders Completed, and that string goes on the wire from the workflow status endpoint. It needs an explicit mapping plus tests asserting the JSON shape, otherwise we silently change the public HTTP contract.
    2. 14 sample host.json files need the preview bundle, and 5 function_app.py files still import deprecated aliases.
    3. CI needs the job split, with durabletask keeping the four version matrix and azurefunctions on 3.13 only. The integration job also moves from 3.12 to 3.13.
    4. The integration harness needs a virtualenv inside each app directory. Upstream's own E2E harness says the Functions Python worker only prioritizes app dependencies over its bundled copies when it can locate them relative to the app dir, and with the venv outside, both protobuf C extensions load and the worker crashes natively during indexing. Our CI creates a workspace level venv, which is exactly that shape. I suspect this is the real reason behind the 3.12 pin, not just Core Tools.

    Breaking changes for the release notes

    For agent-framework-azurefunctions:

    • Minimum Python is now 3.13, up from 3.10. This is forced by 2.x, which requires 3.13 because older Functions Python workers do not isolate worker dependencies from app dependencies and collide with the durable runtime's grpc at load time.
    • It now depends on prerelease packages, azure-functions-durable>=2.0.0b1 and azure-functions>=2.3.0b2.
    • Function apps must switch host.json to the preview extension bundle.
    • Entity names are now lowercased. dafx-TestAgent becomes dafx-testagent. This matches how the standalone DurableTask host has always behaved, but it changes entity addressing, so apps with in-flight orchestrations should drain them or move to a new task hub.

    agent-framework-durabletask is unchanged for consumers. Still Python 3.10+, still no Azure Functions dependency. Its durabletask floor moves to 1.9.0.

    For contributors, uv sync now has to be run separately inside packages/azurefunctions.

    One question

    Given the size, I think this wants to be split across a few PRs rather than one. The workspace split, the code migration, and the samples plus CI are all separable. Happy to do it either way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions