Skip to content

feat: Add support for new Durable Python SDK#353

Open
andystaples wants to merge 6 commits into
Azure:devfrom
andystaples:andystaples/new-durable-converters-v2.x
Open

feat: Add support for new Durable Python SDK#353
andystaples wants to merge 6 commits into
Azure:devfrom
andystaples:andystaples/new-durable-converters-v2.x

Conversation

@andystaples

Copy link
Copy Markdown
Contributor

No description provided.

@andystaples andystaples changed the title Andystaples/new durable converters v2.x feat: Add support for new Durable Python SDK Jul 22, 2026
Comment thread azure/functions/decorators/durable_functions.py Outdated
Comment thread azure/functions/__init__.py Outdated
Comment thread azure/functions/durable_functions.py Outdated
Comment thread azure/functions/durable_functions.py Outdated
Comment thread azure/functions/durable_functions.py Outdated
Comment thread azure/functions/durable_functions.py Outdated
Comment thread tests/test_durable_functions.py
Comment thread azure/functions/decorators/durable_functions.py Outdated
@hallvictoria

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

…le_package, add v2 converter tests

- Revert version bump 2.3.0b2 -> 2.3.0b1 (handled by release process)
- Move non-essential logs to debug and strip all but module-selection-path logs
- Replace try/except with if/else for v1/v2 detection logs
- DurableClientConverter uses get_durable_package() instead of plain import
- Reorder registration so v2 is the if and legacy is the else fallback
- Add tests for the v2 converters and register_durable_converters/get_durable_package
Comment thread azure/functions/decorators/function_app.py Outdated
Comment thread azure/functions/decorators/function_app.py Outdated
Comment thread azure/functions/__init__.py Outdated
_logger.debug("`azure.durable_functions` package not found.")
return None

if hasattr(durable_functions, 'version') and durable_functions.version.startswith("2."):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current SDK does not expose  azure.durable_functions.version. This will always log v1 package is used right?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFD V2 will expose this property

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct — with the current published SDK there's no version attribute, so it takes the else branch and logs v1.x, which is the intended behavior today. The version-based check is forward-compat: once the v2.x (Durable Task) SDK ships exposing version = "2.x", the same code will detect and log v2.x and register the new converters. It's a debug-only log, so no functional impact either way.

Comment thread azure/functions/durable_functions.py Outdated
Comment thread azure/functions/__init__.py Outdated
import azure.durable_functions as durable_functions # noqa
except ImportError:
_logger.debug("`azure.durable_functions` package not found.")
return None

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In which case this will return none? Won't a durable app always has the SDK installed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question — the None path is reachable and intentional in two cases:

  1. Non-durable apps (the common case). register_durable_converters() runs at import of azure.functions for every app. The majority of apps don't have azure-functions-durable installed, so get_durable_package() returns None and registration is a deliberate no-op.

  2. A user references a durable decorator without the SDK installed. The durable decorators (orchestration_trigger, entity_trigger, activity_trigger on TriggerApi; durable_client_input on BindingApi) are defined unconditionally in the base azure-functions library and inherited by every FunctionApp/Blueprint. So a user can reference @app.orchestration_trigger even without the SDK present. In that case _get_durable_blueprint() gets None and raises the explicit "please install azure-functions-durable" error, instead of surfacing a confusing ImportError/AttributeError.

So a correctly-configured durable app will always have the SDK, but None is the right guard for both the non-durable-app import path and the misconfigured-durable-app path.

- Register durable converters lazily on first _ConverterMeta.get() lookup instead of at azure.functions import time, avoiding a re-entrant import of the durable SDK (which imports azure.functions)
- Move the DurableFunctions logger into _get_durable_blueprint and use debug
- Group 'import logging' with the other stdlib imports in durable_functions.py
- Add deferred-registration tests in test_meta.py
@andystaples

Copy link
Copy Markdown
Contributor Author

Thanks @gavin-aguiar for the review.
The agent might have gone a bit overboard with the changes to meta.py and deferred registration - let me know and I can revert and go for a more focused fix

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants