Skip to content

Commit a7bdd01

Browse files
committed
Use the async client (match old behavior)
1 parent df9932d commit a7bdd01

3 files changed

Lines changed: 47 additions & 16 deletions

File tree

azure-functions-durable/CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## Unreleased
9+
10+
### Changed
11+
12+
- `DurableFunctionsClient` is now an async client. Its orchestration and entity
13+
management methods (e.g. `schedule_new_orchestration`, `get_orchestration_state`,
14+
`wait_for_orchestration_completion`) are now coroutines and must be awaited.
15+
This aligns the client with the async API surface of the V1
16+
`DurableOrchestrationClient`.
17+
818
## v0.1.0
919

1020
- Initial implementation

azure-functions-durable/azure/durable_functions/client.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,17 @@
77
import azure.functions as func
88
from urllib.parse import urlparse, quote
99

10-
from durabletask.client import TaskHubGrpcClient
11-
from .internal.azurefunctions_grpc_interceptor import AzureFunctionsDefaultClientInterceptorImpl
10+
from durabletask.client import AsyncTaskHubGrpcClient
11+
from .internal.azurefunctions_grpc_interceptor import AzureFunctionsAsyncDefaultClientInterceptorImpl
1212
from .internal.serialization import DEFAULT_FUNCTIONS_DATA_CONVERTER
1313
from .http import HttpManagementPayload
1414

1515

1616
# Client class used for Durable Functions
17-
class DurableFunctionsClient(TaskHubGrpcClient):
17+
class DurableFunctionsClient(AsyncTaskHubGrpcClient):
1818
"""A gRPC client passed to Durable Functions durable client bindings.
1919
20-
Connects to the Durable Functions runtime using gRPC and provides methods
20+
Connects to the Durable Functions runtime using async gRPC and provides methods
2121
for creating and managing Durable orchestrations, interacting with Durable entities,
2222
and creating HTTP management payloads and check status responses for use with Durable Functions invocations.
2323
"""
@@ -45,7 +45,7 @@ def __init__(self, client_as_string: str):
4545
"""
4646
self._parse_client_configuration(client_as_string)
4747

48-
interceptors = [AzureFunctionsDefaultClientInterceptorImpl(self.taskHubName, self.requiredQueryStringParameters)]
48+
interceptors = [AzureFunctionsAsyncDefaultClientInterceptorImpl(self.taskHubName, self.requiredQueryStringParameters)]
4949

5050
# We pass in None for the metadata so we don't construct an additional interceptor in the parent class
5151
# Since the parent class doesn't use anything metadata for anything else, we can set it as None

azure-functions-durable/azure/durable_functions/internal/azurefunctions_grpc_interceptor.py

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,24 @@
33

44
from importlib.metadata import version
55

6-
from durabletask.internal.grpc_interceptor import DefaultClientInterceptorImpl
6+
from durabletask.internal.grpc_interceptor import (
7+
DefaultAsyncClientInterceptorImpl,
8+
DefaultClientInterceptorImpl,
9+
)
10+
11+
12+
def _build_metadata(taskhub_name: str) -> list[tuple[str, str]]:
13+
"""Build the gRPC metadata headers sent on every Durable Functions call."""
14+
try:
15+
# Get the version of the azurefunctions package
16+
sdk_version = version('durabletask-azurefunctions')
17+
except Exception:
18+
# Fallback if version cannot be determined
19+
sdk_version = "unknown"
20+
user_agent = f"durabletask-python/{sdk_version}"
21+
return [
22+
("taskhub", taskhub_name),
23+
("x-user-agent", user_agent)] # 'user-agent' is a reserved header in grpc, so we use 'x-user-agent' instead
724

825

926
class AzureFunctionsDefaultClientInterceptorImpl(DefaultClientInterceptorImpl):
@@ -14,14 +31,18 @@ class AzureFunctionsDefaultClientInterceptorImpl(DefaultClientInterceptorImpl):
1431

1532
def __init__(self, taskhub_name: str, required_query_string_parameters: str):
1633
self.required_query_string_parameters = required_query_string_parameters
17-
try:
18-
# Get the version of the azurefunctions package
19-
sdk_version = version('durabletask-azurefunctions')
20-
except Exception:
21-
# Fallback if version cannot be determined
22-
sdk_version = "unknown"
23-
user_agent = f"durabletask-python/{sdk_version}"
24-
self._metadata = [
25-
("taskhub", taskhub_name),
26-
("x-user-agent", user_agent)] # 'user-agent' is a reserved header in grpc, so we use 'x-user-agent' instead
34+
self._metadata = _build_metadata(taskhub_name)
35+
super().__init__(self._metadata)
36+
37+
38+
class AzureFunctionsAsyncDefaultClientInterceptorImpl(DefaultAsyncClientInterceptorImpl):
39+
"""Async version of AzureFunctionsDefaultClientInterceptorImpl for use with grpc.aio channels.
40+
41+
This class implements async gRPC interceptors to add Durable Functions headers
42+
(task hub name and user agent) to all async calls."""
43+
required_query_string_parameters: str
44+
45+
def __init__(self, taskhub_name: str, required_query_string_parameters: str):
46+
self.required_query_string_parameters = required_query_string_parameters
47+
self._metadata = _build_metadata(taskhub_name)
2748
super().__init__(self._metadata)

0 commit comments

Comments
 (0)