From 46128cc592ad7efeeeb86b8054c6dcfc373c45ab Mon Sep 17 00:00:00 2001 From: "Hanzhang Zeng (Roger)" Date: Thu, 20 Feb 2020 10:58:19 -0800 Subject: [PATCH 1/5] Added durable functions support by loosing return type checking --- azure_functions_worker/bindings/__init__.py | 2 ++ azure_functions_worker/bindings/generic.py | 4 ++++ azure_functions_worker/bindings/meta.py | 18 +++++++++++++----- azure_functions_worker/functions.py | 10 +++++++++- setup.py | 2 +- 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/azure_functions_worker/bindings/__init__.py b/azure_functions_worker/bindings/__init__.py index 4e34b02e5..f5204d1af 100644 --- a/azure_functions_worker/bindings/__init__.py +++ b/azure_functions_worker/bindings/__init__.py @@ -2,6 +2,7 @@ from .context import Context from .meta import check_input_type_annotation from .meta import check_output_type_annotation +from .meta import has_implicit_output from .meta import is_trigger_binding from .meta import from_incoming_proto, to_outgoing_proto from .out import Out @@ -11,5 +12,6 @@ 'Out', 'Context', 'is_trigger_binding', 'check_input_type_annotation', 'check_output_type_annotation', + 'has_implicit_output', 'from_incoming_proto', 'to_outgoing_proto', 'TraceContext', ) diff --git a/azure_functions_worker/bindings/generic.py b/azure_functions_worker/bindings/generic.py index d30a07813..f325d9898 100644 --- a/azure_functions_worker/bindings/generic.py +++ b/azure_functions_worker/bindings/generic.py @@ -46,3 +46,7 @@ def decode(cls, data: datumdef.Datum, *, trigger_metadata) -> typing.Any: ) return result + + @classmethod + def has_implicit_output(cls) -> bool: + return False diff --git a/azure_functions_worker/bindings/meta.py b/azure_functions_worker/bindings/meta.py index 434d4a96d..d850ee8ac 100644 --- a/azure_functions_worker/bindings/meta.py +++ b/azure_functions_worker/bindings/meta.py @@ -9,6 +9,7 @@ def get_binding_registry(): func = sys.modules.get('azure.functions') + if func is not None: return func.get_binding_registry() else: @@ -20,7 +21,6 @@ def get_binding(bind_name: str) -> object: registry = get_binding_registry() if registry is not None: binding = registry.get(bind_name) - if binding is None: binding = generic.GenericBinding @@ -32,16 +32,24 @@ def is_trigger_binding(bind_name: str) -> bool: return binding.has_trigger_support() -def check_input_type_annotation(binding: str, pytype: type) -> bool: - binding = get_binding(binding) +def check_input_type_annotation(bind_name: str, pytype: type) -> bool: + binding = get_binding(bind_name) return binding.check_input_type_annotation(pytype) -def check_output_type_annotation(binding: str, pytype: type) -> bool: - binding = get_binding(binding) +def check_output_type_annotation(bind_name: str, pytype: type) -> bool: + binding = get_binding(bind_name) return binding.check_output_type_annotation(pytype) +def has_implicit_output(bind_name: str) -> bool: + binding = get_binding(bind_name) + + # If the binding does not have metaclass of meta.InConverter + # The implicit_output does not exist + return getattr(binding, 'has_implicit_output', lambda: False)() + + def from_incoming_proto( binding: str, val: protos.TypedData, *, diff --git a/azure_functions_worker/functions.py b/azure_functions_worker/functions.py index 52795b586..070e90a8c 100644 --- a/azure_functions_worker/functions.py +++ b/azure_functions_worker/functions.py @@ -82,6 +82,13 @@ def add_function(self, function_id: str, assert return_binding_name is not None has_return = True + elif bindings.has_implicit_output(desc.type): + # If the binding specify implicit output binding + # (e.g. orchestrationTrigger, activityTrigger) + # we should enable output even if $return is not specified + has_return = True + return_binding_name = f'{desc.type}_ret' + bound_params[name] = desc else: bound_params[name] = desc @@ -180,7 +187,8 @@ def add_function(self, function_id: str, f'direction in function.json, but its annotation ' f'is azure.functions.Out in Python') - if param_has_anno and param_py_type in (str, bytes): + if param_has_anno and param_py_type in (str, bytes) and ( + not bindings.has_implicit_output(desc.type)): param_bind_type = 'generic' else: param_bind_type = desc.type diff --git a/setup.py b/setup.py index 4c2718a02..daf1769be 100644 --- a/setup.py +++ b/setup.py @@ -279,7 +279,7 @@ def run(self): ], extras_require={ 'dev': [ - 'azure-functions==1.1.0', + 'azure-functions==1.2.0b1', 'flake8~=3.7.9', 'mypy', 'pytest', From e5e923d28142d4e1e6779a8454ad4505c1d6fd0a Mon Sep 17 00:00:00 2001 From: "Hanzhang Zeng (Roger)" Date: Thu, 27 Feb 2020 18:24:17 -0800 Subject: [PATCH 2/5] bindings meta --- azure_functions_worker/bindings/meta.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/azure_functions_worker/bindings/meta.py b/azure_functions_worker/bindings/meta.py index d850ee8ac..392ff26dc 100644 --- a/azure_functions_worker/bindings/meta.py +++ b/azure_functions_worker/bindings/meta.py @@ -12,8 +12,13 @@ def get_binding_registry(): if func is not None: return func.get_binding_registry() - else: + + try: + import azure.functions as func + return func.get_binding_registry() + except ImportError: return None + return None def get_binding(bind_name: str) -> object: From 7196a903d277c1f50f0bf628fbb4ae67303b7c64 Mon Sep 17 00:00:00 2001 From: "Hanzhang Zeng (Roger)" Date: Thu, 27 Feb 2020 18:56:56 -0800 Subject: [PATCH 3/5] Revert "bindings meta" This reverts commit e5e923d28142d4e1e6779a8454ad4505c1d6fd0a. --- azure_functions_worker/bindings/meta.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/azure_functions_worker/bindings/meta.py b/azure_functions_worker/bindings/meta.py index 392ff26dc..d850ee8ac 100644 --- a/azure_functions_worker/bindings/meta.py +++ b/azure_functions_worker/bindings/meta.py @@ -12,13 +12,8 @@ def get_binding_registry(): if func is not None: return func.get_binding_registry() - - try: - import azure.functions as func - return func.get_binding_registry() - except ImportError: + else: return None - return None def get_binding(bind_name: str) -> object: From 4766dfdb9b2639278e75405c389e538da1bed871 Mon Sep 17 00:00:00 2001 From: "Hanzhang Zeng (Roger)" Date: Thu, 27 Feb 2020 19:11:13 -0800 Subject: [PATCH 4/5] Revert "Revert "bindings meta"" This reverts commit 7196a903d277c1f50f0bf628fbb4ae67303b7c64. --- azure_functions_worker/bindings/meta.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/azure_functions_worker/bindings/meta.py b/azure_functions_worker/bindings/meta.py index d850ee8ac..392ff26dc 100644 --- a/azure_functions_worker/bindings/meta.py +++ b/azure_functions_worker/bindings/meta.py @@ -12,8 +12,13 @@ def get_binding_registry(): if func is not None: return func.get_binding_registry() - else: + + try: + import azure.functions as func + return func.get_binding_registry() + except ImportError: return None + return None def get_binding(bind_name: str) -> object: From b3836c34f33af829618668351886bca761a49e0f Mon Sep 17 00:00:00 2001 From: "Hanzhang Zeng (Roger)" Date: Thu, 27 Feb 2020 19:21:19 -0800 Subject: [PATCH 5/5] We should fall back into builtin azure.functions --- azure_functions_worker/bindings/meta.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/azure_functions_worker/bindings/meta.py b/azure_functions_worker/bindings/meta.py index 392ff26dc..6eef6df00 100644 --- a/azure_functions_worker/bindings/meta.py +++ b/azure_functions_worker/bindings/meta.py @@ -10,15 +10,11 @@ def get_binding_registry(): func = sys.modules.get('azure.functions') - if func is not None: - return func.get_binding_registry() - - try: + # If fails to acquire customer's BYO azure-functions, load the builtin + if func is None: import azure.functions as func - return func.get_binding_registry() - except ImportError: - return None - return None + + return func.get_binding_registry() def get_binding(bind_name: str) -> object: