diff --git a/combadge/support/zeep/backends/async_.py b/combadge/support/zeep/backends/async_.py index c254b5f..dddc643 100644 --- a/combadge/support/zeep/backends/async_.py +++ b/combadge/support/zeep/backends/async_.py @@ -78,7 +78,7 @@ def with_params( service_proxy = AsyncServiceProxy( client, client.wsdl.bindings[service.binding_name], - address=service.address, + address=service.address_string, ) else: raise TypeError(type(service)) diff --git a/combadge/support/zeep/backends/base.py b/combadge/support/zeep/backends/base.py index 44ac8c8..78d632d 100644 --- a/combadge/support/zeep/backends/base.py +++ b/combadge/support/zeep/backends/base.py @@ -4,6 +4,8 @@ from dataclasses import dataclass from typing import Any, Generic, TypeVar, Union +from pydantic_core import Url + from combadge._helpers.dataclasses import SLOTS from combadge.core.errors import BackendError @@ -13,7 +15,7 @@ # Before Python 3.10: UnionType = type(Union[int, str]) # type: ignore[assignment, misc] -from pydantic import TypeAdapter +from pydantic import HttpUrl, TypeAdapter from typing_extensions import get_args as get_type_args from typing_extensions import get_origin as get_type_origin from zeep.exceptions import Fault @@ -104,10 +106,26 @@ def _parse_soap_fault(exception: Fault, fault_type: TypeAdapter[_SoapFaultT]) -> @dataclass(**SLOTS) class ByBindingName: - """Create service by binding name and address.""" + """ + Create service by binding name and address. + + Examples: + >>> ByBindingName( + >>> binding_name="{http://www.dataaccess.com/webservicesserver/}NumberConversionSoapBinding", + >>> address=Url("https://www.dataaccess.com/webservicesserver/NumberConversion.wso", + >>> ) + ) + """ binding_name: str - address: str + address: HttpUrl | str + + @property + def address_string(self) -> str: + """Return the service address as a plain `#!python str`.""" + if isinstance(self.address, Url): + return str(self.address) + return self.address @dataclass(**SLOTS) @@ -116,10 +134,7 @@ class ByServiceName: Create service by service and port names. Examples: - >>> backend = SyncZeepBackend.with_params( - >>> "NumberConversion.wsdl", - >>> service=ByServiceName(port_name="NumberConversionSoap"), - >>> ) + >>> ByServiceName(port_name="NumberConversionSoap") """ service_name: str | None = None diff --git a/combadge/support/zeep/backends/sync.py b/combadge/support/zeep/backends/sync.py index 42b0b50..b1abe05 100644 --- a/combadge/support/zeep/backends/sync.py +++ b/combadge/support/zeep/backends/sync.py @@ -61,7 +61,7 @@ def with_params( elif isinstance(service, ByServiceName): service_proxy = client.bind(service.service_name, service.port_name) elif isinstance(service, ByBindingName): - service_proxy = client.create_service(service.binding_name, service.address) + service_proxy = client.create_service(service.binding_name, service.address_string) else: raise TypeError(type(service)) return cls(service_proxy) diff --git a/tests/integration/cassettes/test_number_conversion/test_happy_path_with_params.yaml b/tests/integration/cassettes/test_number_conversion/test_happy_path_with_params.yaml deleted file mode 100644 index db46d0b..0000000 --- a/tests/integration/cassettes/test_number_conversion/test_happy_path_with_params.yaml +++ /dev/null @@ -1,55 +0,0 @@ -interactions: -- request: - body: ' - - 42' - headers: - Accept: - - '*/*' - Accept-Encoding: - - gzip, deflate - Connection: - - keep-alive - Content-Length: - - '291' - Content-Type: - - text/xml; charset=utf-8 - SOAPAction: - - '""' - User-Agent: - - Zeep/4.2.1 (www.python-zeep.org) - method: POST - uri: https://www.dataaccess.com/webservicesserver/NumberConversion.wso - response: - body: - string: !!binary | - H4sIAAAAAAAEAO29B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcpl - VmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/Ih7/Hu8W - ZXqZ101RLT/7aHe881GaL6fVrFhefPbRuj3fPvjo9zj6jZPHTZWtHp0uL/OyWuUpvbRsHuGzzz6a - t+3q0d27zXSeL7JmTF/h83FVX9zFL3dzfenuRwQnTQXSk2p2zX/SB4tHL9aLSV6/qb5b1bPmVd6s - qmVjOlnYHq6ursazrM2y6TRvmvG0Wty9yidNXl8W+IB+5rV2gicCd122R+dV3V6n7VWVPr4bbyEA - Yt8yXvz9Yx6bGYb+Zchz9P8A3rWog1YBAAA= - headers: - Cache-Control: - - private, max-age=0 - Content-Encoding: - - gzip - Content-Length: - - '311' - Content-Type: - - text/xml; charset=utf-8 - Date: - - Fri, 28 Jul 2023 12:21:43 GMT - Server: - - Server - Vary: - - Accept-Encoding - Web-Service: - - DataFlex 19.1 - X-Powered-By: - - ASP.NET - status: - code: 200 - message: OK -version: 1 diff --git a/tests/integration/cassettes/test_number_conversion/test_happy_path_with_params_async.yaml b/tests/integration/cassettes/test_number_conversion/test_happy_path_with_params_async.yaml deleted file mode 100644 index ac3d2d4..0000000 --- a/tests/integration/cassettes/test_number_conversion/test_happy_path_with_params_async.yaml +++ /dev/null @@ -1,52 +0,0 @@ -interactions: -- request: - body: ' - - 42' - headers: - accept: - - '*/*' - accept-encoding: - - gzip, deflate - connection: - - keep-alive - content-length: - - '291' - content-type: - - text/xml; charset=utf-8 - host: - - www.dataaccess.com - soapaction: - - '""' - user-agent: - - Zeep/4.2.1 (www.python-zeep.org) - method: POST - uri: https://www.dataaccess.com/webservicesserver/NumberConversion.wso - response: - content: "\r\n\r\n - \ \r\n \r\n - \ forty two \r\n \r\n - \ \r\n" - headers: - Cache-Control: - - private, max-age=0 - Content-Encoding: - - gzip - Content-Length: - - '311' - Content-Type: - - text/xml; charset=utf-8 - Date: - - Fri, 28 Jul 2023 12:22:51 GMT - Server: - - Server - Vary: - - Accept-Encoding - Web-Service: - - DataFlex 19.1 - X-Powered-By: - - ASP.NET - http_version: HTTP/1.1 - status_code: 200 -version: 1 diff --git a/tests/integration/test_number_conversion.py b/tests/integration/test_number_conversion.py index def4968..64193ec 100644 --- a/tests/integration/test_number_conversion.py +++ b/tests/integration/test_number_conversion.py @@ -5,6 +5,7 @@ import pytest from pydantic import BaseModel, Field, RootModel +from pydantic_core import Url from typing_extensions import assert_type from zeep import AsyncClient, Client @@ -14,7 +15,7 @@ from combadge.support.soap.markers import operation_name from combadge.support.soap.response import BaseSoapFault from combadge.support.zeep.backends.async_ import ZeepBackend as AsyncZeepBackend -from combadge.support.zeep.backends.base import ByServiceName +from combadge.support.zeep.backends.base import ByBindingName, ByServiceName from combadge.support.zeep.backends.sync import ZeepBackend as SyncZeepBackend @@ -108,10 +109,22 @@ async def test_happy_path_scalar_response_async(number_conversion_service_async: @pytest.mark.vcr -def test_happy_path_with_params() -> None: +@pytest.mark.parametrize( + "service", + [ + ByServiceName(port_name="NumberConversionSoap"), + ByBindingName( + binding_name="{http://www.dataaccess.com/webservicesserver/}NumberConversionSoapBinding", + address=Url( + "https://www.dataaccess.com/webservicesserver/NumberConversion.wso", + ), + ), + ], +) +def test_happy_path_with_params_sync(service: ByServiceName | ByBindingName) -> None: backend = SyncZeepBackend.with_params( Path(__file__).parent / "wsdl" / "NumberConversion.wsdl", - service=ByServiceName(port_name="NumberConversionSoap"), + service=service, operation_timeout=1, ) service = SupportsNumberConversion.bind(backend) @@ -120,10 +133,22 @@ def test_happy_path_with_params() -> None: @pytest.mark.vcr -async def test_happy_path_with_params_async() -> None: +@pytest.mark.parametrize( + "service", + [ + ByServiceName(port_name="NumberConversionSoap"), + ByBindingName( + binding_name="{http://www.dataaccess.com/webservicesserver/}NumberConversionSoapBinding", + address=Url( + "https://www.dataaccess.com/webservicesserver/NumberConversion.wso", + ), + ), + ], +) +async def test_happy_path_with_params_async(service: ByServiceName | ByBindingName) -> None: backend = AsyncZeepBackend.with_params( Path(__file__).parent / "wsdl" / "NumberConversion.wsdl", - service=ByServiceName(port_name="NumberConversionSoap"), + service=service, operation_timeout=1, ) service = SupportsNumberConversionAsync.bind(backend)