diff --git a/dapr/clients/__init__.py b/dapr/clients/__init__.py index 1cdfdebb..d1ea3ca8 100644 --- a/dapr/clients/__init__.py +++ b/dapr/clients/__init__.py @@ -84,9 +84,8 @@ def __init__( if invocation_protocol == 'HTTP': if http_timeout_seconds is None: http_timeout_seconds = settings.DAPR_HTTP_TIMEOUT_SECONDS - self.invocation_client = DaprInvocationHttpClient( - headers_callback=headers_callback, timeout=http_timeout_seconds, address=address - ) + self.invocation_client = DaprInvocationHttpClient(headers_callback=headers_callback, + timeout=http_timeout_seconds) elif invocation_protocol == 'GRPC': pass else: diff --git a/dapr/clients/http/client.py b/dapr/clients/http/client.py index 4ac5271e..863e69c1 100644 --- a/dapr/clients/http/client.py +++ b/dapr/clients/http/client.py @@ -33,14 +33,10 @@ class DaprHttpClient: """A Dapr Http API client""" - - def __init__( - self, - message_serializer: 'Serializer', - timeout: Optional[int] = 60, - headers_callback: Optional[Callable[[], Dict[str, str]]] = None, - address: Optional[str] = None, - ): + def __init__(self, + message_serializer: 'Serializer', + timeout: Optional[int] = 60, + headers_callback: Optional[Callable[[], Dict[str, str]]] = None): """Invokes Dapr over HTTP. Args: @@ -51,17 +47,13 @@ def __init__( self._timeout = aiohttp.ClientTimeout(total=timeout) self._serializer = message_serializer self._headers_callback = headers_callback - self._address = address def get_api_url(self) -> str: - if self._address: - return '{}/{}'.format(self._address, settings.DAPR_API_VERSION) if settings.DAPR_HTTP_ENDPOINT: return '{}/{}'.format(settings.DAPR_HTTP_ENDPOINT, settings.DAPR_API_VERSION) - else: - return 'http://{}:{}/{}'.format( - settings.DAPR_RUNTIME_HOST, settings.DAPR_HTTP_PORT, settings.DAPR_API_VERSION - ) + + return 'http://{}:{}/{}'.format(settings.DAPR_RUNTIME_HOST, + settings.DAPR_HTTP_PORT, settings.DAPR_API_VERSION) async def send_bytes( self, diff --git a/dapr/clients/http/dapr_invocation_http_client.py b/dapr/clients/http/dapr_invocation_http_client.py index 462f0d1a..b1923d46 100644 --- a/dapr/clients/http/dapr_invocation_http_client.py +++ b/dapr/clients/http/dapr_invocation_http_client.py @@ -32,18 +32,16 @@ class DaprInvocationHttpClient: """Service Invocation HTTP Client""" def __init__( - self, - timeout: int = 60, - headers_callback: Optional[Callable[[], Dict[str, str]]] = None, - address: Optional[str] = None, - ): + self, + timeout: int = 60, + headers_callback: Optional[Callable[[], Dict[str, str]]] = None): """Invokes Dapr's API for method invocation over HTTP. Args: timeout (int, optional): Timeout in seconds, defaults to 60. headers_callback (lambda: Dict[str, str]], optional): Generates header for each request. """ - self._client = DaprHttpClient(DefaultJSONSerializer(), timeout, headers_callback, address) + self._client = DaprHttpClient(DefaultJSONSerializer(), timeout, headers_callback) async def invoke_method_async( self, diff --git a/daprdocs/content/en/python-sdk-docs/python-client.md b/daprdocs/content/en/python-sdk-docs/python-client.md index 94370003..47f76c83 100644 --- a/daprdocs/content/en/python-sdk-docs/python-client.md +++ b/daprdocs/content/en/python-sdk-docs/python-client.md @@ -101,6 +101,8 @@ The Python SDK allows you to interface with all of the [Dapr building blocks]({{ ### Invoke a service +The Dapr Python SDK provides a simple API for invoking services via either HTTP or gRPC (deprecated). The protocol can be selected by setting the `DAPR_API_METHOD_INVOCATION_PROTOCOL` environment variable, defaulting to HTTP when unset. GRPC service invocation in Dapr is deprecated and GRPC proxying is recommended as an alternative. + ```python from dapr.clients import DaprClient @@ -113,6 +115,12 @@ with DaprClient() as d: resp = d.invoke_method('service-to-invoke', 'method-to-invoke', data='{"id":"100", "FirstName":"Value", "LastName":"Value"}', http_verb='post') ``` +The base endpoint for HTTP api calls is specified in the `DAPR_HTTP_ENDPOINT` environment variable. +If this variable is not set, the endpoint value is derived from the `DAPR_RUNTIME_HOST` and `DAPR_HTTP_PORT` variables, whose default values are `127.0.0.1` and `3500` accordingly. + +The base endpoint for gRPC calls is the one used for the client initialisation ([explained above](#initialising-the-client)). + + - For a full guide on service invocation visit [How-To: Invoke a service]({{< ref howto-invoke-discover-services.md >}}). - Visit [Python SDK examples](https://github.com/dapr/python-sdk/tree/master/examples/invoke-simple) for code samples and instructions to try out service invocation. diff --git a/tests/clients/test_http_service_invocation_client.py b/tests/clients/test_http_service_invocation_client.py index 83d8b433..8ab8659e 100644 --- a/tests/clients/test_http_service_invocation_client.py +++ b/tests/clients/test_http_service_invocation_client.py @@ -59,12 +59,11 @@ def test_get_api_url_default(self): client.invocation_client._client.get_api_url(), ) - def test_get_api_url_endpoint_as_argument(self): - client = DaprClient('http://localhost:5000') - self.assertEqual( - 'http://localhost:5000/{}'.format(settings.DAPR_API_VERSION), - client.invocation_client._client.get_api_url(), - ) + @patch.object(settings, "DAPR_HTTP_ENDPOINT", "https://domain1.com:5000") + def test_dont_get_api_url_endpoint_as_argument(self): + client = DaprClient("http://localhost:5000") + self.assertEqual('https://domain1.com:5000/{}'.format(settings.DAPR_API_VERSION), + client.invocation_client._client.get_api_url()) @patch.object(settings, 'DAPR_HTTP_ENDPOINT', 'https://domain1.com:5000') def test_get_api_url_endpoint_as_env_variable(self): diff --git a/tests/clients/test_secure_http_service_invocation_client.py b/tests/clients/test_secure_http_service_invocation_client.py index 4a85367b..a499c60a 100644 --- a/tests/clients/test_secure_http_service_invocation_client.py +++ b/tests/clients/test_secure_http_service_invocation_client.py @@ -15,6 +15,7 @@ import ssl import typing from asyncio import TimeoutError +from unittest.mock import patch from opentelemetry import trace from opentelemetry.sdk.trace import TracerProvider @@ -27,6 +28,7 @@ from dapr.conf import settings from dapr.proto import common_v1 + from .certs import CERTIFICATE_CHAIN_PATH from .fake_http_server import FakeHttpServer from .test_http_service_invocation_client import DaprInvocationHttpClientTests @@ -48,7 +50,8 @@ def setUp(self): self.server.start() settings.DAPR_HTTP_PORT = self.server_port settings.DAPR_API_METHOD_INVOCATION_PROTOCOL = 'http' - self.client = DaprClient(f'https://localhost:{self.server_port}') + settings.DAPR_HTTP_ENDPOINT = "https://localhost:{}".format(self.server_port) + self.client = DaprClient() self.app_id = 'fakeapp' self.method_name = 'fakemethod' self.invoke_url = f'/v1.0/invoke/{self.app_id}/method/{self.method_name}' @@ -114,3 +117,11 @@ def test_timeout_exception_thrown_when_timeout_reached(self): self.server.set_server_delay(1.5) with self.assertRaises(TimeoutError): new_client.invoke_method(self.app_id, self.method_name, '') + + @patch.object(settings, "DAPR_HTTP_ENDPOINT", None) + def test_get_api_url_default(self): + client = DaprClient() + self.assertEqual( + 'http://{}:{}/{}'.format(settings.DAPR_RUNTIME_HOST, settings.DAPR_HTTP_PORT, + settings.DAPR_API_VERSION), + client.invocation_client._client.get_api_url())