Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion azure/functions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
AsgiFunctionApp, WsgiFunctionApp,
ExternalHttpFunctionApp, BlobSource, McpPropertyType)
from ._durable_functions import OrchestrationContext, EntityContext
from .durable_functions import register_durable_converters
from .decorators.function_app import (FunctionRegister, TriggerApi,
BindingApi, SettingsApi)
from .extension import (ExtensionMeta, FunctionExtensionException,
Expand Down Expand Up @@ -43,6 +44,9 @@
from . import mysql # NoQA


register_durable_converters()


__all__ = (
# Functions
'get_binding_registry',
Expand Down Expand Up @@ -106,4 +110,4 @@
'McpPropertyType'
)

__version__ = '1.25.0b2'
__version__ = '1.25.0b3.dev1'
59 changes: 59 additions & 0 deletions azure/functions/decorators/durable_functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
import logging

_logger = logging.getLogger('azure.functions.DurableFunctions')

df = None


def get_durable_package():
"""Determines which Durable SDK is being used.

If the `azure-functions-durable` package is installed, we
log a warning that this legacy package
is deprecated.

If both the legacy and current packages are installed,
we log a warning and prefer the current package.

If neither package is installed, we return None.
"""
_logger.info("Attempting to import Durable Functions package.")
using_legacy = False
using_durable_task = False
global df
if df:
_logger.info("Durable Functions package already loaded. DF: %s", df)
return df

try:
import azure.durable_functions as durable_functions
using_legacy = True
_logger.warning("`durabletask-azurefunctions` is available now! "
"See <AKA.MS LINK HERE> for more details.")
except ImportError:
_logger.info("`azure-functions-durable` package not found.")
pass
try:
import durabletask.azurefunctions as durable_functions # noqa
using_durable_task = True
except ImportError:
_logger.info("`durabletask-azurefunctions` package not found.")
pass

if using_durable_task and using_legacy:
# Both packages are installed; prefer `durabletask-azurefunctions`.
_logger.warning("Both `azure-functions-durable` and "
"`durabletask-azurefunctions` packages are installed. "
"This may lead to unexpected behavior. Please resolve this "
"conflict by removing one of these packages from the Python "
"environment. Decorators from `durabletask-azurefunctions` will "
"be used.")

if not using_durable_task and not using_legacy:
return None

df = durable_functions

return durable_functions
14 changes: 9 additions & 5 deletions azure/functions/decorators/function_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
DaprBindingTrigger, DaprInvokeOutput, DaprPublishOutput, \
DaprSecretInput, DaprServiceInvocationTrigger, DaprStateInput, \
DaprStateOutput, DaprTopicTrigger
from azure.functions.decorators.durable_functions import get_durable_package
from azure.functions.decorators.eventgrid import EventGridTrigger, \
EventGridOutput
from azure.functions.decorators.eventhub import EventHubTrigger, EventHubOutput
Expand Down Expand Up @@ -57,6 +58,8 @@
from azure.functions.decorators.mysql import MySqlInput, MySqlOutput, \
MySqlTrigger

_logger = logging.getLogger('azure.functions.DurableFunctions')


class Function(object):
"""
Expand Down Expand Up @@ -347,15 +350,16 @@ def _get_durable_blueprint(self):
"""Attempt to import the Durable Functions SDK from which DF
decorators are implemented.
"""
try:
import azure.durable_functions as df
_logger.info("Getting Durable Functions blueprint.")
df = get_durable_package()
if df:
df_bp = df.Blueprint()
return df_bp
except ImportError:
else:
error_message = \
"Attempted to use a Durable Functions decorator, " \
"but the `azure-functions-durable` SDK package could not be " \
"found. Please install `azure-functions-durable` to use " \
"but the `durabletask-azurefunctions` SDK package could not be " \
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the case where the customer tries to use a DF decorator (func.FunctionApp) but doesn't have either package installed. df is None, so we raise an error

"found. Please install `durabletask-azurefunctions` to use " \
"Durable Functions."
raise Exception(error_message)

Expand Down
Loading