From a21afb31b9a52997581c2602778b6e63cf9204ea Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Fri, 3 Sep 2021 16:23:00 +0800 Subject: [PATCH 01/33] codegen --- .../messaging/webpubsubservice/__init__.py | 235 +-- .../webpubsubservice/_configuration.py | 65 + .../messaging/webpubsubservice/_policies.py | 83 - .../messaging/webpubsubservice/_utils.py | 45 - .../messaging/webpubsubservice/_version.py | 13 +- .../_webpubsub_service_client.py | 94 + .../azure/messaging/webpubsubservice/aio.py | 110 - .../webpubsubservice/aio/__init__.py | 10 + .../webpubsubservice/aio/_configuration.py | 61 + .../aio/_webpubsub_service_client.py | 89 + .../aio/operations/__init__.py | 15 + .../aio/operations/_operations.py | 1148 +++++++++++ .../webpubsubservice/core/__init__.py | 0 .../webpubsubservice/core/rest/__init__.py | 65 - .../webpubsubservice/core/rest/_rest.py | 625 ------ .../webpubsubservice/core/rest/_rest_py3.py | 739 ------- .../webpubsubservice/operations/__init__.py | 15 + .../operations/_operations.py | 1772 +++++++++++++++++ .../azure/messaging/webpubsubservice/py.typed | 1 + .../azure/messaging/webpubsubservice/rest.py | 942 --------- .../swagger/README.md | 35 + 21 files changed, 3324 insertions(+), 2838 deletions(-) create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py delete mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py delete mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_utils.py create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_webpubsub_service_client.py delete mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio.py create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_webpubsub_service_client.py create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/__init__.py create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/_operations.py delete mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/core/__init__.py delete mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/core/rest/__init__.py delete mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/core/rest/_rest.py delete mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/core/rest/_rest_py3.py create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/__init__.py create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/_operations.py create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/py.typed delete mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/rest.py create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/swagger/README.md diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py index 529b1f7e9d7d..0aeded867ad4 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py @@ -1,232 +1,19 @@ # coding=utf-8 # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# +# Licensed under the MIT License. See License.txt in the project root for license information. # Code generated by Microsoft (R) AutoRest Code Generator. -# Changes may cause incorrect behavior and will be lost if the code is -# regenerated. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -__all__ = ["build_authentication_token", "WebPubSubServiceClient"] +from ._webpubsub_service_client import WebpubsubServiceClient +from ._version import VERSION -from copy import deepcopy -from datetime import datetime, timedelta -from typing import TYPE_CHECKING +__version__ = VERSION +__all__ = ['WebpubsubServiceClient'] -import jwt -import six - -import azure.core.credentials as corecredentials -import azure.core.pipeline as corepipeline -import azure.core.pipeline.policies as corepolicies -import azure.core.pipeline.transport as coretransport - - -# Temporary location for types that eventually graduate to Azure Core -from .core import rest as corerest -from ._version import VERSION as _VERSION -from ._policies import JwtCredentialPolicy -from ._utils import UTC as _UTC - -if TYPE_CHECKING: - from azure.core.pipeline.policies import HTTPPolicy, SansIOHTTPPolicy - from typing import Any, List, cast, Type, TypeVar - - ClientType = TypeVar("ClientType", bound="WebPubSubServiceClient") - - -def _parse_connection_string(connection_string, **kwargs): - for segment in connection_string.split(";"): - if "=" in segment: - key, value = segment.split("=", maxsplit=1) - key = key.lower() - if key not in ("version", ): - kwargs.setdefault(key, value) - elif segment: - raise ValueError( - "Malformed connection string - expected 'key=value', found segment '{}' in '{}'".format( - segment, connection_string - ) - ) - - if "endpoint" not in kwargs: - raise ValueError("connection_string missing 'endpoint' field") - - if "accesskey" not in kwargs: - raise ValueError("connection_string missing 'accesskey' field") - - return kwargs - -def build_authentication_token(endpoint, hub, **kwargs): - """Build an authentication token for the given endpoint, hub using the provided key. - - :keyword endpoint: connetion string or HTTP or HTTPS endpoint for the WebPubSub service instance. - :type endpoint: ~str - :keyword hub: The hub to give access to. - :type hub: ~str - :keyword accesskey: Key to sign the token with. Required if endpoint is not a connection string - :type accesskey: ~str - :keyword ttl: Optional ttl timedelta for the token. Default is 1 hour. - :type ttl: ~datetime.timedelta - :keyword user: Optional user name (subject) for the token. Default is no user. - :type user: ~str - :keyword roles: Roles for the token. - :type roles: typing.List[str]. Default is no roles. - :returns: ~dict containing the web socket endpoint, the token and a url with the generated access token. - :rtype: ~dict - - - Example: - >>> build_authentication_token(endpoint='https://contoso.com/api/webpubsub', hub='theHub', key='123') - { - 'baseUrl': 'wss://contoso.com/api/webpubsub/client/hubs/theHub', - 'token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ...', - 'url': 'wss://contoso.com/api/webpubsub/client/hubs/theHub?access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ...' - } - """ - if 'accesskey' not in kwargs: - kwargs = _parse_connection_string(endpoint, **kwargs) - endpoint = kwargs.pop('endpoint') - - user = kwargs.pop("user", None) - key = kwargs.pop("accesskey") - ttl = kwargs.pop("ttl", timedelta(hours=1)) - roles = kwargs.pop("roles", []) - endpoint = endpoint.lower() - if not endpoint.startswith("http://") and not endpoint.startswith("https://"): - raise ValueError( - "Invalid endpoint: '{}' has unknown scheme - expected 'http://' or 'https://'".format( - endpoint - ) - ) - - # Ensure endpoint has no trailing slash - endpoint = endpoint.rstrip("/") - - # Switch from http(s) to ws(s) scheme - client_endpoint = "ws" + endpoint[4:] - client_url = "{}/client/hubs/{}".format(client_endpoint, hub) - audience = "{}/client/hubs/{}".format(endpoint, hub) - - payload = { - "aud": audience, - "iat": datetime.now(tz=_UTC), - "exp": datetime.now(tz=_UTC) + ttl, - } - if user: - payload["sub"] = user - if roles: - payload["role"] = roles - - token = six.ensure_str(jwt.encode(payload, key, algorithm="HS256")) - return { - "baseUrl": client_url, - "token": token, - "url": "{}?access_token={}".format(client_url, token), - } - - -class WebPubSubServiceClient(object): - def __init__(self, endpoint, credential, **kwargs): - # type: (str, corecredentials.AzureKeyCredential, Any) -> None - """Create a new WebPubSubServiceClient instance - - :param endpoint: Endpoint to connect to. - :type endpoint: ~str - :param credential: Credentials to use to connect to endpoint. - :type credential: ~azure.core.credentials.AzureKeyCredential - :keyword api_version: Api version to use when communicating with the service. - :type api_version: str - :keyword user: User to connect as. Optional. - :type user: ~str - """ - self.endpoint = endpoint.rstrip("/") - transport = kwargs.pop("transport", None) or coretransport.RequestsTransport( - **kwargs - ) - kwargs.setdefault( - "sdk_moniker", "messaging-webpubsubservice/{}".format(_VERSION) - ) - policies = [ - corepolicies.HeadersPolicy(**kwargs), - corepolicies.UserAgentPolicy(**kwargs), - corepolicies.RetryPolicy(**kwargs), - corepolicies.ProxyPolicy(**kwargs), - corepolicies.CustomHookPolicy(**kwargs), - corepolicies.RedirectPolicy(**kwargs), - JwtCredentialPolicy(credential, kwargs.get("user", None)), - corepolicies.NetworkTraceLoggingPolicy(**kwargs), - ] # type: Any - self._pipeline = corepipeline.Pipeline( - transport, - policies, - ) # type: corepipeline.Pipeline - - @classmethod - def from_connection_string(cls, connection_string, **kwargs): - # type: (Type[ClientType], str, Any) -> ClientType - """Create a new WebPubSubServiceClient from a connection string. - - :param connection_string: Connection string - :type connection_string: ~str - :rtype: WebPubSubServiceClient - """ - kwargs = _parse_connection_string(connection_string, **kwargs) - - kwargs["credential"] = corecredentials.AzureKeyCredential( - kwargs.pop("accesskey") - ) - return cls(**kwargs) - - def __repr__(self): - return " endpoint:'{}'".format(self.endpoint) - - def _format_url(self, url): - # type: (str) -> str - assert self.endpoint[-1] != "/", "My endpoint should not have a trailing slash" - return "/".join([self.endpoint, url.lstrip("/")]) - - def send_request(self, http_request, **kwargs): - # type: (corerest.HttpRequest, Any) -> corerest.HttpResponse - """Runs the network request through the client's chained policies. - - We have helper methods to create requests specific to this service in `azure.messaging.webpubsub.rest`. - Use these helper methods to create the request you pass to this method. See our example below: - - >>> from azure.messaging.webpubsub.rest import build_healthapi_get_health_status_request - >>> request = build_healthapi_get_health_status_request(api_version) - - >>> response = client.send_request(request) - - - For more information on this code flow, see https://aka.ms/azsdk/python/llcwiki - - For advanced cases, you can also create your own :class:`~azure.messaging.webpubsub.core.rest.HttpRequest` - and pass it in. - - :param http_request: The network request you want to make. Required. - :type http_request: ~azure.messaging.webpubsub.core.rest.HttpRequest - :keyword bool stream_response: Whether the response payload will be streamed. Defaults to False. - :return: The response of your network call. Does not do error handling on your response. - :rtype: ~azure.messaging.webpubsub.core.rest.HttpResponse - """ - request_copy = deepcopy(http_request) - request_copy.url = self._format_url(request_copy.url) - - # can't do StreamCOntextManager yet. This client doesn't have a pipeline client, - # StreamContextManager requires a pipeline client. WIll look more into it - # if kwargs.pop("stream_response", False): - # return corerest._StreamContextManager( - # client=self._client, - # request=request_copy, - # ) - pipeline_response = self._pipeline.run(request_copy._internal_request, **kwargs) # pylint: disable=protected-access - response = corerest.HttpResponse( - status_code=pipeline_response.http_response.status_code, - request=request_copy, - _internal_response=pipeline_response.http_response, - ) - response.read() - return response +try: + from ._patch import patch_sdk # type: ignore + patch_sdk() +except ImportError: + pass diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py new file mode 100644 index 000000000000..a161e2652c52 --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py @@ -0,0 +1,65 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import TYPE_CHECKING + +from azure.core.configuration import Configuration +from azure.core.pipeline import policies + +from ._version import VERSION + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any, Optional + + from azure.core.credentials import TokenCredential + + +class WebpubsubServiceClientConfiguration(Configuration): + """Configuration for WebpubsubServiceClient. + + Note that all parameters used to create this instance are saved as instance + attributes. + + :param credential: Credential needed for the client to connect to Azure. + :type credential: ~azure.core.credentials.TokenCredential + """ + + def __init__( + self, + credential, # type: "TokenCredential" + **kwargs # type: Any + ): + # type: (...) -> None + if credential is None: + raise ValueError("Parameter 'credential' must not be None.") + super(WebpubsubServiceClientConfiguration, self).__init__(**kwargs) + + self.credential = credential + self.credential_scopes = kwargs.pop('credential_scopes', []) + kwargs.setdefault('sdk_moniker', 'messaging-webpubsubservice/{}'.format(VERSION)) + self._configure(**kwargs) + + def _configure( + self, + **kwargs # type: Any + ): + # type: (...) -> None + self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) + self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) + self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) + self.retry_policy = kwargs.get('retry_policy') or policies.RetryPolicy(**kwargs) + self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) + self.redirect_policy = kwargs.get('redirect_policy') or policies.RedirectPolicy(**kwargs) + self.authentication_policy = kwargs.get('authentication_policy') + if not self.credential_scopes and not self.authentication_policy: + raise ValueError("You must provide either credential_scopes or authentication_policy as kwargs") + if self.credential and not self.authentication_policy: + self.authentication_policy = policies.BearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py deleted file mode 100644 index 6dc11981689a..000000000000 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py +++ /dev/null @@ -1,83 +0,0 @@ -# -------------------------------------------------------------------------- -# -# Copyright (c) Microsoft Corporation. All rights reserved. -# -# The MIT License (MIT) -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the ""Software""), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. -# -# -------------------------------------------------------------------------- - -import datetime -import typing -import jwt -import six - -from azure.core.pipeline.policies import SansIOHTTPPolicy - -from ._utils import UTC - -if typing.TYPE_CHECKING: - from azure.core.credentials import AzureKeyCredential - from azure.core.pipeline import PipelineRequest - - -class JwtCredentialPolicy(SansIOHTTPPolicy): - - NAME_CLAIM_TYPE = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" - - def __init__(self, credential, user=None): - # type: (AzureKeyCredential, typing.Optional[str]) -> None - """Create a new instance of the policy associated with the given credential. - - :param credential: The azure.core.credentials.AzureKeyCredential instance to use - :type credential: ~azure.core.credentials.AzureKeyCredential - :param user: Optional user name associated with the credential. - :type user: str - """ - self._credential = credential - self._user = user - - def on_request(self, request): - # type: (PipelineRequest) -> typing.Union[None, typing.Awaitable[None]] - """Is executed before sending the request from next policy. - - :param request: Request to be modified before sent from next policy. - :type request: ~azure.core.pipeline.PipelineRequest - """ - request.http_request.headers["Authorization"] = "Bearer " + self._encode( - request.http_request.url - ) - return super(JwtCredentialPolicy, self).on_request(request) - - def _encode(self, url): - # type: (AzureKeyCredential) -> str - data = { - "aud": url, - "exp": datetime.datetime.now(tz=UTC) + datetime.timedelta(seconds=60), - } - if self._user: - data[self.NAME_CLAIM_TYPE] = self._user - - encoded = jwt.encode( - payload=data, - key=self._credential.key, - algorithm="HS256", - ) - return six.ensure_str(encoded) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_utils.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_utils.py deleted file mode 100644 index 042b46dd8848..000000000000 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_utils.py +++ /dev/null @@ -1,45 +0,0 @@ -# -------------------------------------------------------------------------- -# -# Copyright (c) Microsoft Corporation. All rights reserved. -# -# The MIT License (MIT) -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the ""Software""), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. -# -# -------------------------------------------------------------------------- - -import datetime - - -class _UTC_TZ(datetime.tzinfo): - """from https://docs.python.org/2/library/datetime.html#tzinfo-objects""" - - ZERO = datetime.timedelta(0) - - def utcoffset(self, dt): - return self.__class__.ZERO - - def tzname(self, dt): - return "UTC" - - def dst(self, dt): - return self.__class__.ZERO - - -UTC = _UTC_TZ() diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_version.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_version.py index e1816f2340d7..e5754a47ce68 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_version.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_version.py @@ -1,6 +1,9 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- -VERSION = "1.0.0b2" +VERSION = "1.0.0b1" diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_webpubsub_service_client.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_webpubsub_service_client.py new file mode 100644 index 000000000000..e29dd7dd95ca --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_webpubsub_service_client.py @@ -0,0 +1,94 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from copy import deepcopy +from typing import TYPE_CHECKING + +from azure.core import PipelineClient +from msrest import Deserializer, Serializer + +from ._configuration import WebpubsubServiceClientConfiguration +from .operations import HealthApiOperations, WebPubSubOperations + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any, Dict, Optional + + from azure.core.credentials import TokenCredential + from azure.core.rest import HttpRequest, HttpResponse + +class WebpubsubServiceClient(object): + """WebpubsubServiceClient. + + :ivar health_api: HealthApiOperations operations + :vartype health_api: azure.messaging.webpubsubservice.operations.HealthApiOperations + :ivar web_pub_sub: WebPubSubOperations operations + :vartype web_pub_sub: azure.messaging.webpubsubservice.operations.WebPubSubOperations + :param credential: Credential needed for the client to connect to Azure. + :type credential: ~azure.core.credentials.TokenCredential + :keyword endpoint: Service URL. Default value is ''. + :paramtype endpoint: str + """ + + def __init__( + self, + credential, # type: "TokenCredential" + **kwargs # type: Any + ): + # type: (...) -> None + endpoint = kwargs.pop('endpoint', "") # type: str + + self._config = WebpubsubServiceClientConfiguration(credential, **kwargs) + self._client = PipelineClient(base_url=endpoint, config=self._config, **kwargs) + + self._serialize = Serializer() + self._deserialize = Deserializer() + self._serialize.client_side_validation = False + self.health_api = HealthApiOperations(self._client, self._config, self._serialize, self._deserialize) + self.web_pub_sub = WebPubSubOperations(self._client, self._config, self._serialize, self._deserialize) + + + def send_request( + self, + request, # type: HttpRequest + **kwargs # type: Any + ): + # type: (...) -> HttpResponse + """Runs the network request through the client's chained policies. + + >>> from azure.core.rest import HttpRequest + >>> request = HttpRequest("GET", "https://www.example.org/") + + >>> response = client.send_request(request) + + + For more information on this code flow, see https://aka.ms/azsdk/python/protocol/quickstart + + :param request: The network request you want to make. Required. + :type request: ~azure.core.rest.HttpRequest + :keyword bool stream: Whether the response payload will be streamed. Defaults to False. + :return: The response of your network call. Does not do error handling on your response. + :rtype: ~azure.core.rest.HttpResponse + """ + + request_copy = deepcopy(request) + request_copy.url = self._client.format_url(request_copy.url) + return self._client.send_request(request_copy, **kwargs) + + def close(self): + # type: () -> None + self._client.close() + + def __enter__(self): + # type: () -> WebpubsubServiceClient + self._client.__enter__() + return self + + def __exit__(self, *exc_details): + # type: (Any) -> None + self._client.__exit__(*exc_details) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio.py deleted file mode 100644 index 0559416aa7bc..000000000000 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio.py +++ /dev/null @@ -1,110 +0,0 @@ -# coding=utf-8 -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. -# Changes may cause incorrect behavior and will be lost if the code is regenerated. -# -------------------------------------------------------------------------- -__all__ = ["WebPubSubServiceClient"] - -from typing import TYPE_CHECKING -from copy import deepcopy - -import azure.core.pipeline as corepipeline -import azure.core.pipeline.policies as corepolicies -import azure.core.pipeline.transport as coretransport - -# Temporary location for types that eventually graduate to Azure Core -from .core import rest as corerest - -from ._policies import JwtCredentialPolicy - -if TYPE_CHECKING: - import azure.core.credentials as corecredentials - from azure.core.pipeline.policies import HTTPPolicy, SansIOHTTPPolicy - from typing import Any, List, cast # pylint: disable=ungrouped-imports - - -class WebPubSubServiceClient(object): - def __init__(self, endpoint, credential, **kwargs): - # type: (str, corecredentials.AzureKeyCredential, Any) -> None - """Create a new WebPubSubServiceClient instance - - :param endpoint: Endpoint to connect to. - :type endpoint: ~str - :param credential: Credentials to use to connect to endpoint. - :type credential: ~azure.core.credentials.AzureKeyCredential - :keyword api_version: Api version to use when communicating with the service. - :type api_version: str - :keyword user: User to connect as. Optional. - :type user: ~str - """ - self.endpoint = endpoint.rstrip("/") - transport = kwargs.pop("transport", None) or coretransport.RequestsTransport( - **kwargs - ) - policies = [ - corepolicies.HeadersPolicy(**kwargs), - corepolicies.UserAgentPolicy(**kwargs), - corepolicies.AsyncRetryPolicy(**kwargs), - corepolicies.ProxyPolicy(**kwargs), - corepolicies.CustomHookPolicy(**kwargs), - corepolicies.AsyncRedirectPolicy(**kwargs), - JwtCredentialPolicy(credential, kwargs.get("user", None)), - corepolicies.NetworkTraceLoggingPolicy(**kwargs), - ] # type: Any - self._pipeline = corepipeline.AsyncPipeline( - transport, - policies, - ) # type: corepipeline.AsyncPipeline - - def _format_url(self, url): - # type: (str) -> str - assert self.endpoint[-1] != "/", "My endpoint should not have a trailing slash" - return "/".join([self.endpoint, url.lstrip("/")]) - - async def send_request( - self, http_request: corerest.HttpRequest, **kwargs: "Any" - ) -> corerest.AsyncHttpResponse: - """Runs the network request through the client's chained policies. - - We have helper methods to create requests specific to this service in `azure.messaging.webpubsub.rest`. - Use these helper methods to create the request you pass to this method. See our example below: - - >>> from azure.messaging.webpubsub.rest import build_healthapi_get_health_status_request - >>> request = build_healthapi_get_health_status_request(api_version) - - >>> response = await client.send_request(request) - - - For more information on this code flow, see https://aka.ms/azsdk/python/llcwiki - - For advanced cases, you can also create your own :class:`~azure.messaging.webpubsub.core.rest.HttpRequest` - and pass it in. - - :param http_request: The network request you want to make. Required. - :type http_request: ~azure.messaging.webpubsub.core.rest.HttpRequest - :keyword bool stream_response: Whether the response payload will be streamed. Defaults to False. - :return: The response of your network call. Does not do error handling on your response. - :rtype: ~azure.messaging.webpubsub.core.rest.AsyncHttpResponse - """ - request_copy = deepcopy(http_request) - request_copy.url = self._format_url(request_copy.url) - - # can't do AsyncStreamContextManager yet. This client doesn't have a pipeline client, - # AsyncStreamContextManager requires a pipeline client. WIll look more into it - # if kwargs.pop("stream_response", False): - # return corerest._AsyncStreamContextManager( - # client=self._client, - # request=request_copy, - # ) - pipeline_response = await self._pipeline.run( - request_copy._internal_request, **kwargs # pylint: disable=protected-access - ) - response = corerest.AsyncHttpResponse( - status_code=pipeline_response.http_response.status_code, - request=request_copy, - _internal_response=pipeline_response.http_response, - ) - await response.read() - return response diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py new file mode 100644 index 000000000000..89fdb88af896 --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py @@ -0,0 +1,10 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._webpubsub_service_client import WebpubsubServiceClient +__all__ = ['WebpubsubServiceClient'] diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py new file mode 100644 index 000000000000..47d74656977e --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py @@ -0,0 +1,61 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import Any, Optional, TYPE_CHECKING + +from azure.core.configuration import Configuration +from azure.core.pipeline import policies + +from .._version import VERSION + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from azure.core.credentials_async import AsyncTokenCredential + + +class WebpubsubServiceClientConfiguration(Configuration): + """Configuration for WebpubsubServiceClient. + + Note that all parameters used to create this instance are saved as instance + attributes. + + :param credential: Credential needed for the client to connect to Azure. + :type credential: ~azure.core.credentials_async.AsyncTokenCredential + """ + + def __init__( + self, + credential: "AsyncTokenCredential", + **kwargs: Any + ) -> None: + if credential is None: + raise ValueError("Parameter 'credential' must not be None.") + super(WebpubsubServiceClientConfiguration, self).__init__(**kwargs) + + self.credential = credential + self.credential_scopes = kwargs.pop('credential_scopes', []) + kwargs.setdefault('sdk_moniker', 'messaging-webpubsubservice/{}'.format(VERSION)) + self._configure(**kwargs) + + def _configure( + self, + **kwargs: Any + ) -> None: + self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) + self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) + self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) + self.retry_policy = kwargs.get('retry_policy') or policies.AsyncRetryPolicy(**kwargs) + self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) + self.redirect_policy = kwargs.get('redirect_policy') or policies.AsyncRedirectPolicy(**kwargs) + self.authentication_policy = kwargs.get('authentication_policy') + if not self.credential_scopes and not self.authentication_policy: + raise ValueError("You must provide either credential_scopes or authentication_policy as kwargs") + if self.credential and not self.authentication_policy: + self.authentication_policy = policies.AsyncBearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_webpubsub_service_client.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_webpubsub_service_client.py new file mode 100644 index 000000000000..1432f4ce8620 --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_webpubsub_service_client.py @@ -0,0 +1,89 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from copy import deepcopy +from typing import Any, Awaitable, Optional, TYPE_CHECKING + +from azure.core import AsyncPipelineClient +from azure.core.rest import AsyncHttpResponse, HttpRequest +from msrest import Deserializer, Serializer + +from ._configuration import WebpubsubServiceClientConfiguration +from .operations import HealthApiOperations, WebPubSubOperations + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Dict + + from azure.core.credentials_async import AsyncTokenCredential + +class WebpubsubServiceClient: + """WebpubsubServiceClient. + + :ivar health_api: HealthApiOperations operations + :vartype health_api: azure.messaging.webpubsubservice.aio.operations.HealthApiOperations + :ivar web_pub_sub: WebPubSubOperations operations + :vartype web_pub_sub: azure.messaging.webpubsubservice.aio.operations.WebPubSubOperations + :param credential: Credential needed for the client to connect to Azure. + :type credential: ~azure.core.credentials_async.AsyncTokenCredential + :keyword endpoint: Service URL. Default value is ''. + :paramtype endpoint: str + """ + + def __init__( + self, + credential: "AsyncTokenCredential", + *, + endpoint: str = "", + **kwargs: Any + ) -> None: + self._config = WebpubsubServiceClientConfiguration(credential, **kwargs) + self._client = AsyncPipelineClient(base_url=endpoint, config=self._config, **kwargs) + + self._serialize = Serializer() + self._deserialize = Deserializer() + self._serialize.client_side_validation = False + self.health_api = HealthApiOperations(self._client, self._config, self._serialize, self._deserialize) + self.web_pub_sub = WebPubSubOperations(self._client, self._config, self._serialize, self._deserialize) + + + def send_request( + self, + request: HttpRequest, + **kwargs: Any + ) -> Awaitable[AsyncHttpResponse]: + """Runs the network request through the client's chained policies. + + >>> from azure.core.rest import HttpRequest + >>> request = HttpRequest("GET", "https://www.example.org/") + + >>> response = await client.send_request(request) + + + For more information on this code flow, see https://aka.ms/azsdk/python/protocol/quickstart + + :param request: The network request you want to make. Required. + :type request: ~azure.core.rest.HttpRequest + :keyword bool stream: Whether the response payload will be streamed. Defaults to False. + :return: The response of your network call. Does not do error handling on your response. + :rtype: ~azure.core.rest.AsyncHttpResponse + """ + + request_copy = deepcopy(request) + request_copy.url = self._client.format_url(request_copy.url) + return self._client.send_request(request_copy, **kwargs) + + async def close(self) -> None: + await self._client.close() + + async def __aenter__(self) -> "WebpubsubServiceClient": + await self._client.__aenter__() + return self + + async def __aexit__(self, *exc_details) -> None: + await self._client.__aexit__(*exc_details) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/__init__.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/__init__.py new file mode 100644 index 000000000000..a2ac5f07bd4f --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/__init__.py @@ -0,0 +1,15 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._operations import HealthApiOperations +from ._operations import WebPubSubOperations + +__all__ = [ + 'HealthApiOperations', + 'WebPubSubOperations', +] diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/_operations.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/_operations.py new file mode 100644 index 000000000000..3ef37c276158 --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/_operations.py @@ -0,0 +1,1148 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +import functools +from typing import Any, Callable, Dict, Generic, IO, List, Optional, TypeVar, Union +import warnings + +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import AsyncHttpResponse +from azure.core.rest import HttpRequest +from azure.core.tracing.decorator_async import distributed_trace_async + +from ...operations._operations import build_health_api_get_service_status_request, build_web_pub_sub_add_connection_to_group_request, build_web_pub_sub_add_user_to_group_request, build_web_pub_sub_check_permission_request, build_web_pub_sub_close_connection_request, build_web_pub_sub_connection_exists_request, build_web_pub_sub_generate_client_token_request, build_web_pub_sub_grant_permission_request, build_web_pub_sub_group_exists_request, build_web_pub_sub_remove_connection_from_group_request, build_web_pub_sub_remove_user_from_all_groups_request, build_web_pub_sub_remove_user_from_group_request, build_web_pub_sub_revoke_permission_request, build_web_pub_sub_send_to_all_request, build_web_pub_sub_send_to_connection_request, build_web_pub_sub_send_to_group_request, build_web_pub_sub_send_to_user_request, build_web_pub_sub_user_exists_request + +T = TypeVar('T') +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] + +class HealthApiOperations: + """HealthApiOperations async operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + def __init__(self, client, config, serializer, deserializer) -> None: + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + @distributed_trace_async + async def get_service_status( + self, + *, + api_version: Optional[str] = "2021-08-01-preview", + **kwargs: Any + ) -> None: + """Get service health status. + + Get service health status. + + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + + request = build_health_api_get_service_status_request( + api_version=api_version, + template_url=self.get_service_status.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + get_service_status.metadata = {'url': '/api/health'} # type: ignore + +class WebPubSubOperations: + """WebPubSubOperations async operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + def __init__(self, client, config, serializer, deserializer) -> None: + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + @distributed_trace_async + async def generate_client_token( + self, + hub: str, + *, + user_id: Optional[str] = "", + role: Optional[List[str]] = None, + minutes_to_expire: Optional[int] = 60, + api_version: Optional[str] = "2021-08-01-preview", + **kwargs: Any + ) -> Any: + """Generate token for the client to connect Azure Web PubSub service. + + Generate token for the client to connect Azure Web PubSub service. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :keyword user_id: User Id. + :paramtype user_id: str + :keyword role: Roles that the connection with the generated token will have. + :paramtype role: list[str] + :keyword minutes_to_expire: The expire time of the generated token. + :paramtype minutes_to_expire: int + :keyword api_version: Api Version. + :paramtype api_version: str + :return: JSON object + :rtype: Any + :raises: ~azure.core.exceptions.HttpResponseError + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response.json() == { + "token": "str (optional)" + } + """ + cls = kwargs.pop('cls', None) # type: ClsType[Any] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + + request = build_web_pub_sub_generate_client_token_request( + hub=hub, + user_id=user_id, + role=role, + minutes_to_expire=minutes_to_expire, + api_version=api_version, + template_url=self.generate_client_token.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if response.content: + deserialized = response.json() + else: + deserialized = None + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + + generate_client_token.metadata = {'url': '/api/hubs/{hub}/:generateToken'} # type: ignore + + + @distributed_trace_async + async def send_to_all( + self, + hub: str, + message: Union[IO, str], + *, + excluded: Optional[List[str]] = None, + api_version: Optional[str] = "2021-08-01-preview", + **kwargs: Any + ) -> None: + """Broadcast content inside request body to all the connected client connections. + + Broadcast content inside request body to all the connected client connections. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param message: The payload body. + :type message: IO or str + :keyword excluded: Excluded connection Ids. + :paramtype excluded: list[str] + :keyword api_version: Api Version. + :paramtype api_version: str + :keyword str content_type: Media type of the body sent to the API. Default value is + "application/json". Allowed values are: "application/json", "application/octet-stream", + "text/plain." + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + content_type = kwargs.pop('content_type', "text/plain") # type: Optional[str] + + json = None + content = None + if content_type.split(";")[0] in ['application/json', 'application/octet-stream']: + content = message + elif content_type.split(";")[0] in ['text/plain']: + json = message + else: + raise ValueError( + "The content_type '{}' is not one of the allowed values: " + "['application/json', 'application/octet-stream', 'text/plain']".format(content_type) + ) + + request = build_web_pub_sub_send_to_all_request( + hub=hub, + content_type=content_type, + excluded=excluded, + api_version=api_version, + json=json, + content=content, + template_url=self.send_to_all.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + send_to_all.metadata = {'url': '/api/hubs/{hub}/:send'} # type: ignore + + + @distributed_trace_async + async def connection_exists( + self, + hub: str, + connection_id: str, + *, + api_version: Optional[str] = "2021-08-01-preview", + **kwargs: Any + ) -> None: + """Check if the connection with the given connectionId exists. + + Check if the connection with the given connectionId exists. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param connection_id: The connection Id. + :type connection_id: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + + request = build_web_pub_sub_connection_exists_request( + hub=hub, + connection_id=connection_id, + api_version=api_version, + template_url=self.connection_exists.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 404]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + connection_exists.metadata = {'url': '/api/hubs/{hub}/connections/{connectionId}'} # type: ignore + + + @distributed_trace_async + async def close_connection( + self, + hub: str, + connection_id: str, + *, + reason: Optional[str] = None, + api_version: Optional[str] = "2021-08-01-preview", + **kwargs: Any + ) -> None: + """Close the client connection. + + Close the client connection. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param connection_id: Target connection Id. + :type connection_id: str + :keyword reason: The reason closing the client connection. + :paramtype reason: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + + request = build_web_pub_sub_close_connection_request( + hub=hub, + connection_id=connection_id, + reason=reason, + api_version=api_version, + template_url=self.close_connection.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + close_connection.metadata = {'url': '/api/hubs/{hub}/connections/{connectionId}'} # type: ignore + + + @distributed_trace_async + async def send_to_connection( + self, + hub: str, + connection_id: str, + message: Union[IO, str], + *, + api_version: Optional[str] = "2021-08-01-preview", + **kwargs: Any + ) -> None: + """Send content inside request body to the specific connection. + + Send content inside request body to the specific connection. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param connection_id: The connection Id. + :type connection_id: str + :param message: The payload body. + :type message: IO or str + :keyword api_version: Api Version. + :paramtype api_version: str + :keyword str content_type: Media type of the body sent to the API. Default value is + "application/json". Allowed values are: "application/json", "application/octet-stream", + "text/plain." + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + content_type = kwargs.pop('content_type', "text/plain") # type: Optional[str] + + json = None + content = None + if content_type.split(";")[0] in ['application/json', 'application/octet-stream']: + content = message + elif content_type.split(";")[0] in ['text/plain']: + json = message + else: + raise ValueError( + "The content_type '{}' is not one of the allowed values: " + "['application/json', 'application/octet-stream', 'text/plain']".format(content_type) + ) + + request = build_web_pub_sub_send_to_connection_request( + hub=hub, + connection_id=connection_id, + content_type=content_type, + api_version=api_version, + json=json, + content=content, + template_url=self.send_to_connection.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + send_to_connection.metadata = {'url': '/api/hubs/{hub}/connections/{connectionId}/:send'} # type: ignore + + + @distributed_trace_async + async def group_exists( + self, + hub: str, + group: str, + *, + api_version: Optional[str] = "2021-08-01-preview", + **kwargs: Any + ) -> None: + """Check if there are any client connections inside the given group. + + Check if there are any client connections inside the given group. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param group: Target group name, which length should be greater than 0 and less than 1025. + :type group: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + + request = build_web_pub_sub_group_exists_request( + hub=hub, + group=group, + api_version=api_version, + template_url=self.group_exists.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 404]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + group_exists.metadata = {'url': '/api/hubs/{hub}/groups/{group}'} # type: ignore + + + @distributed_trace_async + async def send_to_group( + self, + hub: str, + group: str, + message: Union[IO, str], + *, + excluded: Optional[List[str]] = None, + api_version: Optional[str] = "2021-08-01-preview", + **kwargs: Any + ) -> None: + """Send content inside request body to a group of connections. + + Send content inside request body to a group of connections. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param group: Target group name, which length should be greater than 0 and less than 1025. + :type group: str + :param message: The payload body. + :type message: IO or str + :keyword excluded: Excluded connection Ids. + :paramtype excluded: list[str] + :keyword api_version: Api Version. + :paramtype api_version: str + :keyword str content_type: Media type of the body sent to the API. Default value is + "application/json". Allowed values are: "application/json", "application/octet-stream", + "text/plain." + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + content_type = kwargs.pop('content_type', "text/plain") # type: Optional[str] + + json = None + content = None + if content_type.split(";")[0] in ['application/json', 'application/octet-stream']: + content = message + elif content_type.split(";")[0] in ['text/plain']: + json = message + else: + raise ValueError( + "The content_type '{}' is not one of the allowed values: " + "['application/json', 'application/octet-stream', 'text/plain']".format(content_type) + ) + + request = build_web_pub_sub_send_to_group_request( + hub=hub, + group=group, + content_type=content_type, + excluded=excluded, + api_version=api_version, + json=json, + content=content, + template_url=self.send_to_group.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + send_to_group.metadata = {'url': '/api/hubs/{hub}/groups/{group}/:send'} # type: ignore + + + @distributed_trace_async + async def add_connection_to_group( + self, + hub: str, + group: str, + connection_id: str, + *, + api_version: Optional[str] = "2021-08-01-preview", + **kwargs: Any + ) -> None: + """Add a connection to the target group. + + Add a connection to the target group. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param group: Target group name, which length should be greater than 0 and less than 1025. + :type group: str + :param connection_id: Target connection Id. + :type connection_id: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + + request = build_web_pub_sub_add_connection_to_group_request( + hub=hub, + group=group, + connection_id=connection_id, + api_version=api_version, + template_url=self.add_connection_to_group.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 404]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + add_connection_to_group.metadata = {'url': '/api/hubs/{hub}/groups/{group}/connections/{connectionId}'} # type: ignore + + + @distributed_trace_async + async def remove_connection_from_group( + self, + hub: str, + group: str, + connection_id: str, + *, + api_version: Optional[str] = "2021-08-01-preview", + **kwargs: Any + ) -> None: + """Remove a connection from the target group. + + Remove a connection from the target group. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param group: Target group name, which length should be greater than 0 and less than 1025. + :type group: str + :param connection_id: Target connection Id. + :type connection_id: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + + request = build_web_pub_sub_remove_connection_from_group_request( + hub=hub, + group=group, + connection_id=connection_id, + api_version=api_version, + template_url=self.remove_connection_from_group.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + remove_connection_from_group.metadata = {'url': '/api/hubs/{hub}/groups/{group}/connections/{connectionId}'} # type: ignore + + + @distributed_trace_async + async def user_exists( + self, + hub: str, + user_id: str, + *, + api_version: Optional[str] = "2021-08-01-preview", + **kwargs: Any + ) -> None: + """Check if there are any client connections connected for the given user. + + Check if there are any client connections connected for the given user. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param user_id: Target user Id. + :type user_id: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + + request = build_web_pub_sub_user_exists_request( + hub=hub, + user_id=user_id, + api_version=api_version, + template_url=self.user_exists.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 404]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + user_exists.metadata = {'url': '/api/hubs/{hub}/users/{userId}'} # type: ignore + + + @distributed_trace_async + async def send_to_user( + self, + hub: str, + user_id: str, + message: Union[IO, str], + *, + api_version: Optional[str] = "2021-08-01-preview", + **kwargs: Any + ) -> None: + """Send content inside request body to the specific user. + + Send content inside request body to the specific user. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param user_id: The user Id. + :type user_id: str + :param message: The payload body. + :type message: IO or str + :keyword api_version: Api Version. + :paramtype api_version: str + :keyword str content_type: Media type of the body sent to the API. Default value is + "application/json". Allowed values are: "application/json", "application/octet-stream", + "text/plain." + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + content_type = kwargs.pop('content_type', "text/plain") # type: Optional[str] + + json = None + content = None + if content_type.split(";")[0] in ['application/json', 'application/octet-stream']: + content = message + elif content_type.split(";")[0] in ['text/plain']: + json = message + else: + raise ValueError( + "The content_type '{}' is not one of the allowed values: " + "['application/json', 'application/octet-stream', 'text/plain']".format(content_type) + ) + + request = build_web_pub_sub_send_to_user_request( + hub=hub, + user_id=user_id, + content_type=content_type, + api_version=api_version, + json=json, + content=content, + template_url=self.send_to_user.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + send_to_user.metadata = {'url': '/api/hubs/{hub}/users/{userId}/:send'} # type: ignore + + + @distributed_trace_async + async def add_user_to_group( + self, + hub: str, + group: str, + user_id: str, + *, + api_version: Optional[str] = "2021-08-01-preview", + **kwargs: Any + ) -> None: + """Add a user to the target group. + + Add a user to the target group. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param group: Target group name, which length should be greater than 0 and less than 1025. + :type group: str + :param user_id: Target user Id. + :type user_id: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + + request = build_web_pub_sub_add_user_to_group_request( + hub=hub, + group=group, + user_id=user_id, + api_version=api_version, + template_url=self.add_user_to_group.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 404]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + add_user_to_group.metadata = {'url': '/api/hubs/{hub}/users/{userId}/groups/{group}'} # type: ignore + + + @distributed_trace_async + async def remove_user_from_group( + self, + hub: str, + group: str, + user_id: str, + *, + api_version: Optional[str] = "2021-08-01-preview", + **kwargs: Any + ) -> None: + """Remove a user from the target group. + + Remove a user from the target group. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param group: Target group name, which length should be greater than 0 and less than 1025. + :type group: str + :param user_id: Target user Id. + :type user_id: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + + request = build_web_pub_sub_remove_user_from_group_request( + hub=hub, + group=group, + user_id=user_id, + api_version=api_version, + template_url=self.remove_user_from_group.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + remove_user_from_group.metadata = {'url': '/api/hubs/{hub}/users/{userId}/groups/{group}'} # type: ignore + + + @distributed_trace_async + async def remove_user_from_all_groups( + self, + hub: str, + user_id: str, + *, + api_version: Optional[str] = "2021-08-01-preview", + **kwargs: Any + ) -> None: + """Remove a user from all groups. + + Remove a user from all groups. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param user_id: Target user Id. + :type user_id: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + + request = build_web_pub_sub_remove_user_from_all_groups_request( + hub=hub, + user_id=user_id, + api_version=api_version, + template_url=self.remove_user_from_all_groups.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + remove_user_from_all_groups.metadata = {'url': '/api/hubs/{hub}/users/{userId}/groups'} # type: ignore + + + @distributed_trace_async + async def grant_permission( + self, + hub: str, + permission: str, + connection_id: str, + *, + target_name: Optional[str] = None, + api_version: Optional[str] = "2021-08-01-preview", + **kwargs: Any + ) -> None: + """Grant permission to the connection. + + Grant permission to the connection. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param permission: The permission: current supported actions are joinLeaveGroup and + sendToGroup. Possible values are: "sendToGroup" or "joinLeaveGroup". + :type permission: str + :param connection_id: Target connection Id. + :type connection_id: str + :keyword target_name: The meaning of the target depends on the specific permission. For + joinLeaveGroup and sendToGroup, targetName is a required parameter standing for the group name. + :paramtype target_name: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + + request = build_web_pub_sub_grant_permission_request( + hub=hub, + permission=permission, + connection_id=connection_id, + target_name=target_name, + api_version=api_version, + template_url=self.grant_permission.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + grant_permission.metadata = {'url': '/api/hubs/{hub}/permissions/{permission}/connections/{connectionId}'} # type: ignore + + + @distributed_trace_async + async def revoke_permission( + self, + hub: str, + permission: str, + connection_id: str, + *, + target_name: Optional[str] = None, + api_version: Optional[str] = "2021-08-01-preview", + **kwargs: Any + ) -> None: + """Revoke permission for the connection. + + Revoke permission for the connection. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param permission: The permission: current supported actions are joinLeaveGroup and + sendToGroup. Possible values are: "sendToGroup" or "joinLeaveGroup". + :type permission: str + :param connection_id: Target connection Id. + :type connection_id: str + :keyword target_name: The meaning of the target depends on the specific permission. For + joinLeaveGroup and sendToGroup, targetName is a required parameter standing for the group name. + :paramtype target_name: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + + request = build_web_pub_sub_revoke_permission_request( + hub=hub, + permission=permission, + connection_id=connection_id, + target_name=target_name, + api_version=api_version, + template_url=self.revoke_permission.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + revoke_permission.metadata = {'url': '/api/hubs/{hub}/permissions/{permission}/connections/{connectionId}'} # type: ignore + + + @distributed_trace_async + async def check_permission( + self, + hub: str, + permission: str, + connection_id: str, + *, + target_name: Optional[str] = None, + api_version: Optional[str] = "2021-08-01-preview", + **kwargs: Any + ) -> None: + """Check if a connection has permission to the specified action. + + Check if a connection has permission to the specified action. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param permission: The permission: current supported actions are joinLeaveGroup and + sendToGroup. Possible values are: "sendToGroup" or "joinLeaveGroup". + :type permission: str + :param connection_id: Target connection Id. + :type connection_id: str + :keyword target_name: The meaning of the target depends on the specific permission. For + joinLeaveGroup and sendToGroup, targetName is a required parameter standing for the group name. + :paramtype target_name: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + + request = build_web_pub_sub_check_permission_request( + hub=hub, + permission=permission, + connection_id=connection_id, + target_name=target_name, + api_version=api_version, + template_url=self.check_permission.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 404]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + check_permission.metadata = {'url': '/api/hubs/{hub}/permissions/{permission}/connections/{connectionId}'} # type: ignore + diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/core/__init__.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/core/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/core/rest/__init__.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/core/rest/__init__.py deleted file mode 100644 index a70aae7c472a..000000000000 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/core/rest/__init__.py +++ /dev/null @@ -1,65 +0,0 @@ -# -------------------------------------------------------------------------- -# -# Copyright (c) Microsoft Corporation. All rights reserved. -# -# The MIT License (MIT) -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the ""Software""), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. -# -# -------------------------------------------------------------------------- -try: - from ._rest_py3 import ( - HttpRequest, - HttpResponse, - AsyncHttpResponse, - _StreamContextManager, - _AsyncStreamContextManager, - StreamConsumedError, - ResponseNotReadError, - ResponseClosedError, - ) - - __all__ = [ - "HttpRequest", - "HttpResponse", - "AsyncHttpResponse", - "_StreamContextManager", - "_AsyncStreamContextManager", - "StreamConsumedError", - "ResponseNotReadError", - "ResponseClosedError", - ] -except (SyntaxError, ImportError): - from ._rest import ( - HttpRequest, - HttpResponse, - _StreamContextManager, - StreamConsumedError, - ResponseNotReadError, - ResponseClosedError, - ) - - __all__ = [ - "HttpRequest", - "HttpResponse", - "_StreamContextManager", - "StreamConsumedError", - "ResponseNotReadError", - "ResponseClosedError", - ] diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/core/rest/_rest.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/core/rest/_rest.py deleted file mode 100644 index cee1c039cbda..000000000000 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/core/rest/_rest.py +++ /dev/null @@ -1,625 +0,0 @@ -# -------------------------------------------------------------------------- -# -# Copyright (c) Microsoft Corporation. All rights reserved. -# -# The MIT License (MIT) -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the ""Software""), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. -# -# -------------------------------------------------------------------------- - -# pylint currently complains about typing.Union not being subscriptable -# pylint: disable=unsubscriptable-object - -import codecs -import json -from enum import Enum -import xml.etree.ElementTree as ET -from typing import TYPE_CHECKING, Iterable - -import cgi -import six - -from azure.core.exceptions import HttpResponseError -from azure.core.pipeline.transport import ( - HttpRequest as _PipelineTransportHttpRequest, -) - - -if TYPE_CHECKING: - from typing import ( # pylint: disable=ungrouped-imports - Any, - Optional, - Union, - Mapping, - Sequence, - Tuple, - Iterator, - ) - - ByteStream = Iterable[bytes] - - HeadersType = Union[Mapping[str, str], Sequence[Tuple[str, str]]] - ContentType = Union[str, bytes, ByteStream] - from azure.core.pipeline.transport._base import ( - _HttpResponseBase as _PipelineTransportHttpResponseBase, - ) - from azure.core._pipeline_client import PipelineClient as _PipelineClient - - -class HttpVerbs(str, Enum): - GET = "GET" - PUT = "PUT" - POST = "POST" - HEAD = "HEAD" - PATCH = "PATCH" - DELETE = "DELETE" - MERGE = "MERGE" - - -########################### UTILS SECTION ################################# - - -def _is_stream_or_str_bytes(content): - return isinstance(content, (str, bytes)) or any( - hasattr(content, attr) for attr in ["read", "__iter__", "__aiter__"] - ) - - -def _lookup_encoding(encoding): - # type: (str) -> bool - # including check for whether encoding is known taken from httpx - try: - codecs.lookup(encoding) - return True - except LookupError: - return False - - -def _set_content_length_header(header_name, header_value, internal_request): - # type: (str, str, _PipelineTransportHttpRequest) -> None - valid_methods = ["put", "post", "patch"] - content_length_headers = ["Content-Length", "Transfer-Encoding"] - if internal_request.method.lower() in valid_methods and not any( - [c for c in content_length_headers if c in internal_request.headers] - ): - internal_request.headers[header_name] = header_value - - -def _set_content_type_header(header_value, internal_request): - # type: (str, _PipelineTransportHttpRequest) -> None - if not internal_request.headers.get("Content-Type"): - internal_request.headers["Content-Type"] = header_value - - -def _set_content_body(content, internal_request): - # type: (ContentType, _PipelineTransportHttpRequest) -> None - headers = internal_request.headers - content_type = headers.get("Content-Type") - if _is_stream_or_str_bytes(content): - # stream will be bytes / str, or iterator of bytes / str - internal_request.set_streamed_data_body(content) - if isinstance(content, (str, bytes)) and content: - _set_content_length_header( - "Content-Length", str(len(internal_request.data)), internal_request - ) - if isinstance(content, six.string_types): - _set_content_type_header("text/plain", internal_request) - else: - _set_content_type_header("application/octet-stream", internal_request) - elif isinstance( # pylint: disable=isinstance-second-argument-not-valid-type - content, Iterable - ): - # _set_content_length_header("Transfer-Encoding", "chunked", internal_request) - _set_content_type_header("application/octet-stream", internal_request) - elif isinstance(content, ET.Element): - # XML body - internal_request.set_xml_body(content) - _set_content_type_header("application/xml", internal_request) - _set_content_length_header( - "Content-Length", str(len(internal_request.data)), internal_request - ) - elif content_type and content_type.startswith("text/"): - # Text body - internal_request.set_text_body(content) - _set_content_length_header( - "Content-Length", str(len(internal_request.data)), internal_request - ) - else: - # Other body - internal_request.data = content - internal_request.headers = headers - - -def _set_body(content, data, files, json_body, internal_request): - # type: (ContentType, dict, Any, Any, _PipelineTransportHttpRequest) -> None - if data is not None and not isinstance(data, dict): - content = data - data = None - if content is not None: - _set_content_body(content, internal_request) - elif json_body is not None: - internal_request.set_json_body(json_body) - _set_content_type_header("application/json", internal_request) - elif files is not None: - internal_request.set_formdata_body(files) - # if you don't supply your content type, we'll create a boundary for you with multipart/form-data - # boundary = binascii.hexlify(os.urandom(16)).decode("ascii") # got logic from httpx, thanks httpx! - # _set_content_type_header("multipart/form-data; boundary={}".format(boundary), internal_request) - elif data: - _set_content_type_header("application/x-www-form-urlencoded", internal_request) - internal_request.set_formdata_body(data) - # need to set twice because Content-Type is being popped in set_formdata_body - # don't want to risk changing pipeline.transport, so doing twice here - _set_content_type_header("application/x-www-form-urlencoded", internal_request) - - -def _parse_lines_from_text(text): - # largely taken from httpx's LineDecoder code - lines = [] - last_chunk_of_text = "" - while text: - text_length = len(text) - for idx in range(text_length): - curr_char = text[idx] - next_char = None if idx == len(text) - 1 else text[idx + 1] - if curr_char == "\n": - lines.append(text[: idx + 1]) - text = text[idx + 1 :] - break - if curr_char == "\r" and next_char == "\n": - # if it ends with \r\n, we only do \n - lines.append(text[:idx] + "\n") - text = text[idx + 2 :] - break - if curr_char == "\r" and next_char is not None: - # if it's \r then a normal character, we switch \r to \n - lines.append(text[:idx] + "\n") - text = text[idx + 1 :] - break - if next_char is None: - text = "" - last_chunk_of_text += text - break - if last_chunk_of_text.endswith("\r"): - # if ends with \r, we switch \r to \n - lines.append(last_chunk_of_text[:-1] + "\n") - elif last_chunk_of_text: - lines.append(last_chunk_of_text) - return lines - - -################################## CLASSES ###################################### -class _StreamContextManager(object): - def __init__(self, client, request, **kwargs): - # type: (_PipelineClient, HttpRequest, Any) -> None - self.client = client - self.request = request - self.kwargs = kwargs - - def __enter__(self): - # type: (...) -> HttpResponse - """Actually make the call only when we enter. For sync stream_response calls""" - pipeline_transport_response = self.client._pipeline.run( - self.request._internal_request, stream=True, **self.kwargs - ).http_response - self.response = HttpResponse( # pylint: disable=attribute-defined-outside-init - request=self.request, _internal_response=pipeline_transport_response - ) - return self.response - - def __exit__(self, *args): - """Close our stream connection. For sync calls""" - self.response.__exit__(*args) - - def close(self): - self.response.close() - - -class HttpRequest(object): - """Represents an HTTP request. - - :param method: HTTP method (GET, HEAD, etc.) - :type method: str or ~azure.core.protocol.HttpVerbs - :param str url: The url for your request - :keyword params: Query parameters to be mapped into your URL. Your input - should be a mapping or sequence of query name to query value(s). - :paramtype params: mapping or sequence - :keyword headers: HTTP headers you want in your request. Your input should - be a mapping or sequence of header name to header value. - :paramtype headers: mapping or sequence - :keyword dict data: Form data you want in your request body. Use for form-encoded data, i.e. - HTML forms. - :keyword any json: A JSON serializable object. We handle JSON-serialization for your - object, so use this for more complicated data structures than `data`. - :keyword files: Files you want to in your request body. Use for uploading files with - multipart encoding. Your input should be a mapping or sequence of file name to file content. - Use the `data` kwarg in addition if you want to include non-file data files as part of your request. - :paramtype files: mapping or sequence - :keyword content: Content you want in your request body. Think of it as the kwarg you should input - if your data doesn't fit into `json`, `data`, or `files`. Accepts a bytes type, or a generator - that yields bytes. - :paramtype content: str or bytes or iterable[bytes] or asynciterable[bytes] - :ivar str url: The URL this request is against. - :ivar str method: The method type of this request. - :ivar headers: The HTTP headers you passed in to your request - :vartype headers: mapping or sequence - :ivar bytes content: The content passed in for the request - """ - - def __init__(self, method, url, **kwargs): - # type: (str, str, Any) -> None - - data = kwargs.pop("data", None) - content = kwargs.pop("content", None) - json_body = kwargs.pop("json", None) - files = kwargs.pop("files", None) - - self._internal_request = kwargs.pop( - "_internal_request", - _PipelineTransportHttpRequest( - method=method, - url=url, - headers=kwargs.pop("headers", None), - ), - ) - params = kwargs.pop("params", None) - - if params: - self._internal_request.format_parameters(params) - - _set_body( - content=content, - data=data, - files=files, - json_body=json_body, - internal_request=self._internal_request, - ) - - if kwargs: - raise TypeError( - "You have passed in kwargs '{}' that are not valid kwargs.".format( - "', '".join(list(kwargs.keys())) - ) - ) - - def _set_content_length_header(self): - method_check = self._internal_request.method.lower() in ["put", "post", "patch"] - content_length_unset = "Content-Length" not in self._internal_request.headers - if method_check and content_length_unset: - self._internal_request.headers["Content-Length"] = str( - len(self._internal_request.data) - ) - - @property - def url(self): - # type: (...) -> str - return self._internal_request.url - - @url.setter - def url(self, val): - # type: (str) -> None - self._internal_request.url = val - - @property - def method(self): - # type: (...) -> str - return self._internal_request.method - - @property - def headers(self): - # type: (...) -> HeadersType - return self._internal_request.headers - - @property - def content(self): - # type: (...) -> Any - """Gets the request content.""" - return self._internal_request.data or self._internal_request.files - - def __repr__(self): - return self._internal_request.__repr__() - - def __deepcopy__(self, memo=None): - return HttpRequest( - self.method, - self.url, - _internal_request=self._internal_request.__deepcopy__(memo), - ) - - -class _HttpResponseBase(object): - """Base class for HttpResponse and AsyncHttpResponse. - - :keyword request: The request that resulted in this response. - :paramtype request: ~azure.core.rest.HttpRequest - :ivar int status_code: The status code of this response - :ivar headers: The response headers - :vartype headers: dict[str, any] - :ivar str reason: The reason phrase for this response - :ivar bytes content: The response content in bytes - :ivar str url: The URL that resulted in this response - :ivar str encoding: The response encoding. Is settable, by default - is the response Content-Type header - :ivar str text: The response body as a string. - :ivar request: The request that resulted in this response. - :vartype request: ~azure.core.rest.HttpRequest - :ivar str content_type: The content type of the response - :ivar bool is_error: Whether this response is an error. - """ - - def __init__(self, **kwargs): - # type: (Any) -> None - self._internal_response = kwargs.pop( - "_internal_response" - ) # type: _PipelineTransportHttpResponseBase - self._request = kwargs.pop("request") - self.is_closed = False - self.is_stream_consumed = False - self._num_bytes_downloaded = 0 - - @property - def status_code(self): - # type: (...) -> int - """Returns the status code of the response""" - return self._internal_response.status_code - - @status_code.setter - def status_code(self, val): - # type: (int) -> None - """Set the status code of the response""" - self._internal_response.status_code = val - - @property - def headers(self): - # type: (...) -> HeadersType - """Returns the response headers""" - return self._internal_response.headers - - @property - def reason(self): - # type: (...) -> str - """Returns the reason phrase for the response""" - return self._internal_response.reason - - @property - def content(self): - # type: (...) -> bytes - """Returns the response content in bytes""" - raise NotImplementedError() - - @property - def url(self): - # type: (...) -> str - """Returns the URL that resulted in this response""" - return self._internal_response.request.url - - @property - def encoding(self): - # type: (...) -> Optional[str] - """Returns the response encoding. By default, is specified - by the response Content-Type header. - """ - - try: - return self._encoding - except AttributeError: - return self._get_charset_encoding() - - def _get_charset_encoding(self): - content_type = self.headers.get("Content-Type") - - if not content_type: - return None - _, params = cgi.parse_header(content_type) - encoding = params.get("charset") # -> utf-8 - if encoding is None or not _lookup_encoding(encoding): - return None - return encoding - - @encoding.setter - def encoding(self, value): - # type: (str) -> None - """Sets the response encoding""" - self._encoding = value - - @property - def text(self): - # type: (...) -> str - """Returns the response body as a string""" - _ = ( - self.content - ) # access content to make sure we trigger if response not fully read in - return self._internal_response.text(encoding=self.encoding) - - @property - def request(self): - # type: (...) -> HttpRequest - if self._request: - return self._request - raise RuntimeError( - "You are trying to access the 'request', but there is no request associated with this HttpResponse" - ) - - @request.setter - def request(self, val): - # type: (HttpRequest) -> None - self._request = val - - @property - def content_type(self): - # type: (...) -> Optional[str] - """Content Type of the response""" - return self._internal_response.content_type or self.headers.get("Content-Type") - - @property - def num_bytes_downloaded(self): - # type: (...) -> int - """See how many bytes of your stream response have been downloaded""" - return self._num_bytes_downloaded - - @property - def is_error(self): - # type: (...) -> bool - """See whether your HttpResponse is an error. - - Use .raise_for_status() if you want to raise if this response is an error. - """ - return self.status_code < 400 - - def json(self): - # type: (...) -> Any - """Returns the whole body as a json object. - - :return: The JSON deserialized response body - :rtype: any - :raises json.decoder.JSONDecodeError or ValueError (in python 2.7) if object is not JSON decodable: - """ - return json.loads(self.text) - - def raise_for_status(self): - # type: (...) -> None - """Raises an HttpResponseError if the response has an error status code. - - If response is good, does nothing. - """ - if self.status_code >= 400: - raise HttpResponseError(response=self) - - def __repr__(self): - # type: (...) -> str - content_type_str = ( - ", Content-Type: {}".format(self.content_type) if self.content_type else "" - ) - return "<{}: {} {}{}>".format( - type(self).__name__, self.status_code, self.reason, content_type_str - ) - - def _validate_streaming_access(self): - # type: (...) -> None - if self.is_closed: - raise ResponseClosedError() - if self.is_stream_consumed: - raise StreamConsumedError() - - -class HttpResponse(_HttpResponseBase): - @property - def content(self): - # type: (...) -> bytes - try: - return self._content - except AttributeError: - raise ResponseNotReadError() - - def close(self): - # type: (...) -> None - self.is_closed = True - self._internal_response.internal_response.close() - - def __exit__(self, *args): - # type: (...) -> None - self._internal_response.internal_response.__exit__(*args) - - def read(self): - # type: (...) -> bytes - """ - Read the response's bytes. - - """ - try: - return self._content - except AttributeError: - self._validate_streaming_access() - self._content = ( # pylint: disable=attribute-defined-outside-init - self._internal_response.body() or b"".join(self.iter_raw()) - ) - self._close_stream() - return self._content - - def iter_bytes(self, chunk_size=None): - # type: (int) -> Iterator[bytes] - """Iterate over the bytes in the response stream""" - try: - chunk_size = len(self._content) if chunk_size is None else chunk_size - for i in range(0, len(self._content), chunk_size): - yield self._content[i : i + chunk_size] - - except AttributeError: - for raw_bytes in self.iter_raw(chunk_size=chunk_size): - yield raw_bytes - - def iter_text(self, chunk_size=None): - # type: (int) -> Iterator[str] - """Iterate over the response text""" - for byte in self.iter_bytes(chunk_size): - text = byte.decode(self.encoding or "utf-8") - yield text - - def iter_lines(self, chunk_size=None): - # type: (int) -> Iterator[str] - for text in self.iter_text(chunk_size): - lines = _parse_lines_from_text(text) - for line in lines: - yield line - - def _close_stream(self): - # type: (...) -> None - self.is_stream_consumed = True - self.close() - - def iter_raw(self, **_): - # type: (int) -> Iterator[bytes] - """Iterate over the raw response bytes""" - self._validate_streaming_access() - stream_download = self._internal_response.stream_download(None) - for raw_bytes in stream_download: - self._num_bytes_downloaded += len(raw_bytes) - yield raw_bytes - - self._close_stream() - - -########################### ERRORS SECTION ################################# - - -class StreamConsumedError(Exception): - def __init__(self): - message = ( - "You are attempting to read or stream content that has already been streamed. " - "You have likely already consumed this stream, so it can not be accessed anymore." - ) - super(StreamConsumedError, self).__init__(message) - - -class ResponseClosedError(Exception): - def __init__(self): - message = ( - "You can not try to read or stream this response's content, since the " - "response has been closed." - ) - super(ResponseClosedError, self).__init__(message) - - -class ResponseNotReadError(Exception): - def __init__(self): - message = ( - "You have not read in the response's bytes yet. Call response.read() first." - ) - super(ResponseNotReadError, self).__init__(message) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/core/rest/_rest_py3.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/core/rest/_rest_py3.py deleted file mode 100644 index ed2908d69484..000000000000 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/core/rest/_rest_py3.py +++ /dev/null @@ -1,739 +0,0 @@ -# -------------------------------------------------------------------------- -# -# Copyright (c) Microsoft Corporation. All rights reserved. -# -# The MIT License (MIT) -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the ""Software""), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. -# -# -------------------------------------------------------------------------- - -# pylint currently complains about typing.Union not being subscriptable -# pylint: disable=unsubscriptable-object - - -import asyncio -import codecs -import json -from enum import Enum -import xml.etree.ElementTree as ET -from typing import ( - Any, - AsyncIterable, - IO, - Iterable, - Iterator, - Optional, - Union, - Mapping, - Sequence, - Tuple, - List, -) -from abc import abstractmethod - -import cgi - -from azure.core.exceptions import HttpResponseError -from azure.core.pipeline.transport import ( - HttpRequest as _PipelineTransportHttpRequest, -) - -from azure.core.pipeline.transport._base import ( - _HttpResponseBase as _PipelineTransportHttpResponseBase, -) - -from azure.core._pipeline_client import PipelineClient as _PipelineClient -from azure.core._pipeline_client_async import ( - AsyncPipelineClient as _AsyncPipelineClient, -) - -################################### TYPES SECTION ######################### - -ByteStream = Union[Iterable[bytes], AsyncIterable[bytes]] -PrimitiveData = Optional[Union[str, int, float, bool]] - - -ParamsType = Union[ - Mapping[str, Union[PrimitiveData, Sequence[PrimitiveData]]], - List[Tuple[str, PrimitiveData]], -] - -HeadersType = Union[Mapping[str, str], Sequence[Tuple[str, str]]] - -ContentType = Union[str, bytes, ByteStream] - -FileContent = Union[str, bytes, IO[str], IO[bytes]] -FileType = Union[ - Tuple[Optional[str], FileContent], -] - -FilesType = Union[Mapping[str, FileType], Sequence[Tuple[str, FileType]]] - - - -class HttpVerbs(str, Enum): - GET = "GET" - PUT = "PUT" - POST = "POST" - HEAD = "HEAD" - PATCH = "PATCH" - DELETE = "DELETE" - MERGE = "MERGE" - - -########################### UTILS SECTION ################################# - - -def _is_stream_or_str_bytes(content: Any) -> bool: - return isinstance(content, (str, bytes)) or any( - hasattr(content, attr) for attr in ["read", "__iter__", "__aiter__"] - ) - - -def _lookup_encoding(encoding: str) -> bool: - # including check for whether encoding is known taken from httpx - try: - codecs.lookup(encoding) - return True - except LookupError: - return False - - -def _set_content_length_header( - header_name: str, header_value: str, internal_request: _PipelineTransportHttpRequest -) -> None: - valid_methods = ["put", "post", "patch"] - content_length_headers = ["Content-Length", "Transfer-Encoding"] - if internal_request.method.lower() in valid_methods and not any( - [c for c in content_length_headers if c in internal_request.headers] - ): - internal_request.headers[header_name] = header_value - - -def _set_content_type_header( - header_value: str, internal_request: _PipelineTransportHttpRequest -) -> None: - if not internal_request.headers.get("Content-Type"): - internal_request.headers["Content-Type"] = header_value - - -def _set_content_body( - content: ContentType, internal_request: _PipelineTransportHttpRequest -) -> None: - headers = internal_request.headers - content_type = headers.get("Content-Type") - if _is_stream_or_str_bytes(content): - # stream will be bytes / str, or iterator of bytes / str - internal_request.set_streamed_data_body(content) - if isinstance(content, str) and content: - _set_content_length_header( - "Content-Length", str(len(internal_request.data)), internal_request - ) - _set_content_type_header("text/plain", internal_request) - elif isinstance(content, bytes) and content: - _set_content_length_header( - "Content-Length", str(len(internal_request.data)), internal_request - ) - _set_content_type_header("application/octet-stream", internal_request) - elif isinstance(content, (Iterable, AsyncIterable)): # pylint: disable=isinstance-second-argument-not-valid-type - # _set_content_length_header("Transfer-Encoding", "chunked", internal_request) - _set_content_type_header("application/octet-stream", internal_request) - elif isinstance(content, ET.Element): - # XML body - internal_request.set_xml_body(content) - _set_content_type_header("application/xml", internal_request) - _set_content_length_header( - "Content-Length", str(len(internal_request.data)), internal_request - ) - elif content_type and content_type.startswith("text/"): - # Text body - internal_request.set_text_body(content) - _set_content_length_header( - "Content-Length", str(len(internal_request.data)), internal_request - ) - else: - # Other body - internal_request.data = content - internal_request.headers = headers - - -def _set_body( - content: ContentType, - data: dict, - files: Any, - json_body: Any, - internal_request: _PipelineTransportHttpRequest, -) -> None: - if data is not None and not isinstance(data, dict): - content = data - data = None - if content is not None: - _set_content_body(content, internal_request) - elif json_body is not None: - internal_request.set_json_body(json_body) - _set_content_type_header("application/json", internal_request) - elif files is not None: - internal_request.set_formdata_body(files) - # if you don't supply your content type, we'll create a boundary for you with multipart/form-data - # boundary = binascii.hexlify(os.urandom(16)).decode( - # "ascii" - #) # got logic from httpx, thanks httpx! - # _set_content_type_header("multipart/form-data; boundary={}".format(boundary), internal_request) - elif data: - _set_content_type_header("application/x-www-form-urlencoded", internal_request) - internal_request.set_formdata_body(data) - # need to set twice because Content-Type is being popped in set_formdata_body - # don't want to risk changing pipeline.transport, so doing twice here - _set_content_type_header("application/x-www-form-urlencoded", internal_request) - - -def _parse_lines_from_text(text): - # largely taken from httpx's LineDecoder code - lines = [] - last_chunk_of_text = "" - while text: - text_length = len(text) - for idx in range(text_length): - curr_char = text[idx] - next_char = None if idx == len(text) - 1 else text[idx + 1] - if curr_char == "\n": - lines.append(text[: idx + 1]) - text = text[idx + 1 :] - break - if curr_char == "\r" and next_char == "\n": - # if it ends with \r\n, we only do \n - lines.append(text[:idx] + "\n") - text = text[idx + 2 :] - break - if curr_char == "\r" and next_char is not None: - # if it's \r then a normal character, we switch \r to \n - lines.append(text[:idx] + "\n") - text = text[idx + 1 :] - break - if next_char is None: - text = "" - last_chunk_of_text += text - break - if last_chunk_of_text.endswith("\r"): - # if ends with \r, we switch \r to \n - lines.append(last_chunk_of_text[:-1] + "\n") - elif last_chunk_of_text: - lines.append(last_chunk_of_text) - return lines - - -class _StreamContextManagerBase: - def __init__( - self, - client: Union[_PipelineClient, _AsyncPipelineClient], - request: "HttpRequest", - **kwargs - ): - """Used so we can treat stream requests and responses as a context manager. - - In Autorest, we only return a `StreamContextManager` if users pass in `stream_response` True - - Actually sends request when we enter the context manager, closes response when we exit. - - Heavily inspired from httpx, we want the same behavior for it to feel consistent for users - """ - self.client = client - self.request = request - self.kwargs = kwargs - - @abstractmethod - def close(self): - ... - - -class _StreamContextManager(_StreamContextManagerBase): - def __enter__(self) -> "HttpResponse": - """Actually make the call only when we enter. For sync stream_response calls""" - pipeline_transport_response = self.client._pipeline.run( - self.request._internal_request, stream=True, **self.kwargs - ).http_response - self.response = HttpResponse( # pylint: disable=attribute-defined-outside-init - request=self.request, _internal_response=pipeline_transport_response - ) - return self.response - - def __exit__(self, *args): - """Close our stream connection. For sync calls""" - self.response.__exit__(*args) - - def close(self): - self.response.close() - - -class _AsyncStreamContextManager(_StreamContextManagerBase): - async def __aenter__(self) -> "AsyncHttpResponse": - """Actually make the call only when we enter. For async stream_response calls.""" - if not isinstance(self.client, _AsyncPipelineClient): - raise TypeError( - "Only sync calls should enter here. If you mean to do a sync call, " - "make sure to use 'with' instead." - ) - pipeline_transport_response = ( - await self.client._pipeline.run( - self.request._internal_request, stream=True, **self.kwargs - ) - ).http_response - self.response = AsyncHttpResponse( # pylint: disable=attribute-defined-outside-init - request=self.request, _internal_response=pipeline_transport_response - ) - return self.response - - async def __aexit__(self, *args): - await self.response.__aexit__(*args) - - async def close(self): # pylint: disable=invalid-overridden-method - await self.response.close() - - -################################## CLASSES ###################################### - - -class HttpRequest: - """Represents an HTTP request. - - :param method: HTTP method (GET, HEAD, etc.) - :type method: str or ~azure.core.protocol.HttpVerbs - :param str url: The url for your request - :keyword params: Query parameters to be mapped into your URL. Your input - should be a mapping or sequence of query name to query value(s). - :paramtype params: mapping or sequence - :keyword headers: HTTP headers you want in your request. Your input should - be a mapping or sequence of header name to header value. - :paramtype headers: mapping or sequence - :keyword any json: A JSON serializable object. We handle JSON-serialization for your - object, so use this for more complicated data structures than `data`. - :keyword content: Content you want in your request body. Think of it as the kwarg you should input - if your data doesn't fit into `json`, `data`, or `files`. Accepts a bytes type, or a generator - that yields bytes. - :paramtype content: str or bytes or iterable[bytes] or asynciterable[bytes] - :keyword dict data: Form data you want in your request body. Use for form-encoded data, i.e. - HTML forms. - :keyword files: Files you want to in your request body. Use for uploading files with - multipart encoding. Your input should be a mapping or sequence of file name to file content. - Use the `data` kwarg in addition if you want to include non-file data files as part of your request. - :paramtype files: mapping or sequence - :ivar str url: The URL this request is against. - :ivar str method: The method type of this request. - :ivar headers: The HTTP headers you passed in to your request - :vartype headers: mapping or sequence - :ivar bytes content: The content passed in for the request - """ - - def __init__( - self, - method: str, - url: str, - *, - params: Optional[ParamsType] = None, - headers: Optional[HeadersType] = None, - json: Any = None, # pylint: disable=redefined-outer-name - content: Optional[ContentType] = None, - data: Optional[dict] = None, - files: Optional[FilesType] = None, - **kwargs - ): - # type: (str, str, Any) -> None - - self._internal_request = kwargs.pop( - "_internal_request", - _PipelineTransportHttpRequest( - method=method, - url=url, - headers=headers, - ), - ) - - if params: - self._internal_request.format_parameters(params) - - _set_body( - content=content, - data=data, - files=files, - json_body=json, - internal_request=self._internal_request, - ) - - if kwargs: - raise TypeError( - "You have passed in kwargs '{}' that are not valid kwargs.".format( - "', '".join(list(kwargs.keys())) - ) - ) - - def _set_content_length_header(self) -> None: - method_check = self._internal_request.method.lower() in ["put", "post", "patch"] - content_length_unset = "Content-Length" not in self._internal_request.headers - if method_check and content_length_unset: - self._internal_request.headers["Content-Length"] = str( - len(self._internal_request.data) - ) - - @property - def url(self) -> str: - return self._internal_request.url - - @url.setter - def url(self, val: str) -> None: - self._internal_request.url = val - - @property - def method(self) -> str: - return self._internal_request.method - - @property - def headers(self) -> HeadersType: - return self._internal_request.headers - - @property - def content(self) -> Any: - """Gets the request content.""" - return self._internal_request.data or self._internal_request.files - - def __repr__(self) -> str: - return self._internal_request.__repr__() - - def __deepcopy__(self, memo=None) -> "HttpRequest": - return HttpRequest( - self.method, - self.url, - _internal_request=self._internal_request.__deepcopy__(memo), - ) - - -class _HttpResponseBase: - """Base class for HttpResponse and AsyncHttpResponse. - - :keyword request: The request that resulted in this response. - :paramtype request: ~azure.core.rest.HttpRequest - :ivar int status_code: The status code of this response - :ivar headers: The response headers - :vartype headers: dict[str, any] - :ivar str reason: The reason phrase for this response - :ivar bytes content: The response content in bytes - :ivar str url: The URL that resulted in this response - :ivar str encoding: The response encoding. Is settable, by default - is the response Content-Type header - :ivar str text: The response body as a string. - :ivar request: The request that resulted in this response. - :vartype request: ~azure.core.rest.HttpRequest - :ivar str content_type: The content type of the response - :ivar bool is_closed: Whether the network connection has been closed yet - :ivar bool is_stream_consumed: When getting a stream response, checks - whether the stream has been fully consumed - :ivar int num_bytes_downloaded: The number of bytes in your stream that - have been downloaded - """ - - def __init__(self, *, request: HttpRequest, **kwargs): - self._internal_response = kwargs.pop( - "_internal_response" - ) # type: _PipelineTransportHttpResponseBase - self._request = request - self.is_closed = False - self.is_stream_consumed = False - self._num_bytes_downloaded = 0 - - @property - def status_code(self) -> int: - """Returns the status code of the response""" - return self._internal_response.status_code - - @status_code.setter - def status_code(self, val: int) -> None: - """Set the status code of the response""" - self._internal_response.status_code = val - - @property - def headers(self) -> HeadersType: - """Returns the response headers""" - return self._internal_response.headers - - @property - def reason(self) -> str: - """Returns the reason phrase for the response""" - return self._internal_response.reason - - @property - def content(self) -> bytes: - """Returns the response content in bytes""" - raise NotImplementedError() - - @property - def url(self) -> str: - """Returns the URL that resulted in this response""" - return self._internal_response.request.url - - @property - def encoding(self) -> str: - """Returns the response encoding. By default, is specified - by the response Content-Type header. - """ - - try: - return self._encoding - except AttributeError: - return self._get_charset_encoding() - - def _get_charset_encoding(self) -> str: - content_type = self.headers.get("Content-Type") - - if not content_type: - return None - _, params = cgi.parse_header(content_type) - encoding = params.get("charset") # -> utf-8 - if encoding is None or not _lookup_encoding(encoding): - return None - return encoding - - @encoding.setter - def encoding(self, value: str) -> None: - # type: (str) -> None - """Sets the response encoding""" - self._encoding = value - - @property - def text(self) -> str: - """Returns the response body as a string""" - _ = self.content # access content to make sure we trigger if response not fully read in - return self._internal_response.text(encoding=self.encoding) - - @property - def request(self) -> HttpRequest: - if self._request: - return self._request - raise RuntimeError( - "You are trying to access the 'request', but there is no request associated with this HttpResponse" - ) - - @request.setter - def request(self, val: HttpRequest) -> None: - self._request = val - - @property - def content_type(self) -> Optional[str]: - """Content Type of the response""" - return self._internal_response.content_type or self.headers.get("Content-Type") - - @property - def num_bytes_downloaded(self) -> int: - """See how many bytes of your stream response have been downloaded""" - return self._num_bytes_downloaded - - def json(self) -> Any: - """Returns the whole body as a json object. - - :return: The JSON deserialized response body - :rtype: any - :raises json.decoder.JSONDecodeError or ValueError (in python 2.7) if object is not JSON decodable: - """ - return json.loads(self.text) - - def raise_for_status(self) -> None: - """Raises an HttpResponseError if the response has an error status code. - - If response is good, does nothing. - """ - if self.status_code >= 400: - raise HttpResponseError(response=self) - - def __repr__(self) -> str: - content_type_str = ( - ", Content-Type: {}".format(self.content_type) if self.content_type else "" - ) - return "<{}: {} {}{}>".format( - type(self).__name__, self.status_code, self.reason, content_type_str - ) - - def _validate_streaming_access(self) -> None: - if self.is_closed: - raise ResponseClosedError() - if self.is_stream_consumed: - raise StreamConsumedError() - - -class HttpResponse(_HttpResponseBase): - @property - def content(self): - # type: (...) -> bytes - try: - return self._content - except AttributeError: - raise ResponseNotReadError() - - def close(self) -> None: - self.is_closed = True - self._internal_response.internal_response.close() - - def __exit__(self, *args) -> None: - self._internal_response.internal_response.__exit__(*args) - - def read(self) -> bytes: - """ - Read the response's bytes. - - """ - try: - return self._content - except AttributeError: - self._validate_streaming_access() - self._content = (self._internal_response.body() or # pylint: disable=attribute-defined-outside-init - b"".join(self.iter_raw())) - self._close_stream() - return self._content - - def iter_bytes(self, chunk_size: int = None) -> Iterator[bytes]: - """Iterate over the bytes in the response stream""" - try: - chunk_size = len(self._content) if chunk_size is None else chunk_size - for i in range(0, len(self._content), chunk_size): - yield self._content[i : i + chunk_size] - - except AttributeError: - for raw_bytes in self.iter_raw(chunk_size=chunk_size): - yield raw_bytes - - def iter_text(self, chunk_size: int = None) -> Iterator[str]: - """Iterate over the response text""" - for byte in self.iter_bytes(chunk_size): - text = byte.decode(self.encoding or "utf-8") - yield text - - def iter_lines(self, chunk_size: int = None) -> Iterator[str]: - for text in self.iter_text(chunk_size): - lines = _parse_lines_from_text(text) - for line in lines: - yield line - - def _close_stream(self) -> None: - self.is_stream_consumed = True - self.close() - - def iter_raw(self, **_) -> Iterator[bytes]: - """Iterate over the raw response bytes""" - self._validate_streaming_access() - stream_download = self._internal_response.stream_download(None) - for raw_bytes in stream_download: - self._num_bytes_downloaded += len(raw_bytes) - yield raw_bytes - - self._close_stream() - - -class AsyncHttpResponse(_HttpResponseBase): - @property - def content(self) -> bytes: - try: - return self._content - except AttributeError: - raise ResponseNotReadError() - - async def _close_stream(self) -> None: - self.is_stream_consumed = True - await self.close() - - async def read(self) -> bytes: - """ - Read the response's bytes. - - """ - try: - return self._content - except AttributeError: - self._validate_streaming_access() - await self._internal_response.load_body() - self._content = self._internal_response._body # pylint: disable=protected-access,attribute-defined-outside-init - await self._close_stream() - return self._content - - async def iter_bytes(self, chunk_size: int = None) -> Iterator[bytes]: - """Iterate over the bytes in the response stream""" - try: - chunk_size = len(self._content) if chunk_size is None else chunk_size - for i in range(0, len(self._content), chunk_size): - yield self._content[i : i + chunk_size] - - except AttributeError: - async for raw_bytes in self.iter_raw(chunk_size=chunk_size): - yield raw_bytes - - async def iter_text(self, chunk_size: int = None) -> Iterator[str]: - """Iterate over the response text""" - async for byte in self.iter_bytes(chunk_size): - text = byte.decode(self.encoding or "utf-8") - yield text - - async def iter_lines(self, chunk_size: int = None) -> Iterator[str]: - async for text in self.iter_text(chunk_size): - lines = _parse_lines_from_text(text) - for line in lines: - yield line - - async def iter_raw(self, **_) -> Iterator[bytes]: - """Iterate over the raw response bytes""" - self._validate_streaming_access() - stream_download = self._internal_response.stream_download(None) - async for raw_bytes in stream_download: - self._num_bytes_downloaded += len(raw_bytes) - yield raw_bytes - - await self._close_stream() - - async def close(self) -> None: - self.is_closed = True - self._internal_response.internal_response.close() - await asyncio.sleep(0) - - async def __aexit__(self, *args) -> None: - await self._internal_response.internal_response.__aexit__(*args) - - -########################### ERRORS SECTION ################################# - - -class StreamConsumedError(Exception): - def __init__(self) -> None: - message = ( - "You are attempting to read or stream content that has already been streamed. " - "You have likely already consumed this stream, so it can not be accessed anymore." - ) - super().__init__(message) - - -class ResponseClosedError(Exception): - def __init__(self) -> None: - message = ( - "You can not try to read or stream this response's content, since the " - "response has been closed." - ) - super().__init__(message) - - -class ResponseNotReadError(Exception): - def __init__(self) -> None: - message = ( - "You have not read in the response's bytes yet. Call response.read() first." - ) - super().__init__(message) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/__init__.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/__init__.py new file mode 100644 index 000000000000..a2ac5f07bd4f --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/__init__.py @@ -0,0 +1,15 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._operations import HealthApiOperations +from ._operations import WebPubSubOperations + +__all__ = [ + 'HealthApiOperations', + 'WebPubSubOperations', +] diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/_operations.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/_operations.py new file mode 100644 index 000000000000..9837c993726a --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/_operations.py @@ -0,0 +1,1772 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +import functools +from typing import TYPE_CHECKING +import warnings + +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import HttpResponse +from azure.core.pipeline.transport._base import _format_url_section +from azure.core.rest import HttpRequest +from azure.core.tracing.decorator import distributed_trace +from msrest import Serializer + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any, Callable, Dict, Generic, IO, List, Optional, TypeVar, Union + + T = TypeVar('T') + ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] + +_SERIALIZER = Serializer() +# fmt: off + +def build_health_api_get_service_status_request( + **kwargs # type: Any +): + # type: (...) -> HttpRequest + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + # Construct URL + url = kwargs.pop("template_url", '/api/health') + + # Construct parameters + query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] + if api_version is not None: + query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + return HttpRequest( + method="HEAD", + url=url, + params=query_parameters, + **kwargs + ) + + +def build_web_pub_sub_generate_client_token_request( + hub, # type: str + **kwargs # type: Any +): + # type: (...) -> HttpRequest + user_id = kwargs.pop('user_id', "") # type: Optional[str] + role = kwargs.pop('role', None) # type: Optional[List[str]] + minutes_to_expire = kwargs.pop('minutes_to_expire', 60) # type: Optional[int] + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + accept = "application/json, text/json" + # Construct URL + url = kwargs.pop("template_url", '/api/hubs/{hub}/:generateToken') + path_format_arguments = { + "hub": _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), + } + + url = _format_url_section(url, **path_format_arguments) + + # Construct parameters + query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] + if user_id is not None: + query_parameters['userId'] = _SERIALIZER.query("user_id", user_id, 'str') + if role is not None: + query_parameters['role'] = [_SERIALIZER.query("role", q, 'str') if q is not None else '' for q in role] + if minutes_to_expire is not None: + query_parameters['minutesToExpire'] = _SERIALIZER.query("minutes_to_expire", minutes_to_expire, 'int') + if api_version is not None: + query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = kwargs.pop("headers", {}) # type: Dict[str, Any] + header_parameters['Accept'] = _SERIALIZER.header("accept", accept, 'str') + + return HttpRequest( + method="POST", + url=url, + params=query_parameters, + headers=header_parameters, + **kwargs + ) + + +def build_web_pub_sub_send_to_all_request( + hub, # type: str + **kwargs # type: Any +): + # type: (...) -> HttpRequest + content_type = kwargs.pop('content_type', None) # type: Optional[str] + excluded = kwargs.pop('excluded', None) # type: Optional[List[str]] + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + # Construct URL + url = kwargs.pop("template_url", '/api/hubs/{hub}/:send') + path_format_arguments = { + "hub": _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), + } + + url = _format_url_section(url, **path_format_arguments) + + # Construct parameters + query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] + if excluded is not None: + query_parameters['excluded'] = [_SERIALIZER.query("excluded", q, 'str') if q is not None else '' for q in excluded] + if api_version is not None: + query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = kwargs.pop("headers", {}) # type: Dict[str, Any] + if content_type is not None: + header_parameters['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str') + + return HttpRequest( + method="POST", + url=url, + params=query_parameters, + headers=header_parameters, + **kwargs + ) + + +def build_web_pub_sub_connection_exists_request( + hub, # type: str + connection_id, # type: str + **kwargs # type: Any +): + # type: (...) -> HttpRequest + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + # Construct URL + url = kwargs.pop("template_url", '/api/hubs/{hub}/connections/{connectionId}') + path_format_arguments = { + "hub": _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), + "connectionId": _SERIALIZER.url("connection_id", connection_id, 'str', min_length=1), + } + + url = _format_url_section(url, **path_format_arguments) + + # Construct parameters + query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] + if api_version is not None: + query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + return HttpRequest( + method="HEAD", + url=url, + params=query_parameters, + **kwargs + ) + + +def build_web_pub_sub_close_connection_request( + hub, # type: str + connection_id, # type: str + **kwargs # type: Any +): + # type: (...) -> HttpRequest + reason = kwargs.pop('reason', None) # type: Optional[str] + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + # Construct URL + url = kwargs.pop("template_url", '/api/hubs/{hub}/connections/{connectionId}') + path_format_arguments = { + "hub": _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), + "connectionId": _SERIALIZER.url("connection_id", connection_id, 'str', min_length=1), + } + + url = _format_url_section(url, **path_format_arguments) + + # Construct parameters + query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] + if reason is not None: + query_parameters['reason'] = _SERIALIZER.query("reason", reason, 'str') + if api_version is not None: + query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + return HttpRequest( + method="DELETE", + url=url, + params=query_parameters, + **kwargs + ) + + +def build_web_pub_sub_send_to_connection_request( + hub, # type: str + connection_id, # type: str + **kwargs # type: Any +): + # type: (...) -> HttpRequest + content_type = kwargs.pop('content_type', None) # type: Optional[str] + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + # Construct URL + url = kwargs.pop("template_url", '/api/hubs/{hub}/connections/{connectionId}/:send') + path_format_arguments = { + "hub": _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), + "connectionId": _SERIALIZER.url("connection_id", connection_id, 'str', min_length=1), + } + + url = _format_url_section(url, **path_format_arguments) + + # Construct parameters + query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] + if api_version is not None: + query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = kwargs.pop("headers", {}) # type: Dict[str, Any] + if content_type is not None: + header_parameters['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str') + + return HttpRequest( + method="POST", + url=url, + params=query_parameters, + headers=header_parameters, + **kwargs + ) + + +def build_web_pub_sub_group_exists_request( + hub, # type: str + group, # type: str + **kwargs # type: Any +): + # type: (...) -> HttpRequest + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + # Construct URL + url = kwargs.pop("template_url", '/api/hubs/{hub}/groups/{group}') + path_format_arguments = { + "hub": _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), + "group": _SERIALIZER.url("group", group, 'str', max_length=1024, min_length=1), + } + + url = _format_url_section(url, **path_format_arguments) + + # Construct parameters + query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] + if api_version is not None: + query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + return HttpRequest( + method="HEAD", + url=url, + params=query_parameters, + **kwargs + ) + + +def build_web_pub_sub_send_to_group_request( + hub, # type: str + group, # type: str + **kwargs # type: Any +): + # type: (...) -> HttpRequest + content_type = kwargs.pop('content_type', None) # type: Optional[str] + excluded = kwargs.pop('excluded', None) # type: Optional[List[str]] + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + # Construct URL + url = kwargs.pop("template_url", '/api/hubs/{hub}/groups/{group}/:send') + path_format_arguments = { + "hub": _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), + "group": _SERIALIZER.url("group", group, 'str', max_length=1024, min_length=1), + } + + url = _format_url_section(url, **path_format_arguments) + + # Construct parameters + query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] + if excluded is not None: + query_parameters['excluded'] = [_SERIALIZER.query("excluded", q, 'str') if q is not None else '' for q in excluded] + if api_version is not None: + query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = kwargs.pop("headers", {}) # type: Dict[str, Any] + if content_type is not None: + header_parameters['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str') + + return HttpRequest( + method="POST", + url=url, + params=query_parameters, + headers=header_parameters, + **kwargs + ) + + +def build_web_pub_sub_add_connection_to_group_request( + hub, # type: str + group, # type: str + connection_id, # type: str + **kwargs # type: Any +): + # type: (...) -> HttpRequest + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + # Construct URL + url = kwargs.pop("template_url", '/api/hubs/{hub}/groups/{group}/connections/{connectionId}') + path_format_arguments = { + "hub": _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), + "group": _SERIALIZER.url("group", group, 'str', max_length=1024, min_length=1), + "connectionId": _SERIALIZER.url("connection_id", connection_id, 'str', min_length=1), + } + + url = _format_url_section(url, **path_format_arguments) + + # Construct parameters + query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] + if api_version is not None: + query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + return HttpRequest( + method="PUT", + url=url, + params=query_parameters, + **kwargs + ) + + +def build_web_pub_sub_remove_connection_from_group_request( + hub, # type: str + group, # type: str + connection_id, # type: str + **kwargs # type: Any +): + # type: (...) -> HttpRequest + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + # Construct URL + url = kwargs.pop("template_url", '/api/hubs/{hub}/groups/{group}/connections/{connectionId}') + path_format_arguments = { + "hub": _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), + "group": _SERIALIZER.url("group", group, 'str', max_length=1024, min_length=1), + "connectionId": _SERIALIZER.url("connection_id", connection_id, 'str', min_length=1), + } + + url = _format_url_section(url, **path_format_arguments) + + # Construct parameters + query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] + if api_version is not None: + query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + return HttpRequest( + method="DELETE", + url=url, + params=query_parameters, + **kwargs + ) + + +def build_web_pub_sub_user_exists_request( + hub, # type: str + user_id, # type: str + **kwargs # type: Any +): + # type: (...) -> HttpRequest + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + # Construct URL + url = kwargs.pop("template_url", '/api/hubs/{hub}/users/{userId}') + path_format_arguments = { + "hub": _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), + "userId": _SERIALIZER.url("user_id", user_id, 'str', min_length=1), + } + + url = _format_url_section(url, **path_format_arguments) + + # Construct parameters + query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] + if api_version is not None: + query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + return HttpRequest( + method="HEAD", + url=url, + params=query_parameters, + **kwargs + ) + + +def build_web_pub_sub_send_to_user_request( + hub, # type: str + user_id, # type: str + **kwargs # type: Any +): + # type: (...) -> HttpRequest + content_type = kwargs.pop('content_type', None) # type: Optional[str] + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + # Construct URL + url = kwargs.pop("template_url", '/api/hubs/{hub}/users/{userId}/:send') + path_format_arguments = { + "hub": _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), + "userId": _SERIALIZER.url("user_id", user_id, 'str', min_length=1), + } + + url = _format_url_section(url, **path_format_arguments) + + # Construct parameters + query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] + if api_version is not None: + query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + # Construct headers + header_parameters = kwargs.pop("headers", {}) # type: Dict[str, Any] + if content_type is not None: + header_parameters['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str') + + return HttpRequest( + method="POST", + url=url, + params=query_parameters, + headers=header_parameters, + **kwargs + ) + + +def build_web_pub_sub_add_user_to_group_request( + hub, # type: str + group, # type: str + user_id, # type: str + **kwargs # type: Any +): + # type: (...) -> HttpRequest + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + # Construct URL + url = kwargs.pop("template_url", '/api/hubs/{hub}/users/{userId}/groups/{group}') + path_format_arguments = { + "hub": _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), + "group": _SERIALIZER.url("group", group, 'str', max_length=1024, min_length=1), + "userId": _SERIALIZER.url("user_id", user_id, 'str', min_length=1), + } + + url = _format_url_section(url, **path_format_arguments) + + # Construct parameters + query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] + if api_version is not None: + query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + return HttpRequest( + method="PUT", + url=url, + params=query_parameters, + **kwargs + ) + + +def build_web_pub_sub_remove_user_from_group_request( + hub, # type: str + group, # type: str + user_id, # type: str + **kwargs # type: Any +): + # type: (...) -> HttpRequest + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + # Construct URL + url = kwargs.pop("template_url", '/api/hubs/{hub}/users/{userId}/groups/{group}') + path_format_arguments = { + "hub": _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), + "group": _SERIALIZER.url("group", group, 'str', max_length=1024, min_length=1), + "userId": _SERIALIZER.url("user_id", user_id, 'str', min_length=1), + } + + url = _format_url_section(url, **path_format_arguments) + + # Construct parameters + query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] + if api_version is not None: + query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + return HttpRequest( + method="DELETE", + url=url, + params=query_parameters, + **kwargs + ) + + +def build_web_pub_sub_remove_user_from_all_groups_request( + hub, # type: str + user_id, # type: str + **kwargs # type: Any +): + # type: (...) -> HttpRequest + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + # Construct URL + url = kwargs.pop("template_url", '/api/hubs/{hub}/users/{userId}/groups') + path_format_arguments = { + "hub": _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), + "userId": _SERIALIZER.url("user_id", user_id, 'str', min_length=1), + } + + url = _format_url_section(url, **path_format_arguments) + + # Construct parameters + query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] + if api_version is not None: + query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + return HttpRequest( + method="DELETE", + url=url, + params=query_parameters, + **kwargs + ) + + +def build_web_pub_sub_grant_permission_request( + hub, # type: str + permission, # type: str + connection_id, # type: str + **kwargs # type: Any +): + # type: (...) -> HttpRequest + target_name = kwargs.pop('target_name', None) # type: Optional[str] + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + # Construct URL + url = kwargs.pop("template_url", '/api/hubs/{hub}/permissions/{permission}/connections/{connectionId}') + path_format_arguments = { + "hub": _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), + "permission": _SERIALIZER.url("permission", permission, 'str'), + "connectionId": _SERIALIZER.url("connection_id", connection_id, 'str', min_length=1), + } + + url = _format_url_section(url, **path_format_arguments) + + # Construct parameters + query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] + if target_name is not None: + query_parameters['targetName'] = _SERIALIZER.query("target_name", target_name, 'str') + if api_version is not None: + query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + return HttpRequest( + method="PUT", + url=url, + params=query_parameters, + **kwargs + ) + + +def build_web_pub_sub_revoke_permission_request( + hub, # type: str + permission, # type: str + connection_id, # type: str + **kwargs # type: Any +): + # type: (...) -> HttpRequest + target_name = kwargs.pop('target_name', None) # type: Optional[str] + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + # Construct URL + url = kwargs.pop("template_url", '/api/hubs/{hub}/permissions/{permission}/connections/{connectionId}') + path_format_arguments = { + "hub": _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), + "permission": _SERIALIZER.url("permission", permission, 'str'), + "connectionId": _SERIALIZER.url("connection_id", connection_id, 'str', min_length=1), + } + + url = _format_url_section(url, **path_format_arguments) + + # Construct parameters + query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] + if target_name is not None: + query_parameters['targetName'] = _SERIALIZER.query("target_name", target_name, 'str') + if api_version is not None: + query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + return HttpRequest( + method="DELETE", + url=url, + params=query_parameters, + **kwargs + ) + + +def build_web_pub_sub_check_permission_request( + hub, # type: str + permission, # type: str + connection_id, # type: str + **kwargs # type: Any +): + # type: (...) -> HttpRequest + target_name = kwargs.pop('target_name', None) # type: Optional[str] + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + # Construct URL + url = kwargs.pop("template_url", '/api/hubs/{hub}/permissions/{permission}/connections/{connectionId}') + path_format_arguments = { + "hub": _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), + "permission": _SERIALIZER.url("permission", permission, 'str'), + "connectionId": _SERIALIZER.url("connection_id", connection_id, 'str', min_length=1), + } + + url = _format_url_section(url, **path_format_arguments) + + # Construct parameters + query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] + if target_name is not None: + query_parameters['targetName'] = _SERIALIZER.query("target_name", target_name, 'str') + if api_version is not None: + query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') + + return HttpRequest( + method="HEAD", + url=url, + params=query_parameters, + **kwargs + ) + +# fmt: on +class HealthApiOperations(object): + """HealthApiOperations operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + def __init__(self, client, config, serializer, deserializer): + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + @distributed_trace + def get_service_status( + self, + **kwargs # type: Any + ): + # type: (...) -> None + """Get service health status. + + Get service health status. + + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + + request = build_health_api_get_service_status_request( + api_version=api_version, + template_url=self.get_service_status.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + get_service_status.metadata = {'url': '/api/health'} # type: ignore + +class WebPubSubOperations(object): + """WebPubSubOperations operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + def __init__(self, client, config, serializer, deserializer): + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + @distributed_trace + def generate_client_token( + self, + hub, # type: str + **kwargs # type: Any + ): + # type: (...) -> Any + """Generate token for the client to connect Azure Web PubSub service. + + Generate token for the client to connect Azure Web PubSub service. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :keyword user_id: User Id. + :paramtype user_id: str + :keyword role: Roles that the connection with the generated token will have. + :paramtype role: list[str] + :keyword minutes_to_expire: The expire time of the generated token. + :paramtype minutes_to_expire: int + :keyword api_version: Api Version. + :paramtype api_version: str + :return: JSON object + :rtype: Any + :raises: ~azure.core.exceptions.HttpResponseError + + Example: + .. code-block:: python + + # response body for status code(s): 200 + response.json() == { + "token": "str (optional)" + } + """ + cls = kwargs.pop('cls', None) # type: ClsType[Any] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + user_id = kwargs.pop('user_id', "") # type: Optional[str] + role = kwargs.pop('role', None) # type: Optional[List[str]] + minutes_to_expire = kwargs.pop('minutes_to_expire', 60) # type: Optional[int] + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + + request = build_web_pub_sub_generate_client_token_request( + hub=hub, + user_id=user_id, + role=role, + minutes_to_expire=minutes_to_expire, + api_version=api_version, + template_url=self.generate_client_token.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if response.content: + deserialized = response.json() + else: + deserialized = None + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + + generate_client_token.metadata = {'url': '/api/hubs/{hub}/:generateToken'} # type: ignore + + + @distributed_trace + def send_to_all( + self, + hub, # type: str + message, # type: Union[IO, str] + **kwargs # type: Any + ): + # type: (...) -> None + """Broadcast content inside request body to all the connected client connections. + + Broadcast content inside request body to all the connected client connections. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param message: The payload body. + :type message: IO or str + :keyword excluded: Excluded connection Ids. + :paramtype excluded: list[str] + :keyword api_version: Api Version. + :paramtype api_version: str + :keyword str content_type: Media type of the body sent to the API. Default value is + "application/json". Allowed values are: "application/json", "application/octet-stream", + "text/plain." + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + content_type = kwargs.pop('content_type', "text/plain") # type: Optional[str] + excluded = kwargs.pop('excluded', None) # type: Optional[List[str]] + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + json = None + content = None + if content_type.split(";")[0] in ['application/json', 'application/octet-stream']: + content = message + elif content_type.split(";")[0] in ['text/plain']: + json = message + else: + raise ValueError( + "The content_type '{}' is not one of the allowed values: " + "['application/json', 'application/octet-stream', 'text/plain']".format(content_type) + ) + + request = build_web_pub_sub_send_to_all_request( + hub=hub, + content_type=content_type, + excluded=excluded, + api_version=api_version, + json=json, + content=content, + template_url=self.send_to_all.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + send_to_all.metadata = {'url': '/api/hubs/{hub}/:send'} # type: ignore + + + @distributed_trace + def connection_exists( + self, + hub, # type: str + connection_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + """Check if the connection with the given connectionId exists. + + Check if the connection with the given connectionId exists. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param connection_id: The connection Id. + :type connection_id: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + + request = build_web_pub_sub_connection_exists_request( + hub=hub, + connection_id=connection_id, + api_version=api_version, + template_url=self.connection_exists.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 404]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + connection_exists.metadata = {'url': '/api/hubs/{hub}/connections/{connectionId}'} # type: ignore + + + @distributed_trace + def close_connection( + self, + hub, # type: str + connection_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + """Close the client connection. + + Close the client connection. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param connection_id: Target connection Id. + :type connection_id: str + :keyword reason: The reason closing the client connection. + :paramtype reason: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + reason = kwargs.pop('reason', None) # type: Optional[str] + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + + request = build_web_pub_sub_close_connection_request( + hub=hub, + connection_id=connection_id, + reason=reason, + api_version=api_version, + template_url=self.close_connection.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + close_connection.metadata = {'url': '/api/hubs/{hub}/connections/{connectionId}'} # type: ignore + + + @distributed_trace + def send_to_connection( + self, + hub, # type: str + connection_id, # type: str + message, # type: Union[IO, str] + **kwargs # type: Any + ): + # type: (...) -> None + """Send content inside request body to the specific connection. + + Send content inside request body to the specific connection. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param connection_id: The connection Id. + :type connection_id: str + :param message: The payload body. + :type message: IO or str + :keyword api_version: Api Version. + :paramtype api_version: str + :keyword str content_type: Media type of the body sent to the API. Default value is + "application/json". Allowed values are: "application/json", "application/octet-stream", + "text/plain." + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + content_type = kwargs.pop('content_type', "text/plain") # type: Optional[str] + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + json = None + content = None + if content_type.split(";")[0] in ['application/json', 'application/octet-stream']: + content = message + elif content_type.split(";")[0] in ['text/plain']: + json = message + else: + raise ValueError( + "The content_type '{}' is not one of the allowed values: " + "['application/json', 'application/octet-stream', 'text/plain']".format(content_type) + ) + + request = build_web_pub_sub_send_to_connection_request( + hub=hub, + connection_id=connection_id, + content_type=content_type, + api_version=api_version, + json=json, + content=content, + template_url=self.send_to_connection.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + send_to_connection.metadata = {'url': '/api/hubs/{hub}/connections/{connectionId}/:send'} # type: ignore + + + @distributed_trace + def group_exists( + self, + hub, # type: str + group, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + """Check if there are any client connections inside the given group. + + Check if there are any client connections inside the given group. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param group: Target group name, which length should be greater than 0 and less than 1025. + :type group: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + + request = build_web_pub_sub_group_exists_request( + hub=hub, + group=group, + api_version=api_version, + template_url=self.group_exists.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 404]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + group_exists.metadata = {'url': '/api/hubs/{hub}/groups/{group}'} # type: ignore + + + @distributed_trace + def send_to_group( + self, + hub, # type: str + group, # type: str + message, # type: Union[IO, str] + **kwargs # type: Any + ): + # type: (...) -> None + """Send content inside request body to a group of connections. + + Send content inside request body to a group of connections. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param group: Target group name, which length should be greater than 0 and less than 1025. + :type group: str + :param message: The payload body. + :type message: IO or str + :keyword excluded: Excluded connection Ids. + :paramtype excluded: list[str] + :keyword api_version: Api Version. + :paramtype api_version: str + :keyword str content_type: Media type of the body sent to the API. Default value is + "application/json". Allowed values are: "application/json", "application/octet-stream", + "text/plain." + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + content_type = kwargs.pop('content_type', "text/plain") # type: Optional[str] + excluded = kwargs.pop('excluded', None) # type: Optional[List[str]] + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + json = None + content = None + if content_type.split(";")[0] in ['application/json', 'application/octet-stream']: + content = message + elif content_type.split(";")[0] in ['text/plain']: + json = message + else: + raise ValueError( + "The content_type '{}' is not one of the allowed values: " + "['application/json', 'application/octet-stream', 'text/plain']".format(content_type) + ) + + request = build_web_pub_sub_send_to_group_request( + hub=hub, + group=group, + content_type=content_type, + excluded=excluded, + api_version=api_version, + json=json, + content=content, + template_url=self.send_to_group.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + send_to_group.metadata = {'url': '/api/hubs/{hub}/groups/{group}/:send'} # type: ignore + + + @distributed_trace + def add_connection_to_group( + self, + hub, # type: str + group, # type: str + connection_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + """Add a connection to the target group. + + Add a connection to the target group. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param group: Target group name, which length should be greater than 0 and less than 1025. + :type group: str + :param connection_id: Target connection Id. + :type connection_id: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + + request = build_web_pub_sub_add_connection_to_group_request( + hub=hub, + group=group, + connection_id=connection_id, + api_version=api_version, + template_url=self.add_connection_to_group.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 404]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + add_connection_to_group.metadata = {'url': '/api/hubs/{hub}/groups/{group}/connections/{connectionId}'} # type: ignore + + + @distributed_trace + def remove_connection_from_group( + self, + hub, # type: str + group, # type: str + connection_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + """Remove a connection from the target group. + + Remove a connection from the target group. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param group: Target group name, which length should be greater than 0 and less than 1025. + :type group: str + :param connection_id: Target connection Id. + :type connection_id: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + + request = build_web_pub_sub_remove_connection_from_group_request( + hub=hub, + group=group, + connection_id=connection_id, + api_version=api_version, + template_url=self.remove_connection_from_group.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + remove_connection_from_group.metadata = {'url': '/api/hubs/{hub}/groups/{group}/connections/{connectionId}'} # type: ignore + + + @distributed_trace + def user_exists( + self, + hub, # type: str + user_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + """Check if there are any client connections connected for the given user. + + Check if there are any client connections connected for the given user. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param user_id: Target user Id. + :type user_id: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + + request = build_web_pub_sub_user_exists_request( + hub=hub, + user_id=user_id, + api_version=api_version, + template_url=self.user_exists.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 404]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + user_exists.metadata = {'url': '/api/hubs/{hub}/users/{userId}'} # type: ignore + + + @distributed_trace + def send_to_user( + self, + hub, # type: str + user_id, # type: str + message, # type: Union[IO, str] + **kwargs # type: Any + ): + # type: (...) -> None + """Send content inside request body to the specific user. + + Send content inside request body to the specific user. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param user_id: The user Id. + :type user_id: str + :param message: The payload body. + :type message: IO or str + :keyword api_version: Api Version. + :paramtype api_version: str + :keyword str content_type: Media type of the body sent to the API. Default value is + "application/json". Allowed values are: "application/json", "application/octet-stream", + "text/plain." + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + content_type = kwargs.pop('content_type', "text/plain") # type: Optional[str] + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + json = None + content = None + if content_type.split(";")[0] in ['application/json', 'application/octet-stream']: + content = message + elif content_type.split(";")[0] in ['text/plain']: + json = message + else: + raise ValueError( + "The content_type '{}' is not one of the allowed values: " + "['application/json', 'application/octet-stream', 'text/plain']".format(content_type) + ) + + request = build_web_pub_sub_send_to_user_request( + hub=hub, + user_id=user_id, + content_type=content_type, + api_version=api_version, + json=json, + content=content, + template_url=self.send_to_user.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + send_to_user.metadata = {'url': '/api/hubs/{hub}/users/{userId}/:send'} # type: ignore + + + @distributed_trace + def add_user_to_group( + self, + hub, # type: str + group, # type: str + user_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + """Add a user to the target group. + + Add a user to the target group. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param group: Target group name, which length should be greater than 0 and less than 1025. + :type group: str + :param user_id: Target user Id. + :type user_id: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + + request = build_web_pub_sub_add_user_to_group_request( + hub=hub, + group=group, + user_id=user_id, + api_version=api_version, + template_url=self.add_user_to_group.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 404]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + add_user_to_group.metadata = {'url': '/api/hubs/{hub}/users/{userId}/groups/{group}'} # type: ignore + + + @distributed_trace + def remove_user_from_group( + self, + hub, # type: str + group, # type: str + user_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + """Remove a user from the target group. + + Remove a user from the target group. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param group: Target group name, which length should be greater than 0 and less than 1025. + :type group: str + :param user_id: Target user Id. + :type user_id: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + + request = build_web_pub_sub_remove_user_from_group_request( + hub=hub, + group=group, + user_id=user_id, + api_version=api_version, + template_url=self.remove_user_from_group.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + remove_user_from_group.metadata = {'url': '/api/hubs/{hub}/users/{userId}/groups/{group}'} # type: ignore + + + @distributed_trace + def remove_user_from_all_groups( + self, + hub, # type: str + user_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + """Remove a user from all groups. + + Remove a user from all groups. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param user_id: Target user Id. + :type user_id: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + + request = build_web_pub_sub_remove_user_from_all_groups_request( + hub=hub, + user_id=user_id, + api_version=api_version, + template_url=self.remove_user_from_all_groups.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + remove_user_from_all_groups.metadata = {'url': '/api/hubs/{hub}/users/{userId}/groups'} # type: ignore + + + @distributed_trace + def grant_permission( + self, + hub, # type: str + permission, # type: str + connection_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + """Grant permission to the connection. + + Grant permission to the connection. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param permission: The permission: current supported actions are joinLeaveGroup and + sendToGroup. Possible values are: "sendToGroup" or "joinLeaveGroup". + :type permission: str + :param connection_id: Target connection Id. + :type connection_id: str + :keyword target_name: The meaning of the target depends on the specific permission. For + joinLeaveGroup and sendToGroup, targetName is a required parameter standing for the group name. + :paramtype target_name: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + target_name = kwargs.pop('target_name', None) # type: Optional[str] + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + + request = build_web_pub_sub_grant_permission_request( + hub=hub, + permission=permission, + connection_id=connection_id, + target_name=target_name, + api_version=api_version, + template_url=self.grant_permission.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + grant_permission.metadata = {'url': '/api/hubs/{hub}/permissions/{permission}/connections/{connectionId}'} # type: ignore + + + @distributed_trace + def revoke_permission( + self, + hub, # type: str + permission, # type: str + connection_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + """Revoke permission for the connection. + + Revoke permission for the connection. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param permission: The permission: current supported actions are joinLeaveGroup and + sendToGroup. Possible values are: "sendToGroup" or "joinLeaveGroup". + :type permission: str + :param connection_id: Target connection Id. + :type connection_id: str + :keyword target_name: The meaning of the target depends on the specific permission. For + joinLeaveGroup and sendToGroup, targetName is a required parameter standing for the group name. + :paramtype target_name: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + target_name = kwargs.pop('target_name', None) # type: Optional[str] + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + + request = build_web_pub_sub_revoke_permission_request( + hub=hub, + permission=permission, + connection_id=connection_id, + target_name=target_name, + api_version=api_version, + template_url=self.revoke_permission.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + revoke_permission.metadata = {'url': '/api/hubs/{hub}/permissions/{permission}/connections/{connectionId}'} # type: ignore + + + @distributed_trace + def check_permission( + self, + hub, # type: str + permission, # type: str + connection_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + """Check if a connection has permission to the specified action. + + Check if a connection has permission to the specified action. + + :param hub: Target hub name, which should start with alphabetic characters and only contain + alpha-numeric characters or underscore. + :type hub: str + :param permission: The permission: current supported actions are joinLeaveGroup and + sendToGroup. Possible values are: "sendToGroup" or "joinLeaveGroup". + :type permission: str + :param connection_id: Target connection Id. + :type connection_id: str + :keyword target_name: The meaning of the target depends on the specific permission. For + joinLeaveGroup and sendToGroup, targetName is a required parameter standing for the group name. + :paramtype target_name: str + :keyword api_version: Api Version. + :paramtype api_version: str + :return: None + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + target_name = kwargs.pop('target_name', None) # type: Optional[str] + api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] + + + request = build_web_pub_sub_check_permission_request( + hub=hub, + permission=permission, + connection_id=connection_id, + target_name=target_name, + api_version=api_version, + template_url=self.check_permission.metadata['url'], + ) + request.url = self._client.format_url(request.url) + + pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 404]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + check_permission.metadata = {'url': '/api/hubs/{hub}/permissions/{permission}/connections/{connectionId}'} # type: ignore + diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/py.typed b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/py.typed new file mode 100644 index 000000000000..e5aff4f83af8 --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/py.typed @@ -0,0 +1 @@ +# Marker file for PEP 561. \ No newline at end of file diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/rest.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/rest.py deleted file mode 100644 index 9d57abd5a1c0..000000000000 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/rest.py +++ /dev/null @@ -1,942 +0,0 @@ -# coding=utf-8 -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. -# Changes may cause incorrect behavior and will be lost if the code is regenerated. -# -------------------------------------------------------------------------- - -# pylint: disable=line-too-long - -__all__ = [ - 'build_add_connection_to_group_request', - 'build_add_user_to_group_request', - 'build_connection_exists_request', - 'build_group_exists_request', - 'build_check_permission_request', - 'build_user_exists_request', - 'build_close_client_connection_request', - 'build_grant_permission_request', - 'build_healthapi_get_health_status_request', - 'build_remove_connection_from_group_request', - 'build_remove_user_from_all_groups_request', - 'build_remove_user_from_group_request', - 'build_revoke_permission_request', - 'build_send_to_all_request', - 'build_send_to_connection_request', - 'build_send_to_group_request', - 'build_send_to_user_request' -] -from typing import TYPE_CHECKING -from msrest import Serializer -from azure.core.pipeline.transport._base import _format_url_section -from azure.messaging.webpubsubservice.core.rest import HttpRequest - -if TYPE_CHECKING: - # pylint: disable=unused-import,ungrouped-imports - from typing import Any, IO, List, Optional, Union, Dict - from typing_extensions import Literal - Permissions = Union[Literal['joinLeaveGroup'], Literal['sendToGroup']] # pylint: disable=unsubscriptable-object - -_SERIALIZER = Serializer() - - -def build_healthapi_get_health_status_request( - **kwargs # type: Any -): - # type: (...) -> HttpRequest - """Get service health status. - - Get service health status. - - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this request builder into your code flow. - - :keyword api_version: Api Version. - :paramtype api_version: str - :return: Returns an :class:`~azure.messaging.webpubsubservice.core.rest.HttpRequest` that you will pass to the client's `send_request` method. - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this response into your code flow. - :rtype: ~azure.messaging.webpubsubservice.core.rest.HttpRequest - """ - api_version = kwargs.pop('api_version', "2021-05-01-preview") # type: Optional[str] - - # Construct URL - url = kwargs.pop("template_url", '/api/health') - - # Construct parameters - query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] - if api_version is not None: - query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') - - return HttpRequest( - method="HEAD", - url=url, - params=query_parameters, - **kwargs - ) - - -def build_send_to_all_request( - hub, # type: str - **kwargs # type: Any -): - # type: (...) -> HttpRequest - """Broadcast content inside request body to all the connected client connections. - - Broadcast content inside request body to all the connected client connections. - - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this request builder into your code flow. - - :param hub: Target hub name, which should start with alphabetic characters and only contain - alpha-numeric characters or underscore. - :type hub: str - :keyword json: The payload body. - :paramtype json: Any - :keyword content: The payload body. - :paramtype content: IO - :keyword excluded: Excluded connection Ids. - :paramtype excluded: list[str] - :keyword api_version: Api Version. - :paramtype api_version: str - :return: Returns an :class:`~azure.messaging.webpubsubservice.core.rest.HttpRequest` that you will pass to the client's `send_request` method. - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this response into your code flow. - :rtype: ~azure.messaging.webpubsubservice.core.rest.HttpRequest - - Example: - .. code-block:: python - - # JSON input template you can fill out and use as your `json` input. - json = "Any (optional)" - """ - excluded = kwargs.pop('excluded', None) # type: Optional[List[str]] - api_version = kwargs.pop('api_version', "2021-05-01-preview") # type: Optional[str] - content_type = kwargs.pop("content_type", None) - - # Construct URL - url = kwargs.pop("template_url", '/api/hubs/{hub}/:send') - path_format_arguments = { - 'hub': _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), - } - url = _format_url_section(url, **path_format_arguments) - - # Construct parameters - query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] - if excluded is not None: - query_parameters['excluded'] = [_SERIALIZER.query("excluded", q, 'str') if q is not None else '' for q in excluded] - if api_version is not None: - query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') - - # Construct headers - header_parameters = kwargs.pop("headers", {}) # type: Dict[str, Any] - if content_type is not None: - header_parameters['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str') - - return HttpRequest( - method="POST", - url=url, - params=query_parameters, - headers=header_parameters, - **kwargs - ) - - -def build_connection_exists_request( - hub, # type: str - connection_id, # type: str - **kwargs # type: Any -): - # type: (...) -> HttpRequest - """Check if the connection with the given connectionId exists. - - Check if the connection with the given connectionId exists. - - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this request builder into your code flow. - - :param hub: Target hub name, which should start with alphabetic characters and only contain - alpha-numeric characters or underscore. - :type hub: str - :param connection_id: The connection Id. - :type connection_id: str - :keyword api_version: Api Version. - :paramtype api_version: str - :return: Returns an :class:`~azure.messaging.webpubsubservice.core.rest.HttpRequest` that you will pass to the client's `send_request` method. - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this response into your code flow. - :rtype: ~azure.messaging.webpubsubservice.core.rest.HttpRequest - """ - api_version = kwargs.pop('api_version', "2021-05-01-preview") # type: Optional[str] - - # Construct URL - url = kwargs.pop("template_url", '/api/hubs/{hub}/connections/{connectionId}') - path_format_arguments = { - 'hub': _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), - 'connectionId': _SERIALIZER.url("connection_id", connection_id, 'str', min_length=1), - } - url = _format_url_section(url, **path_format_arguments) - - # Construct parameters - query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] - if api_version is not None: - query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') - - return HttpRequest( - method="HEAD", - url=url, - params=query_parameters, - **kwargs - ) - - -def build_close_client_connection_request( - hub, # type: str - connection_id, # type: str - **kwargs # type: Any -): - # type: (...) -> HttpRequest - """Close the client connection. - - Close the client connection. - - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this request builder into your code flow. - - :param hub: Target hub name, which should start with alphabetic characters and only contain - alpha-numeric characters or underscore. - :type hub: str - :param connection_id: Target connection Id. - :type connection_id: str - :keyword reason: The reason closing the client connection. - :paramtype reason: str - :keyword api_version: Api Version. - :paramtype api_version: str - :return: Returns an :class:`~azure.messaging.webpubsubservice.core.rest.HttpRequest` that you will pass to the client's `send_request` method. - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this response into your code flow. - :rtype: ~azure.messaging.webpubsubservice.core.rest.HttpRequest - """ - reason = kwargs.pop('reason', None) # type: Optional[str] - api_version = kwargs.pop('api_version', "2021-05-01-preview") # type: Optional[str] - - # Construct URL - url = kwargs.pop("template_url", '/api/hubs/{hub}/connections/{connectionId}') - path_format_arguments = { - 'hub': _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), - 'connectionId': _SERIALIZER.url("connection_id", connection_id, 'str', min_length=1), - } - url = _format_url_section(url, **path_format_arguments) - - # Construct parameters - query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] - if reason is not None: - query_parameters['reason'] = _SERIALIZER.query("reason", reason, 'str') - if api_version is not None: - query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') - - return HttpRequest( - method="DELETE", - url=url, - params=query_parameters, - **kwargs - ) - - -def build_send_to_connection_request( - hub, # type: str - connection_id, # type: str - **kwargs # type: Any -): - # type: (...) -> HttpRequest - """Send content inside request body to the specific connection. - - Send content inside request body to the specific connection. - - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this request builder into your code flow. - - :param hub: Target hub name, which should start with alphabetic characters and only contain - alpha-numeric characters or underscore. - :type hub: str - :param connection_id: The connection Id. - :type connection_id: str - :keyword json: The payload body. - :paramtype json: Any - :keyword content: The payload body. - :paramtype content: IO - :keyword api_version: Api Version. - :paramtype api_version: str - :return: Returns an :class:`~azure.messaging.webpubsubservice.core.rest.HttpRequest` that you will pass to the client's `send_request` method. - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this response into your code flow. - :rtype: ~azure.messaging.webpubsubservice.core.rest.HttpRequest - - Example: - .. code-block:: python - - # JSON input template you can fill out and use as your `json` input. - json = "Any (optional)" - """ - api_version = kwargs.pop('api_version', "2021-05-01-preview") # type: Optional[str] - content_type = kwargs.pop("content_type", None) - - # Construct URL - url = kwargs.pop("template_url", '/api/hubs/{hub}/connections/{connectionId}/:send') - path_format_arguments = { - 'hub': _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), - 'connectionId': _SERIALIZER.url("connection_id", connection_id, 'str', min_length=1), - } - url = _format_url_section(url, **path_format_arguments) - - # Construct parameters - query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] - if api_version is not None: - query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') - - # Construct headers - header_parameters = kwargs.pop("headers", {}) # type: Dict[str, Any] - if content_type is not None: - header_parameters['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str') - - return HttpRequest( - method="POST", - url=url, - params=query_parameters, - headers=header_parameters, - **kwargs - ) - - -def build_group_exists_request( - hub, # type: str - group, # type: str - **kwargs # type: Any -): - # type: (...) -> HttpRequest - """Check if there are any client connections inside the given group. - - Check if there are any client connections inside the given group. - - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this request builder into your code flow. - - :param hub: Target hub name, which should start with alphabetic characters and only contain - alpha-numeric characters or underscore. - :type hub: str - :param group: Target group name, which length should be greater than 0 and less than 1025. - :type group: str - :keyword api_version: Api Version. - :paramtype api_version: str - :return: Returns an :class:`~azure.messaging.webpubsubservice.core.rest.HttpRequest` that you will pass to the client's `send_request` method. - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this response into your code flow. - :rtype: ~azure.messaging.webpubsubservice.core.rest.HttpRequest - """ - api_version = kwargs.pop('api_version', "2021-05-01-preview") # type: Optional[str] - - # Construct URL - url = kwargs.pop("template_url", '/api/hubs/{hub}/groups/{group}') - path_format_arguments = { - 'hub': _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), - 'group': _SERIALIZER.url("group", group, 'str', max_length=1024, min_length=1), - } - url = _format_url_section(url, **path_format_arguments) - - # Construct parameters - query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] - if api_version is not None: - query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') - - return HttpRequest( - method="HEAD", - url=url, - params=query_parameters, - **kwargs - ) - - -def build_send_to_group_request( - hub, # type: str - group, # type: str - **kwargs # type: Any -): - # type: (...) -> HttpRequest - """Send content inside request body to a group of connections. - - Send content inside request body to a group of connections. - - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this request builder into your code flow. - - :param hub: Target hub name, which should start with alphabetic characters and only contain - alpha-numeric characters or underscore. - :type hub: str - :param group: Target group name, which length should be greater than 0 and less than 1025. - :type group: str - :keyword json: The payload body. - :paramtype json: Any - :keyword content: The payload body. - :paramtype content: IO - :keyword excluded: Excluded connection Ids. - :paramtype excluded: list[str] - :keyword api_version: Api Version. - :paramtype api_version: str - :return: Returns an :class:`~azure.messaging.webpubsubservice.core.rest.HttpRequest` that you will pass to the client's `send_request` method. - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this response into your code flow. - :rtype: ~azure.messaging.webpubsubservice.core.rest.HttpRequest - - Example: - .. code-block:: python - - # JSON input template you can fill out and use as your `json` input. - json = "Any (optional)" - """ - excluded = kwargs.pop('excluded', None) # type: Optional[List[str]] - api_version = kwargs.pop('api_version', "2021-05-01-preview") # type: Optional[str] - content_type = kwargs.pop("content_type", None) - - # Construct URL - url = kwargs.pop("template_url", '/api/hubs/{hub}/groups/{group}/:send') - path_format_arguments = { - 'hub': _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), - 'group': _SERIALIZER.url("group", group, 'str', max_length=1024, min_length=1), - } - url = _format_url_section(url, **path_format_arguments) - - # Construct parameters - query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] - if excluded is not None: - query_parameters['excluded'] = [_SERIALIZER.query("excluded", q, 'str') if q is not None else '' for q in excluded] - if api_version is not None: - query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') - - # Construct headers - header_parameters = kwargs.pop("headers", {}) # type: Dict[str, Any] - if content_type is not None: - header_parameters['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str') - - return HttpRequest( - method="POST", - url=url, - params=query_parameters, - headers=header_parameters, - **kwargs - ) - - -def build_add_connection_to_group_request( - hub, # type: str - group, # type: str - connection_id, # type: str - **kwargs # type: Any -): - # type: (...) -> HttpRequest - """Add a connection to the target group. - - Add a connection to the target group. - - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this request builder into your code flow. - - :param hub: Target hub name, which should start with alphabetic characters and only contain - alpha-numeric characters or underscore. - :type hub: str - :param group: Target group name, which length should be greater than 0 and less than 1025. - :type group: str - :param connection_id: Target connection Id. - :type connection_id: str - :keyword api_version: Api Version. - :paramtype api_version: str - :return: Returns an :class:`~azure.messaging.webpubsubservice.core.rest.HttpRequest` that you will pass to the client's `send_request` method. - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this response into your code flow. - :rtype: ~azure.messaging.webpubsubservice.core.rest.HttpRequest - """ - api_version = kwargs.pop('api_version', "2021-05-01-preview") # type: Optional[str] - - # Construct URL - url = kwargs.pop("template_url", '/api/hubs/{hub}/groups/{group}/connections/{connectionId}') - path_format_arguments = { - 'hub': _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), - 'group': _SERIALIZER.url("group", group, 'str', max_length=1024, min_length=1), - 'connectionId': _SERIALIZER.url("connection_id", connection_id, 'str', min_length=1), - } - url = _format_url_section(url, **path_format_arguments) - - # Construct parameters - query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] - if api_version is not None: - query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') - - return HttpRequest( - method="PUT", - url=url, - params=query_parameters, - **kwargs - ) - - -def build_remove_connection_from_group_request( - hub, # type: str - group, # type: str - connection_id, # type: str - **kwargs # type: Any -): - # type: (...) -> HttpRequest - """Remove a connection from the target group. - - Remove a connection from the target group. - - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this request builder into your code flow. - - :param hub: Target hub name, which should start with alphabetic characters and only contain - alpha-numeric characters or underscore. - :type hub: str - :param group: Target group name, which length should be greater than 0 and less than 1025. - :type group: str - :param connection_id: Target connection Id. - :type connection_id: str - :keyword api_version: Api Version. - :paramtype api_version: str - :return: Returns an :class:`~azure.messaging.webpubsubservice.core.rest.HttpRequest` that you will pass to the client's `send_request` method. - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this response into your code flow. - :rtype: ~azure.messaging.webpubsubservice.core.rest.HttpRequest - """ - api_version = kwargs.pop('api_version', "2021-05-01-preview") # type: Optional[str] - - # Construct URL - url = kwargs.pop("template_url", '/api/hubs/{hub}/groups/{group}/connections/{connectionId}') - path_format_arguments = { - 'hub': _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), - 'group': _SERIALIZER.url("group", group, 'str', max_length=1024, min_length=1), - 'connectionId': _SERIALIZER.url("connection_id", connection_id, 'str', min_length=1), - } - url = _format_url_section(url, **path_format_arguments) - - # Construct parameters - query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] - if api_version is not None: - query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') - - return HttpRequest( - method="DELETE", - url=url, - params=query_parameters, - **kwargs - ) - - -def build_user_exists_request( - hub, # type: str - user_id, # type: str - **kwargs # type: Any -): - # type: (...) -> HttpRequest - """Check if there are any client connections connected for the given user. - - Check if there are any client connections connected for the given user. - - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this request builder into your code flow. - - :param hub: Target hub name, which should start with alphabetic characters and only contain - alpha-numeric characters or underscore. - :type hub: str - :param user_id: Target user Id. - :type user_id: str - :keyword api_version: Api Version. - :paramtype api_version: str - :return: Returns an :class:`~azure.messaging.webpubsubservice.core.rest.HttpRequest` that you will pass to the client's `send_request` method. - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this response into your code flow. - :rtype: ~azure.messaging.webpubsubservice.core.rest.HttpRequest - """ - api_version = kwargs.pop('api_version', "2021-05-01-preview") # type: Optional[str] - - # Construct URL - url = kwargs.pop("template_url", '/api/hubs/{hub}/users/{userId}') - path_format_arguments = { - 'hub': _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), - 'userId': _SERIALIZER.url("user_id", user_id, 'str', min_length=1), - } - url = _format_url_section(url, **path_format_arguments) - - # Construct parameters - query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] - if api_version is not None: - query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') - - return HttpRequest( - method="HEAD", - url=url, - params=query_parameters, - **kwargs - ) - - -def build_send_to_user_request( - hub, # type: str - user_id, # type: str - **kwargs # type: Any -): - # type: (...) -> HttpRequest - """Send content inside request body to the specific user. - - Send content inside request body to the specific user. - - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this request builder into your code flow. - - :param hub: Target hub name, which should start with alphabetic characters and only contain - alpha-numeric characters or underscore. - :type hub: str - :param user_id: The user Id. - :type user_id: str - :keyword json: The payload body. - :paramtype json: Any - :keyword content: The payload body. - :paramtype content: IO - :keyword api_version: Api Version. - :paramtype api_version: str - :return: Returns an :class:`~azure.messaging.webpubsubservice.core.rest.HttpRequest` that you will pass to the client's `send_request` method. - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this response into your code flow. - :rtype: ~azure.messaging.webpubsubservice.core.rest.HttpRequest - - Example: - .. code-block:: python - - # JSON input template you can fill out and use as your `json` input. - json = "Any (optional)" - """ - api_version = kwargs.pop('api_version', "2021-05-01-preview") # type: Optional[str] - content_type = kwargs.pop("content_type", None) - - # Construct URL - url = kwargs.pop("template_url", '/api/hubs/{hub}/users/{userId}/:send') - path_format_arguments = { - 'hub': _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), - 'userId': _SERIALIZER.url("user_id", user_id, 'str', min_length=1), - } - url = _format_url_section(url, **path_format_arguments) - - # Construct parameters - query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] - if api_version is not None: - query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') - - # Construct headers - header_parameters = kwargs.pop("headers", {}) # type: Dict[str, Any] - if content_type is not None: - header_parameters['Content-Type'] = _SERIALIZER.header("content_type", content_type, 'str') - - return HttpRequest( - method="POST", - url=url, - params=query_parameters, - headers=header_parameters, - **kwargs - ) - - -def build_add_user_to_group_request( - hub, # type: str - group, # type: str - user_id, # type: str - **kwargs # type: Any -): - # type: (...) -> HttpRequest - """Add a user to the target group. - - Add a user to the target group. - - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this request builder into your code flow. - - :param hub: Target hub name, which should start with alphabetic characters and only contain - alpha-numeric characters or underscore. - :type hub: str - :param group: Target group name, which length should be greater than 0 and less than 1025. - :type group: str - :param user_id: Target user Id. - :type user_id: str - :keyword api_version: Api Version. - :paramtype api_version: str - :return: Returns an :class:`~azure.messaging.webpubsubservice.core.rest.HttpRequest` that you will pass to the client's `send_request` method. - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this response into your code flow. - :rtype: ~azure.messaging.webpubsubservice.core.rest.HttpRequest - """ - api_version = kwargs.pop('api_version', "2021-05-01-preview") # type: Optional[str] - - # Construct URL - url = kwargs.pop("template_url", '/api/hubs/{hub}/users/{userId}/groups/{group}') - path_format_arguments = { - 'hub': _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), - 'group': _SERIALIZER.url("group", group, 'str', max_length=1024, min_length=1), - 'userId': _SERIALIZER.url("user_id", user_id, 'str', min_length=1), - } - url = _format_url_section(url, **path_format_arguments) - - # Construct parameters - query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] - if api_version is not None: - query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') - - return HttpRequest( - method="PUT", - url=url, - params=query_parameters, - **kwargs - ) - - -def build_remove_user_from_group_request( - hub, # type: str - group, # type: str - user_id, # type: str - **kwargs # type: Any -): - # type: (...) -> HttpRequest - """Remove a user from the target group. - - Remove a user from the target group. - - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this request builder into your code flow. - - :param hub: Target hub name, which should start with alphabetic characters and only contain - alpha-numeric characters or underscore. - :type hub: str - :param group: Target group name, which length should be greater than 0 and less than 1025. - :type group: str - :param user_id: Target user Id. - :type user_id: str - :keyword api_version: Api Version. - :paramtype api_version: str - :return: Returns an :class:`~azure.messaging.webpubsubservice.core.rest.HttpRequest` that you will pass to the client's `send_request` method. - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this response into your code flow. - :rtype: ~azure.messaging.webpubsubservice.core.rest.HttpRequest - """ - api_version = kwargs.pop('api_version', "2021-05-01-preview") # type: Optional[str] - - # Construct URL - url = kwargs.pop("template_url", '/api/hubs/{hub}/users/{userId}/groups/{group}') - path_format_arguments = { - 'hub': _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), - 'group': _SERIALIZER.url("group", group, 'str', max_length=1024, min_length=1), - 'userId': _SERIALIZER.url("user_id", user_id, 'str', min_length=1), - } - url = _format_url_section(url, **path_format_arguments) - - # Construct parameters - query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] - if api_version is not None: - query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') - - return HttpRequest( - method="DELETE", - url=url, - params=query_parameters, - **kwargs - ) - - -def build_remove_user_from_all_groups_request( - hub, # type: str - user_id, # type: str - **kwargs # type: Any -): - # type: (...) -> HttpRequest - """Remove a user from all groups. - - Remove a user from all groups. - - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this request builder into your code flow. - - :param hub: Target hub name, which should start with alphabetic characters and only contain - alpha-numeric characters or underscore. - :type hub: str - :param user_id: Target user Id. - :type user_id: str - :keyword api_version: Api Version. - :paramtype api_version: str - :return: Returns an :class:`~azure.messaging.webpubsubservice.core.rest.HttpRequest` that you will pass to the client's `send_request` method. - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this response into your code flow. - :rtype: ~azure.messaging.webpubsubservice.core.rest.HttpRequest - """ - api_version = kwargs.pop('api_version', "2021-05-01-preview") # type: Optional[str] - - # Construct URL - url = kwargs.pop("template_url", '/api/hubs/{hub}/users/{userId}/groups') - path_format_arguments = { - 'hub': _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), - 'userId': _SERIALIZER.url("user_id", user_id, 'str', min_length=1), - } - url = _format_url_section(url, **path_format_arguments) - - # Construct parameters - query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] - if api_version is not None: - query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') - - return HttpRequest( - method="DELETE", - url=url, - params=query_parameters, - **kwargs - ) - - -def build_grant_permission_request( - hub, # type: str - permission, # type: Permissions - connection_id, # type: str - **kwargs # type: Any -): - # type: (...) -> HttpRequest - """Grant permission to the connection. - - Grant permission to the connection. - - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this request builder into your code flow. - - :param hub: Target hub name, which should start with alphabetic characters and only contain - alpha-numeric characters or underscore. - :type hub: str - :param permission: The permission: current supported actions are joinLeaveGroup and - sendToGroup. - :type permission: str or ~Permissions - :param connection_id: Target connection Id. - :type connection_id: str - :keyword target_name: Optional. If not set, grant the permission to all the targets. If set, - grant the permission to the specific target. The meaning of the target depends on the specific - permission. - :paramtype target_name: str - :keyword api_version: Api Version. - :paramtype api_version: str - :return: Returns an :class:`~azure.messaging.webpubsubservice.core.rest.HttpRequest` that you will pass to the client's `send_request` method. - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this response into your code flow. - :rtype: ~azure.messaging.webpubsubservice.core.rest.HttpRequest - """ - target_name = kwargs.pop('target_name', None) # type: Optional[str] - api_version = kwargs.pop('api_version', "2021-05-01-preview") # type: Optional[str] - - # Construct URL - url = kwargs.pop("template_url", '/api/hubs/{hub}/permissions/{permission}/connections/{connectionId}') - path_format_arguments = { - 'hub': _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), - 'permission': _SERIALIZER.url("permission", permission, 'str'), - 'connectionId': _SERIALIZER.url("connection_id", connection_id, 'str', min_length=1), - } - url = _format_url_section(url, **path_format_arguments) - - # Construct parameters - query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] - if target_name is not None: - query_parameters['targetName'] = _SERIALIZER.query("target_name", target_name, 'str') - if api_version is not None: - query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') - - return HttpRequest( - method="PUT", - url=url, - params=query_parameters, - **kwargs - ) - - -def build_revoke_permission_request( - hub, # type: str - permission, # type: Permissions - connection_id, # type: str - **kwargs # type: Any -): - # type: (...) -> HttpRequest - """Revoke permission for the connection. - - Revoke permission for the connection. - - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this request builder into your code flow. - - :param hub: Target hub name, which should start with alphabetic characters and only contain - alpha-numeric characters or underscore. - :type hub: str - :param permission: The permission: current supported actions are joinLeaveGroup and - sendToGroup. - :type permission: str or ~Permissions - :param connection_id: Target connection Id. - :type connection_id: str - :keyword target_name: Optional. If not set, revoke the permission for all targets. If set, - revoke the permission for the specific target. The meaning of the target depends on the - specific permission. - :paramtype target_name: str - :keyword api_version: Api Version. - :paramtype api_version: str - :return: Returns an :class:`~azure.messaging.webpubsubservice.core.rest.HttpRequest` that you will pass to the client's `send_request` method. - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this response into your code flow. - :rtype: ~azure.messaging.webpubsubservice.core.rest.HttpRequest - """ - target_name = kwargs.pop('target_name', None) # type: Optional[str] - api_version = kwargs.pop('api_version', "2021-05-01-preview") # type: Optional[str] - - # Construct URL - url = kwargs.pop("template_url", '/api/hubs/{hub}/permissions/{permission}/connections/{connectionId}') - path_format_arguments = { - 'hub': _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), - 'permission': _SERIALIZER.url("permission", permission, 'str'), - 'connectionId': _SERIALIZER.url("connection_id", connection_id, 'str', min_length=1), - } - url = _format_url_section(url, **path_format_arguments) - - # Construct parameters - query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] - if target_name is not None: - query_parameters['targetName'] = _SERIALIZER.query("target_name", target_name, 'str') - if api_version is not None: - query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') - - return HttpRequest( - method="DELETE", - url=url, - params=query_parameters, - **kwargs - ) - - -def build_check_permission_request( - hub, # type: str - permission, # type: Permissions - connection_id, # type: str - **kwargs # type: Any -): - # type: (...) -> HttpRequest - """Check if a connection has permission to the specified action. - - Check if a connection has permission to the specified action. - - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this request builder into your code flow. - - :param hub: Target hub name, which should start with alphabetic characters and only contain - alpha-numeric characters or underscore. - :type hub: str - :param permission: The permission: current supported actions are joinLeaveGroup and - sendToGroup. - :type permission: ~Permissions - :param connection_id: Target connection Id. - :type connection_id: str - :keyword target_name: Optional. If not set, get the permission for all targets. If set, get the - permission for the specific target. The meaning of the target depends on the specific - permission. - :paramtype target_name: str - :keyword api_version: Api Version. - :paramtype api_version: str - :return: Returns an :class:`~azure.messaging.webpubsubservice.core.rest.HttpRequest` that you will pass to the client's `send_request` method. - See https://aka.ms/azsdk/python/llcwiki for how to incorporate this response into your code flow. - :rtype: ~azure.messaging.webpubsubservice.core.rest.HttpRequest - """ - target_name = kwargs.pop('target_name', None) # type: Optional[str] - api_version = kwargs.pop('api_version', "2021-05-01-preview") # type: Optional[str] - - # Construct URL - url = kwargs.pop("template_url", '/api/hubs/{hub}/permissions/{permission}/connections/{connectionId}') - path_format_arguments = { - 'hub': _SERIALIZER.url("hub", hub, 'str', pattern=r'^[A-Za-z][A-Za-z0-9_`,.[\]]{0,127}$'), - 'permission': _SERIALIZER.url("permission", permission, 'str'), - 'connectionId': _SERIALIZER.url("connection_id", connection_id, 'str', min_length=1), - } - url = _format_url_section(url, **path_format_arguments) - - # Construct parameters - query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] - if target_name is not None: - query_parameters['targetName'] = _SERIALIZER.query("target_name", target_name, 'str') - if api_version is not None: - query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') - - return HttpRequest( - method="HEAD", - url=url, - params=query_parameters, - **kwargs - ) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/swagger/README.md b/sdk/webpubsub/azure-messaging-webpubsubservice/swagger/README.md new file mode 100644 index 000000000000..d078399e609c --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/swagger/README.md @@ -0,0 +1,35 @@ +# Azure Purview for Python + +> see https://aka.ms/autorest + +### Setup + +Install Autorest v3 + +```ps +npm install -g autorest +``` + +### Generation + +```ps +cd +autorest +``` + +### Settings + +```yaml +input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/webpubsub/data-plane/WebPubSub/preview/2021-08-01-preview/webpubsub.json +output-folder: ../azure/messaging/webpubsubservice +namespace: azure.messaging.webpubsubservice +package-name: azure-messaging-webpubsubservice +license-header: MICROSOFT_MIT_NO_VERSION +clear-output-folder: true +no-namespace-folders: true +python: true +title: WebpubsubServiceClient +version-tolerant: true +package-version: 1.0.0b1 +add-credential: true +``` From a4d3d152767512dcceb34a876c5081c8127d7ef7 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Mon, 6 Sep 2021 16:55:29 +0800 Subject: [PATCH 02/33] update test --- .../CHANGELOG.md | 4 +- .../README.md | 72 +++++++++++++------ .../messaging/webpubsubservice/__init__.py | 4 +- .../webpubsubservice/_configuration.py | 10 ++- ...ient.py => _web_pub_sub_service_client.py} | 10 +-- .../webpubsubservice/aio/__init__.py | 4 +- .../webpubsubservice/aio/_configuration.py | 10 ++- ...ient.py => _web_pub_sub_service_client.py} | 10 +-- .../azure-messaging-webpubsubservice/setup.py | 6 +- .../swagger/README.md | 3 +- .../tests/conftest.py | 15 ++++ .../test_smoke.test_health_api_status.yaml | 28 ++++++++ ...test_smoke.test_webpubsub_send_to_all.yaml | 34 +++++++++ .../tests/test_smoke.py | 20 ++++++ .../tests/testcase.py | 29 ++++++++ 15 files changed, 205 insertions(+), 54 deletions(-) rename sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/{_webpubsub_service_client.py => _web_pub_sub_service_client.py} (93%) rename sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/{_webpubsub_service_client.py => _web_pub_sub_service_client.py} (93%) create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/tests/conftest.py create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase.py diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/CHANGELOG.md b/sdk/webpubsub/azure-messaging-webpubsubservice/CHANGELOG.md index 45abf33ffcf2..276a63f851cd 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/CHANGELOG.md +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/CHANGELOG.md @@ -2,8 +2,10 @@ ## 1.0.0b2 (Unreleased) +- Add operations to client +- Support AAD ## 1.0.0b1 (2021-04-27) -Initial version +- Initial version diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/README.md b/sdk/webpubsub/azure-messaging-webpubsubservice/README.md index 9135d4d09e22..91cef22aa22b 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/README.md +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/README.md @@ -43,14 +43,26 @@ python -m pip install azure-messaging-webpubsubservice ### Authenticating the client -In order to interact with the Azure WebPubSub service, you'll need to create an instance of the [WebPubSubServiceClient][webpubsubservice_client_class] class. In order to authenticate against the service, you need to pass in an AzureKeyCredential instance with endpoint and api key. The endpoint and api key can be found on the azure portal. +To use an [Azure Active Directory (AAD) token credential][authenticate_with_token], +provide an instance of the desired credential type obtained from the +[azure-identity][azure_identity_credentials] library. + +To authenticate with AAD, you must first [pip][pip] install [`azure-identity`][azure_identity_pip] and +[enable AAD authentication on your Purview resource][enable_aad] + +After setup, you can choose which type of [credential][azure_identity_credentials] from azure.identity to use. +As an example, [DefaultAzureCredential][default_azure_credential] +can be used to authenticate the client: + +Set the values of the client ID, tenant ID, and client secret of the AAD application as environment variables: +AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET + +Use the returned token credential to authenticate the client: ```python >>> from azure.messaging.webpubsubservice import WebPubSubServiceClient ->>> from azure.core.credentials import AzureKeyCredential ->>> client = WebPubSubServiceClient(endpoint='', credential=AzureKeyCredential('somesecret')) ->>> client -'> +>>> from azure.identity import DefaultAzureCredential +>>> client = WebPubSubServiceClient(endpoint='https://myname.webpubsub.azure.com', credential=DefaultAzureCredential()) ``` ## Examples @@ -59,22 +71,16 @@ In order to interact with the Azure WebPubSub service, you'll need to create an ```python >>> from azure.messaging.webpubsubservice import WebPubSubServiceClient ->>> from azure.core.credentials import AzureKeyCredential ->>> from azure.messaging.webpubsubservice.rest import build_send_to_all_request ->>> client = WebPubSubServiceClient(endpoint='', credential=AzureKeyCredential('somesecret')) ->>> request = build_send_to_all_request('default', json={ 'Hello': 'webpubsub!' }) ->>> request - ->>> response = client.send_request(request) ->>> response - ->>> response.status_code -202 +>>> from azure.identity import DefaultAzureCredential +>>> from azure.core.exceptions import HttpResponseError + +>>> client = WebPubSubServiceClient(endpoint='https://myname.webpubsub.azure.com', credential=DefaultAzureCredential()) >>> with open('file.json', 'r') as f: ->>> request = build_send_to_all_request('ahub', content=f, content_type='application/json') ->>> response = client.send_request(request) ->>> print(response) - + try: + client.web_pub_sub.send_to_all('ahub', content=f, content_type='application/json') + except HttpResponseError as e: + print('service responds error') + ``` ## Key concepts @@ -107,10 +113,32 @@ This SDK uses Python standard logging library. You can configure logging print out debugging information to the stdout or anywhere you want. ```python +import sys import logging +from azure.identity import DefaultAzureCredential +>>> from azure.messaging.webpubsubservice import WebPubSubServiceClient + +# Create a logger for the 'azure' SDK +logger = logging.getLogger('azure') +logger.setLevel(logging.DEBUG) -logging.basicConfig(level=logging.DEBUG) -```` +# Configure a console output +handler = logging.StreamHandler(stream=sys.stdout) +logger.addHandler(handler) + +endpoint = "https://myname.webpubsub.azure.com" +credential = DefaultAzureCredential() + +# This client will log detailed information about its HTTP sessions, at DEBUG level +client = WebPubSubServiceClient(endpoint=endpoint, credential=credential, logging_enable=True) +``` + +Similarly, `logging_enable` can enable detailed logging for a single call, +even when it isn't enabled for the client: + +```python +result = client.web_pub_sub.send_to_all(logging_enable=True) +``` Http request and response details are printed to stdout with this logging config. diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py index 0aeded867ad4..656cd0b03180 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py @@ -6,11 +6,11 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._webpubsub_service_client import WebpubsubServiceClient +from ._web_pub_sub_service_client import WebPubSubServiceClient from ._version import VERSION __version__ = VERSION -__all__ = ['WebpubsubServiceClient'] +__all__ = ['WebPubSubServiceClient'] try: from ._patch import patch_sdk # type: ignore diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py index a161e2652c52..c9073f30f623 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py @@ -20,8 +20,8 @@ from azure.core.credentials import TokenCredential -class WebpubsubServiceClientConfiguration(Configuration): - """Configuration for WebpubsubServiceClient. +class WebPubSubServiceClientConfiguration(Configuration): + """Configuration for WebPubSubServiceClient. Note that all parameters used to create this instance are saved as instance attributes. @@ -38,10 +38,10 @@ def __init__( # type: (...) -> None if credential is None: raise ValueError("Parameter 'credential' must not be None.") - super(WebpubsubServiceClientConfiguration, self).__init__(**kwargs) + super(WebPubSubServiceClientConfiguration, self).__init__(**kwargs) self.credential = credential - self.credential_scopes = kwargs.pop('credential_scopes', []) + self.credential_scopes = kwargs.pop('credential_scopes', ['https://webpubsub.azure.com/.default']) kwargs.setdefault('sdk_moniker', 'messaging-webpubsubservice/{}'.format(VERSION)) self._configure(**kwargs) @@ -59,7 +59,5 @@ def _configure( self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) self.redirect_policy = kwargs.get('redirect_policy') or policies.RedirectPolicy(**kwargs) self.authentication_policy = kwargs.get('authentication_policy') - if not self.credential_scopes and not self.authentication_policy: - raise ValueError("You must provide either credential_scopes or authentication_policy as kwargs") if self.credential and not self.authentication_policy: self.authentication_policy = policies.BearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_webpubsub_service_client.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py similarity index 93% rename from sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_webpubsub_service_client.py rename to sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py index e29dd7dd95ca..2b69eac16e8a 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_webpubsub_service_client.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py @@ -12,7 +12,7 @@ from azure.core import PipelineClient from msrest import Deserializer, Serializer -from ._configuration import WebpubsubServiceClientConfiguration +from ._configuration import WebPubSubServiceClientConfiguration from .operations import HealthApiOperations, WebPubSubOperations if TYPE_CHECKING: @@ -22,8 +22,8 @@ from azure.core.credentials import TokenCredential from azure.core.rest import HttpRequest, HttpResponse -class WebpubsubServiceClient(object): - """WebpubsubServiceClient. +class WebPubSubServiceClient(object): + """WebPubSubServiceClient. :ivar health_api: HealthApiOperations operations :vartype health_api: azure.messaging.webpubsubservice.operations.HealthApiOperations @@ -43,7 +43,7 @@ def __init__( # type: (...) -> None endpoint = kwargs.pop('endpoint', "") # type: str - self._config = WebpubsubServiceClientConfiguration(credential, **kwargs) + self._config = WebPubSubServiceClientConfiguration(credential, **kwargs) self._client = PipelineClient(base_url=endpoint, config=self._config, **kwargs) self._serialize = Serializer() @@ -85,7 +85,7 @@ def close(self): self._client.close() def __enter__(self): - # type: () -> WebpubsubServiceClient + # type: () -> WebPubSubServiceClient self._client.__enter__() return self diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py index 89fdb88af896..1ce892c0a9e6 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py @@ -6,5 +6,5 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._webpubsub_service_client import WebpubsubServiceClient -__all__ = ['WebpubsubServiceClient'] +from ._web_pub_sub_service_client import WebPubSubServiceClient +__all__ = ['WebPubSubServiceClient'] diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py index 47d74656977e..49311d80530d 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py @@ -18,8 +18,8 @@ from azure.core.credentials_async import AsyncTokenCredential -class WebpubsubServiceClientConfiguration(Configuration): - """Configuration for WebpubsubServiceClient. +class WebPubSubServiceClientConfiguration(Configuration): + """Configuration for WebPubSubServiceClient. Note that all parameters used to create this instance are saved as instance attributes. @@ -35,10 +35,10 @@ def __init__( ) -> None: if credential is None: raise ValueError("Parameter 'credential' must not be None.") - super(WebpubsubServiceClientConfiguration, self).__init__(**kwargs) + super(WebPubSubServiceClientConfiguration, self).__init__(**kwargs) self.credential = credential - self.credential_scopes = kwargs.pop('credential_scopes', []) + self.credential_scopes = kwargs.pop('credential_scopes', ['https://webpubsub.azure.com/.default']) kwargs.setdefault('sdk_moniker', 'messaging-webpubsubservice/{}'.format(VERSION)) self._configure(**kwargs) @@ -55,7 +55,5 @@ def _configure( self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) self.redirect_policy = kwargs.get('redirect_policy') or policies.AsyncRedirectPolicy(**kwargs) self.authentication_policy = kwargs.get('authentication_policy') - if not self.credential_scopes and not self.authentication_policy: - raise ValueError("You must provide either credential_scopes or authentication_policy as kwargs") if self.credential and not self.authentication_policy: self.authentication_policy = policies.AsyncBearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_webpubsub_service_client.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py similarity index 93% rename from sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_webpubsub_service_client.py rename to sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py index 1432f4ce8620..a733e3fa6e0c 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_webpubsub_service_client.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py @@ -13,7 +13,7 @@ from azure.core.rest import AsyncHttpResponse, HttpRequest from msrest import Deserializer, Serializer -from ._configuration import WebpubsubServiceClientConfiguration +from ._configuration import WebPubSubServiceClientConfiguration from .operations import HealthApiOperations, WebPubSubOperations if TYPE_CHECKING: @@ -22,8 +22,8 @@ from azure.core.credentials_async import AsyncTokenCredential -class WebpubsubServiceClient: - """WebpubsubServiceClient. +class WebPubSubServiceClient: + """WebPubSubServiceClient. :ivar health_api: HealthApiOperations operations :vartype health_api: azure.messaging.webpubsubservice.aio.operations.HealthApiOperations @@ -42,7 +42,7 @@ def __init__( endpoint: str = "", **kwargs: Any ) -> None: - self._config = WebpubsubServiceClientConfiguration(credential, **kwargs) + self._config = WebPubSubServiceClientConfiguration(credential, **kwargs) self._client = AsyncPipelineClient(base_url=endpoint, config=self._config, **kwargs) self._serialize = Serializer() @@ -81,7 +81,7 @@ def send_request( async def close(self) -> None: await self._client.close() - async def __aenter__(self) -> "WebpubsubServiceClient": + async def __aenter__(self) -> "WebPubSubServiceClient": await self._client.__aenter__() return self diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py b/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py index f5403c2290e5..fb4d6cd327c3 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py @@ -61,10 +61,8 @@ ] ), install_requires=[ - "azure-core<2.0.0,>=1.10.0", - "msrest>=0.6.18", - "cryptography>=2.1.4", - "pyjwt>=1.7.1", + "azure-core<2.0.0,>=1.16.0", + "msrest>=0.6.21", "six>=1.12.0", ], extras_require={ diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/swagger/README.md b/sdk/webpubsub/azure-messaging-webpubsubservice/swagger/README.md index d078399e609c..e8d43208ecdc 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/swagger/README.md +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/swagger/README.md @@ -28,8 +28,9 @@ license-header: MICROSOFT_MIT_NO_VERSION clear-output-folder: true no-namespace-folders: true python: true -title: WebpubsubServiceClient +title: WebPubSubServiceClient version-tolerant: true package-version: 1.0.0b1 add-credential: true +credential-scopes: https://webpubsub.azure.com/.default ``` diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/conftest.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/conftest.py new file mode 100644 index 000000000000..a6ab83f7f5f0 --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/conftest.py @@ -0,0 +1,15 @@ +# coding: utf-8 +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- + +import sys + +# fixture needs to be visible from conftest + +# Ignore async tests for Python < 3.5 +collect_ignore_glob = [] +if sys.version_info < (3, 5): + collect_ignore_glob.append("*_async.py") \ No newline at end of file diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml new file mode 100644 index 000000000000..d0915ba6396d --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml @@ -0,0 +1,28 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-messaging-webpubsubservice/1.0.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0) + method: HEAD + uri: https://myservice.webpubsub.azure.com/api/health?api-version=2021-08-01-preview + response: + body: + string: '' + headers: + connection: + - keep-alive + date: + - Mon, 06 Sep 2021 08:53:24 GMT + strict-transport-security: + - max-age=15724800; includeSubDomains + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml new file mode 100644 index 000000000000..dcf51bbb6ae1 --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml @@ -0,0 +1,34 @@ +interactions: +- request: + body: '{"hello": "world!!!"}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '21' + Content-Type: + - text/plain + User-Agent: + - azsdk-python-messaging-webpubsubservice/1.0.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0) + method: POST + uri: https://myservice.webpubsub.azure.com/api/hubs/hub/:send?api-version=2021-08-01-preview + response: + body: + string: '' + headers: + connection: + - keep-alive + content-length: + - '0' + date: + - Mon, 06 Sep 2021 08:53:31 GMT + strict-transport-security: + - max-age=15724800; includeSubDomains + status: + code: 202 + message: Accepted +version: 1 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py new file mode 100644 index 000000000000..a7f2405f6ca8 --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py @@ -0,0 +1,20 @@ +# coding: utf-8 +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# ------------------------------------------------------------------------- +from testcase import WebpubsubTest, WebpubsubPowerShellPreparer + + +class WebpubsubSmokeTest(WebpubsubTest): + + @WebpubsubPowerShellPreparer() + def test_health_api_status(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint) + client.health_api.get_service_status() + + @WebpubsubPowerShellPreparer() + def test_webpubsub_send_to_all(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint) + client.web_pub_sub.send_to_all('hub', {'hello': 'world!!!'}) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase.py new file mode 100644 index 000000000000..ff53a46fa351 --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase.py @@ -0,0 +1,29 @@ +# coding: utf-8 +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import functools +from devtools_testutils import AzureTestCase, PowerShellPreparer +from azure.messaging.webpubsubservice import WebPubSubServiceClient + + +class WebpubsubTest(AzureTestCase): + def __init__(self, method_name, **kwargs): + super(WebpubsubTest, self).__init__(method_name, **kwargs) + + def create_client(self, endpoint): + credential = self.get_credential(WebPubSubServiceClient) + return self.create_client_from_credential( + WebPubSubServiceClient, + credential=credential, + endpoint=endpoint, + ) + + +WebpubsubPowerShellPreparer = functools.partial( + PowerShellPreparer, + "webpubsub", + webpubsub_endpoint="https://myservice.webpubsub.azure.com" +) From c3995d581fac631f218eb7ea1f1f15fe1ad809d7 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Mon, 6 Sep 2021 17:05:47 +0800 Subject: [PATCH 03/33] update readme.md --- sdk/webpubsub/azure-messaging-webpubsubservice/README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/README.md b/sdk/webpubsub/azure-messaging-webpubsubservice/README.md index 91cef22aa22b..10a2c9e54020 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/README.md +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/README.md @@ -48,7 +48,7 @@ provide an instance of the desired credential type obtained from the [azure-identity][azure_identity_credentials] library. To authenticate with AAD, you must first [pip][pip] install [`azure-identity`][azure_identity_pip] and -[enable AAD authentication on your Purview resource][enable_aad] +[enable AAD authentication on your Webpubsub resource][enable_aad] After setup, you can choose which type of [credential][azure_identity_credentials] from azure.identity to use. As an example, [DefaultAzureCredential][default_azure_credential] @@ -174,3 +174,9 @@ additional questions or comments. [code_of_conduct]: https://opensource.microsoft.com/codeofconduct/ [coc_faq]: https://opensource.microsoft.com/codeofconduct/faq/ [coc_contact]: mailto:opencode@microsoft.com +[authenticate_with_token]: https://docs.microsoft.com/azure/cognitive-services/authentication?tabs=powershell#authenticate-with-an-authentication-token +[azure_identity_credentials]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/identity/azure-identity#credentials +[azure_identity_pip]: https://pypi.org/project/azure-identity/ +[default_azure_credential]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/identity/azure-identity#defaultazurecredential +[pip]: https://pypi.org/project/pip/ +[enable_aad]: https://docs.microsoft.com/en-us/azure/azure-web-pubsub/howto-develop-create-instance From 95d910af5f41bc2eac579aa8033f74cd89406380 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Wed, 8 Sep 2021 13:41:35 +0800 Subject: [PATCH 04/33] add test --- .../webpubsubservice/_configuration.py | 16 +-- .../messaging/webpubsubservice/_policies.py | 83 +++++++++++++ .../messaging/webpubsubservice/_utils.py | 45 +++++++ .../_web_pub_sub_service_client.py | 112 +++++++++++++++++- .../webpubsubservice/aio/_configuration.py | 13 +- .../aio/_web_pub_sub_service_client.py | 14 ++- .../examples/send_messages.py | 31 ++--- .../test_smoke.test_health_api_status.yaml | 2 +- ...test_smoke.test_webpubsub_send_to_all.yaml | 4 +- ...st_smoke_async.test_health_api_status.yaml | 20 ++++ ...moke_async.test_webpubsub_send_to_all.yaml | 25 ++++ .../tests/test_send_requests.py | 38 ------ .../tests/test_smoke.py | 2 +- .../tests/test_smoke_async.py | 21 ++++ .../tests/testcase_async.py | 21 ++++ 15 files changed, 368 insertions(+), 79 deletions(-) create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_utils.py create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml delete mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_send_requests.py create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase_async.py diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py index c9073f30f623..8b78b8e0414f 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py @@ -12,12 +12,13 @@ from azure.core.pipeline import policies from ._version import VERSION +from ._policies import JwtCredentialPolicy if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports - from typing import Any, Optional + from typing import Any, Optional, Union - from azure.core.credentials import TokenCredential + from azure.core.credentials import TokenCredential, AzureKeyCredential class WebPubSubServiceClientConfiguration(Configuration): @@ -27,17 +28,15 @@ class WebPubSubServiceClientConfiguration(Configuration): attributes. :param credential: Credential needed for the client to connect to Azure. - :type credential: ~azure.core.credentials.TokenCredential + :type credential: Union[~azure.core.credentials.TokenCredential, ~azure.core.credentials.AzureKeyCredential] """ def __init__( self, - credential, # type: "TokenCredential" + credential, # type: Union[TokenCredential, AzureKeyCredential] **kwargs # type: Any ): # type: (...) -> None - if credential is None: - raise ValueError("Parameter 'credential' must not be None.") super(WebPubSubServiceClientConfiguration, self).__init__(**kwargs) self.credential = credential @@ -60,4 +59,7 @@ def _configure( self.redirect_policy = kwargs.get('redirect_policy') or policies.RedirectPolicy(**kwargs) self.authentication_policy = kwargs.get('authentication_policy') if self.credential and not self.authentication_policy: - self.authentication_policy = policies.BearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) + if kwargs.get("accesskey"): + self.authentication_policy = JwtCredentialPolicy(self.credential) + else: + self.authentication_policy = policies.BearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py new file mode 100644 index 000000000000..6dc11981689a --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py @@ -0,0 +1,83 @@ +# -------------------------------------------------------------------------- +# +# Copyright (c) Microsoft Corporation. All rights reserved. +# +# The MIT License (MIT) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the ""Software""), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# +# -------------------------------------------------------------------------- + +import datetime +import typing +import jwt +import six + +from azure.core.pipeline.policies import SansIOHTTPPolicy + +from ._utils import UTC + +if typing.TYPE_CHECKING: + from azure.core.credentials import AzureKeyCredential + from azure.core.pipeline import PipelineRequest + + +class JwtCredentialPolicy(SansIOHTTPPolicy): + + NAME_CLAIM_TYPE = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" + + def __init__(self, credential, user=None): + # type: (AzureKeyCredential, typing.Optional[str]) -> None + """Create a new instance of the policy associated with the given credential. + + :param credential: The azure.core.credentials.AzureKeyCredential instance to use + :type credential: ~azure.core.credentials.AzureKeyCredential + :param user: Optional user name associated with the credential. + :type user: str + """ + self._credential = credential + self._user = user + + def on_request(self, request): + # type: (PipelineRequest) -> typing.Union[None, typing.Awaitable[None]] + """Is executed before sending the request from next policy. + + :param request: Request to be modified before sent from next policy. + :type request: ~azure.core.pipeline.PipelineRequest + """ + request.http_request.headers["Authorization"] = "Bearer " + self._encode( + request.http_request.url + ) + return super(JwtCredentialPolicy, self).on_request(request) + + def _encode(self, url): + # type: (AzureKeyCredential) -> str + data = { + "aud": url, + "exp": datetime.datetime.now(tz=UTC) + datetime.timedelta(seconds=60), + } + if self._user: + data[self.NAME_CLAIM_TYPE] = self._user + + encoded = jwt.encode( + payload=data, + key=self._credential.key, + algorithm="HS256", + ) + return six.ensure_str(encoded) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_utils.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_utils.py new file mode 100644 index 000000000000..042b46dd8848 --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_utils.py @@ -0,0 +1,45 @@ +# -------------------------------------------------------------------------- +# +# Copyright (c) Microsoft Corporation. All rights reserved. +# +# The MIT License (MIT) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the ""Software""), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# +# -------------------------------------------------------------------------- + +import datetime + + +class _UTC_TZ(datetime.tzinfo): + """from https://docs.python.org/2/library/datetime.html#tzinfo-objects""" + + ZERO = datetime.timedelta(0) + + def utcoffset(self, dt): + return self.__class__.ZERO + + def tzname(self, dt): + return "UTC" + + def dst(self, dt): + return self.__class__.ZERO + + +UTC = _UTC_TZ() diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py index 2b69eac16e8a..bc90ce7aafa4 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py @@ -8,12 +8,18 @@ from copy import deepcopy from typing import TYPE_CHECKING +from datetime import datetime, timedelta + +import jwt +import six from azure.core import PipelineClient from msrest import Deserializer, Serializer +from azure.core.credentials import AzureKeyCredential from ._configuration import WebPubSubServiceClientConfiguration from .operations import HealthApiOperations, WebPubSubOperations +from ._utils import UTC as _UTC if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports @@ -22,6 +28,30 @@ from azure.core.credentials import TokenCredential from azure.core.rest import HttpRequest, HttpResponse + +def _parse_connection_string(connection_string, **kwargs): + # type: (str, Any) -> Dict[Any] + for segment in connection_string.split(";"): + if "=" in segment: + key, value = segment.split("=", maxsplit=1) + key = key.lower() + if key not in ("version",): + kwargs.setdefault(key, value) + elif segment: + raise ValueError( + "Malformed connection string - expected 'key=value', found segment '{}' in '{}'".format( + segment, connection_string + ) + ) + + if "endpoint" not in kwargs: + raise ValueError("connection_string missing 'endpoint' field") + + if "accesskey" not in kwargs: + raise ValueError("connection_string missing 'accesskey' field") + + return kwargs + class WebPubSubServiceClient(object): """WebPubSubServiceClient. @@ -29,6 +59,8 @@ class WebPubSubServiceClient(object): :vartype health_api: azure.messaging.webpubsubservice.operations.HealthApiOperations :ivar web_pub_sub: WebPubSubOperations operations :vartype web_pub_sub: azure.messaging.webpubsubservice.operations.WebPubSubOperations + :keyword connection_string: connection string needed for the client to connect to Azure. + :paramtype connection_string: str :param credential: Credential needed for the client to connect to Azure. :type credential: ~azure.core.credentials.TokenCredential :keyword endpoint: Service URL. Default value is ''. @@ -37,12 +69,18 @@ class WebPubSubServiceClient(object): def __init__( self, - credential, # type: "TokenCredential" + connection_string=None, # type: str + credential=None, # type: "TokenCredential" **kwargs # type: Any ): # type: (...) -> None - endpoint = kwargs.pop('endpoint', "") # type: str + if connection_string: + kwargs = _parse_connection_string(connection_string, **kwargs) + credential = AzureKeyCredential(kwargs.get("accesskey")) + elif credential is None: + raise ValueError("Parameter 'credential' and 'connection_string' must not be None at the same time.") + endpoint = kwargs.pop('endpoint', "") # type: str self._config = WebPubSubServiceClientConfiguration(credential, **kwargs) self._client = PipelineClient(base_url=endpoint, config=self._config, **kwargs) @@ -92,3 +130,73 @@ def __enter__(self): def __exit__(self, *exc_details): # type: (Any) -> None self._client.__exit__(*exc_details) + + @staticmethod + def build_authentication_token(endpoint, hub, **kwargs): + # type: (str, str, Any) -> Dict[Any] + """Build an authentication token for the given endpoint, hub using the provided key. + + :keyword endpoint: connetion string or HTTP or HTTPS endpoint for the WebPubSub service instance. + :type endpoint: ~str + :keyword hub: The hub to give access to. + :type hub: ~str + :keyword accesskey: Key to sign the token with. Required if endpoint is not a connection string + :type accesskey: ~str + :keyword ttl: Optional ttl timedelta for the token. Default is 1 hour. + :type ttl: ~datetime.timedelta + :keyword user: Optional user name (subject) for the token. Default is no user. + :type user: ~str + :keyword roles: Roles for the token. + :type roles: typing.List[str]. Default is no roles. + :returns: ~dict containing the web socket endpoint, the token and a url with the generated access token. + :rtype: ~dict + + + Example: + >>> build_authentication_token(endpoint='https://contoso.com/api/webpubsub', hub='theHub', key='123') + { + 'baseUrl': 'wss://contoso.com/api/webpubsub/client/hubs/theHub', + 'token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ...', + 'url': 'wss://contoso.com/api/webpubsub/client/hubs/theHub?access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ...' + } + """ + if 'accesskey' not in kwargs: + kwargs = _parse_connection_string(endpoint, **kwargs) + endpoint = kwargs.pop('endpoint') + + user = kwargs.pop("user", None) + key = kwargs.pop("accesskey") + ttl = kwargs.pop("ttl", timedelta(hours=1)) + roles = kwargs.pop("roles", []) + endpoint = endpoint.lower() + if not endpoint.startswith("http://") and not endpoint.startswith("https://"): + raise ValueError( + "Invalid endpoint: '{}' has unknown scheme - expected 'http://' or 'https://'".format( + endpoint + ) + ) + + # Ensure endpoint has no trailing slash + endpoint = endpoint.rstrip("/") + + # Switch from http(s) to ws(s) scheme + client_endpoint = "ws" + endpoint[4:] + client_url = "{}/client/hubs/{}".format(client_endpoint, hub) + audience = "{}/client/hubs/{}".format(endpoint, hub) + + payload = { + "aud": audience, + "iat": datetime.now(tz=_UTC), + "exp": datetime.now(tz=_UTC) + ttl, + } + if user: + payload["sub"] = user + if roles: + payload["role"] = roles + + token = six.ensure_str(jwt.encode(payload, key, algorithm="HS256")) + return { + "baseUrl": client_url, + "token": token, + "url": "{}?access_token={}".format(client_url, token), + } diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py index 49311d80530d..3c12313f2bc4 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py @@ -6,16 +6,18 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from typing import Any, Optional, TYPE_CHECKING +from typing import Any, Optional, TYPE_CHECKING, Union from azure.core.configuration import Configuration from azure.core.pipeline import policies from .._version import VERSION +from .._policies import JwtCredentialPolicy if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports from azure.core.credentials_async import AsyncTokenCredential + from azure.core.credentials import AzureKeyCredential class WebPubSubServiceClientConfiguration(Configuration): @@ -25,12 +27,12 @@ class WebPubSubServiceClientConfiguration(Configuration): attributes. :param credential: Credential needed for the client to connect to Azure. - :type credential: ~azure.core.credentials_async.AsyncTokenCredential + :type credential: Union[~azure.core.credentials_async.AsyncTokenCredential, ~azure.core.credentials.AzureKeyCredential] """ def __init__( self, - credential: "AsyncTokenCredential", + credential: Union["AsyncTokenCredential", "AzureKeyCredential"], **kwargs: Any ) -> None: if credential is None: @@ -56,4 +58,7 @@ def _configure( self.redirect_policy = kwargs.get('redirect_policy') or policies.AsyncRedirectPolicy(**kwargs) self.authentication_policy = kwargs.get('authentication_policy') if self.credential and not self.authentication_policy: - self.authentication_policy = policies.AsyncBearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) + if kwargs.get("accesskey"): + self.authentication_policy = JwtCredentialPolicy(self.credential) + else: + self.authentication_policy = policies.AsyncBearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py index a733e3fa6e0c..b8bed4c79d39 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py @@ -12,9 +12,11 @@ from azure.core import AsyncPipelineClient from azure.core.rest import AsyncHttpResponse, HttpRequest from msrest import Deserializer, Serializer +from azure.core.credentials import AzureKeyCredential from ._configuration import WebPubSubServiceClientConfiguration from .operations import HealthApiOperations, WebPubSubOperations +from .._web_pub_sub_service_client import _parse_connection_string if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports @@ -37,11 +39,17 @@ class WebPubSubServiceClient: def __init__( self, - credential: "AsyncTokenCredential", - *, - endpoint: str = "", + connection_string: str = None, + credential: "AsyncTokenCredential" = None, **kwargs: Any ) -> None: + if connection_string: + kwargs = _parse_connection_string(connection_string, **kwargs) + credential = AzureKeyCredential(kwargs.get("accesskey")) + elif credential is None: + raise ValueError("Parameter 'credential' and 'connection_string' must not be None at the same time.") + + endpoint = kwargs.pop('endpoint', "") # type: str self._config = WebPubSubServiceClientConfiguration(credential, **kwargs) self._client = AsyncPipelineClient(base_url=endpoint, config=self._config, **kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages.py b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages.py index 96913de2dde1..e5822ddc8567 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages.py @@ -3,7 +3,6 @@ import os from azure.messaging.webpubsubservice import WebPubSubServiceClient -from azure.messaging.webpubsubservice.rest import * logging.basicConfig(level=logging.DEBUG) LOG = logging.getLogger() @@ -11,44 +10,34 @@ try: connection_string = os.environ['WEBPUBSUB_CONNECTION_STRING'] except KeyError: - LOG.error("Missing environment variable 'WEBPUBSUB_CONNECTION_STRING' - please set if before running the example") + # LOG.error("Missing environment variable 'WEBPUBSUB_CONNECTION_STRING' - please set if before running the example") exit() # Build a client from the connection string. And for this example, we have enabled debug # tracing. For production code, this should be turned off. -client = WebPubSubServiceClient.from_connection_string(connection_string, tracing_enabled=True) +client = WebPubSubServiceClient(connection_string, logging_enable=True) -# Send a json message to everybody on the given hub... -request = build_send_to_all_request('myHub', json={ 'Hello': 'all!' }) -print(request.headers) -response = client.send_request(request) try: # Raise an exception if the service rejected the call - response.raise_for_status() + client.web_pub_sub.send_to_all('Hub', message={'Hello': 'all!'}) print('Successfully sent a JSON message') except: - print('Failed to send JSON message: {}'.format(response)) - + print('Failed to send JSON message') # Send a text message to everybody on the given hub... -request = build_send_to_all_request('ahub', content='hello, text!', content_type='text/plain') -response = client.send_request(request) try: # Raise an exception if the service rejected the call - response.raise_for_status() - print('Successfully sent a TEXT message') + client.web_pub_sub.send_to_all('Hub', message='hello, text!', content_type='text/plain') + print('Successfully sent a JSON message') except: - print('Failed to send TEXT message: {}'.format(response)) - + print('Failed to send JSON message') # Send a json message from a stream to everybody on the given hub... -request = build_send_to_all_request('ahub', content=io.BytesIO(b'{ "hello": "world" }'), content_type='application/json') -response = client.send_request(request) try: # Raise an exception if the service rejected the call - response.raise_for_status() - print('Successfully sent a JSON message from a stream') + client.web_pub_sub.send_to_all('Hub', message=io.BytesIO(b'{ "hello": "world" }'), content_type='application/json') + print('Successfully sent a JSON message') except: - print('Failed to send JSON message from a stream: {}'.format(response)) + print('Failed to send JSON message') diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml index d0915ba6396d..c5d81e88cad7 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml @@ -19,7 +19,7 @@ interactions: connection: - keep-alive date: - - Mon, 06 Sep 2021 08:53:24 GMT + - Wed, 08 Sep 2021 05:40:48 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml index dcf51bbb6ae1..b7884f375960 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml @@ -15,7 +15,7 @@ interactions: User-Agent: - azsdk-python-messaging-webpubsubservice/1.0.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0) method: POST - uri: https://myservice.webpubsub.azure.com/api/hubs/hub/:send?api-version=2021-08-01-preview + uri: https://myservice.webpubsub.azure.com/api/hubs/Hub/:send?api-version=2021-08-01-preview response: body: string: '' @@ -25,7 +25,7 @@ interactions: content-length: - '0' date: - - Mon, 06 Sep 2021 08:53:31 GMT + - Wed, 08 Sep 2021 05:40:36 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml new file mode 100644 index 000000000000..cb67b5c42a8a --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml @@ -0,0 +1,20 @@ +interactions: +- request: + body: null + headers: + User-Agent: + - azsdk-python-messaging-webpubsubservice/1.0.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0) + method: HEAD + uri: https://myservice.webpubsub.azure.com/api/health?api-version=2021-08-01-preview + response: + body: + string: '' + headers: + connection: keep-alive + date: Wed, 08 Sep 2021 05:28:42 GMT + strict-transport-security: max-age=15724800; includeSubDomains + status: + code: 200 + message: OK + url: https://webpubsub-yyc.webpubsub.azure.com/api/health?api-version=2021-08-01-preview +version: 1 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml new file mode 100644 index 000000000000..c1dae35c581d --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml @@ -0,0 +1,25 @@ +interactions: +- request: + body: '{"hello": "world!!!"}' + headers: + Content-Length: + - '21' + Content-Type: + - text/plain + User-Agent: + - azsdk-python-messaging-webpubsubservice/1.0.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0) + method: POST + uri: https://myservice.webpubsub.azure.com/api/hubs/Hub/:send?api-version=2021-08-01-preview + response: + body: + string: '' + headers: + connection: keep-alive + content-length: '0' + date: Wed, 08 Sep 2021 05:28:44 GMT + strict-transport-security: max-age=15724800; includeSubDomains + status: + code: 202 + message: Accepted + url: https://webpubsub-yyc.webpubsub.azure.com/api/hubs/Hub/:send?api-version=2021-08-01-preview +version: 1 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_send_requests.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_send_requests.py deleted file mode 100644 index 4f402e2e719b..000000000000 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_send_requests.py +++ /dev/null @@ -1,38 +0,0 @@ -import io - -from azure.messaging.webpubsubservice import WebPubSubServiceClient -from azure.messaging.webpubsubservice.rest import * - -from azure.core.credentials import AzureKeyCredential - -def test_build_text_request(): - request = build_send_to_all_request('hub', content='hello world', content_type='text/plain') - - assert request.headers['content-type'] == 'text/plain' - assert request.content == 'hello world' - -def test_build_json_request(): - client = WebPubSubServiceClient('https://www.microsoft.com/api', AzureKeyCredential('abcd')) - request = build_send_to_all_request('hub', json={'hello': 'world'}) - assert request.headers['content-type'] == 'application/json' - -def test_build_stream_request(): - stream = io.BytesIO(b'1234') - client = WebPubSubServiceClient('https://www.microsoft.com/api', AzureKeyCredential('abcd')) - request = build_send_to_all_request('hub', content=stream, content_type='application/octet-stream') - assert request.headers['content-type'] == 'application/octet-stream' - -def test_build_stream_json_request(): - stream = io.BytesIO(b'{ "hello": "web" }') - client = WebPubSubServiceClient('https://www.microsoft.com/api', AzureKeyCredential('abcd')) - request = build_send_to_all_request('hub', content=stream, content_type='application/octet-json') - assert request.headers['content-type'] == 'application/octet-json' - -def test_build_send_message_exclude(): - stream = io.BytesIO(b'{ "hello": "web" }') - client = WebPubSubServiceClient('https://www.microsoft.com/api', AzureKeyCredential('abcd')) - request = build_send_to_all_request('hub', content=stream, content_type='application/octet-json', excluded=['a', 'b', 'c']) - assert 'excluded=a&' in request.url - assert 'excluded=b&' in request.url - assert 'excluded=c' in request.url - assert 'excluded=d' not in request.url diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py index a7f2405f6ca8..90328ecb9b7d 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py @@ -17,4 +17,4 @@ def test_health_api_status(self, webpubsub_endpoint): @WebpubsubPowerShellPreparer() def test_webpubsub_send_to_all(self, webpubsub_endpoint): client = self.create_client(endpoint=webpubsub_endpoint) - client.web_pub_sub.send_to_all('hub', {'hello': 'world!!!'}) + client.web_pub_sub.send_to_all('Hub', {'hello': 'world!!!'}) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py new file mode 100644 index 000000000000..a5e038b3fdac --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py @@ -0,0 +1,21 @@ +# coding: utf-8 +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# ------------------------------------------------------------------------- +from testcase import WebpubsubPowerShellPreparer +from testcase_async import WebpubsubTestAsync + + +class WebpubsubSmokeTestAsync(WebpubsubTestAsync): + + @WebpubsubPowerShellPreparer() + async def test_health_api_status(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint) + await client.health_api.get_service_status() + + @WebpubsubPowerShellPreparer() + async def test_webpubsub_send_to_all(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint) + await client.web_pub_sub.send_to_all('Hub', {'hello': 'world!!!'}) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase_async.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase_async.py new file mode 100644 index 000000000000..74e56b95bfe1 --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase_async.py @@ -0,0 +1,21 @@ +# coding: utf-8 +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +from devtools_testutils import AzureTestCase +from azure.messaging.webpubsubservice.aio import WebPubSubServiceClient + + +class WebpubsubTestAsync(AzureTestCase): + def __init__(self, method_name, **kwargs): + super(WebpubsubTestAsync, self).__init__(method_name, **kwargs) + + def create_client(self, endpoint): + credential = self.get_credential(WebPubSubServiceClient, is_async=True) + return self.create_client_from_credential( + WebPubSubServiceClient, + credential=credential, + endpoint=endpoint, + ) From 090c8c193f3cd435c85bcce15473522e2bf269b8 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Wed, 8 Sep 2021 14:03:28 +0800 Subject: [PATCH 05/33] from connection string --- .../_web_pub_sub_service_client.py | 27 ++++++++++++------- .../aio/_web_pub_sub_service_client.py | 27 ++++++++++++------- .../examples/send_messages.py | 2 +- .../test_smoke.test_health_api_status.yaml | 2 +- ...test_smoke.test_webpubsub_send_to_all.yaml | 2 +- ...st_smoke_async.test_health_api_status.yaml | 2 +- ...moke_async.test_webpubsub_send_to_all.yaml | 2 +- 7 files changed, 39 insertions(+), 25 deletions(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py index bc90ce7aafa4..98840ee4b0cf 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py @@ -23,7 +23,7 @@ if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports - from typing import Any, Dict, Optional + from typing import Any, Dict, Optional, Union from azure.core.credentials import TokenCredential from azure.core.rest import HttpRequest, HttpResponse @@ -62,24 +62,17 @@ class WebPubSubServiceClient(object): :keyword connection_string: connection string needed for the client to connect to Azure. :paramtype connection_string: str :param credential: Credential needed for the client to connect to Azure. - :type credential: ~azure.core.credentials.TokenCredential + :type credential: Union[~azure.core.credentials.TokenCredential, ~azure.core.credentials.AzureKeyCredential] :keyword endpoint: Service URL. Default value is ''. :paramtype endpoint: str """ def __init__( self, - connection_string=None, # type: str - credential=None, # type: "TokenCredential" + credential, # type: Union[TokenCredential, AzureKeyCredential] **kwargs # type: Any ): # type: (...) -> None - if connection_string: - kwargs = _parse_connection_string(connection_string, **kwargs) - credential = AzureKeyCredential(kwargs.get("accesskey")) - elif credential is None: - raise ValueError("Parameter 'credential' and 'connection_string' must not be None at the same time.") - endpoint = kwargs.pop('endpoint', "") # type: str self._config = WebPubSubServiceClientConfiguration(credential, **kwargs) self._client = PipelineClient(base_url=endpoint, config=self._config, **kwargs) @@ -200,3 +193,17 @@ def build_authentication_token(endpoint, hub, **kwargs): "token": token, "url": "{}?access_token={}".format(client_url, token), } + + @classmethod + def from_connection_string(cls, connection_string, **kwargs): + # type: (Type[ClientType], str, Any) -> ClientType + """Create a new WebPubSubServiceClient from a connection string. + + :param connection_string: Connection string + :type connection_string: ~str + :rtype: WebPubSubServiceClient + """ + kwargs = _parse_connection_string(connection_string, **kwargs) + + credential = AzureKeyCredential(kwargs.get("accesskey")) + return cls(credential=credential, **kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py index b8bed4c79d39..e1ffb16843db 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py @@ -7,7 +7,7 @@ # -------------------------------------------------------------------------- from copy import deepcopy -from typing import Any, Awaitable, Optional, TYPE_CHECKING +from typing import Any, Awaitable, Optional, TYPE_CHECKING, Union from azure.core import AsyncPipelineClient from azure.core.rest import AsyncHttpResponse, HttpRequest @@ -32,23 +32,16 @@ class WebPubSubServiceClient: :ivar web_pub_sub: WebPubSubOperations operations :vartype web_pub_sub: azure.messaging.webpubsubservice.aio.operations.WebPubSubOperations :param credential: Credential needed for the client to connect to Azure. - :type credential: ~azure.core.credentials_async.AsyncTokenCredential + :type credential: Union[~azure.core.credentials_async.AsyncTokenCredential, ~azure.core.credentials.AzureKeyCredential] :keyword endpoint: Service URL. Default value is ''. :paramtype endpoint: str """ def __init__( self, - connection_string: str = None, - credential: "AsyncTokenCredential" = None, + credential: Union["AsyncTokenCredential", "AzureKeyCredential"], **kwargs: Any ) -> None: - if connection_string: - kwargs = _parse_connection_string(connection_string, **kwargs) - credential = AzureKeyCredential(kwargs.get("accesskey")) - elif credential is None: - raise ValueError("Parameter 'credential' and 'connection_string' must not be None at the same time.") - endpoint = kwargs.pop('endpoint', "") # type: str self._config = WebPubSubServiceClientConfiguration(credential, **kwargs) self._client = AsyncPipelineClient(base_url=endpoint, config=self._config, **kwargs) @@ -95,3 +88,17 @@ async def __aenter__(self) -> "WebPubSubServiceClient": async def __aexit__(self, *exc_details) -> None: await self._client.__aexit__(*exc_details) + + @classmethod + def from_connection_string(cls, connection_string, **kwargs): + # type: (Type[ClientType], str, Any) -> ClientType + """Create a new WebPubSubServiceClient from a connection string. + + :param connection_string: Connection string + :type connection_string: ~str + :rtype: WebPubSubServiceClient + """ + kwargs = _parse_connection_string(connection_string, **kwargs) + + credential = AzureKeyCredential(kwargs.pop("accesskey")) + return cls(credential=credential, **kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages.py b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages.py index e5822ddc8567..ae3552cd29d4 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages.py @@ -15,7 +15,7 @@ # Build a client from the connection string. And for this example, we have enabled debug # tracing. For production code, this should be turned off. -client = WebPubSubServiceClient(connection_string, logging_enable=True) +client = WebPubSubServiceClient.from_connection_string(connection_string, logging_enable=True) try: # Raise an exception if the service rejected the call diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml index c5d81e88cad7..4a4306e533f8 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml @@ -19,7 +19,7 @@ interactions: connection: - keep-alive date: - - Wed, 08 Sep 2021 05:40:48 GMT + - Wed, 08 Sep 2021 05:56:40 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml index b7884f375960..587e4d0376de 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml @@ -25,7 +25,7 @@ interactions: content-length: - '0' date: - - Wed, 08 Sep 2021 05:40:36 GMT + - Wed, 08 Sep 2021 05:56:43 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml index cb67b5c42a8a..407d08ca210e 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml @@ -11,7 +11,7 @@ interactions: string: '' headers: connection: keep-alive - date: Wed, 08 Sep 2021 05:28:42 GMT + date: Wed, 08 Sep 2021 05:57:01 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 200 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml index c1dae35c581d..65838021e14e 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml @@ -16,7 +16,7 @@ interactions: headers: connection: keep-alive content-length: '0' - date: Wed, 08 Sep 2021 05:28:44 GMT + date: Wed, 08 Sep 2021 05:57:03 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 202 From a4fdbbb15096815f48610f2c89370ad7eabb91f9 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Wed, 8 Sep 2021 15:02:10 +0800 Subject: [PATCH 06/33] example --- .../examples/send_messages_aad.py | 51 +++++++++++++++++++ ....py => send_messages_connection_string.py} | 2 +- .../test_smoke.test_health_api_status.yaml | 2 +- ...test_smoke.test_webpubsub_send_to_all.yaml | 2 +- ...st_smoke_async.test_health_api_status.yaml | 2 +- ...moke_async.test_webpubsub_send_to_all.yaml | 2 +- 6 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py rename sdk/webpubsub/azure-messaging-webpubsubservice/examples/{send_messages.py => send_messages_connection_string.py} (92%) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py new file mode 100644 index 000000000000..056ecfde24bd --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py @@ -0,0 +1,51 @@ +import io +import logging +import os + +from azure.messaging.webpubsubservice import WebPubSubServiceClient +from azure.identity import ClientSecretCredential + +logging.basicConfig(level=logging.DEBUG) +LOG = logging.getLogger() + +# Set the values of the client ID, tenant ID, and client secret of the AAD application as environment variables: +# AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET, WEBPUBSUB_ENDPOINT +try: + tenant_id = os.environ.get("AZURE_TENANT_ID") + client_id = os.environ.get("AZURE_CLIENT_ID") + secret = os.environ.get("AZURE_CLIENT_SECRET") + endpoint = os.environ.get("WEBPUBSUB_ENDPOINT") + credential = ClientSecretCredential(tenant_id=tenant_id, client_id=client_id, client_secret=secret) +except KeyError: + LOG.error("Missing environment variable 'AZURE_TENANT_ID' or 'AZURE_CLIENT_ID' or 'AZURE_CLIENT_SECRET' or 'WEBPUBSUB_ENDPOINT' - please set if before running the example") + exit() + +# Build a client from the connection string. And for this example, we have enabled debug +# tracing. For production code, this should be turned off. +client = WebPubSubServiceClient(credential=credential, endpoint=endpoint) + +# Send a json message to everybody on the given hub... +try: + # Raise an exception if the service rejected the call + client.web_pub_sub.send_to_all('Hub', message={'Hello': 'all!'}) + print('Successfully sent a JSON message') +except: + print('Failed to send JSON message') + +# Send a text message to everybody on the given hub... +try: + # Raise an exception if the service rejected the call + client.web_pub_sub.send_to_all('Hub', message='hello, text!', content_type='text/plain') + print('Successfully sent a JSON message') +except: + print('Failed to send JSON message') + + +# Send a json message from a stream to everybody on the given hub... +try: + # Raise an exception if the service rejected the call + client.web_pub_sub.send_to_all('Hub', message=io.BytesIO(b'{ "hello": "world" }'), content_type='application/json') + print('Successfully sent a JSON message') +except: + print('Failed to send JSON message') + diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages.py b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_connection_string.py similarity index 92% rename from sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages.py rename to sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_connection_string.py index ae3552cd29d4..afb1bdf9efe3 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_connection_string.py @@ -10,7 +10,7 @@ try: connection_string = os.environ['WEBPUBSUB_CONNECTION_STRING'] except KeyError: - # LOG.error("Missing environment variable 'WEBPUBSUB_CONNECTION_STRING' - please set if before running the example") + LOG.error("Missing environment variable 'WEBPUBSUB_CONNECTION_STRING' - please set if before running the example") exit() # Build a client from the connection string. And for this example, we have enabled debug diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml index 4a4306e533f8..7c8d05e085c7 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml @@ -19,7 +19,7 @@ interactions: connection: - keep-alive date: - - Wed, 08 Sep 2021 05:56:40 GMT + - Wed, 08 Sep 2021 07:01:44 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml index 587e4d0376de..3a59e0724784 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml @@ -25,7 +25,7 @@ interactions: content-length: - '0' date: - - Wed, 08 Sep 2021 05:56:43 GMT + - Wed, 08 Sep 2021 07:01:46 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml index 407d08ca210e..d7ab7b44e4e3 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml @@ -11,7 +11,7 @@ interactions: string: '' headers: connection: keep-alive - date: Wed, 08 Sep 2021 05:57:01 GMT + date: Wed, 08 Sep 2021 07:01:54 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 200 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml index 65838021e14e..c6bd5f0b4a14 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml @@ -16,7 +16,7 @@ interactions: headers: connection: keep-alive content-length: '0' - date: Wed, 08 Sep 2021 05:57:03 GMT + date: Wed, 08 Sep 2021 07:01:56 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 202 From 156eaa6168890bd0292d97b8f46ddf703eba0cd5 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Wed, 8 Sep 2021 15:14:01 +0800 Subject: [PATCH 07/33] Update _version.py --- .../azure/messaging/webpubsubservice/_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_version.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_version.py index e5754a47ce68..dfa6ee022f15 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_version.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_version.py @@ -6,4 +6,4 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -VERSION = "1.0.0b1" +VERSION = "1.0.0b2" From c37433852fa738272b6b5410112cbd03ef53a1a9 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Wed, 8 Sep 2021 16:32:00 +0800 Subject: [PATCH 08/33] api management proxy --- .../webpubsubservice/_configuration.py | 10 ++++++-- .../messaging/webpubsubservice/_policies.py | 25 +++++++++++++++++++ .../webpubsubservice/aio/_configuration.py | 3 ++- shared_requirements.txt | 1 + 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py index 8b78b8e0414f..7a109f871a48 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py @@ -12,7 +12,7 @@ from azure.core.pipeline import policies from ._version import VERSION -from ._policies import JwtCredentialPolicy +from ._policies import JwtCredentialPolicy, ApiManagementProxy if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports @@ -21,6 +21,12 @@ from azure.core.credentials import TokenCredential, AzureKeyCredential +def _proxy_policy(**kwargs): + if kwargs.get('proxy_endpoint'): + return ApiManagementProxy(kwargs.get('endpoint'), kwargs.get('proxy_endpoint')) + return None + + class WebPubSubServiceClientConfiguration(Configuration): """Configuration for WebPubSubServiceClient. @@ -51,7 +57,7 @@ def _configure( # type: (...) -> None self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) - self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) + self.proxy_policy = _proxy_policy(**kwargs) or policies.ProxyPolicy(**kwargs) self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) self.retry_policy = kwargs.get('retry_policy') or policies.RetryPolicy(**kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py index 6dc11981689a..c9e7d0b095c7 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py @@ -81,3 +81,28 @@ def _encode(self, url): algorithm="HS256", ) return six.ensure_str(encoded) + + +class ApiManagementProxy(SansIOHTTPPolicy): + + def __init__(self, endpoint, proxy_endpoint): + # type: (str, str) -> None + """Create a new instance of the policy. + + :param endpoint: endpoint to be replaced + :type endpoint: str + :param proxy_endpoint: proxy endpoint + :type proxy_endpoint: str + """ + self._endpoint = endpoint + self._proxy_endpoint = proxy_endpoint + + def on_request(self, request): + # type: (PipelineRequest) -> typing.Union[None, typing.Awaitable[None]] + """Is executed before sending the request from next policy. + + :param request: Request to be modified before sent from next policy. + :type request: ~azure.core.pipeline.PipelineRequest + """ + request.http_request.url = request.http_request.url.replace(self._endpoint, self._proxy_endpoint) + return super(ApiManagementProxy, self).on_request(request) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py index 3c12313f2bc4..99a92fd2ecd9 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py @@ -13,6 +13,7 @@ from .._version import VERSION from .._policies import JwtCredentialPolicy +from .._configuration import _proxy_policy if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports @@ -50,7 +51,7 @@ def _configure( ) -> None: self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) - self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) + self.proxy_policy = _proxy_policy(**kwargs) or policies.ProxyPolicy(**kwargs) self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) self.retry_policy = kwargs.get('retry_policy') or policies.AsyncRetryPolicy(**kwargs) diff --git a/shared_requirements.txt b/shared_requirements.txt index 9e2f21db00c4..5d764c4ec7d6 100644 --- a/shared_requirements.txt +++ b/shared_requirements.txt @@ -282,6 +282,7 @@ opentelemetry-sdk<2.0.0,>=1.0.0 #override azure-purview-scanning msrest>=0.6.21 #override azure-purview-account msrest>=0.6.21 #override azure-purview-account azure-core<2.0.0,>=1.16.0 +#override azure-messaging-webpubsubservice azure-core<2.0.0,>=1.16.0 #override azure-mgmt-rdbms msrest>=0.6.21 #override azure-mgmt-peering msrest>=0.6.21 #override azure-mgmt-elastic msrest>=0.6.21 From d25309accd0e18bfb311b27db4947b46b98acbd0 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Wed, 8 Sep 2021 16:34:07 +0800 Subject: [PATCH 09/33] Update _web_pub_sub_service_client.py --- .../webpubsubservice/aio/_web_pub_sub_service_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py index e1ffb16843db..9faf27719e68 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py @@ -100,5 +100,5 @@ def from_connection_string(cls, connection_string, **kwargs): """ kwargs = _parse_connection_string(connection_string, **kwargs) - credential = AzureKeyCredential(kwargs.pop("accesskey")) + credential = AzureKeyCredential(kwargs.get("accesskey")) return cls(credential=credential, **kwargs) From ec2ddb62471ec56259b7931ec8dcefa462aa8e7b Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Thu, 9 Sep 2021 14:21:54 +0800 Subject: [PATCH 10/33] review --- .../README.md | 30 +++- .../messaging/webpubsubservice/__init__.py | 4 +- .../webpubsubservice/_configuration.py | 15 +- .../messaging/webpubsubservice/_policies.py | 16 +- .../_web_pub_sub_service_client.py | 143 +++++++++--------- .../webpubsubservice/aio/_configuration.py | 11 +- .../aio/_web_pub_sub_service_client.py | 2 +- .../examples/send_messages_aad.py | 21 ++- .../send_messages_connection_string.py | 13 +- .../azure-messaging-webpubsubservice/setup.py | 2 + .../test_smoke.test_health_api_status.yaml | 4 +- ...test_smoke.test_webpubsub_send_to_all.yaml | 4 +- ...st_smoke_async.test_health_api_status.yaml | 4 +- ...moke_async.test_webpubsub_send_to_all.yaml | 4 +- 14 files changed, 147 insertions(+), 126 deletions(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/README.md b/sdk/webpubsub/azure-messaging-webpubsubservice/README.md index 10a2c9e54020..335e09baa575 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/README.md +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/README.md @@ -43,6 +43,26 @@ python -m pip install azure-messaging-webpubsubservice ### Authenticating the client +#### 1. Create with an API Key Credential + +You can get the [API key][api_key] or [Connection string][connection_string] in the [Azure Portal][azure_portal]. +Once you have the value for the API key or Connection string, you can pass it as a string into an instance of [AzureKeyCredential][azure-key-credential]. +Use the key as the credential parameter to authenticate the client: + +```python +>>> from azure.messaging.webpubsubservice import WebPubSubServiceClient +>>> from azure.core.credentials import AzureKeyCredential + +>>> client = WebPubSubServiceClient(endpoint='', credential=AzureKeyCredential("")) +``` +Or +```python +>>> from azure.messaging.webpubsubservice import WebPubSubServiceClient + +>>> client = WebPubSubServiceClient.from_connection_string(connection_string='') +``` + +#### 2. Create with an Azure Active Directory Credential To use an [Azure Active Directory (AAD) token credential][authenticate_with_token], provide an instance of the desired credential type obtained from the [azure-identity][azure_identity_credentials] library. @@ -62,7 +82,7 @@ Use the returned token credential to authenticate the client: ```python >>> from azure.messaging.webpubsubservice import WebPubSubServiceClient >>> from azure.identity import DefaultAzureCredential ->>> client = WebPubSubServiceClient(endpoint='https://myname.webpubsub.azure.com', credential=DefaultAzureCredential()) +>>> client = WebPubSubServiceClient(endpoint='', credential=DefaultAzureCredential()) ``` ## Examples @@ -74,7 +94,7 @@ Use the returned token credential to authenticate the client: >>> from azure.identity import DefaultAzureCredential >>> from azure.core.exceptions import HttpResponseError ->>> client = WebPubSubServiceClient(endpoint='https://myname.webpubsub.azure.com', credential=DefaultAzureCredential()) +>>> client = WebPubSubServiceClient(endpoint='', credential=DefaultAzureCredential()) >>> with open('file.json', 'r') as f: try: client.web_pub_sub.send_to_all('ahub', content=f, content_type='application/json') @@ -126,7 +146,7 @@ logger.setLevel(logging.DEBUG) handler = logging.StreamHandler(stream=sys.stdout) logger.addHandler(handler) -endpoint = "https://myname.webpubsub.azure.com" +endpoint = "" credential = DefaultAzureCredential() # This client will log detailed information about its HTTP sessions, at DEBUG level @@ -180,3 +200,7 @@ additional questions or comments. [default_azure_credential]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/identity/azure-identity#defaultazurecredential [pip]: https://pypi.org/project/pip/ [enable_aad]: https://docs.microsoft.com/en-us/azure/azure-web-pubsub/howto-develop-create-instance +[api_key]: https://docs.microsoft.com/en-us/azure/azure-web-pubsub/howto-websocket-connect?tabs=browser#authorization +[connection_string]: https://docs.microsoft.com/en-us/azure/azure-web-pubsub/howto-websocket-connect?tabs=browser#authorization +[azure_portal]: https://docs.microsoft.com/en-us/azure/azure-web-pubsub/howto-develop-create-instance +[azure-key-credential]: https://aka.ms/azsdk-python-core-azurekeycredential \ No newline at end of file diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py index 656cd0b03180..554de553055e 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py @@ -6,11 +6,11 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._web_pub_sub_service_client import WebPubSubServiceClient +from ._web_pub_sub_service_client import WebPubSubServiceClient, build_authentication_token from ._version import VERSION __version__ = VERSION -__all__ = ['WebPubSubServiceClient'] +__all__ = ['WebPubSubServiceClient', 'build_authentication_token'] try: from ._patch import patch_sdk # type: ignore diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py index 7a109f871a48..85a65a31862e 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py @@ -13,18 +13,13 @@ from ._version import VERSION from ._policies import JwtCredentialPolicy, ApiManagementProxy +from azure.core.credentials import AzureKeyCredential if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports from typing import Any, Optional, Union - from azure.core.credentials import TokenCredential, AzureKeyCredential - - -def _proxy_policy(**kwargs): - if kwargs.get('proxy_endpoint'): - return ApiManagementProxy(kwargs.get('endpoint'), kwargs.get('proxy_endpoint')) - return None + from azure.core.credentials import TokenCredential class WebPubSubServiceClientConfiguration(Configuration): @@ -57,7 +52,7 @@ def _configure( # type: (...) -> None self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) - self.proxy_policy = _proxy_policy(**kwargs) or policies.ProxyPolicy(**kwargs) + self.proxy_policy = kwargs.get('proxy_policy') or ApiManagementProxy(kwargs.get('endpoint'), kwargs.get('proxy_endpoint'), **kwargs) self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) self.retry_policy = kwargs.get('retry_policy') or policies.RetryPolicy(**kwargs) @@ -65,7 +60,7 @@ def _configure( self.redirect_policy = kwargs.get('redirect_policy') or policies.RedirectPolicy(**kwargs) self.authentication_policy = kwargs.get('authentication_policy') if self.credential and not self.authentication_policy: - if kwargs.get("accesskey"): - self.authentication_policy = JwtCredentialPolicy(self.credential) + if isinstance(self.credential, AzureKeyCredential): + self.authentication_policy = JwtCredentialPolicy(self.credential, kwargs.get('user')) else: self.authentication_policy = policies.BearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py index c9e7d0b095c7..1cb8c7e4eda9 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py @@ -29,7 +29,7 @@ import jwt import six -from azure.core.pipeline.policies import SansIOHTTPPolicy +from azure.core.pipeline.policies import SansIOHTTPPolicy, ProxyPolicy from ._utils import UTC @@ -83,10 +83,10 @@ def _encode(self, url): return six.ensure_str(encoded) -class ApiManagementProxy(SansIOHTTPPolicy): +class ApiManagementProxy(ProxyPolicy): - def __init__(self, endpoint, proxy_endpoint): - # type: (str, str) -> None + def __init__(self, endpoint=None, proxy_endpoint=None, **kwargs): + # type: (typing.Optional[str], typing.Optional[str]) -> None """Create a new instance of the policy. :param endpoint: endpoint to be replaced @@ -94,15 +94,17 @@ def __init__(self, endpoint, proxy_endpoint): :param proxy_endpoint: proxy endpoint :type proxy_endpoint: str """ + super(ApiManagementProxy, self).__init__(**kwargs) self._endpoint = endpoint self._proxy_endpoint = proxy_endpoint def on_request(self, request): - # type: (PipelineRequest) -> typing.Union[None, typing.Awaitable[None]] + # type: (PipelineRequest) -> None """Is executed before sending the request from next policy. :param request: Request to be modified before sent from next policy. :type request: ~azure.core.pipeline.PipelineRequest """ - request.http_request.url = request.http_request.url.replace(self._endpoint, self._proxy_endpoint) - return super(ApiManagementProxy, self).on_request(request) + super(ApiManagementProxy, self).on_request(request) + if self._endpoint and self._proxy_endpoint: + request.http_request.url = request.http_request.url.replace(self._endpoint, self._proxy_endpoint) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py index 98840ee4b0cf..1fbf1e22c5a7 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py @@ -52,6 +52,77 @@ def _parse_connection_string(connection_string, **kwargs): return kwargs + +def build_authentication_token(endpoint, hub, **kwargs): + # type: (str, str, Any) -> Dict[Any] + """Build an authentication token for the given endpoint, hub using the provided key. + + :keyword endpoint: connetion string or HTTP or HTTPS endpoint for the WebPubSub service instance. + :type endpoint: ~str + :keyword hub: The hub to give access to. + :type hub: ~str + :keyword accesskey: Key to sign the token with. Required if endpoint is not a connection string + :type accesskey: ~str + :keyword ttl: Optional ttl timedelta for the token. Default is 1 hour. + :type ttl: ~datetime.timedelta + :keyword user: Optional user name (subject) for the token. Default is no user. + :type user: ~str + :keyword roles: Roles for the token. + :type roles: typing.List[str]. Default is no roles. + :returns: ~dict containing the web socket endpoint, the token and a url with the generated access token. + :rtype: ~dict + + + Example: + >>> build_authentication_token(endpoint='https://contoso.com/api/webpubsub', hub='theHub', key='123') + { + 'baseUrl': 'wss://contoso.com/api/webpubsub/client/hubs/theHub', + 'token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ...', + 'url': 'wss://contoso.com/api/webpubsub/client/hubs/theHub?access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ...' + } + """ + if 'accesskey' not in kwargs: + kwargs = _parse_connection_string(endpoint, **kwargs) + endpoint = kwargs.pop('endpoint') + + user = kwargs.pop("user", None) + key = kwargs.pop("accesskey") + ttl = kwargs.pop("ttl", timedelta(hours=1)) + roles = kwargs.pop("roles", []) + endpoint = endpoint.lower() + if not endpoint.startswith("http://") and not endpoint.startswith("https://"): + raise ValueError( + "Invalid endpoint: '{}' has unknown scheme - expected 'http://' or 'https://'".format( + endpoint + ) + ) + + # Ensure endpoint has no trailing slash + endpoint = endpoint.rstrip("/") + + # Switch from http(s) to ws(s) scheme + client_endpoint = "ws" + endpoint[4:] + client_url = "{}/client/hubs/{}".format(client_endpoint, hub) + audience = "{}/client/hubs/{}".format(endpoint, hub) + + payload = { + "aud": audience, + "iat": datetime.now(tz=_UTC), + "exp": datetime.now(tz=_UTC) + ttl, + } + if user: + payload["sub"] = user + if roles: + payload["role"] = roles + + token = six.ensure_str(jwt.encode(payload, key, algorithm="HS256")) + return { + "baseUrl": client_url, + "token": token, + "url": "{}?access_token={}".format(client_url, token), + } + + class WebPubSubServiceClient(object): """WebPubSubServiceClient. @@ -124,76 +195,6 @@ def __exit__(self, *exc_details): # type: (Any) -> None self._client.__exit__(*exc_details) - @staticmethod - def build_authentication_token(endpoint, hub, **kwargs): - # type: (str, str, Any) -> Dict[Any] - """Build an authentication token for the given endpoint, hub using the provided key. - - :keyword endpoint: connetion string or HTTP or HTTPS endpoint for the WebPubSub service instance. - :type endpoint: ~str - :keyword hub: The hub to give access to. - :type hub: ~str - :keyword accesskey: Key to sign the token with. Required if endpoint is not a connection string - :type accesskey: ~str - :keyword ttl: Optional ttl timedelta for the token. Default is 1 hour. - :type ttl: ~datetime.timedelta - :keyword user: Optional user name (subject) for the token. Default is no user. - :type user: ~str - :keyword roles: Roles for the token. - :type roles: typing.List[str]. Default is no roles. - :returns: ~dict containing the web socket endpoint, the token and a url with the generated access token. - :rtype: ~dict - - - Example: - >>> build_authentication_token(endpoint='https://contoso.com/api/webpubsub', hub='theHub', key='123') - { - 'baseUrl': 'wss://contoso.com/api/webpubsub/client/hubs/theHub', - 'token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ...', - 'url': 'wss://contoso.com/api/webpubsub/client/hubs/theHub?access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ...' - } - """ - if 'accesskey' not in kwargs: - kwargs = _parse_connection_string(endpoint, **kwargs) - endpoint = kwargs.pop('endpoint') - - user = kwargs.pop("user", None) - key = kwargs.pop("accesskey") - ttl = kwargs.pop("ttl", timedelta(hours=1)) - roles = kwargs.pop("roles", []) - endpoint = endpoint.lower() - if not endpoint.startswith("http://") and not endpoint.startswith("https://"): - raise ValueError( - "Invalid endpoint: '{}' has unknown scheme - expected 'http://' or 'https://'".format( - endpoint - ) - ) - - # Ensure endpoint has no trailing slash - endpoint = endpoint.rstrip("/") - - # Switch from http(s) to ws(s) scheme - client_endpoint = "ws" + endpoint[4:] - client_url = "{}/client/hubs/{}".format(client_endpoint, hub) - audience = "{}/client/hubs/{}".format(endpoint, hub) - - payload = { - "aud": audience, - "iat": datetime.now(tz=_UTC), - "exp": datetime.now(tz=_UTC) + ttl, - } - if user: - payload["sub"] = user - if roles: - payload["role"] = roles - - token = six.ensure_str(jwt.encode(payload, key, algorithm="HS256")) - return { - "baseUrl": client_url, - "token": token, - "url": "{}?access_token={}".format(client_url, token), - } - @classmethod def from_connection_string(cls, connection_string, **kwargs): # type: (Type[ClientType], str, Any) -> ClientType @@ -205,5 +206,5 @@ def from_connection_string(cls, connection_string, **kwargs): """ kwargs = _parse_connection_string(connection_string, **kwargs) - credential = AzureKeyCredential(kwargs.get("accesskey")) + credential = AzureKeyCredential(kwargs.pop("accesskey")) return cls(credential=credential, **kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py index 99a92fd2ecd9..e4cd156eca8e 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py @@ -12,13 +12,12 @@ from azure.core.pipeline import policies from .._version import VERSION -from .._policies import JwtCredentialPolicy -from .._configuration import _proxy_policy +from .._policies import JwtCredentialPolicy, ApiManagementProxy +from azure.core.credentials import AzureKeyCredential if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports from azure.core.credentials_async import AsyncTokenCredential - from azure.core.credentials import AzureKeyCredential class WebPubSubServiceClientConfiguration(Configuration): @@ -51,7 +50,7 @@ def _configure( ) -> None: self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) - self.proxy_policy = _proxy_policy(**kwargs) or policies.ProxyPolicy(**kwargs) + self.proxy_policy = kwargs.get('proxy_policy') or ApiManagementProxy(kwargs.get('endpoint'), kwargs.get('proxy_endpoint'), **kwargs) self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) self.retry_policy = kwargs.get('retry_policy') or policies.AsyncRetryPolicy(**kwargs) @@ -59,7 +58,7 @@ def _configure( self.redirect_policy = kwargs.get('redirect_policy') or policies.AsyncRedirectPolicy(**kwargs) self.authentication_policy = kwargs.get('authentication_policy') if self.credential and not self.authentication_policy: - if kwargs.get("accesskey"): - self.authentication_policy = JwtCredentialPolicy(self.credential) + if isinstance(self.credential, AzureKeyCredential): + self.authentication_policy = JwtCredentialPolicy(self.credential, kwargs.get('user')) else: self.authentication_policy = policies.AsyncBearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py index 9faf27719e68..e1ffb16843db 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py @@ -100,5 +100,5 @@ def from_connection_string(cls, connection_string, **kwargs): """ kwargs = _parse_connection_string(connection_string, **kwargs) - credential = AzureKeyCredential(kwargs.get("accesskey")) + credential = AzureKeyCredential(kwargs.pop("accesskey")) return cls(credential=credential, **kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py index 056ecfde24bd..b21694f922ed 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py @@ -3,7 +3,8 @@ import os from azure.messaging.webpubsubservice import WebPubSubServiceClient -from azure.identity import ClientSecretCredential +from azure.identity import DefaultAzureCredential +from azure.core.exceptions import HttpResponseError logging.basicConfig(level=logging.DEBUG) LOG = logging.getLogger() @@ -11,34 +12,30 @@ # Set the values of the client ID, tenant ID, and client secret of the AAD application as environment variables: # AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET, WEBPUBSUB_ENDPOINT try: - tenant_id = os.environ.get("AZURE_TENANT_ID") - client_id = os.environ.get("AZURE_CLIENT_ID") - secret = os.environ.get("AZURE_CLIENT_SECRET") endpoint = os.environ.get("WEBPUBSUB_ENDPOINT") - credential = ClientSecretCredential(tenant_id=tenant_id, client_id=client_id, client_secret=secret) except KeyError: LOG.error("Missing environment variable 'AZURE_TENANT_ID' or 'AZURE_CLIENT_ID' or 'AZURE_CLIENT_SECRET' or 'WEBPUBSUB_ENDPOINT' - please set if before running the example") exit() # Build a client from the connection string. And for this example, we have enabled debug # tracing. For production code, this should be turned off. -client = WebPubSubServiceClient(credential=credential, endpoint=endpoint) +client = WebPubSubServiceClient(credential=DefaultAzureCredential(), endpoint=endpoint) # Send a json message to everybody on the given hub... try: # Raise an exception if the service rejected the call client.web_pub_sub.send_to_all('Hub', message={'Hello': 'all!'}) print('Successfully sent a JSON message') -except: - print('Failed to send JSON message') +except HttpResponseError as e: + print('Failed to send JSON message: {}'.format(e.response.json())) # Send a text message to everybody on the given hub... try: # Raise an exception if the service rejected the call client.web_pub_sub.send_to_all('Hub', message='hello, text!', content_type='text/plain') print('Successfully sent a JSON message') -except: - print('Failed to send JSON message') +except HttpResponseError as e: + print('Failed to send JSON message: {}'.format(e.response.json())) # Send a json message from a stream to everybody on the given hub... @@ -46,6 +43,6 @@ # Raise an exception if the service rejected the call client.web_pub_sub.send_to_all('Hub', message=io.BytesIO(b'{ "hello": "world" }'), content_type='application/json') print('Successfully sent a JSON message') -except: - print('Failed to send JSON message') +except HttpResponseError as e: + print('Failed to send JSON message: {}'.format(e.response.json())) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_connection_string.py b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_connection_string.py index afb1bdf9efe3..b9ff2a137a6a 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_connection_string.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_connection_string.py @@ -3,6 +3,7 @@ import os from azure.messaging.webpubsubservice import WebPubSubServiceClient +from azure.core.exceptions import HttpResponseError logging.basicConfig(level=logging.DEBUG) LOG = logging.getLogger() @@ -21,16 +22,16 @@ # Raise an exception if the service rejected the call client.web_pub_sub.send_to_all('Hub', message={'Hello': 'all!'}) print('Successfully sent a JSON message') -except: - print('Failed to send JSON message') +except HttpResponseError as e: + print('Failed to send JSON message: {}'.format(e.response.json())) # Send a text message to everybody on the given hub... try: # Raise an exception if the service rejected the call client.web_pub_sub.send_to_all('Hub', message='hello, text!', content_type='text/plain') print('Successfully sent a JSON message') -except: - print('Failed to send JSON message') +except HttpResponseError as e: + print('Failed to send JSON message: {}'.format(e.response.json())) # Send a json message from a stream to everybody on the given hub... @@ -38,6 +39,6 @@ # Raise an exception if the service rejected the call client.web_pub_sub.send_to_all('Hub', message=io.BytesIO(b'{ "hello": "world" }'), content_type='application/json') print('Successfully sent a JSON message') -except: - print('Failed to send JSON message') +except HttpResponseError as e: + print('Failed to send JSON message: {}'.format(e.response.json())) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py b/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py index fb4d6cd327c3..28df370305b5 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py @@ -63,6 +63,8 @@ install_requires=[ "azure-core<2.0.0,>=1.16.0", "msrest>=0.6.21", + "cryptography>=2.1.4", + "pyjwt>=1.7.1", "six>=1.12.0", ], extras_require={ diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml index 7c8d05e085c7..d54c59fedaaa 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml @@ -9,7 +9,7 @@ interactions: Connection: - keep-alive User-Agent: - - azsdk-python-messaging-webpubsubservice/1.0.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0) + - azsdk-python-messaging-webpubsubservice/1.0.0b2 Python/3.7.3 (Windows-10-10.0.19041-SP0) method: HEAD uri: https://myservice.webpubsub.azure.com/api/health?api-version=2021-08-01-preview response: @@ -19,7 +19,7 @@ interactions: connection: - keep-alive date: - - Wed, 08 Sep 2021 07:01:44 GMT + - Thu, 09 Sep 2021 06:18:32 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml index 3a59e0724784..0637aa200c04 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml @@ -13,7 +13,7 @@ interactions: Content-Type: - text/plain User-Agent: - - azsdk-python-messaging-webpubsubservice/1.0.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0) + - azsdk-python-messaging-webpubsubservice/1.0.0b2 Python/3.7.3 (Windows-10-10.0.19041-SP0) method: POST uri: https://myservice.webpubsub.azure.com/api/hubs/Hub/:send?api-version=2021-08-01-preview response: @@ -25,7 +25,7 @@ interactions: content-length: - '0' date: - - Wed, 08 Sep 2021 07:01:46 GMT + - Thu, 09 Sep 2021 06:18:35 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml index d7ab7b44e4e3..61470dba8f05 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml @@ -3,7 +3,7 @@ interactions: body: null headers: User-Agent: - - azsdk-python-messaging-webpubsubservice/1.0.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0) + - azsdk-python-messaging-webpubsubservice/1.0.0b2 Python/3.7.3 (Windows-10-10.0.19041-SP0) method: HEAD uri: https://myservice.webpubsub.azure.com/api/health?api-version=2021-08-01-preview response: @@ -11,7 +11,7 @@ interactions: string: '' headers: connection: keep-alive - date: Wed, 08 Sep 2021 07:01:54 GMT + date: Thu, 09 Sep 2021 06:18:46 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 200 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml index c6bd5f0b4a14..ebce955fc379 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml @@ -7,7 +7,7 @@ interactions: Content-Type: - text/plain User-Agent: - - azsdk-python-messaging-webpubsubservice/1.0.0b1 Python/3.7.3 (Windows-10-10.0.19041-SP0) + - azsdk-python-messaging-webpubsubservice/1.0.0b2 Python/3.7.3 (Windows-10-10.0.19041-SP0) method: POST uri: https://myservice.webpubsub.azure.com/api/hubs/Hub/:send?api-version=2021-08-01-preview response: @@ -16,7 +16,7 @@ interactions: headers: connection: keep-alive content-length: '0' - date: Wed, 08 Sep 2021 07:01:56 GMT + date: Thu, 09 Sep 2021 06:18:48 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 202 From bebb4863857887938ea45bc0552c874966e3e67c Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Thu, 9 Sep 2021 16:47:03 +0800 Subject: [PATCH 11/33] api management --- .../messaging/webpubsubservice/_configuration.py | 2 +- .../azure/messaging/webpubsubservice/_policies.py | 11 ++++++----- .../webpubsubservice/_web_pub_sub_service_client.py | 1 + .../messaging/webpubsubservice/aio/_configuration.py | 2 +- .../aio/_web_pub_sub_service_client.py | 1 + shared_requirements.txt | 1 + 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py index 85a65a31862e..fad24b169ed7 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py @@ -52,7 +52,7 @@ def _configure( # type: (...) -> None self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) - self.proxy_policy = kwargs.get('proxy_policy') or ApiManagementProxy(kwargs.get('endpoint'), kwargs.get('proxy_endpoint'), **kwargs) + self.proxy_policy = kwargs.get('proxy_policy') or ApiManagementProxy(**kwargs) self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) self.retry_policy = kwargs.get('retry_policy') or policies.RetryPolicy(**kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py index 1cb8c7e4eda9..a3654234bd6c 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py @@ -85,7 +85,7 @@ def _encode(self, url): class ApiManagementProxy(ProxyPolicy): - def __init__(self, endpoint=None, proxy_endpoint=None, **kwargs): + def __init__(self, **kwargs): # type: (typing.Optional[str], typing.Optional[str]) -> None """Create a new instance of the policy. @@ -94,9 +94,10 @@ def __init__(self, endpoint=None, proxy_endpoint=None, **kwargs): :param proxy_endpoint: proxy endpoint :type proxy_endpoint: str """ + self._endpoint = kwargs.pop('origin_endpoint', None) + self._reverse_proxy_endpoint = kwargs.pop('reverse_proxy_endpoint', None) super(ApiManagementProxy, self).__init__(**kwargs) - self._endpoint = endpoint - self._proxy_endpoint = proxy_endpoint + def on_request(self, request): # type: (PipelineRequest) -> None @@ -106,5 +107,5 @@ def on_request(self, request): :type request: ~azure.core.pipeline.PipelineRequest """ super(ApiManagementProxy, self).on_request(request) - if self._endpoint and self._proxy_endpoint: - request.http_request.url = request.http_request.url.replace(self._endpoint, self._proxy_endpoint) + if self._endpoint and self._reverse_proxy_endpoint: + request.http_request.url = request.http_request.url.replace(self._endpoint, self._reverse_proxy_endpoint) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py index 1fbf1e22c5a7..eac8ba62f8d4 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py @@ -145,6 +145,7 @@ def __init__( ): # type: (...) -> None endpoint = kwargs.pop('endpoint', "") # type: str + kwargs['origin_endpoint'] = endpoint self._config = WebPubSubServiceClientConfiguration(credential, **kwargs) self._client = PipelineClient(base_url=endpoint, config=self._config, **kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py index e4cd156eca8e..c435ff6f8ab8 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py @@ -50,7 +50,7 @@ def _configure( ) -> None: self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) - self.proxy_policy = kwargs.get('proxy_policy') or ApiManagementProxy(kwargs.get('endpoint'), kwargs.get('proxy_endpoint'), **kwargs) + self.proxy_policy = kwargs.get('proxy_policy') or ApiManagementProxy(**kwargs) self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) self.retry_policy = kwargs.get('retry_policy') or policies.AsyncRetryPolicy(**kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py index e1ffb16843db..301b0a70ead2 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py @@ -43,6 +43,7 @@ def __init__( **kwargs: Any ) -> None: endpoint = kwargs.pop('endpoint', "") # type: str + kwargs['origin_endpoint'] = endpoint self._config = WebPubSubServiceClientConfiguration(credential, **kwargs) self._client = AsyncPipelineClient(base_url=endpoint, config=self._config, **kwargs) diff --git a/shared_requirements.txt b/shared_requirements.txt index 5d764c4ec7d6..884a42dec863 100644 --- a/shared_requirements.txt +++ b/shared_requirements.txt @@ -283,6 +283,7 @@ opentelemetry-sdk<2.0.0,>=1.0.0 #override azure-purview-account msrest>=0.6.21 #override azure-purview-account azure-core<2.0.0,>=1.16.0 #override azure-messaging-webpubsubservice azure-core<2.0.0,>=1.16.0 +#override azure-messaging-webpubsubservice msrest>=0.6.21 #override azure-mgmt-rdbms msrest>=0.6.21 #override azure-mgmt-peering msrest>=0.6.21 #override azure-mgmt-elastic msrest>=0.6.21 From 859ccc6e1f787d20fbf05ae55b36cafcd6a6543a Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Fri, 10 Sep 2021 09:56:30 +0800 Subject: [PATCH 12/33] fix dependency --- sdk/webpubsub/azure-messaging-webpubsubservice/setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py b/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py index 28df370305b5..d212bc6fe0fe 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py @@ -63,7 +63,6 @@ install_requires=[ "azure-core<2.0.0,>=1.16.0", "msrest>=0.6.21", - "cryptography>=2.1.4", "pyjwt>=1.7.1", "six>=1.12.0", ], From 18ee661bc54b0cdeea7b540d14ad5c6611e1dab2 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Fri, 10 Sep 2021 11:15:39 +0800 Subject: [PATCH 13/33] fix dependency --- eng/tox/allowed_pylint_failures.py | 1 + 1 file changed, 1 insertion(+) diff --git a/eng/tox/allowed_pylint_failures.py b/eng/tox/allowed_pylint_failures.py index c929b50632ab..454d96f3ca4c 100644 --- a/eng/tox/allowed_pylint_failures.py +++ b/eng/tox/allowed_pylint_failures.py @@ -55,6 +55,7 @@ "azure-purview-scanning", "azure-purview-catalog", "azure-purview-account", + "azure-messaging-webpubsubservice", "azure-messaging-nspkg", "azure-agrifood-farming", "azure-eventhub", From fe01cff929f1c7f405112600eaa40d951f4e9216 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Fri, 10 Sep 2021 14:34:23 +0800 Subject: [PATCH 14/33] apim proxy --- .../webpubsubservice/_configuration.py | 4 +- .../messaging/webpubsubservice/_policies.py | 5 +- .../webpubsubservice/aio/_configuration.py | 4 +- .../examples/send_messages_aad.py | 2 +- .../examples/send_messages_aad_apim_proxy.py | 49 +++++++++++++++++++ ...d_messages_connection_string_apim_proxy.py | 45 +++++++++++++++++ .../test_smoke.test_health_api_status.yaml | 2 +- ...test_smoke.test_webpubsub_send_to_all.yaml | 6 +-- ...bsub_send_to_all_api_management_proxy.yaml | 34 +++++++++++++ ...st_smoke_async.test_health_api_status.yaml | 2 +- ...moke_async.test_webpubsub_send_to_all.yaml | 6 +-- ...test_webpubsub_send_to_all_apim_proxy.yaml | 25 ++++++++++ .../tests/test_smoke.py | 7 ++- .../tests/test_smoke_async.py | 7 ++- .../tests/testcase.py | 6 ++- .../tests/testcase_async.py | 3 +- 16 files changed, 186 insertions(+), 21 deletions(-) create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad_apim_proxy.py create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_connection_string_apim_proxy.py create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py index fad24b169ed7..1db338f83a88 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py @@ -52,11 +52,11 @@ def _configure( # type: (...) -> None self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) - self.proxy_policy = kwargs.get('proxy_policy') or ApiManagementProxy(**kwargs) + self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) self.retry_policy = kwargs.get('retry_policy') or policies.RetryPolicy(**kwargs) - self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) + self.custom_hook_policy = kwargs.get('custom_hook_policy') or ApiManagementProxy(**kwargs) self.redirect_policy = kwargs.get('redirect_policy') or policies.RedirectPolicy(**kwargs) self.authentication_policy = kwargs.get('authentication_policy') if self.credential and not self.authentication_policy: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py index a3654234bd6c..8f68612c45de 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py @@ -29,7 +29,7 @@ import jwt import six -from azure.core.pipeline.policies import SansIOHTTPPolicy, ProxyPolicy +from azure.core.pipeline.policies import SansIOHTTPPolicy, CustomHookPolicy from ._utils import UTC @@ -83,7 +83,7 @@ def _encode(self, url): return six.ensure_str(encoded) -class ApiManagementProxy(ProxyPolicy): +class ApiManagementProxy(CustomHookPolicy): def __init__(self, **kwargs): # type: (typing.Optional[str], typing.Optional[str]) -> None @@ -98,7 +98,6 @@ def __init__(self, **kwargs): self._reverse_proxy_endpoint = kwargs.pop('reverse_proxy_endpoint', None) super(ApiManagementProxy, self).__init__(**kwargs) - def on_request(self, request): # type: (PipelineRequest) -> None """Is executed before sending the request from next policy. diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py index c435ff6f8ab8..bd977f3fbf59 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py @@ -50,11 +50,11 @@ def _configure( ) -> None: self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) - self.proxy_policy = kwargs.get('proxy_policy') or ApiManagementProxy(**kwargs) + self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) self.retry_policy = kwargs.get('retry_policy') or policies.AsyncRetryPolicy(**kwargs) - self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) + self.custom_hook_policy = kwargs.get('custom_hook_policy') or ApiManagementProxy(**kwargs) self.redirect_policy = kwargs.get('redirect_policy') or policies.AsyncRedirectPolicy(**kwargs) self.authentication_policy = kwargs.get('authentication_policy') if self.credential and not self.authentication_policy: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py index b21694f922ed..432543ba0a2b 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py @@ -14,7 +14,7 @@ try: endpoint = os.environ.get("WEBPUBSUB_ENDPOINT") except KeyError: - LOG.error("Missing environment variable 'AZURE_TENANT_ID' or 'AZURE_CLIENT_ID' or 'AZURE_CLIENT_SECRET' or 'WEBPUBSUB_ENDPOINT' - please set if before running the example") + LOG.error("Missing environment variable 'WEBPUBSUB_ENDPOINT' - please set if before running the example") exit() # Build a client from the connection string. And for this example, we have enabled debug diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad_apim_proxy.py b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad_apim_proxy.py new file mode 100644 index 000000000000..b7875e3f84c8 --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad_apim_proxy.py @@ -0,0 +1,49 @@ +import io +import logging +import os + +from azure.messaging.webpubsubservice import WebPubSubServiceClient +from azure.identity import DefaultAzureCredential +from azure.core.exceptions import HttpResponseError + +logging.basicConfig(level=logging.DEBUG) +LOG = logging.getLogger() + +# Set the values of the client ID, tenant ID, and client secret of the AAD application as environment variables: +# AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET, WEBPUBSUB_ENDPOINT +try: + endpoint = os.environ.get("WEBPUBSUB_ENDPOINT") + revers_proxy_endpoint = os.environ.get("WEBPUBSUB_REVERSE_RPOXY_ENDPOINT") +except KeyError: + LOG.error("Missing environment variable 'WEBPUBSUB_ENDPOINT' or 'WEBPUBSUB_REVERSE_RPOXY_ENDPOINT' - please set if before running the example") + exit() + +# Build a client from the connection string. And for this example, we have enabled debug +# tracing. For production code, this should be turned off. +client = WebPubSubServiceClient(credential=DefaultAzureCredential(), endpoint=endpoint, revers_proxy_endpoint=revers_proxy_endpoint) + +# Send a json message to everybody on the given hub... +try: + # Raise an exception if the service rejected the call + client.web_pub_sub.send_to_all('Hub', message={'Hello': 'revers_proxy_endpoint!'}) + print('Successfully sent a JSON message') +except HttpResponseError as e: + print('Failed to send JSON message: {}'.format(e.response.json())) + +# Send a text message to everybody on the given hub... +try: + # Raise an exception if the service rejected the call + client.web_pub_sub.send_to_all('Hub', message='hello, revers_proxy_endpoint!', content_type='text/plain') + print('Successfully sent a JSON message') +except HttpResponseError as e: + print('Failed to send JSON message: {}'.format(e.response.json())) + + +# Send a json message from a stream to everybody on the given hub... +try: + # Raise an exception if the service rejected the call + client.web_pub_sub.send_to_all('Hub', message=io.BytesIO(b'{ "hello": "revers_proxy_endpoint" }'), content_type='application/json') + print('Successfully sent a JSON message') +except HttpResponseError as e: + print('Failed to send JSON message: {}'.format(e.response.json())) + diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_connection_string_apim_proxy.py b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_connection_string_apim_proxy.py new file mode 100644 index 000000000000..5dc85457d919 --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_connection_string_apim_proxy.py @@ -0,0 +1,45 @@ +import io +import logging +import os + +from azure.messaging.webpubsubservice import WebPubSubServiceClient +from azure.core.exceptions import HttpResponseError + +logging.basicConfig(level=logging.DEBUG) +LOG = logging.getLogger() + +try: + connection_string = os.environ['WEBPUBSUB_CONNECTION_STRING'] + revers_proxy_endpoint = os.environ.get("WEBPUBSUB_REVERSE_RPOXY_ENDPOINT") +except KeyError: + LOG.error("Missing environment variable 'WEBPUBSUB_CONNECTION_STRING' or 'WEBPUBSUB_REVERSE_RPOXY_ENDPOINT' - please set if before running the example") + exit() + +# Build a client from the connection string. And for this example, we have enabled debug +# tracing. For production code, this should be turned off. +client = WebPubSubServiceClient.from_connection_string(connection_string, logging_enable=True, revers_proxy_endpoint=revers_proxy_endpoint) + +try: + # Raise an exception if the service rejected the call + client.web_pub_sub.send_to_all('Hub', message={'Hello': 'connection_string_reverse_proxy!'}) + print('Successfully sent a JSON message') +except HttpResponseError as e: + print('Failed to send JSON message: {}'.format(e.response.json())) + +# Send a text message to everybody on the given hub... +try: + # Raise an exception if the service rejected the call + client.web_pub_sub.send_to_all('Hub', message='hello, connection_string_reverse_proxy!', content_type='text/plain') + print('Successfully sent a JSON message') +except HttpResponseError as e: + print('Failed to send JSON message: {}'.format(e.response.json())) + + +# Send a json message from a stream to everybody on the given hub... +try: + # Raise an exception if the service rejected the call + client.web_pub_sub.send_to_all('Hub', message=io.BytesIO(b'{ "hello": "connection_string_reverse_proxy" }'), content_type='application/json') + print('Successfully sent a JSON message') +except HttpResponseError as e: + print('Failed to send JSON message: {}'.format(e.response.json())) + diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml index d54c59fedaaa..037768f5cb69 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml @@ -19,7 +19,7 @@ interactions: connection: - keep-alive date: - - Thu, 09 Sep 2021 06:18:32 GMT + - Fri, 10 Sep 2021 06:17:26 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml index 0637aa200c04..a262a1145d75 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml @@ -1,6 +1,6 @@ interactions: - request: - body: '{"hello": "world!!!"}' + body: '{"hello": "test_webpubsub_send_to_all"}' headers: Accept: - '*/*' @@ -9,7 +9,7 @@ interactions: Connection: - keep-alive Content-Length: - - '21' + - '39' Content-Type: - text/plain User-Agent: @@ -25,7 +25,7 @@ interactions: content-length: - '0' date: - - Thu, 09 Sep 2021 06:18:35 GMT + - Fri, 10 Sep 2021 06:17:28 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml new file mode 100644 index 000000000000..520493029865 --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml @@ -0,0 +1,34 @@ +interactions: +- request: + body: '{"hello": "test_webpubsub_send_to_all_api_management_proxy"}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '60' + Content-Type: + - text/plain + User-Agent: + - azsdk-python-messaging-webpubsubservice/1.0.0b2 Python/3.7.3 (Windows-10-10.0.19041-SP0) + method: POST + uri: https://myservice.webpubsub.azure.com/api/hubs/Hub/:send?api-version=2021-08-01-preview + response: + body: + string: '' + headers: + connection: + - keep-alive + content-length: + - '0' + date: + - Fri, 10 Sep 2021 06:17:31 GMT + strict-transport-security: + - max-age=15724800; includeSubDomains + status: + code: 202 + message: Accepted +version: 1 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml index 61470dba8f05..5e88eb3375e5 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml @@ -11,7 +11,7 @@ interactions: string: '' headers: connection: keep-alive - date: Thu, 09 Sep 2021 06:18:46 GMT + date: Fri, 10 Sep 2021 06:22:22 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 200 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml index ebce955fc379..a9fa233a5496 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml @@ -1,9 +1,9 @@ interactions: - request: - body: '{"hello": "world!!!"}' + body: '{"hello": "test_webpubsub_send_to_all"}' headers: Content-Length: - - '21' + - '39' Content-Type: - text/plain User-Agent: @@ -16,7 +16,7 @@ interactions: headers: connection: keep-alive content-length: '0' - date: Thu, 09 Sep 2021 06:18:48 GMT + date: Fri, 10 Sep 2021 06:22:24 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 202 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml new file mode 100644 index 000000000000..21beaf2aa57d --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml @@ -0,0 +1,25 @@ +interactions: +- request: + body: '{"hello": "test_webpubsub_send_to_all_apim_proxy"}' + headers: + Content-Length: + - '50' + Content-Type: + - text/plain + User-Agent: + - azsdk-python-messaging-webpubsubservice/1.0.0b2 Python/3.7.3 (Windows-10-10.0.19041-SP0) + method: POST + uri: https://myservice.webpubsub.azure.com/api/hubs/Hub/:send?api-version=2021-08-01-preview + response: + body: + string: '' + headers: + connection: keep-alive + content-length: '0' + date: Fri, 10 Sep 2021 06:22:27 GMT + strict-transport-security: max-age=15724800; includeSubDomains + status: + code: 202 + message: Accepted + url: https://webpubsub-yyc.webpubsub.azure.com/api/hubs/Hub/:send?api-version=2021-08-01-preview +version: 1 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py index 90328ecb9b7d..67091565e3a1 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py @@ -17,4 +17,9 @@ def test_health_api_status(self, webpubsub_endpoint): @WebpubsubPowerShellPreparer() def test_webpubsub_send_to_all(self, webpubsub_endpoint): client = self.create_client(endpoint=webpubsub_endpoint) - client.web_pub_sub.send_to_all('Hub', {'hello': 'world!!!'}) + client.web_pub_sub.send_to_all('Hub', {'hello': 'test_webpubsub_send_to_all'}) + + @WebpubsubPowerShellPreparer() + def test_webpubsub_send_to_all_api_management_proxy(self, webpubsub_endpoint, reverse_proxy_endpoint=None): + client = self.create_client(endpoint=webpubsub_endpoint, reverse_proxy_endpoint=reverse_proxy_endpoint) + client.web_pub_sub.send_to_all('Hub', {'hello': 'test_webpubsub_send_to_all_api_management_proxy'}) \ No newline at end of file diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py index a5e038b3fdac..e4a39afa287e 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py @@ -18,4 +18,9 @@ async def test_health_api_status(self, webpubsub_endpoint): @WebpubsubPowerShellPreparer() async def test_webpubsub_send_to_all(self, webpubsub_endpoint): client = self.create_client(endpoint=webpubsub_endpoint) - await client.web_pub_sub.send_to_all('Hub', {'hello': 'world!!!'}) + await client.web_pub_sub.send_to_all('Hub', {'hello': 'test_webpubsub_send_to_all'}) + + @WebpubsubPowerShellPreparer() + async def test_webpubsub_send_to_all_apim_proxy(self, webpubsub_endpoint, reverse_proxy_endpoint=None): + client = self.create_client(endpoint=webpubsub_endpoint, reverse_proxy_endpoint=reverse_proxy_endpoint) + await client.web_pub_sub.send_to_all('Hub', {'hello': 'test_webpubsub_send_to_all_apim_proxy'}) \ No newline at end of file diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase.py index ff53a46fa351..9f2875e70fc4 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase.py @@ -13,17 +13,19 @@ class WebpubsubTest(AzureTestCase): def __init__(self, method_name, **kwargs): super(WebpubsubTest, self).__init__(method_name, **kwargs) - def create_client(self, endpoint): + def create_client(self, endpoint, reverse_proxy_endpoint=None): credential = self.get_credential(WebPubSubServiceClient) return self.create_client_from_credential( WebPubSubServiceClient, credential=credential, endpoint=endpoint, + reverse_proxy_endpoint=reverse_proxy_endpoint ) WebpubsubPowerShellPreparer = functools.partial( PowerShellPreparer, "webpubsub", - webpubsub_endpoint="https://myservice.webpubsub.azure.com" + webpubsub_endpoint="https://myservice.webpubsub.azure.com", + webpubsub_reverse_proxy_endpoint="https://myservice.azure-api.net" ) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase_async.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase_async.py index 74e56b95bfe1..46f9f1662b8e 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase_async.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase_async.py @@ -12,10 +12,11 @@ class WebpubsubTestAsync(AzureTestCase): def __init__(self, method_name, **kwargs): super(WebpubsubTestAsync, self).__init__(method_name, **kwargs) - def create_client(self, endpoint): + def create_client(self, endpoint, reverse_proxy_endpoint=None): credential = self.get_credential(WebPubSubServiceClient, is_async=True) return self.create_client_from_credential( WebPubSubServiceClient, credential=credential, endpoint=endpoint, + reverse_proxy_endpoint=reverse_proxy_endpoint ) From 3983c0354a4509fb0dc1f43d50713784ec10daff Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Mon, 13 Sep 2021 10:50:13 +0800 Subject: [PATCH 15/33] edit code in _patch.py instead of generated code --- .../README.md | 2 +- .../messaging/webpubsubservice/__init__.py | 4 +- .../webpubsubservice/_configuration.py | 17 +- .../messaging/webpubsubservice/_patch.py | 327 ++++++++++++++++++ .../messaging/webpubsubservice/_policies.py | 110 ------ .../messaging/webpubsubservice/_utils.py | 45 --- .../_web_pub_sub_service_client.py | 125 +------ .../webpubsubservice/aio/__init__.py | 6 + .../webpubsubservice/aio/_configuration.py | 15 +- .../messaging/webpubsubservice/aio/_patch.py | 140 ++++++++ .../aio/_web_pub_sub_service_client.py | 26 +- .../test_smoke.test_health_api_status.yaml | 2 +- ...test_smoke.test_webpubsub_send_to_all.yaml | 2 +- ...bsub_send_to_all_api_management_proxy.yaml | 2 +- ...st_smoke_async.test_health_api_status.yaml | 2 +- ...moke_async.test_webpubsub_send_to_all.yaml | 2 +- ...test_webpubsub_send_to_all_apim_proxy.yaml | 2 +- 17 files changed, 503 insertions(+), 326 deletions(-) create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py delete mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py delete mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_utils.py create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/README.md b/sdk/webpubsub/azure-messaging-webpubsubservice/README.md index 335e09baa575..da0dc543328c 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/README.md +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/README.md @@ -99,7 +99,7 @@ Use the returned token credential to authenticate the client: try: client.web_pub_sub.send_to_all('ahub', content=f, content_type='application/json') except HttpResponseError as e: - print('service responds error') + print('service responds error: {}'.format(e.response.json())) ``` diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py index 554de553055e..656cd0b03180 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py @@ -6,11 +6,11 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._web_pub_sub_service_client import WebPubSubServiceClient, build_authentication_token +from ._web_pub_sub_service_client import WebPubSubServiceClient from ._version import VERSION __version__ = VERSION -__all__ = ['WebPubSubServiceClient', 'build_authentication_token'] +__all__ = ['WebPubSubServiceClient'] try: from ._patch import patch_sdk # type: ignore diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py index 1db338f83a88..c9073f30f623 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py @@ -12,12 +12,10 @@ from azure.core.pipeline import policies from ._version import VERSION -from ._policies import JwtCredentialPolicy, ApiManagementProxy -from azure.core.credentials import AzureKeyCredential if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports - from typing import Any, Optional, Union + from typing import Any, Optional from azure.core.credentials import TokenCredential @@ -29,15 +27,17 @@ class WebPubSubServiceClientConfiguration(Configuration): attributes. :param credential: Credential needed for the client to connect to Azure. - :type credential: Union[~azure.core.credentials.TokenCredential, ~azure.core.credentials.AzureKeyCredential] + :type credential: ~azure.core.credentials.TokenCredential """ def __init__( self, - credential, # type: Union[TokenCredential, AzureKeyCredential] + credential, # type: "TokenCredential" **kwargs # type: Any ): # type: (...) -> None + if credential is None: + raise ValueError("Parameter 'credential' must not be None.") super(WebPubSubServiceClientConfiguration, self).__init__(**kwargs) self.credential = credential @@ -56,11 +56,8 @@ def _configure( self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) self.retry_policy = kwargs.get('retry_policy') or policies.RetryPolicy(**kwargs) - self.custom_hook_policy = kwargs.get('custom_hook_policy') or ApiManagementProxy(**kwargs) + self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) self.redirect_policy = kwargs.get('redirect_policy') or policies.RedirectPolicy(**kwargs) self.authentication_policy = kwargs.get('authentication_policy') if self.credential and not self.authentication_policy: - if isinstance(self.credential, AzureKeyCredential): - self.authentication_policy = JwtCredentialPolicy(self.credential, kwargs.get('user')) - else: - self.authentication_policy = policies.BearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) + self.authentication_policy = policies.BearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py new file mode 100644 index 000000000000..bf10d19a3538 --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py @@ -0,0 +1,327 @@ +# -------------------------------------------------------------------------- +# +# Copyright (c) Microsoft Corporation. All rights reserved. +# +# The MIT License (MIT) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the ""Software""), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# +# -------------------------------------------------------------------------- +import typing +import jwt +import six +from datetime import datetime, timedelta, tzinfo +from typing import TYPE_CHECKING + +from ._version import VERSION +from .operations import HealthApiOperations, WebPubSubOperations +from ._web_pub_sub_service_client import WebPubSubServiceClient + +from msrest import Deserializer, Serializer +from azure.core.pipeline import policies +from azure.core import PipelineClient +from azure.core.configuration import Configuration +from azure.core.pipeline.policies import SansIOHTTPPolicy, CustomHookPolicy +from azure.core.credentials import AzureKeyCredential + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Type, TypeVar, Any, Union, Dict + + ClientType = TypeVar("ClientType", bound="WebPubSubServiceClient") + + from azure.core.credentials import TokenCredential + from azure.core.pipeline import PipelineRequest + + +class _UTC_TZ(tzinfo): + """from https://docs.python.org/2/library/datetime.html#tzinfo-objects""" + + ZERO = timedelta(0) + + def utcoffset(self, dt): + return self.__class__.ZERO + + def tzname(self, dt): + return "UTC" + + def dst(self, dt): + return self.__class__.ZERO + + +def _parse_connection_string(connection_string, **kwargs): + # type: (str, Any) -> Dict[Any] + for segment in connection_string.split(";"): + if "=" in segment: + key, value = segment.split("=", maxsplit=1) + key = key.lower() + if key not in ("version",): + kwargs.setdefault(key, value) + elif segment: + raise ValueError( + "Malformed connection string - expected 'key=value', found segment '{}' in '{}'".format( + segment, connection_string + ) + ) + + if "endpoint" not in kwargs: + raise ValueError("connection_string missing 'endpoint' field") + + if "accesskey" not in kwargs: + raise ValueError("connection_string missing 'accesskey' field") + + return kwargs + + +def build_authentication_token(endpoint, hub, **kwargs): + # type: (str, str, Any) -> Dict[Any] + """Build an authentication token for the given endpoint, hub using the provided key. + + :keyword endpoint: connetion string or HTTP or HTTPS endpoint for the WebPubSub service instance. + :type endpoint: ~str + :keyword hub: The hub to give access to. + :type hub: ~str + :keyword accesskey: Key to sign the token with. Required if endpoint is not a connection string + :type accesskey: ~str + :keyword ttl: Optional ttl timedelta for the token. Default is 1 hour. + :type ttl: ~datetime.timedelta + :keyword user: Optional user name (subject) for the token. Default is no user. + :type user: ~str + :keyword roles: Roles for the token. + :type roles: typing.List[str]. Default is no roles. + :returns: ~dict containing the web socket endpoint, the token and a url with the generated access token. + :rtype: ~dict + + + Example: + >>> build_authentication_token(endpoint='https://contoso.com/api/webpubsub', hub='theHub', key='123') + { + 'baseUrl': 'wss://contoso.com/api/webpubsub/client/hubs/theHub', + 'token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ...', + 'url': 'wss://contoso.com/api/webpubsub/client/hubs/theHub?access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ...' + } + """ + if 'accesskey' not in kwargs: + kwargs = _parse_connection_string(endpoint, **kwargs) + endpoint = kwargs.pop('endpoint') + + user = kwargs.pop("user", None) + key = kwargs.pop("accesskey") + ttl = kwargs.pop("ttl", timedelta(hours=1)) + roles = kwargs.pop("roles", []) + endpoint = endpoint.lower() + if not endpoint.startswith("http://") and not endpoint.startswith("https://"): + raise ValueError( + "Invalid endpoint: '{}' has unknown scheme - expected 'http://' or 'https://'".format( + endpoint + ) + ) + + # Ensure endpoint has no trailing slash + endpoint = endpoint.rstrip("/") + + # Switch from http(s) to ws(s) scheme + client_endpoint = "ws" + endpoint[4:] + client_url = "{}/client/hubs/{}".format(client_endpoint, hub) + audience = "{}/client/hubs/{}".format(endpoint, hub) + + payload = { + "aud": audience, + "iat": datetime.now(tz=_UTC_TZ()), + "exp": datetime.now(tz=_UTC_TZ()) + ttl, + } + if user: + payload["sub"] = user + if roles: + payload["role"] = roles + + token = six.ensure_str(jwt.encode(payload, key, algorithm="HS256")) + return { + "baseUrl": client_url, + "token": token, + "url": "{}?access_token={}".format(client_url, token), + } + + +class JwtCredentialPolicy(SansIOHTTPPolicy): + + NAME_CLAIM_TYPE = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" + + def __init__(self, credential, user=None): + # type: (AzureKeyCredential, typing.Optional[str]) -> None + """Create a new instance of the policy associated with the given credential. + + :param credential: The azure.core.credentials.AzureKeyCredential instance to use + :type credential: ~azure.core.credentials.AzureKeyCredential + :param user: Optional user name associated with the credential. + :type user: str + """ + self._credential = credential + self._user = user + + def on_request(self, request): + # type: (PipelineRequest) -> typing.Union[None, typing.Awaitable[None]] + """Is executed before sending the request from next policy. + + :param request: Request to be modified before sent from next policy. + :type request: ~azure.core.pipeline.PipelineRequest + """ + request.http_request.headers["Authorization"] = "Bearer " + self._encode( + request.http_request.url + ) + return super(JwtCredentialPolicy, self).on_request(request) + + def _encode(self, url): + # type: (AzureKeyCredential) -> str + data = { + "aud": url, + "exp": datetime.now(tz=_UTC_TZ()) + timedelta(seconds=60), + } + if self._user: + data[self.NAME_CLAIM_TYPE] = self._user + + encoded = jwt.encode( + payload=data, + key=self._credential.key, + algorithm="HS256", + ) + return six.ensure_str(encoded) + + +class ApiManagementProxy(CustomHookPolicy): + + def __init__(self, **kwargs): + # type: (typing.Optional[str], typing.Optional[str]) -> None + """Create a new instance of the policy. + + :param endpoint: endpoint to be replaced + :type endpoint: str + :param proxy_endpoint: proxy endpoint + :type proxy_endpoint: str + """ + self._endpoint = kwargs.pop('origin_endpoint', None) + self._reverse_proxy_endpoint = kwargs.pop('reverse_proxy_endpoint', None) + super(ApiManagementProxy, self).__init__(**kwargs) + + def on_request(self, request): + # type: (PipelineRequest) -> None + """Is executed before sending the request from next policy. + + :param request: Request to be modified before sent from next policy. + :type request: ~azure.core.pipeline.PipelineRequest + """ + super(ApiManagementProxy, self).on_request(request) + if self._endpoint and self._reverse_proxy_endpoint: + request.http_request.url = request.http_request.url.replace(self._endpoint, self._reverse_proxy_endpoint) + + +class WebPubSubServiceClientConfiguration(Configuration): + """Configuration for WebPubSubServiceClient. + + Note that all parameters used to create this instance are saved as instance + attributes. + + :param credential: Credential needed for the client to connect to Azure. + :type credential: Union[~azure.core.credentials.TokenCredential, ~azure.core.credentials.AzureKeyCredential] + """ + + def __init__( + self, + credential, # type: Union[TokenCredential, AzureKeyCredential] + **kwargs # type: Any + ): + # type: (...) -> None + super(WebPubSubServiceClientConfiguration, self).__init__(**kwargs) + + self.credential = credential + self.credential_scopes = kwargs.pop('credential_scopes', ['https://webpubsub.azure.com/.default']) + kwargs.setdefault('sdk_moniker', 'messaging-webpubsubservice/{}'.format(VERSION)) + self._configure(**kwargs) + + def _configure( + self, + **kwargs # type: Any + ): + # type: (...) -> None + self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) + self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) + self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) + self.retry_policy = kwargs.get('retry_policy') or policies.RetryPolicy(**kwargs) + self.custom_hook_policy = kwargs.get('custom_hook_policy') or ApiManagementProxy(**kwargs) + self.redirect_policy = kwargs.get('redirect_policy') or policies.RedirectPolicy(**kwargs) + self.authentication_policy = kwargs.get('authentication_policy') + if self.credential and not self.authentication_policy: + if isinstance(self.credential, AzureKeyCredential): + self.authentication_policy = JwtCredentialPolicy(self.credential, kwargs.get('user')) + else: + self.authentication_policy = policies.BearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) + + +class WebPubSubServicePatchClient(object): + """PatchClient. + + :ivar health_api: HealthApiOperations operations + :vartype health_api: azure.messaging.webpubsubservice.operations.HealthApiOperations + :ivar web_pub_sub: WebPubSubOperations operations + :vartype web_pub_sub: azure.messaging.webpubsubservice.operations.WebPubSubOperations + :keyword connection_string: connection string needed for the client to connect to Azure. + :paramtype connection_string: str + :param credential: Credential needed for the client to connect to Azure. + :type credential: Union[~azure.core.credentials.TokenCredential, ~azure.core.credentials.AzureKeyCredential] + :keyword endpoint: Service URL. Default value is ''. + :paramtype endpoint: str + """ + + def __init__( + self, + credential, # type: Union[TokenCredential, AzureKeyCredential] + **kwargs # type: Any + ): + # type: (...) -> None + endpoint = kwargs.pop('endpoint', "") # type: str + kwargs['origin_endpoint'] = endpoint + self._config = WebPubSubServiceClientConfiguration(credential, **kwargs) + self._client = PipelineClient(base_url=endpoint, config=self._config, **kwargs) + + self._serialize = Serializer() + self._deserialize = Deserializer() + self._serialize.client_side_validation = False + self.health_api = HealthApiOperations(self._client, self._config, self._serialize, self._deserialize) + self.web_pub_sub = WebPubSubOperations(self._client, self._config, self._serialize, self._deserialize) + + @classmethod + def from_connection_string(cls, connection_string, **kwargs): + # type: (Type[ClientType], str, Any) -> ClientType + """Create a new WebPubSubServiceClient from a connection string. + + :param connection_string: Connection string + :type connection_string: ~str + :rtype: WebPubSubServiceClient + """ + kwargs = _parse_connection_string(connection_string, **kwargs) + + credential = AzureKeyCredential(kwargs.pop("accesskey")) + return cls(credential=credential, **kwargs) + + +def patch_sdk(): + WebPubSubServiceClient.__init__ = WebPubSubServicePatchClient.__init__ + WebPubSubServiceClient.from_connection_string = WebPubSubServicePatchClient.from_connection_string diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py deleted file mode 100644 index 8f68612c45de..000000000000 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_policies.py +++ /dev/null @@ -1,110 +0,0 @@ -# -------------------------------------------------------------------------- -# -# Copyright (c) Microsoft Corporation. All rights reserved. -# -# The MIT License (MIT) -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the ""Software""), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. -# -# -------------------------------------------------------------------------- - -import datetime -import typing -import jwt -import six - -from azure.core.pipeline.policies import SansIOHTTPPolicy, CustomHookPolicy - -from ._utils import UTC - -if typing.TYPE_CHECKING: - from azure.core.credentials import AzureKeyCredential - from azure.core.pipeline import PipelineRequest - - -class JwtCredentialPolicy(SansIOHTTPPolicy): - - NAME_CLAIM_TYPE = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" - - def __init__(self, credential, user=None): - # type: (AzureKeyCredential, typing.Optional[str]) -> None - """Create a new instance of the policy associated with the given credential. - - :param credential: The azure.core.credentials.AzureKeyCredential instance to use - :type credential: ~azure.core.credentials.AzureKeyCredential - :param user: Optional user name associated with the credential. - :type user: str - """ - self._credential = credential - self._user = user - - def on_request(self, request): - # type: (PipelineRequest) -> typing.Union[None, typing.Awaitable[None]] - """Is executed before sending the request from next policy. - - :param request: Request to be modified before sent from next policy. - :type request: ~azure.core.pipeline.PipelineRequest - """ - request.http_request.headers["Authorization"] = "Bearer " + self._encode( - request.http_request.url - ) - return super(JwtCredentialPolicy, self).on_request(request) - - def _encode(self, url): - # type: (AzureKeyCredential) -> str - data = { - "aud": url, - "exp": datetime.datetime.now(tz=UTC) + datetime.timedelta(seconds=60), - } - if self._user: - data[self.NAME_CLAIM_TYPE] = self._user - - encoded = jwt.encode( - payload=data, - key=self._credential.key, - algorithm="HS256", - ) - return six.ensure_str(encoded) - - -class ApiManagementProxy(CustomHookPolicy): - - def __init__(self, **kwargs): - # type: (typing.Optional[str], typing.Optional[str]) -> None - """Create a new instance of the policy. - - :param endpoint: endpoint to be replaced - :type endpoint: str - :param proxy_endpoint: proxy endpoint - :type proxy_endpoint: str - """ - self._endpoint = kwargs.pop('origin_endpoint', None) - self._reverse_proxy_endpoint = kwargs.pop('reverse_proxy_endpoint', None) - super(ApiManagementProxy, self).__init__(**kwargs) - - def on_request(self, request): - # type: (PipelineRequest) -> None - """Is executed before sending the request from next policy. - - :param request: Request to be modified before sent from next policy. - :type request: ~azure.core.pipeline.PipelineRequest - """ - super(ApiManagementProxy, self).on_request(request) - if self._endpoint and self._reverse_proxy_endpoint: - request.http_request.url = request.http_request.url.replace(self._endpoint, self._reverse_proxy_endpoint) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_utils.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_utils.py deleted file mode 100644 index 042b46dd8848..000000000000 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_utils.py +++ /dev/null @@ -1,45 +0,0 @@ -# -------------------------------------------------------------------------- -# -# Copyright (c) Microsoft Corporation. All rights reserved. -# -# The MIT License (MIT) -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the ""Software""), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. -# -# -------------------------------------------------------------------------- - -import datetime - - -class _UTC_TZ(datetime.tzinfo): - """from https://docs.python.org/2/library/datetime.html#tzinfo-objects""" - - ZERO = datetime.timedelta(0) - - def utcoffset(self, dt): - return self.__class__.ZERO - - def tzname(self, dt): - return "UTC" - - def dst(self, dt): - return self.__class__.ZERO - - -UTC = _UTC_TZ() diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py index eac8ba62f8d4..2b69eac16e8a 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py @@ -8,121 +8,20 @@ from copy import deepcopy from typing import TYPE_CHECKING -from datetime import datetime, timedelta - -import jwt -import six from azure.core import PipelineClient from msrest import Deserializer, Serializer -from azure.core.credentials import AzureKeyCredential from ._configuration import WebPubSubServiceClientConfiguration from .operations import HealthApiOperations, WebPubSubOperations -from ._utils import UTC as _UTC if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports - from typing import Any, Dict, Optional, Union + from typing import Any, Dict, Optional from azure.core.credentials import TokenCredential from azure.core.rest import HttpRequest, HttpResponse - -def _parse_connection_string(connection_string, **kwargs): - # type: (str, Any) -> Dict[Any] - for segment in connection_string.split(";"): - if "=" in segment: - key, value = segment.split("=", maxsplit=1) - key = key.lower() - if key not in ("version",): - kwargs.setdefault(key, value) - elif segment: - raise ValueError( - "Malformed connection string - expected 'key=value', found segment '{}' in '{}'".format( - segment, connection_string - ) - ) - - if "endpoint" not in kwargs: - raise ValueError("connection_string missing 'endpoint' field") - - if "accesskey" not in kwargs: - raise ValueError("connection_string missing 'accesskey' field") - - return kwargs - - -def build_authentication_token(endpoint, hub, **kwargs): - # type: (str, str, Any) -> Dict[Any] - """Build an authentication token for the given endpoint, hub using the provided key. - - :keyword endpoint: connetion string or HTTP or HTTPS endpoint for the WebPubSub service instance. - :type endpoint: ~str - :keyword hub: The hub to give access to. - :type hub: ~str - :keyword accesskey: Key to sign the token with. Required if endpoint is not a connection string - :type accesskey: ~str - :keyword ttl: Optional ttl timedelta for the token. Default is 1 hour. - :type ttl: ~datetime.timedelta - :keyword user: Optional user name (subject) for the token. Default is no user. - :type user: ~str - :keyword roles: Roles for the token. - :type roles: typing.List[str]. Default is no roles. - :returns: ~dict containing the web socket endpoint, the token and a url with the generated access token. - :rtype: ~dict - - - Example: - >>> build_authentication_token(endpoint='https://contoso.com/api/webpubsub', hub='theHub', key='123') - { - 'baseUrl': 'wss://contoso.com/api/webpubsub/client/hubs/theHub', - 'token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ...', - 'url': 'wss://contoso.com/api/webpubsub/client/hubs/theHub?access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ...' - } - """ - if 'accesskey' not in kwargs: - kwargs = _parse_connection_string(endpoint, **kwargs) - endpoint = kwargs.pop('endpoint') - - user = kwargs.pop("user", None) - key = kwargs.pop("accesskey") - ttl = kwargs.pop("ttl", timedelta(hours=1)) - roles = kwargs.pop("roles", []) - endpoint = endpoint.lower() - if not endpoint.startswith("http://") and not endpoint.startswith("https://"): - raise ValueError( - "Invalid endpoint: '{}' has unknown scheme - expected 'http://' or 'https://'".format( - endpoint - ) - ) - - # Ensure endpoint has no trailing slash - endpoint = endpoint.rstrip("/") - - # Switch from http(s) to ws(s) scheme - client_endpoint = "ws" + endpoint[4:] - client_url = "{}/client/hubs/{}".format(client_endpoint, hub) - audience = "{}/client/hubs/{}".format(endpoint, hub) - - payload = { - "aud": audience, - "iat": datetime.now(tz=_UTC), - "exp": datetime.now(tz=_UTC) + ttl, - } - if user: - payload["sub"] = user - if roles: - payload["role"] = roles - - token = six.ensure_str(jwt.encode(payload, key, algorithm="HS256")) - return { - "baseUrl": client_url, - "token": token, - "url": "{}?access_token={}".format(client_url, token), - } - - class WebPubSubServiceClient(object): """WebPubSubServiceClient. @@ -130,22 +29,20 @@ class WebPubSubServiceClient(object): :vartype health_api: azure.messaging.webpubsubservice.operations.HealthApiOperations :ivar web_pub_sub: WebPubSubOperations operations :vartype web_pub_sub: azure.messaging.webpubsubservice.operations.WebPubSubOperations - :keyword connection_string: connection string needed for the client to connect to Azure. - :paramtype connection_string: str :param credential: Credential needed for the client to connect to Azure. - :type credential: Union[~azure.core.credentials.TokenCredential, ~azure.core.credentials.AzureKeyCredential] + :type credential: ~azure.core.credentials.TokenCredential :keyword endpoint: Service URL. Default value is ''. :paramtype endpoint: str """ def __init__( self, - credential, # type: Union[TokenCredential, AzureKeyCredential] + credential, # type: "TokenCredential" **kwargs # type: Any ): # type: (...) -> None endpoint = kwargs.pop('endpoint', "") # type: str - kwargs['origin_endpoint'] = endpoint + self._config = WebPubSubServiceClientConfiguration(credential, **kwargs) self._client = PipelineClient(base_url=endpoint, config=self._config, **kwargs) @@ -195,17 +92,3 @@ def __enter__(self): def __exit__(self, *exc_details): # type: (Any) -> None self._client.__exit__(*exc_details) - - @classmethod - def from_connection_string(cls, connection_string, **kwargs): - # type: (Type[ClientType], str, Any) -> ClientType - """Create a new WebPubSubServiceClient from a connection string. - - :param connection_string: Connection string - :type connection_string: ~str - :rtype: WebPubSubServiceClient - """ - kwargs = _parse_connection_string(connection_string, **kwargs) - - credential = AzureKeyCredential(kwargs.pop("accesskey")) - return cls(credential=credential, **kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py index 1ce892c0a9e6..d33c98d8f4c4 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py @@ -8,3 +8,9 @@ from ._web_pub_sub_service_client import WebPubSubServiceClient __all__ = ['WebPubSubServiceClient'] + +try: + from ._patch import patch_sdk # type: ignore + patch_sdk() +except ImportError: + pass diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py index bd977f3fbf59..49311d80530d 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py @@ -6,14 +6,12 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from typing import Any, Optional, TYPE_CHECKING, Union +from typing import Any, Optional, TYPE_CHECKING from azure.core.configuration import Configuration from azure.core.pipeline import policies from .._version import VERSION -from .._policies import JwtCredentialPolicy, ApiManagementProxy -from azure.core.credentials import AzureKeyCredential if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports @@ -27,12 +25,12 @@ class WebPubSubServiceClientConfiguration(Configuration): attributes. :param credential: Credential needed for the client to connect to Azure. - :type credential: Union[~azure.core.credentials_async.AsyncTokenCredential, ~azure.core.credentials.AzureKeyCredential] + :type credential: ~azure.core.credentials_async.AsyncTokenCredential """ def __init__( self, - credential: Union["AsyncTokenCredential", "AzureKeyCredential"], + credential: "AsyncTokenCredential", **kwargs: Any ) -> None: if credential is None: @@ -54,11 +52,8 @@ def _configure( self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) self.retry_policy = kwargs.get('retry_policy') or policies.AsyncRetryPolicy(**kwargs) - self.custom_hook_policy = kwargs.get('custom_hook_policy') or ApiManagementProxy(**kwargs) + self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) self.redirect_policy = kwargs.get('redirect_policy') or policies.AsyncRedirectPolicy(**kwargs) self.authentication_policy = kwargs.get('authentication_policy') if self.credential and not self.authentication_policy: - if isinstance(self.credential, AzureKeyCredential): - self.authentication_policy = JwtCredentialPolicy(self.credential, kwargs.get('user')) - else: - self.authentication_policy = policies.AsyncBearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) + self.authentication_policy = policies.AsyncBearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py new file mode 100644 index 000000000000..ebcf89207763 --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py @@ -0,0 +1,140 @@ +# -------------------------------------------------------------------------- +# +# Copyright (c) Microsoft Corporation. All rights reserved. +# +# The MIT License (MIT) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the ""Software""), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# +# -------------------------------------------------------------------------- + +from typing import Any, TYPE_CHECKING, Union + + +from azure.core import AsyncPipelineClient +from msrest import Deserializer, Serializer + +from .._version import VERSION +from .operations import HealthApiOperations, WebPubSubOperations +from .._patch import JwtCredentialPolicy, ApiManagementProxy +from ._web_pub_sub_service_client import WebPubSubServiceClient + + +from azure.core.configuration import Configuration +from azure.core.pipeline import policies +from azure.core.credentials import AzureKeyCredential + + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Dict, TypeVar, Type + ClientType = TypeVar("ClientType", bound="WebPubSubServiceClient") + + from azure.core.credentials_async import AsyncTokenCredential + + +class WebPubSubServiceClientConfiguration(Configuration): + """Configuration for WebPubSubServiceClient. + + Note that all parameters used to create this instance are saved as instance + attributes. + + :param credential: Credential needed for the client to connect to Azure. + :type credential: Union[~azure.core.credentials_async.AsyncTokenCredential, ~azure.core.credentials.AzureKeyCredential] + """ + + def __init__( + self, + credential: Union["AsyncTokenCredential", "AzureKeyCredential"], + **kwargs: Any + ) -> None: + if credential is None: + raise ValueError("Parameter 'credential' must not be None.") + super(WebPubSubServiceClientConfiguration, self).__init__(**kwargs) + + self.credential = credential + self.credential_scopes = kwargs.pop('credential_scopes', ['https://webpubsub.azure.com/.default']) + kwargs.setdefault('sdk_moniker', 'messaging-webpubsubservice/{}'.format(VERSION)) + self._configure(**kwargs) + + def _configure( + self, + **kwargs: Any + ) -> None: + self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) + self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) + self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) + self.retry_policy = kwargs.get('retry_policy') or policies.AsyncRetryPolicy(**kwargs) + self.custom_hook_policy = kwargs.get('custom_hook_policy') or ApiManagementProxy(**kwargs) + self.redirect_policy = kwargs.get('redirect_policy') or policies.AsyncRedirectPolicy(**kwargs) + self.authentication_policy = kwargs.get('authentication_policy') + if self.credential and not self.authentication_policy: + if isinstance(self.credential, AzureKeyCredential): + self.authentication_policy = JwtCredentialPolicy(self.credential, kwargs.get('user')) + else: + self.authentication_policy = policies.AsyncBearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) + +class AsyncWebPubSubServicePatchClient: + """WebPubSubServiceClient. + + :ivar health_api: HealthApiOperations operations + :vartype health_api: azure.messaging.webpubsubservice.aio.operations.HealthApiOperations + :ivar web_pub_sub: WebPubSubOperations operations + :vartype web_pub_sub: azure.messaging.webpubsubservice.aio.operations.WebPubSubOperations + :param credential: Credential needed for the client to connect to Azure. + :type credential: Union[~azure.core.credentials_async.AsyncTokenCredential, ~azure.core.credentials.AzureKeyCredential] + :keyword endpoint: Service URL. Default value is ''. + :paramtype endpoint: str + """ + + def __init__( + self, + credential: Union["AsyncTokenCredential", "AzureKeyCredential"], + **kwargs: Any + ) -> None: + endpoint = kwargs.pop('endpoint', "") # type: str + kwargs['origin_endpoint'] = endpoint + self._config = WebPubSubServiceClientConfiguration(credential, **kwargs) + self._client = AsyncPipelineClient(base_url=endpoint, config=self._config, **kwargs) + + self._serialize = Serializer() + self._deserialize = Deserializer() + self._serialize.client_side_validation = False + self.health_api = HealthApiOperations(self._client, self._config, self._serialize, self._deserialize) + self.web_pub_sub = WebPubSubOperations(self._client, self._config, self._serialize, self._deserialize) + + @classmethod + def from_connection_string(cls, connection_string, **kwargs): + # type: (Type[ClientType], str, Any) -> ClientType + """Create a new WebPubSubServiceClient from a connection string. + :param connection_string: Connection string + :type connection_string: ~str + :rtype: WebPubSubServiceClient + """ + kwargs = _parse_connection_string(connection_string, **kwargs) + + credential = AzureKeyCredential(kwargs.pop("accesskey")) + return cls(credential=credential, **kwargs) + + +def patch_sdk(): + WebPubSubServiceClient.__init__ = AsyncWebPubSubServicePatchClient.__init__ + WebPubSubServiceClient.from_connection_string = AsyncWebPubSubServicePatchClient.from_connection_string diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py index 301b0a70ead2..a733e3fa6e0c 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py @@ -7,16 +7,14 @@ # -------------------------------------------------------------------------- from copy import deepcopy -from typing import Any, Awaitable, Optional, TYPE_CHECKING, Union +from typing import Any, Awaitable, Optional, TYPE_CHECKING from azure.core import AsyncPipelineClient from azure.core.rest import AsyncHttpResponse, HttpRequest from msrest import Deserializer, Serializer -from azure.core.credentials import AzureKeyCredential from ._configuration import WebPubSubServiceClientConfiguration from .operations import HealthApiOperations, WebPubSubOperations -from .._web_pub_sub_service_client import _parse_connection_string if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports @@ -32,18 +30,18 @@ class WebPubSubServiceClient: :ivar web_pub_sub: WebPubSubOperations operations :vartype web_pub_sub: azure.messaging.webpubsubservice.aio.operations.WebPubSubOperations :param credential: Credential needed for the client to connect to Azure. - :type credential: Union[~azure.core.credentials_async.AsyncTokenCredential, ~azure.core.credentials.AzureKeyCredential] + :type credential: ~azure.core.credentials_async.AsyncTokenCredential :keyword endpoint: Service URL. Default value is ''. :paramtype endpoint: str """ def __init__( self, - credential: Union["AsyncTokenCredential", "AzureKeyCredential"], + credential: "AsyncTokenCredential", + *, + endpoint: str = "", **kwargs: Any ) -> None: - endpoint = kwargs.pop('endpoint', "") # type: str - kwargs['origin_endpoint'] = endpoint self._config = WebPubSubServiceClientConfiguration(credential, **kwargs) self._client = AsyncPipelineClient(base_url=endpoint, config=self._config, **kwargs) @@ -89,17 +87,3 @@ async def __aenter__(self) -> "WebPubSubServiceClient": async def __aexit__(self, *exc_details) -> None: await self._client.__aexit__(*exc_details) - - @classmethod - def from_connection_string(cls, connection_string, **kwargs): - # type: (Type[ClientType], str, Any) -> ClientType - """Create a new WebPubSubServiceClient from a connection string. - - :param connection_string: Connection string - :type connection_string: ~str - :rtype: WebPubSubServiceClient - """ - kwargs = _parse_connection_string(connection_string, **kwargs) - - credential = AzureKeyCredential(kwargs.pop("accesskey")) - return cls(credential=credential, **kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml index 037768f5cb69..e040c6d4711a 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml @@ -19,7 +19,7 @@ interactions: connection: - keep-alive date: - - Fri, 10 Sep 2021 06:17:26 GMT + - Mon, 13 Sep 2021 02:40:34 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml index a262a1145d75..1420490de3eb 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml @@ -25,7 +25,7 @@ interactions: content-length: - '0' date: - - Fri, 10 Sep 2021 06:17:28 GMT + - Mon, 13 Sep 2021 02:40:37 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml index 520493029865..da5e8293436c 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml @@ -25,7 +25,7 @@ interactions: content-length: - '0' date: - - Fri, 10 Sep 2021 06:17:31 GMT + - Mon, 13 Sep 2021 02:40:39 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml index 5e88eb3375e5..8b0b8326416c 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml @@ -11,7 +11,7 @@ interactions: string: '' headers: connection: keep-alive - date: Fri, 10 Sep 2021 06:22:22 GMT + date: Mon, 13 Sep 2021 02:41:27 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 200 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml index a9fa233a5496..4261243c68db 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml @@ -16,7 +16,7 @@ interactions: headers: connection: keep-alive content-length: '0' - date: Fri, 10 Sep 2021 06:22:24 GMT + date: Mon, 13 Sep 2021 02:41:29 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 202 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml index 21beaf2aa57d..1047da554a3e 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml @@ -16,7 +16,7 @@ interactions: headers: connection: keep-alive content-length: '0' - date: Fri, 10 Sep 2021 06:22:27 GMT + date: Mon, 13 Sep 2021 02:41:32 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 202 From 9cc207e88aee5466cb151bf3956f2ffc8b46256c Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Mon, 13 Sep 2021 14:21:34 +0800 Subject: [PATCH 16/33] review --- .../azure/messaging/webpubsubservice/__init__.py | 3 +++ .../azure/messaging/webpubsubservice/aio/_patch.py | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py index 656cd0b03180..74a9e821e4e3 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py @@ -15,5 +15,8 @@ try: from ._patch import patch_sdk # type: ignore patch_sdk() + + from ._patch import build_authentication_token + __all__.append('build_authentication_token') except ImportError: pass diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py index ebcf89207763..3c1111f1969e 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py @@ -32,7 +32,7 @@ from .._version import VERSION from .operations import HealthApiOperations, WebPubSubOperations -from .._patch import JwtCredentialPolicy, ApiManagementProxy +from .._patch import JwtCredentialPolicy, ApiManagementProxy, _parse_connection_string from ._web_pub_sub_service_client import WebPubSubServiceClient @@ -92,6 +92,7 @@ def _configure( else: self.authentication_policy = policies.AsyncBearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) + class AsyncWebPubSubServicePatchClient: """WebPubSubServiceClient. From b4bfd53017d77b30aa01674db8e5de5446c74b54 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Mon, 13 Sep 2021 15:30:58 +0800 Subject: [PATCH 17/33] fix broken link --- sdk/webpubsub/azure-messaging-webpubsubservice/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/README.md b/sdk/webpubsub/azure-messaging-webpubsubservice/README.md index da0dc543328c..92d60407b54c 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/README.md +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/README.md @@ -199,8 +199,8 @@ additional questions or comments. [azure_identity_pip]: https://pypi.org/project/azure-identity/ [default_azure_credential]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/identity/azure-identity#defaultazurecredential [pip]: https://pypi.org/project/pip/ -[enable_aad]: https://docs.microsoft.com/en-us/azure/azure-web-pubsub/howto-develop-create-instance -[api_key]: https://docs.microsoft.com/en-us/azure/azure-web-pubsub/howto-websocket-connect?tabs=browser#authorization -[connection_string]: https://docs.microsoft.com/en-us/azure/azure-web-pubsub/howto-websocket-connect?tabs=browser#authorization -[azure_portal]: https://docs.microsoft.com/en-us/azure/azure-web-pubsub/howto-develop-create-instance +[enable_aad]: https://docs.microsoft.com/azure/azure-web-pubsub/howto-develop-create-instance +[api_key]: https://docs.microsoft.com/azure/azure-web-pubsub/howto-websocket-connect?tabs=browser#authorization +[connection_string]: https://docs.microsoft.com/azure/azure-web-pubsub/howto-websocket-connect?tabs=browser#authorization +[azure_portal]: https://docs.microsoft.com/azure/azure-web-pubsub/howto-develop-create-instance [azure-key-credential]: https://aka.ms/azsdk-python-core-azurekeycredential \ No newline at end of file From be9026ebcd4bd37740c7dc0fdac8206ea0cad74c Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Mon, 13 Sep 2021 17:01:02 +0800 Subject: [PATCH 18/33] Update setup.py --- sdk/webpubsub/azure-messaging-webpubsubservice/setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py b/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py index d212bc6fe0fe..28df370305b5 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py @@ -63,6 +63,7 @@ install_requires=[ "azure-core<2.0.0,>=1.16.0", "msrest>=0.6.21", + "cryptography>=2.1.4", "pyjwt>=1.7.1", "six>=1.12.0", ], From e296dbeee8f5493463083586501dd45e0720fa36 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Tue, 14 Sep 2021 15:46:29 +0800 Subject: [PATCH 19/33] Update dev_requirements.txt --- .../azure-messaging-webpubsubservice/dev_requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/dev_requirements.txt b/sdk/webpubsub/azure-messaging-webpubsubservice/dev_requirements.txt index 7e186f5cb543..b7de0d29b347 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/dev_requirements.txt +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/dev_requirements.txt @@ -1,7 +1,7 @@ -e ../../../tools/azure-devtools -e ../../../tools/azure-sdk-tools ../../core/azure-core -../../identity/azure-identity +azure-identity==1.6.1 ../../nspkg/azure-messaging-nspkg aiohttp>=3.0; python_version >= '3.5' typing_extensions>=3.7.2 From a367a37dee11a8e2692e7a57e5f9095d30deeed1 Mon Sep 17 00:00:00 2001 From: Yuchao Yan Date: Tue, 14 Sep 2021 16:22:23 +0800 Subject: [PATCH 20/33] fix ci --- .../azure-messaging-webpubsubservice/dev_requirements.txt | 2 +- sdk/webpubsub/azure-messaging-webpubsubservice/setup.py | 2 +- shared_requirements.txt | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/dev_requirements.txt b/sdk/webpubsub/azure-messaging-webpubsubservice/dev_requirements.txt index b7de0d29b347..7e186f5cb543 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/dev_requirements.txt +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/dev_requirements.txt @@ -1,7 +1,7 @@ -e ../../../tools/azure-devtools -e ../../../tools/azure-sdk-tools ../../core/azure-core -azure-identity==1.6.1 +../../identity/azure-identity ../../nspkg/azure-messaging-nspkg aiohttp>=3.0; python_version >= '3.5' typing_extensions>=3.7.2 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py b/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py index 28df370305b5..50dc4325e817 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py @@ -63,7 +63,7 @@ install_requires=[ "azure-core<2.0.0,>=1.16.0", "msrest>=0.6.21", - "cryptography>=2.1.4", + "cryptography>=2.5.0", "pyjwt>=1.7.1", "six>=1.12.0", ], diff --git a/shared_requirements.txt b/shared_requirements.txt index 884a42dec863..1d03bfe589b7 100644 --- a/shared_requirements.txt +++ b/shared_requirements.txt @@ -223,6 +223,7 @@ opentelemetry-sdk<2.0.0,>=1.0.0 #override azure-messaging-webpubsubservice msrest>=0.6.18 #override azure-messaging-webpubsubservice pyjwt>=1.7.1 #override azure-messaging-webpubsubservice six>=1.12.0 +#override azure-messaging-webpubsubservice cryptography>=2.5.0 #override azure-mixedreality-authentication azure-core<2.0.0,>=1.4.0 #override azure-iot-deviceupdate azure-core<2.0.0,>=1.6.0 #override azure-mgmt-changeanalysis msrest>=0.6.21 From 9f954b20f15ae5a25848785418cd0ed261d9089d Mon Sep 17 00:00:00 2001 From: Yuchao Yan Date: Tue, 14 Sep 2021 17:23:46 +0800 Subject: [PATCH 21/33] fix ci --- sdk/webpubsub/azure-messaging-webpubsubservice/setup.py | 2 +- shared_requirements.txt | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py b/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py index 50dc4325e817..f0f590cba3a3 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py @@ -63,7 +63,7 @@ install_requires=[ "azure-core<2.0.0,>=1.16.0", "msrest>=0.6.21", - "cryptography>=2.5.0", + "cryptography>=2.8.0", "pyjwt>=1.7.1", "six>=1.12.0", ], diff --git a/shared_requirements.txt b/shared_requirements.txt index 1d03bfe589b7..e43257b8e00a 100644 --- a/shared_requirements.txt +++ b/shared_requirements.txt @@ -219,11 +219,11 @@ opentelemetry-sdk<2.0.0,>=1.0.0 #override azure-core-tracing-opentelemetry opentelemetry-api<2.0.0,>=1.0.0 #override azure-identity six>=1.12.0 #override azure-keyvault-keys six>=1.12.0 -#override azure-messaging-webpubsubservice azure-core<2.0.0,>=1.10.0 -#override azure-messaging-webpubsubservice msrest>=0.6.18 +#override azure-messaging-webpubsubservice azure-core<2.0.0,>=1.16.0 +#override azure-messaging-webpubsubservice msrest>=0.6.21 #override azure-messaging-webpubsubservice pyjwt>=1.7.1 #override azure-messaging-webpubsubservice six>=1.12.0 -#override azure-messaging-webpubsubservice cryptography>=2.5.0 +#override azure-messaging-webpubsubservice cryptography>=2.8.0 #override azure-mixedreality-authentication azure-core<2.0.0,>=1.4.0 #override azure-iot-deviceupdate azure-core<2.0.0,>=1.6.0 #override azure-mgmt-changeanalysis msrest>=0.6.21 @@ -283,8 +283,6 @@ opentelemetry-sdk<2.0.0,>=1.0.0 #override azure-purview-scanning msrest>=0.6.21 #override azure-purview-account msrest>=0.6.21 #override azure-purview-account azure-core<2.0.0,>=1.16.0 -#override azure-messaging-webpubsubservice azure-core<2.0.0,>=1.16.0 -#override azure-messaging-webpubsubservice msrest>=0.6.21 #override azure-mgmt-rdbms msrest>=0.6.21 #override azure-mgmt-peering msrest>=0.6.21 #override azure-mgmt-elastic msrest>=0.6.21 From 0fd5b47cef6e241a6bff291a506a24e9dd4c2c23 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Wed, 15 Sep 2021 10:57:23 +0800 Subject: [PATCH 22/33] fix ci failure of windows_python27 --- .../azure/messaging/webpubsubservice/__init__.py | 3 ++- .../azure/messaging/webpubsubservice/_patch.py | 6 +++--- .../azure/messaging/webpubsubservice/aio/__init__.py | 3 +++ .../azure/messaging/webpubsubservice/aio/_patch.py | 6 +++--- .../tests/recordings/test_smoke.test_health_api_status.yaml | 2 +- .../recordings/test_smoke.test_webpubsub_send_to_all.yaml | 2 +- ...oke.test_webpubsub_send_to_all_api_management_proxy.yaml | 2 +- .../recordings/test_smoke_async.test_health_api_status.yaml | 2 +- .../test_smoke_async.test_webpubsub_send_to_all.yaml | 2 +- ...t_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml | 2 +- 10 files changed, 17 insertions(+), 13 deletions(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py index 74a9e821e4e3..9d3d67883a97 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py @@ -17,6 +17,7 @@ patch_sdk() from ._patch import build_authentication_token - __all__.append('build_authentication_token') + from ._patch import WebPubSubServicePatchClient as WebPubSubServiceClient + __all__ = ['WebPubSubServiceClient', 'build_authentication_token'] except ImportError: pass diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py index bf10d19a3538..cfa17ae20ac8 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py @@ -1,3 +1,4 @@ +# coding=utf-8 # -------------------------------------------------------------------------- # # Copyright (c) Microsoft Corporation. All rights reserved. @@ -275,7 +276,7 @@ def _configure( self.authentication_policy = policies.BearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) -class WebPubSubServicePatchClient(object): +class WebPubSubServicePatchClient(WebPubSubServiceClient): """PatchClient. :ivar health_api: HealthApiOperations operations @@ -323,5 +324,4 @@ def from_connection_string(cls, connection_string, **kwargs): def patch_sdk(): - WebPubSubServiceClient.__init__ = WebPubSubServicePatchClient.__init__ - WebPubSubServiceClient.from_connection_string = WebPubSubServicePatchClient.from_connection_string + pass diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py index d33c98d8f4c4..0f6145021a0e 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py @@ -12,5 +12,8 @@ try: from ._patch import patch_sdk # type: ignore patch_sdk() + + from ._patch import AsyncWebPubSubServicePatchClient as WebPubSubServiceClient + __all__ = ['WebPubSubServiceClient'] except ImportError: pass diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py index 3c1111f1969e..9599a4c9d924 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py @@ -1,3 +1,4 @@ +# coding=utf-8 # -------------------------------------------------------------------------- # # Copyright (c) Microsoft Corporation. All rights reserved. @@ -93,7 +94,7 @@ def _configure( self.authentication_policy = policies.AsyncBearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) -class AsyncWebPubSubServicePatchClient: +class AsyncWebPubSubServicePatchClient(WebPubSubServiceClient): """WebPubSubServiceClient. :ivar health_api: HealthApiOperations operations @@ -137,5 +138,4 @@ def from_connection_string(cls, connection_string, **kwargs): def patch_sdk(): - WebPubSubServiceClient.__init__ = AsyncWebPubSubServicePatchClient.__init__ - WebPubSubServiceClient.from_connection_string = AsyncWebPubSubServicePatchClient.from_connection_string + pass diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml index e040c6d4711a..58ff815ebdd3 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml @@ -19,7 +19,7 @@ interactions: connection: - keep-alive date: - - Mon, 13 Sep 2021 02:40:34 GMT + - Wed, 15 Sep 2021 02:40:56 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml index 1420490de3eb..d5bb32c865b6 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml @@ -25,7 +25,7 @@ interactions: content-length: - '0' date: - - Mon, 13 Sep 2021 02:40:37 GMT + - Wed, 15 Sep 2021 02:40:59 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml index da5e8293436c..70f2a75dfd78 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml @@ -25,7 +25,7 @@ interactions: content-length: - '0' date: - - Mon, 13 Sep 2021 02:40:39 GMT + - Wed, 15 Sep 2021 02:41:02 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml index 8b0b8326416c..a52653292171 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml @@ -11,7 +11,7 @@ interactions: string: '' headers: connection: keep-alive - date: Mon, 13 Sep 2021 02:41:27 GMT + date: Wed, 15 Sep 2021 02:45:10 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 200 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml index 4261243c68db..335213546c06 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml @@ -16,7 +16,7 @@ interactions: headers: connection: keep-alive content-length: '0' - date: Mon, 13 Sep 2021 02:41:29 GMT + date: Wed, 15 Sep 2021 02:45:11 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 202 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml index 1047da554a3e..f71968d24923 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml @@ -16,7 +16,7 @@ interactions: headers: connection: keep-alive content-length: '0' - date: Mon, 13 Sep 2021 02:41:32 GMT + date: Wed, 15 Sep 2021 02:45:13 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 202 From b95cbee31d836ef35c95b3e64f47a44d8f0b7b2c Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Wed, 15 Sep 2021 17:32:10 +0800 Subject: [PATCH 23/33] Update sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py Co-authored-by: Liangying.Wei --- .../examples/send_messages_aad.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py index 432543ba0a2b..ab1a99282436 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py @@ -33,7 +33,7 @@ try: # Raise an exception if the service rejected the call client.web_pub_sub.send_to_all('Hub', message='hello, text!', content_type='text/plain') - print('Successfully sent a JSON message') + print('Successfully sent a text message') except HttpResponseError as e: print('Failed to send JSON message: {}'.format(e.response.json())) From 1ce7f49c98af14cc2608fb4a526e6c21e24d0757 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Wed, 15 Sep 2021 17:32:26 +0800 Subject: [PATCH 24/33] Update sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py Co-authored-by: Liangying.Wei --- .../examples/send_messages_aad.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py index ab1a99282436..e3eaa0778e6f 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py @@ -35,7 +35,7 @@ client.web_pub_sub.send_to_all('Hub', message='hello, text!', content_type='text/plain') print('Successfully sent a text message') except HttpResponseError as e: - print('Failed to send JSON message: {}'.format(e.response.json())) + print('Failed to send text message: {}'.format(e.response.json())) # Send a json message from a stream to everybody on the given hub... From d34c3a0fa1c4636bd306909f967c588302b04971 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Wed, 15 Sep 2021 17:43:29 +0800 Subject: [PATCH 25/33] Update README.md --- sdk/webpubsub/azure-messaging-webpubsubservice/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/README.md b/sdk/webpubsub/azure-messaging-webpubsubservice/README.md index 92d60407b54c..ba07622c432c 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/README.md +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/README.md @@ -157,7 +157,7 @@ Similarly, `logging_enable` can enable detailed logging for a single call, even when it isn't enabled for the client: ```python -result = client.web_pub_sub.send_to_all(logging_enable=True) +result = client.web_pub_sub.send_to_all(..., logging_enable=True) ``` Http request and response details are printed to stdout with this logging config. @@ -203,4 +203,4 @@ additional questions or comments. [api_key]: https://docs.microsoft.com/azure/azure-web-pubsub/howto-websocket-connect?tabs=browser#authorization [connection_string]: https://docs.microsoft.com/azure/azure-web-pubsub/howto-websocket-connect?tabs=browser#authorization [azure_portal]: https://docs.microsoft.com/azure/azure-web-pubsub/howto-develop-create-instance -[azure-key-credential]: https://aka.ms/azsdk-python-core-azurekeycredential \ No newline at end of file +[azure-key-credential]: https://aka.ms/azsdk-python-core-azurekeycredential From 3dd7beaf147354fe041fe0bfc3c24e55683d196b Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Thu, 16 Sep 2021 15:40:25 +0800 Subject: [PATCH 26/33] review --- .../CHANGELOG.md | 1 + .../README.md | 7 +-- .../messaging/webpubsubservice/__init__.py | 2 +- .../messaging/webpubsubservice/_patch.py | 6 +-- .../webpubsubservice/aio/__init__.py | 2 +- .../messaging/webpubsubservice/aio/_patch.py | 4 +- .../samples/README.md | 51 +++++++++++++++++++ .../send_messages_aad.py | 34 +++++++++++-- .../send_messages_aad_apim_proxy.py | 41 ++++++++++++--- .../send_messages_connection_string.py | 26 ++++++++++ ...d_messages_connection_string_apim_proxy.py | 30 ++++++++++- .../azure-messaging-webpubsubservice/setup.py | 2 +- .../test_smoke.test_health_api_status.yaml | 2 +- ...est_smoke.test_webpubsub_send_request.yaml | 34 +++++++++++++ ...test_smoke.test_webpubsub_send_to_all.yaml | 2 +- ...bsub_send_to_all_api_management_proxy.yaml | 6 +-- ...st_smoke_async.test_health_api_status.yaml | 2 +- ...moke_async.test_webpubsub_send_to_all.yaml | 2 +- ...test_webpubsub_send_to_all_apim_proxy.yaml | 7 ++- .../tests/test_smoke.py | 15 ++++-- .../tests/test_smoke_async.py | 4 +- shared_requirements.txt | 2 +- 22 files changed, 237 insertions(+), 45 deletions(-) create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/samples/README.md rename sdk/webpubsub/azure-messaging-webpubsubservice/{examples => samples}/send_messages_aad.py (56%) rename sdk/webpubsub/azure-messaging-webpubsubservice/{examples => samples}/send_messages_aad_apim_proxy.py (50%) rename sdk/webpubsub/azure-messaging-webpubsubservice/{examples => samples}/send_messages_connection_string.py (56%) rename sdk/webpubsub/azure-messaging-webpubsubservice/{examples => samples}/send_messages_connection_string_apim_proxy.py (55%) create mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_request.yaml diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/CHANGELOG.md b/sdk/webpubsub/azure-messaging-webpubsubservice/CHANGELOG.md index 276a63f851cd..ef8bdf99210e 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/CHANGELOG.md +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/CHANGELOG.md @@ -4,6 +4,7 @@ - Add operations to client - Support AAD +- Support Api Management Proxy ## 1.0.0b1 (2021-04-27) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/README.md b/sdk/webpubsub/azure-messaging-webpubsubservice/README.md index ba07622c432c..4daeaac475d1 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/README.md +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/README.md @@ -46,7 +46,7 @@ python -m pip install azure-messaging-webpubsubservice #### 1. Create with an API Key Credential You can get the [API key][api_key] or [Connection string][connection_string] in the [Azure Portal][azure_portal]. -Once you have the value for the API key or Connection string, you can pass it as a string into an instance of [AzureKeyCredential][azure-key-credential]. +Once you have the value for the API key, you can pass it as a string into an instance of [AzureKeyCredential][azure-key-credential]. Use the key as the credential parameter to authenticate the client: ```python @@ -55,7 +55,9 @@ Use the key as the credential parameter to authenticate the client: >>> client = WebPubSubServiceClient(endpoint='', credential=AzureKeyCredential("")) ``` -Or + +Once you have the value for the connection string, you can pass it as a string into the function `from_connection_string` and it will +authenticate the client: ```python >>> from azure.messaging.webpubsubservice import WebPubSubServiceClient @@ -187,7 +189,6 @@ additional questions or comments. [webpubsubservice_docs]: https://aka.ms/awps/doc [azure_cli]: https://docs.microsoft.com/cli/azure [azure_sub]: https://azure.microsoft.com/free/ -[webpubsubservice_client_class]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py [package]: https://pypi.org/project/azure-messaging-webpubsubservice/ [default_cred_ref]: https://aka.ms/azsdk-python-identity-default-cred-ref [cla]: https://cla.microsoft.com diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py index 9d3d67883a97..46c29b5a072b 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/__init__.py @@ -17,7 +17,7 @@ patch_sdk() from ._patch import build_authentication_token - from ._patch import WebPubSubServicePatchClient as WebPubSubServiceClient + from ._patch import WebPubSubServiceClient __all__ = ['WebPubSubServiceClient', 'build_authentication_token'] except ImportError: pass diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py index cfa17ae20ac8..52e6d0ab7985 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py @@ -32,7 +32,7 @@ from ._version import VERSION from .operations import HealthApiOperations, WebPubSubOperations -from ._web_pub_sub_service_client import WebPubSubServiceClient +from ._web_pub_sub_service_client import WebPubSubServiceClient as GeneratedWebPubSubServiceClient from msrest import Deserializer, Serializer from azure.core.pipeline import policies @@ -276,8 +276,8 @@ def _configure( self.authentication_policy = policies.BearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) -class WebPubSubServicePatchClient(WebPubSubServiceClient): - """PatchClient. +class WebPubSubServiceClient(GeneratedWebPubSubServiceClient): + """WebPubSubServiceClient. :ivar health_api: HealthApiOperations operations :vartype health_api: azure.messaging.webpubsubservice.operations.HealthApiOperations diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py index 0f6145021a0e..0f1f57df7395 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/__init__.py @@ -13,7 +13,7 @@ from ._patch import patch_sdk # type: ignore patch_sdk() - from ._patch import AsyncWebPubSubServicePatchClient as WebPubSubServiceClient + from ._patch import WebPubSubServiceClient __all__ = ['WebPubSubServiceClient'] except ImportError: pass diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py index 9599a4c9d924..1cb440298c11 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py @@ -34,7 +34,7 @@ from .._version import VERSION from .operations import HealthApiOperations, WebPubSubOperations from .._patch import JwtCredentialPolicy, ApiManagementProxy, _parse_connection_string -from ._web_pub_sub_service_client import WebPubSubServiceClient +from ._web_pub_sub_service_client import WebPubSubServiceClient as GeneratedWebPubSubServiceClient from azure.core.configuration import Configuration @@ -94,7 +94,7 @@ def _configure( self.authentication_policy = policies.AsyncBearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) -class AsyncWebPubSubServicePatchClient(WebPubSubServiceClient): +class WebPubSubServiceClient(GeneratedWebPubSubServiceClient): """WebPubSubServiceClient. :ivar health_api: HealthApiOperations operations diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/README.md b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/README.md new file mode 100644 index 000000000000..124940513f4a --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/README.md @@ -0,0 +1,51 @@ + +# Samples for Azure Web PubSub client library for Python + +These code samples show common scenario operations with the Azure Web PubSub client library. +The async versions of the samples require Python 3.6 or later. + +You can authenticate your client with API key or through Azure Active Directory with a token credential from [azure-identity][azure_identity], there is introduction in [README.md][readme] +about the authentication knowledge. These sample programs show common scenarios: + +|**File Name**|**Description**| +|----------------|-------------| +|[send_message_aad.py][send_message_aad] |Send message through AAD authentication| +|[send_messages_aad_apim_proxy.py][send_messages_aad_apim_proxy] |Send message through AAD authentication with Api management proxy| +|[send_messages_connection_string.py][send_messages_connection_string] |Send message through connection string authentication| +|[send_messages_connection_string_apim_proxy.py][send_messages_connection_string_apim_proxy] |Send message through connection string authentication with Api management proxy| + +## Prerequisites +* Python 2.7, or 3.6 or later is required to use this package (3.6 or later if using asyncio) +* You must have an [Azure Web PubSub account][azure_web_pubsub_account] to run these samples. +## Setup + +1. Install the Azure Web PubSub client library for Python with [pip][pip]: + +```bash +pip install azure-messaging-webpubsub +``` + +* If authenticating with Azure Active Directory, make sure you have [azure-identity][azure_identity_pip] installed: + ```bash + pip install azure-identity + ``` + +2. Clone or download this sample repository + +3. Open the sample folder in Visual Studio Code or your IDE of choice. + +## Running the samples + +1. Open a terminal window and `cd` to the directory that the samples are saved in. +2. Set the environment variables specified in the sample file you wish to run. +3. Follow the usage described in the file, e.g. `python send_message_aad.py` + +[azure_identity]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/identity/azure-identity +[readme]: ../README.md +[pip]: https://pypi.org/project/pip/ +[azure_identity_pip]: https://pypi.org/project/azure-identity/ +[send_message_aad]: send_messages_aad.py +[send_messages_aad_apim_proxy]: send_messages_aad_apim_proxy.py +[send_messages_connection_string]: send_messages_connection_string.py +[send_messages_connection_string_apim_proxy]: send_messages_connection_string_apim_proxy.py +[azure_web_pubsub_account]: https://docs.microsoft.com/azure/azure-web-pubsub/howto-develop-create-instance \ No newline at end of file diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad.py similarity index 56% rename from sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py rename to sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad.py index e3eaa0778e6f..0f37aeb83522 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad.py @@ -1,3 +1,29 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# +# Copyright (c) Microsoft Corporation. All rights reserved. +# +# The MIT License (MIT) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the ""Software""), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# +# -------------------------------------------------------------------------- import io import logging import os @@ -12,19 +38,18 @@ # Set the values of the client ID, tenant ID, and client secret of the AAD application as environment variables: # AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET, WEBPUBSUB_ENDPOINT try: - endpoint = os.environ.get("WEBPUBSUB_ENDPOINT") + endpoint = os.environ["WEBPUBSUB_ENDPOINT"] except KeyError: LOG.error("Missing environment variable 'WEBPUBSUB_ENDPOINT' - please set if before running the example") exit() -# Build a client from the connection string. And for this example, we have enabled debug -# tracing. For production code, this should be turned off. +# Build a client through AAD client = WebPubSubServiceClient(credential=DefaultAzureCredential(), endpoint=endpoint) # Send a json message to everybody on the given hub... try: # Raise an exception if the service rejected the call - client.web_pub_sub.send_to_all('Hub', message={'Hello': 'all!'}) + client.web_pub_sub.send_to_all('Hub', message={'Hello': 'all'}) print('Successfully sent a JSON message') except HttpResponseError as e: print('Failed to send JSON message: {}'.format(e.response.json())) @@ -45,4 +70,3 @@ print('Successfully sent a JSON message') except HttpResponseError as e: print('Failed to send JSON message: {}'.format(e.response.json())) - diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad_apim_proxy.py b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad_apim_proxy.py similarity index 50% rename from sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad_apim_proxy.py rename to sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad_apim_proxy.py index b7875e3f84c8..3cb231fa7cf0 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_aad_apim_proxy.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad_apim_proxy.py @@ -1,3 +1,29 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# +# Copyright (c) Microsoft Corporation. All rights reserved. +# +# The MIT License (MIT) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the ""Software""), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# +# -------------------------------------------------------------------------- import io import logging import os @@ -12,20 +38,19 @@ # Set the values of the client ID, tenant ID, and client secret of the AAD application as environment variables: # AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET, WEBPUBSUB_ENDPOINT try: - endpoint = os.environ.get("WEBPUBSUB_ENDPOINT") - revers_proxy_endpoint = os.environ.get("WEBPUBSUB_REVERSE_RPOXY_ENDPOINT") + endpoint = os.environ["WEBPUBSUB_ENDPOINT"] + reverse_proxy_endpoint = os.environ["WEBPUBSUB_REVERSE_RPOXY_ENDPOINT"] except KeyError: LOG.error("Missing environment variable 'WEBPUBSUB_ENDPOINT' or 'WEBPUBSUB_REVERSE_RPOXY_ENDPOINT' - please set if before running the example") exit() -# Build a client from the connection string. And for this example, we have enabled debug -# tracing. For production code, this should be turned off. -client = WebPubSubServiceClient(credential=DefaultAzureCredential(), endpoint=endpoint, revers_proxy_endpoint=revers_proxy_endpoint) +# Build a client through AAD +client = WebPubSubServiceClient(credential=DefaultAzureCredential(), endpoint=endpoint, reverse_proxy_endpoint=reverse_proxy_endpoint) # Send a json message to everybody on the given hub... try: # Raise an exception if the service rejected the call - client.web_pub_sub.send_to_all('Hub', message={'Hello': 'revers_proxy_endpoint!'}) + client.web_pub_sub.send_to_all('Hub', message={'Hello': 'reverse_proxy_endpoint!'}) print('Successfully sent a JSON message') except HttpResponseError as e: print('Failed to send JSON message: {}'.format(e.response.json())) @@ -33,7 +58,7 @@ # Send a text message to everybody on the given hub... try: # Raise an exception if the service rejected the call - client.web_pub_sub.send_to_all('Hub', message='hello, revers_proxy_endpoint!', content_type='text/plain') + client.web_pub_sub.send_to_all('Hub', message='hello, reverse_proxy_endpoint!', content_type='text/plain') print('Successfully sent a JSON message') except HttpResponseError as e: print('Failed to send JSON message: {}'.format(e.response.json())) @@ -42,7 +67,7 @@ # Send a json message from a stream to everybody on the given hub... try: # Raise an exception if the service rejected the call - client.web_pub_sub.send_to_all('Hub', message=io.BytesIO(b'{ "hello": "revers_proxy_endpoint" }'), content_type='application/json') + client.web_pub_sub.send_to_all('Hub', message=io.BytesIO(b'{ "hello": "reverse_proxy_endpoint" }'), content_type='application/json') print('Successfully sent a JSON message') except HttpResponseError as e: print('Failed to send JSON message: {}'.format(e.response.json())) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_connection_string.py b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string.py similarity index 56% rename from sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_connection_string.py rename to sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string.py index b9ff2a137a6a..b5d4b47ee6ae 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_connection_string.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string.py @@ -1,3 +1,29 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# +# Copyright (c) Microsoft Corporation. All rights reserved. +# +# The MIT License (MIT) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the ""Software""), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# +# -------------------------------------------------------------------------- import io import logging import os diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_connection_string_apim_proxy.py b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string_apim_proxy.py similarity index 55% rename from sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_connection_string_apim_proxy.py rename to sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string_apim_proxy.py index 5dc85457d919..a22723320831 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/examples/send_messages_connection_string_apim_proxy.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string_apim_proxy.py @@ -1,3 +1,29 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# +# Copyright (c) Microsoft Corporation. All rights reserved. +# +# The MIT License (MIT) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the ""Software""), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# +# -------------------------------------------------------------------------- import io import logging import os @@ -10,14 +36,14 @@ try: connection_string = os.environ['WEBPUBSUB_CONNECTION_STRING'] - revers_proxy_endpoint = os.environ.get("WEBPUBSUB_REVERSE_RPOXY_ENDPOINT") + reverse_proxy_endpoint = os.environ["WEBPUBSUB_REVERSE_RPOXY_ENDPOINT"] except KeyError: LOG.error("Missing environment variable 'WEBPUBSUB_CONNECTION_STRING' or 'WEBPUBSUB_REVERSE_RPOXY_ENDPOINT' - please set if before running the example") exit() # Build a client from the connection string. And for this example, we have enabled debug # tracing. For production code, this should be turned off. -client = WebPubSubServiceClient.from_connection_string(connection_string, logging_enable=True, revers_proxy_endpoint=revers_proxy_endpoint) +client = WebPubSubServiceClient.from_connection_string(connection_string, logging_enable=True, reverse_proxy_endpoint=reverse_proxy_endpoint) try: # Raise an exception if the service rejected the call diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py b/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py index f0f590cba3a3..839894ced78a 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/setup.py @@ -61,7 +61,7 @@ ] ), install_requires=[ - "azure-core<2.0.0,>=1.16.0", + "azure-core<2.0.0,>=1.18.0", "msrest>=0.6.21", "cryptography>=2.8.0", "pyjwt>=1.7.1", diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml index 58ff815ebdd3..d303555311af 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml @@ -19,7 +19,7 @@ interactions: connection: - keep-alive date: - - Wed, 15 Sep 2021 02:40:56 GMT + - Thu, 16 Sep 2021 07:22:28 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_request.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_request.yaml new file mode 100644 index 000000000000..8ab27d86d7c1 --- /dev/null +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_request.yaml @@ -0,0 +1,34 @@ +interactions: +- request: + body: test_webpubsub_send_request + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '27' + Content-Type: + - text/plain + User-Agent: + - azsdk-python-messaging-webpubsubservice/1.0.0b2 Python/3.7.3 (Windows-10-10.0.19041-SP0) + method: POST + uri: https://myservice.webpubsub.azure.com/api/hubs/Hub/:send?api-version=2021-08-01-preview + response: + body: + string: '' + headers: + connection: + - keep-alive + content-length: + - '0' + date: + - Thu, 16 Sep 2021 07:22:31 GMT + strict-transport-security: + - max-age=15724800; includeSubDomains + status: + code: 202 + message: Accepted +version: 1 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml index d5bb32c865b6..0661ecf093b1 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml @@ -25,7 +25,7 @@ interactions: content-length: - '0' date: - - Wed, 15 Sep 2021 02:40:59 GMT + - Thu, 16 Sep 2021 07:22:33 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml index 70f2a75dfd78..ad57a6ae7eed 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml @@ -15,17 +15,15 @@ interactions: User-Agent: - azsdk-python-messaging-webpubsubservice/1.0.0b2 Python/3.7.3 (Windows-10-10.0.19041-SP0) method: POST - uri: https://myservice.webpubsub.azure.com/api/hubs/Hub/:send?api-version=2021-08-01-preview + uri: https://myservice.azure-api.net/api/hubs/Hub/:send?api-version=2021-08-01-preview response: body: string: '' headers: - connection: - - keep-alive content-length: - '0' date: - - Wed, 15 Sep 2021 02:41:02 GMT + - Thu, 16 Sep 2021 07:22:34 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml index a52653292171..6fd6893894c1 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml @@ -11,7 +11,7 @@ interactions: string: '' headers: connection: keep-alive - date: Wed, 15 Sep 2021 02:45:10 GMT + date: Thu, 16 Sep 2021 07:22:40 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 200 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml index 335213546c06..6ec6c58efb12 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml @@ -16,7 +16,7 @@ interactions: headers: connection: keep-alive content-length: '0' - date: Wed, 15 Sep 2021 02:45:11 GMT + date: Thu, 16 Sep 2021 07:22:43 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 202 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml index f71968d24923..eb5765b0aa06 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml @@ -9,17 +9,16 @@ interactions: User-Agent: - azsdk-python-messaging-webpubsubservice/1.0.0b2 Python/3.7.3 (Windows-10-10.0.19041-SP0) method: POST - uri: https://myservice.webpubsub.azure.com/api/hubs/Hub/:send?api-version=2021-08-01-preview + uri: https://myservice.azure-api.net/api/hubs/Hub/:send?api-version=2021-08-01-preview response: body: string: '' headers: - connection: keep-alive content-length: '0' - date: Wed, 15 Sep 2021 02:45:13 GMT + date: Thu, 16 Sep 2021 07:22:45 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 202 message: Accepted - url: https://webpubsub-yyc.webpubsub.azure.com/api/hubs/Hub/:send?api-version=2021-08-01-preview + url: https://apimanagement-yyc.azure-api.net/api/hubs/Hub/:send?api-version=2021-08-01-preview version: 1 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py index 67091565e3a1..71cbcd06f4bd 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py @@ -5,7 +5,7 @@ # license information. # ------------------------------------------------------------------------- from testcase import WebpubsubTest, WebpubsubPowerShellPreparer - +from azure.messaging.webpubsubservice.operations._operations import build_web_pub_sub_send_to_all_request class WebpubsubSmokeTest(WebpubsubTest): @@ -20,6 +20,13 @@ def test_webpubsub_send_to_all(self, webpubsub_endpoint): client.web_pub_sub.send_to_all('Hub', {'hello': 'test_webpubsub_send_to_all'}) @WebpubsubPowerShellPreparer() - def test_webpubsub_send_to_all_api_management_proxy(self, webpubsub_endpoint, reverse_proxy_endpoint=None): - client = self.create_client(endpoint=webpubsub_endpoint, reverse_proxy_endpoint=reverse_proxy_endpoint) - client.web_pub_sub.send_to_all('Hub', {'hello': 'test_webpubsub_send_to_all_api_management_proxy'}) \ No newline at end of file + def test_webpubsub_send_to_all_api_management_proxy(self, webpubsub_endpoint, webpubsub_reverse_proxy_endpoint=None): + client = self.create_client(endpoint=webpubsub_endpoint, reverse_proxy_endpoint=webpubsub_reverse_proxy_endpoint) + client.web_pub_sub.send_to_all('Hub', {'hello': 'test_webpubsub_send_to_all_api_management_proxy'}) + + @WebpubsubPowerShellPreparer() + def test_webpubsub_send_request(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint) + request = build_web_pub_sub_send_to_all_request('Hub', content='test_webpubsub_send_request', content_type='text/plain') + response = client.send_request(request) + assert response.status_code == 202 \ No newline at end of file diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py index e4a39afa287e..a91db336e36a 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py @@ -21,6 +21,6 @@ async def test_webpubsub_send_to_all(self, webpubsub_endpoint): await client.web_pub_sub.send_to_all('Hub', {'hello': 'test_webpubsub_send_to_all'}) @WebpubsubPowerShellPreparer() - async def test_webpubsub_send_to_all_apim_proxy(self, webpubsub_endpoint, reverse_proxy_endpoint=None): - client = self.create_client(endpoint=webpubsub_endpoint, reverse_proxy_endpoint=reverse_proxy_endpoint) + async def test_webpubsub_send_to_all_apim_proxy(self, webpubsub_endpoint, webpubsub_reverse_proxy_endpoint=None): + client = self.create_client(endpoint=webpubsub_endpoint, reverse_proxy_endpoint=webpubsub_reverse_proxy_endpoint) await client.web_pub_sub.send_to_all('Hub', {'hello': 'test_webpubsub_send_to_all_apim_proxy'}) \ No newline at end of file diff --git a/shared_requirements.txt b/shared_requirements.txt index e43257b8e00a..5c61dc91ca05 100644 --- a/shared_requirements.txt +++ b/shared_requirements.txt @@ -219,7 +219,7 @@ opentelemetry-sdk<2.0.0,>=1.0.0 #override azure-core-tracing-opentelemetry opentelemetry-api<2.0.0,>=1.0.0 #override azure-identity six>=1.12.0 #override azure-keyvault-keys six>=1.12.0 -#override azure-messaging-webpubsubservice azure-core<2.0.0,>=1.16.0 +#override azure-messaging-webpubsubservice azure-core<2.0.0,>=1.18.0 #override azure-messaging-webpubsubservice msrest>=0.6.21 #override azure-messaging-webpubsubservice pyjwt>=1.7.1 #override azure-messaging-webpubsubservice six>=1.12.0 From 8dcfcb90f25ad2290e85a746d5148b4d85a1086f Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Thu, 16 Sep 2021 15:56:40 +0800 Subject: [PATCH 27/33] regenerate code --- .../webpubsubservice/_configuration.py | 6 ++ .../messaging/webpubsubservice/_patch.py | 23 +++-- .../_web_pub_sub_service_client.py | 18 ++-- .../webpubsubservice/aio/_configuration.py | 6 ++ .../messaging/webpubsubservice/aio/_patch.py | 15 +++- .../aio/_web_pub_sub_service_client.py | 18 ++-- .../aio/operations/_operations.py | 90 +++++++++++++++---- .../operations/_operations.py | 90 +++++++++++++++---- .../test_smoke.test_health_api_status.yaml | 2 +- ...est_smoke.test_webpubsub_send_request.yaml | 2 +- ...test_smoke.test_webpubsub_send_to_all.yaml | 2 +- ...bsub_send_to_all_api_management_proxy.yaml | 2 +- ...st_smoke_async.test_health_api_status.yaml | 2 +- ...moke_async.test_webpubsub_send_to_all.yaml | 2 +- ...test_webpubsub_send_to_all_apim_proxy.yaml | 2 +- 15 files changed, 212 insertions(+), 68 deletions(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py index c9073f30f623..e257c83a7382 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_configuration.py @@ -26,20 +26,26 @@ class WebPubSubServiceClientConfiguration(Configuration): Note that all parameters used to create this instance are saved as instance attributes. + :param endpoint: HTTP or HTTPS endpoint for the Web PubSub service instance. + :type endpoint: str :param credential: Credential needed for the client to connect to Azure. :type credential: ~azure.core.credentials.TokenCredential """ def __init__( self, + endpoint, # type: str credential, # type: "TokenCredential" **kwargs # type: Any ): # type: (...) -> None + if endpoint is None: + raise ValueError("Parameter 'endpoint' must not be None.") if credential is None: raise ValueError("Parameter 'credential' must not be None.") super(WebPubSubServiceClientConfiguration, self).__init__(**kwargs) + self.endpoint = endpoint self.credential = credential self.credential_scopes = kwargs.pop('credential_scopes', ['https://webpubsub.azure.com/.default']) kwargs.setdefault('sdk_moniker', 'messaging-webpubsubservice/{}'.format(VERSION)) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py index 52e6d0ab7985..3130b3ccdd57 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py @@ -238,18 +238,26 @@ class WebPubSubServiceClientConfiguration(Configuration): Note that all parameters used to create this instance are saved as instance attributes. + :param endpoint: HTTP or HTTPS endpoint for the Web PubSub service instance. + :type endpoint: str :param credential: Credential needed for the client to connect to Azure. :type credential: Union[~azure.core.credentials.TokenCredential, ~azure.core.credentials.AzureKeyCredential] """ def __init__( self, + endpoint, # type: str credential, # type: Union[TokenCredential, AzureKeyCredential] **kwargs # type: Any ): # type: (...) -> None + if endpoint is None: + raise ValueError("Parameter 'endpoint' must not be None.") + if credential is None: + raise ValueError("Parameter 'credential' must not be None.") super(WebPubSubServiceClientConfiguration, self).__init__(**kwargs) + self.endpoint = endpoint self.credential = credential self.credential_scopes = kwargs.pop('credential_scopes', ['https://webpubsub.azure.com/.default']) kwargs.setdefault('sdk_moniker', 'messaging-webpubsubservice/{}'.format(VERSION)) @@ -283,24 +291,23 @@ class WebPubSubServiceClient(GeneratedWebPubSubServiceClient): :vartype health_api: azure.messaging.webpubsubservice.operations.HealthApiOperations :ivar web_pub_sub: WebPubSubOperations operations :vartype web_pub_sub: azure.messaging.webpubsubservice.operations.WebPubSubOperations - :keyword connection_string: connection string needed for the client to connect to Azure. - :paramtype connection_string: str + :param endpoint: HTTP or HTTPS endpoint for the Web PubSub service instance. + :type endpoint: str :param credential: Credential needed for the client to connect to Azure. - :type credential: Union[~azure.core.credentials.TokenCredential, ~azure.core.credentials.AzureKeyCredential] - :keyword endpoint: Service URL. Default value is ''. - :paramtype endpoint: str + :type credential: ~azure.core.credentials.TokenCredential """ def __init__( self, + endpoint, # type: str credential, # type: Union[TokenCredential, AzureKeyCredential] **kwargs # type: Any ): # type: (...) -> None - endpoint = kwargs.pop('endpoint', "") # type: str kwargs['origin_endpoint'] = endpoint - self._config = WebPubSubServiceClientConfiguration(credential, **kwargs) - self._client = PipelineClient(base_url=endpoint, config=self._config, **kwargs) + _endpoint = '{Endpoint}' + self._config = WebPubSubServiceClientConfiguration(endpoint, credential, **kwargs) + self._client = PipelineClient(base_url=_endpoint, config=self._config, **kwargs) self._serialize = Serializer() self._deserialize = Deserializer() diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py index 2b69eac16e8a..f3ba66caa656 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py @@ -29,22 +29,22 @@ class WebPubSubServiceClient(object): :vartype health_api: azure.messaging.webpubsubservice.operations.HealthApiOperations :ivar web_pub_sub: WebPubSubOperations operations :vartype web_pub_sub: azure.messaging.webpubsubservice.operations.WebPubSubOperations + :param endpoint: HTTP or HTTPS endpoint for the Web PubSub service instance. + :type endpoint: str :param credential: Credential needed for the client to connect to Azure. :type credential: ~azure.core.credentials.TokenCredential - :keyword endpoint: Service URL. Default value is ''. - :paramtype endpoint: str """ def __init__( self, + endpoint, # type: str credential, # type: "TokenCredential" **kwargs # type: Any ): # type: (...) -> None - endpoint = kwargs.pop('endpoint', "") # type: str - - self._config = WebPubSubServiceClientConfiguration(credential, **kwargs) - self._client = PipelineClient(base_url=endpoint, config=self._config, **kwargs) + _endpoint = '{Endpoint}' + self._config = WebPubSubServiceClientConfiguration(endpoint, credential, **kwargs) + self._client = PipelineClient(base_url=_endpoint, config=self._config, **kwargs) self._serialize = Serializer() self._deserialize = Deserializer() @@ -77,7 +77,11 @@ def send_request( """ request_copy = deepcopy(request) - request_copy.url = self._client.format_url(request_copy.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + + request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) return self._client.send_request(request_copy, **kwargs) def close(self): diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py index 49311d80530d..f549a3d17b2c 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_configuration.py @@ -24,19 +24,25 @@ class WebPubSubServiceClientConfiguration(Configuration): Note that all parameters used to create this instance are saved as instance attributes. + :param endpoint: HTTP or HTTPS endpoint for the Web PubSub service instance. + :type endpoint: str :param credential: Credential needed for the client to connect to Azure. :type credential: ~azure.core.credentials_async.AsyncTokenCredential """ def __init__( self, + endpoint: str, credential: "AsyncTokenCredential", **kwargs: Any ) -> None: + if endpoint is None: + raise ValueError("Parameter 'endpoint' must not be None.") if credential is None: raise ValueError("Parameter 'credential' must not be None.") super(WebPubSubServiceClientConfiguration, self).__init__(**kwargs) + self.endpoint = endpoint self.credential = credential self.credential_scopes = kwargs.pop('credential_scopes', ['https://webpubsub.azure.com/.default']) kwargs.setdefault('sdk_moniker', 'messaging-webpubsubservice/{}'.format(VERSION)) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py index 1cb440298c11..3074095a950e 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py @@ -56,19 +56,25 @@ class WebPubSubServiceClientConfiguration(Configuration): Note that all parameters used to create this instance are saved as instance attributes. + :param endpoint: HTTP or HTTPS endpoint for the Web PubSub service instance. + :type endpoint: str :param credential: Credential needed for the client to connect to Azure. :type credential: Union[~azure.core.credentials_async.AsyncTokenCredential, ~azure.core.credentials.AzureKeyCredential] """ def __init__( self, + endpoint: str, credential: Union["AsyncTokenCredential", "AzureKeyCredential"], **kwargs: Any ) -> None: + if endpoint is None: + raise ValueError("Parameter 'endpoint' must not be None.") if credential is None: raise ValueError("Parameter 'credential' must not be None.") super(WebPubSubServiceClientConfiguration, self).__init__(**kwargs) + self.endpoint = endpoint self.credential = credential self.credential_scopes = kwargs.pop('credential_scopes', ['https://webpubsub.azure.com/.default']) kwargs.setdefault('sdk_moniker', 'messaging-webpubsubservice/{}'.format(VERSION)) @@ -103,19 +109,22 @@ class WebPubSubServiceClient(GeneratedWebPubSubServiceClient): :vartype web_pub_sub: azure.messaging.webpubsubservice.aio.operations.WebPubSubOperations :param credential: Credential needed for the client to connect to Azure. :type credential: Union[~azure.core.credentials_async.AsyncTokenCredential, ~azure.core.credentials.AzureKeyCredential] + :param endpoint: HTTP or HTTPS endpoint for the Web PubSub service instance. + :type endpoint: str :keyword endpoint: Service URL. Default value is ''. :paramtype endpoint: str """ def __init__( self, + endpoint: str, credential: Union["AsyncTokenCredential", "AzureKeyCredential"], **kwargs: Any ) -> None: - endpoint = kwargs.pop('endpoint', "") # type: str kwargs['origin_endpoint'] = endpoint - self._config = WebPubSubServiceClientConfiguration(credential, **kwargs) - self._client = AsyncPipelineClient(base_url=endpoint, config=self._config, **kwargs) + _endpoint = '{Endpoint}' + self._config = WebPubSubServiceClientConfiguration(endpoint, credential, **kwargs) + self._client = AsyncPipelineClient(base_url=_endpoint, config=self._config, **kwargs) self._serialize = Serializer() self._deserialize = Deserializer() diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py index a733e3fa6e0c..c28ac3a8a4e5 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py @@ -29,21 +29,21 @@ class WebPubSubServiceClient: :vartype health_api: azure.messaging.webpubsubservice.aio.operations.HealthApiOperations :ivar web_pub_sub: WebPubSubOperations operations :vartype web_pub_sub: azure.messaging.webpubsubservice.aio.operations.WebPubSubOperations + :param endpoint: HTTP or HTTPS endpoint for the Web PubSub service instance. + :type endpoint: str :param credential: Credential needed for the client to connect to Azure. :type credential: ~azure.core.credentials_async.AsyncTokenCredential - :keyword endpoint: Service URL. Default value is ''. - :paramtype endpoint: str """ def __init__( self, + endpoint: str, credential: "AsyncTokenCredential", - *, - endpoint: str = "", **kwargs: Any ) -> None: - self._config = WebPubSubServiceClientConfiguration(credential, **kwargs) - self._client = AsyncPipelineClient(base_url=endpoint, config=self._config, **kwargs) + _endpoint = '{Endpoint}' + self._config = WebPubSubServiceClientConfiguration(endpoint, credential, **kwargs) + self._client = AsyncPipelineClient(base_url=_endpoint, config=self._config, **kwargs) self._serialize = Serializer() self._deserialize = Deserializer() @@ -75,7 +75,11 @@ def send_request( """ request_copy = deepcopy(request) - request_copy.url = self._client.format_url(request_copy.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + + request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) return self._client.send_request(request_copy, **kwargs) async def close(self) -> None: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/_operations.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/_operations.py index 3ef37c276158..0875fc84bb0e 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/_operations.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/_operations.py @@ -66,7 +66,10 @@ async def get_service_status( api_version=api_version, template_url=self.get_service_status.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -151,7 +154,10 @@ async def generate_client_token( api_version=api_version, template_url=self.generate_client_token.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -232,7 +238,10 @@ async def send_to_all( content=content, template_url=self.send_to_all.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -284,7 +293,10 @@ async def connection_exists( api_version=api_version, template_url=self.connection_exists.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -340,7 +352,10 @@ async def close_connection( api_version=api_version, template_url=self.close_connection.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -414,7 +429,10 @@ async def send_to_connection( content=content, template_url=self.send_to_connection.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -466,7 +484,10 @@ async def group_exists( api_version=api_version, template_url=self.group_exists.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -544,7 +565,10 @@ async def send_to_group( content=content, template_url=self.send_to_group.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -600,7 +624,10 @@ async def add_connection_to_group( api_version=api_version, template_url=self.add_connection_to_group.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -656,7 +683,10 @@ async def remove_connection_from_group( api_version=api_version, template_url=self.remove_connection_from_group.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -708,7 +738,10 @@ async def user_exists( api_version=api_version, template_url=self.user_exists.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -782,7 +815,10 @@ async def send_to_user( content=content, template_url=self.send_to_user.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -838,7 +874,10 @@ async def add_user_to_group( api_version=api_version, template_url=self.add_user_to_group.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -894,7 +933,10 @@ async def remove_user_from_group( api_version=api_version, template_url=self.remove_user_from_group.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -946,7 +988,10 @@ async def remove_user_from_all_groups( api_version=api_version, template_url=self.remove_user_from_all_groups.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -1008,7 +1053,10 @@ async def grant_permission( api_version=api_version, template_url=self.grant_permission.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -1070,7 +1118,10 @@ async def revoke_permission( api_version=api_version, template_url=self.revoke_permission.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -1132,7 +1183,10 @@ async def check_permission( api_version=api_version, template_url=self.check_permission.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/_operations.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/_operations.py index 9837c993726a..af92a7a75292 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/_operations.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/_operations.py @@ -677,7 +677,10 @@ def get_service_status( api_version=api_version, template_url=self.get_service_status.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -763,7 +766,10 @@ def generate_client_token( api_version=api_version, template_url=self.generate_client_token.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -844,7 +850,10 @@ def send_to_all( content=content, template_url=self.send_to_all.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -897,7 +906,10 @@ def connection_exists( api_version=api_version, template_url=self.connection_exists.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -954,7 +966,10 @@ def close_connection( api_version=api_version, template_url=self.close_connection.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -1028,7 +1043,10 @@ def send_to_connection( content=content, template_url=self.send_to_connection.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -1081,7 +1099,10 @@ def group_exists( api_version=api_version, template_url=self.group_exists.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -1159,7 +1180,10 @@ def send_to_group( content=content, template_url=self.send_to_group.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -1216,7 +1240,10 @@ def add_connection_to_group( api_version=api_version, template_url=self.add_connection_to_group.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -1273,7 +1300,10 @@ def remove_connection_from_group( api_version=api_version, template_url=self.remove_connection_from_group.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -1326,7 +1356,10 @@ def user_exists( api_version=api_version, template_url=self.user_exists.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -1400,7 +1433,10 @@ def send_to_user( content=content, template_url=self.send_to_user.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -1457,7 +1493,10 @@ def add_user_to_group( api_version=api_version, template_url=self.add_user_to_group.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -1514,7 +1553,10 @@ def remove_user_from_group( api_version=api_version, template_url=self.remove_user_from_group.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -1567,7 +1609,10 @@ def remove_user_from_all_groups( api_version=api_version, template_url=self.remove_user_from_all_groups.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -1630,7 +1675,10 @@ def grant_permission( api_version=api_version, template_url=self.grant_permission.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -1693,7 +1741,10 @@ def revoke_permission( api_version=api_version, template_url=self.revoke_permission.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response @@ -1756,7 +1807,10 @@ def check_permission( api_version=api_version, template_url=self.check_permission.metadata['url'], ) - request.url = self._client.format_url(request.url) + path_format_arguments = { + "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), + } + request.url = self._client.format_url(request.url, **path_format_arguments) pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) response = pipeline_response.http_response diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml index d303555311af..93df8ba8fac9 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml @@ -19,7 +19,7 @@ interactions: connection: - keep-alive date: - - Thu, 16 Sep 2021 07:22:28 GMT + - Thu, 16 Sep 2021 07:55:30 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_request.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_request.yaml index 8ab27d86d7c1..567c090df450 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_request.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_request.yaml @@ -25,7 +25,7 @@ interactions: content-length: - '0' date: - - Thu, 16 Sep 2021 07:22:31 GMT + - Thu, 16 Sep 2021 07:55:32 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml index 0661ecf093b1..f4bb578dfad0 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml @@ -25,7 +25,7 @@ interactions: content-length: - '0' date: - - Thu, 16 Sep 2021 07:22:33 GMT + - Thu, 16 Sep 2021 07:55:35 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml index ad57a6ae7eed..36bd0dcbec08 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml @@ -23,7 +23,7 @@ interactions: content-length: - '0' date: - - Thu, 16 Sep 2021 07:22:34 GMT + - Thu, 16 Sep 2021 07:55:37 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml index 6fd6893894c1..904d9f7838f6 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml @@ -11,7 +11,7 @@ interactions: string: '' headers: connection: keep-alive - date: Thu, 16 Sep 2021 07:22:40 GMT + date: Thu, 16 Sep 2021 07:55:46 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 200 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml index 6ec6c58efb12..1011f41c7407 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml @@ -16,7 +16,7 @@ interactions: headers: connection: keep-alive content-length: '0' - date: Thu, 16 Sep 2021 07:22:43 GMT + date: Thu, 16 Sep 2021 07:55:48 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 202 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml index eb5765b0aa06..488c4dde2a16 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml @@ -15,7 +15,7 @@ interactions: string: '' headers: content-length: '0' - date: Thu, 16 Sep 2021 07:22:45 GMT + date: Thu, 16 Sep 2021 07:55:50 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 202 From 5fa9d2598b289b8db159b068d00377ff097d5233 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Thu, 16 Sep 2021 16:50:01 +0800 Subject: [PATCH 28/33] fix ci --- .../samples/README.md | 51 ------------------- 1 file changed, 51 deletions(-) delete mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/samples/README.md diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/README.md b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/README.md deleted file mode 100644 index 124940513f4a..000000000000 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/README.md +++ /dev/null @@ -1,51 +0,0 @@ - -# Samples for Azure Web PubSub client library for Python - -These code samples show common scenario operations with the Azure Web PubSub client library. -The async versions of the samples require Python 3.6 or later. - -You can authenticate your client with API key or through Azure Active Directory with a token credential from [azure-identity][azure_identity], there is introduction in [README.md][readme] -about the authentication knowledge. These sample programs show common scenarios: - -|**File Name**|**Description**| -|----------------|-------------| -|[send_message_aad.py][send_message_aad] |Send message through AAD authentication| -|[send_messages_aad_apim_proxy.py][send_messages_aad_apim_proxy] |Send message through AAD authentication with Api management proxy| -|[send_messages_connection_string.py][send_messages_connection_string] |Send message through connection string authentication| -|[send_messages_connection_string_apim_proxy.py][send_messages_connection_string_apim_proxy] |Send message through connection string authentication with Api management proxy| - -## Prerequisites -* Python 2.7, or 3.6 or later is required to use this package (3.6 or later if using asyncio) -* You must have an [Azure Web PubSub account][azure_web_pubsub_account] to run these samples. -## Setup - -1. Install the Azure Web PubSub client library for Python with [pip][pip]: - -```bash -pip install azure-messaging-webpubsub -``` - -* If authenticating with Azure Active Directory, make sure you have [azure-identity][azure_identity_pip] installed: - ```bash - pip install azure-identity - ``` - -2. Clone or download this sample repository - -3. Open the sample folder in Visual Studio Code or your IDE of choice. - -## Running the samples - -1. Open a terminal window and `cd` to the directory that the samples are saved in. -2. Set the environment variables specified in the sample file you wish to run. -3. Follow the usage described in the file, e.g. `python send_message_aad.py` - -[azure_identity]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/identity/azure-identity -[readme]: ../README.md -[pip]: https://pypi.org/project/pip/ -[azure_identity_pip]: https://pypi.org/project/azure-identity/ -[send_message_aad]: send_messages_aad.py -[send_messages_aad_apim_proxy]: send_messages_aad_apim_proxy.py -[send_messages_connection_string]: send_messages_connection_string.py -[send_messages_connection_string_apim_proxy]: send_messages_connection_string_apim_proxy.py -[azure_web_pubsub_account]: https://docs.microsoft.com/azure/azure-web-pubsub/howto-develop-create-instance \ No newline at end of file From 55537f74660f8740461a3380f39369d67dff2ace Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Thu, 16 Sep 2021 17:13:16 +0800 Subject: [PATCH 29/33] fix ci --- sdk/webpubsub/azure-messaging-webpubsubservice/MANIFEST.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/MANIFEST.in b/sdk/webpubsub/azure-messaging-webpubsubservice/MANIFEST.in index a3b68055b727..2094336fbe77 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/MANIFEST.in +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/MANIFEST.in @@ -3,4 +3,4 @@ include azure/__init__.py include azure/messaging/__init__.py include LICENSE.txt recursive-include tests *.py -recursive-include examples *.py *.md \ No newline at end of file +recursive-include samples *.py *.md \ No newline at end of file From f49f435b1f603f427cdb62dd48ccb6a0e6f0ea12 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Fri, 17 Sep 2021 10:26:38 +0800 Subject: [PATCH 30/33] move operation onto client --- .../messaging/webpubsubservice/_patch.py | 7 - .../_web_pub_sub_service_client.py | 10 +- .../messaging/webpubsubservice/aio/_patch.py | 13 +- .../aio/_web_pub_sub_service_client.py | 10 +- .../aio/operations/__init__.py | 6 +- .../aio/operations/_operations.py | 117 ++---------- .../webpubsubservice/operations/__init__.py | 6 +- .../operations/_operations.py | 172 ++++-------------- .../samples/send_messages_aad.py | 6 +- .../samples/send_messages_aad_apim_proxy.py | 6 +- .../send_messages_connection_string.py | 6 +- ...d_messages_connection_string_apim_proxy.py | 6 +- .../swagger/README.md | 28 ++- .../test_smoke.test_health_api_status.yaml | 28 --- ...est_smoke.test_webpubsub_send_request.yaml | 2 +- ...test_smoke.test_webpubsub_send_to_all.yaml | 2 +- ...bsub_send_to_all_api_management_proxy.yaml | 2 +- ...st_smoke_async.test_health_api_status.yaml | 20 -- ...moke_async.test_webpubsub_send_to_all.yaml | 2 +- ...test_webpubsub_send_to_all_apim_proxy.yaml | 2 +- .../tests/test_smoke.py | 14 +- .../tests/test_smoke_async.py | 9 +- 22 files changed, 115 insertions(+), 359 deletions(-) delete mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml delete mode 100644 sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py index 3130b3ccdd57..bf1f9b445225 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py @@ -31,7 +31,6 @@ from typing import TYPE_CHECKING from ._version import VERSION -from .operations import HealthApiOperations, WebPubSubOperations from ._web_pub_sub_service_client import WebPubSubServiceClient as GeneratedWebPubSubServiceClient from msrest import Deserializer, Serializer @@ -287,10 +286,6 @@ def _configure( class WebPubSubServiceClient(GeneratedWebPubSubServiceClient): """WebPubSubServiceClient. - :ivar health_api: HealthApiOperations operations - :vartype health_api: azure.messaging.webpubsubservice.operations.HealthApiOperations - :ivar web_pub_sub: WebPubSubOperations operations - :vartype web_pub_sub: azure.messaging.webpubsubservice.operations.WebPubSubOperations :param endpoint: HTTP or HTTPS endpoint for the Web PubSub service instance. :type endpoint: str :param credential: Credential needed for the client to connect to Azure. @@ -312,8 +307,6 @@ def __init__( self._serialize = Serializer() self._deserialize = Deserializer() self._serialize.client_side_validation = False - self.health_api = HealthApiOperations(self._client, self._config, self._serialize, self._deserialize) - self.web_pub_sub = WebPubSubOperations(self._client, self._config, self._serialize, self._deserialize) @classmethod def from_connection_string(cls, connection_string, **kwargs): diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py index f3ba66caa656..260190e94194 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_web_pub_sub_service_client.py @@ -13,7 +13,7 @@ from msrest import Deserializer, Serializer from ._configuration import WebPubSubServiceClientConfiguration -from .operations import HealthApiOperations, WebPubSubOperations +from .operations import WebPubSubServiceClientOperationsMixin if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports @@ -22,13 +22,9 @@ from azure.core.credentials import TokenCredential from azure.core.rest import HttpRequest, HttpResponse -class WebPubSubServiceClient(object): +class WebPubSubServiceClient(WebPubSubServiceClientOperationsMixin): """WebPubSubServiceClient. - :ivar health_api: HealthApiOperations operations - :vartype health_api: azure.messaging.webpubsubservice.operations.HealthApiOperations - :ivar web_pub_sub: WebPubSubOperations operations - :vartype web_pub_sub: azure.messaging.webpubsubservice.operations.WebPubSubOperations :param endpoint: HTTP or HTTPS endpoint for the Web PubSub service instance. :type endpoint: str :param credential: Credential needed for the client to connect to Azure. @@ -49,8 +45,6 @@ def __init__( self._serialize = Serializer() self._deserialize = Deserializer() self._serialize.client_side_validation = False - self.health_api = HealthApiOperations(self._client, self._config, self._serialize, self._deserialize) - self.web_pub_sub = WebPubSubOperations(self._client, self._config, self._serialize, self._deserialize) def send_request( diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py index 3074095a950e..822904f98ce1 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_patch.py @@ -32,7 +32,6 @@ from msrest import Deserializer, Serializer from .._version import VERSION -from .operations import HealthApiOperations, WebPubSubOperations from .._patch import JwtCredentialPolicy, ApiManagementProxy, _parse_connection_string from ._web_pub_sub_service_client import WebPubSubServiceClient as GeneratedWebPubSubServiceClient @@ -103,16 +102,10 @@ def _configure( class WebPubSubServiceClient(GeneratedWebPubSubServiceClient): """WebPubSubServiceClient. - :ivar health_api: HealthApiOperations operations - :vartype health_api: azure.messaging.webpubsubservice.aio.operations.HealthApiOperations - :ivar web_pub_sub: WebPubSubOperations operations - :vartype web_pub_sub: azure.messaging.webpubsubservice.aio.operations.WebPubSubOperations - :param credential: Credential needed for the client to connect to Azure. - :type credential: Union[~azure.core.credentials_async.AsyncTokenCredential, ~azure.core.credentials.AzureKeyCredential] :param endpoint: HTTP or HTTPS endpoint for the Web PubSub service instance. :type endpoint: str - :keyword endpoint: Service URL. Default value is ''. - :paramtype endpoint: str + :param credential: Credential needed for the client to connect to Azure. + :type credential: ~azure.core.credentials_async.AsyncTokenCredential """ def __init__( @@ -129,8 +122,6 @@ def __init__( self._serialize = Serializer() self._deserialize = Deserializer() self._serialize.client_side_validation = False - self.health_api = HealthApiOperations(self._client, self._config, self._serialize, self._deserialize) - self.web_pub_sub = WebPubSubOperations(self._client, self._config, self._serialize, self._deserialize) @classmethod def from_connection_string(cls, connection_string, **kwargs): diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py index c28ac3a8a4e5..fe48e209c2a6 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/_web_pub_sub_service_client.py @@ -14,7 +14,7 @@ from msrest import Deserializer, Serializer from ._configuration import WebPubSubServiceClientConfiguration -from .operations import HealthApiOperations, WebPubSubOperations +from .operations import WebPubSubServiceClientOperationsMixin if TYPE_CHECKING: # pylint: disable=unused-import,ungrouped-imports @@ -22,13 +22,9 @@ from azure.core.credentials_async import AsyncTokenCredential -class WebPubSubServiceClient: +class WebPubSubServiceClient(WebPubSubServiceClientOperationsMixin): """WebPubSubServiceClient. - :ivar health_api: HealthApiOperations operations - :vartype health_api: azure.messaging.webpubsubservice.aio.operations.HealthApiOperations - :ivar web_pub_sub: WebPubSubOperations operations - :vartype web_pub_sub: azure.messaging.webpubsubservice.aio.operations.WebPubSubOperations :param endpoint: HTTP or HTTPS endpoint for the Web PubSub service instance. :type endpoint: str :param credential: Credential needed for the client to connect to Azure. @@ -48,8 +44,6 @@ def __init__( self._serialize = Serializer() self._deserialize = Deserializer() self._serialize.client_side_validation = False - self.health_api = HealthApiOperations(self._client, self._config, self._serialize, self._deserialize) - self.web_pub_sub = WebPubSubOperations(self._client, self._config, self._serialize, self._deserialize) def send_request( diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/__init__.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/__init__.py index a2ac5f07bd4f..af83bc4323b2 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/__init__.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/__init__.py @@ -6,10 +6,8 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._operations import HealthApiOperations -from ._operations import WebPubSubOperations +from ._operations import WebPubSubServiceClientOperationsMixin __all__ = [ - 'HealthApiOperations', - 'WebPubSubOperations', + 'WebPubSubServiceClientOperationsMixin', ] diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/_operations.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/_operations.py index 0875fc84bb0e..fa76c744db13 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/_operations.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/aio/operations/_operations.py @@ -15,91 +15,12 @@ from azure.core.rest import HttpRequest from azure.core.tracing.decorator_async import distributed_trace_async -from ...operations._operations import build_health_api_get_service_status_request, build_web_pub_sub_add_connection_to_group_request, build_web_pub_sub_add_user_to_group_request, build_web_pub_sub_check_permission_request, build_web_pub_sub_close_connection_request, build_web_pub_sub_connection_exists_request, build_web_pub_sub_generate_client_token_request, build_web_pub_sub_grant_permission_request, build_web_pub_sub_group_exists_request, build_web_pub_sub_remove_connection_from_group_request, build_web_pub_sub_remove_user_from_all_groups_request, build_web_pub_sub_remove_user_from_group_request, build_web_pub_sub_revoke_permission_request, build_web_pub_sub_send_to_all_request, build_web_pub_sub_send_to_connection_request, build_web_pub_sub_send_to_group_request, build_web_pub_sub_send_to_user_request, build_web_pub_sub_user_exists_request +from ...operations._operations import build_add_connection_to_group_request, build_add_user_to_group_request, build_check_permission_request, build_close_connection_request, build_connection_exists_request, build_generate_client_token_request, build_grant_permission_request, build_group_exists_request, build_remove_connection_from_group_request, build_remove_user_from_all_groups_request, build_remove_user_from_group_request, build_revoke_permission_request, build_send_to_all_request, build_send_to_connection_request, build_send_to_group_request, build_send_to_user_request, build_user_exists_request T = TypeVar('T') ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] -class HealthApiOperations: - """HealthApiOperations async operations. - - You should not instantiate this class directly. Instead, you should create a Client instance that - instantiates it for you and attaches it as an attribute. - - :param client: Client for service requests. - :param config: Configuration of service client. - :param serializer: An object model serializer. - :param deserializer: An object model deserializer. - """ - - def __init__(self, client, config, serializer, deserializer) -> None: - self._client = client - self._serialize = serializer - self._deserialize = deserializer - self._config = config - - @distributed_trace_async - async def get_service_status( - self, - *, - api_version: Optional[str] = "2021-08-01-preview", - **kwargs: Any - ) -> None: - """Get service health status. - - Get service health status. - - :keyword api_version: Api Version. - :paramtype api_version: str - :return: None - :rtype: None - :raises: ~azure.core.exceptions.HttpResponseError - """ - cls = kwargs.pop('cls', None) # type: ClsType[None] - error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError - } - error_map.update(kwargs.pop('error_map', {})) - - - request = build_health_api_get_service_status_request( - api_version=api_version, - template_url=self.get_service_status.metadata['url'], - ) - path_format_arguments = { - "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), - } - request.url = self._client.format_url(request.url, **path_format_arguments) - - pipeline_response = await self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - if cls: - return cls(pipeline_response, None, {}) - - get_service_status.metadata = {'url': '/api/health'} # type: ignore - -class WebPubSubOperations: - """WebPubSubOperations async operations. - - You should not instantiate this class directly. Instead, you should create a Client instance that - instantiates it for you and attaches it as an attribute. - - :param client: Client for service requests. - :param config: Configuration of service client. - :param serializer: An object model serializer. - :param deserializer: An object model deserializer. - """ - - def __init__(self, client, config, serializer, deserializer) -> None: - self._client = client - self._serialize = serializer - self._deserialize = deserializer - self._config = config +class WebPubSubServiceClientOperationsMixin: @distributed_trace_async async def generate_client_token( @@ -146,7 +67,7 @@ async def generate_client_token( error_map.update(kwargs.pop('error_map', {})) - request = build_web_pub_sub_generate_client_token_request( + request = build_generate_client_token_request( hub=hub, user_id=user_id, role=role, @@ -229,7 +150,7 @@ async def send_to_all( "['application/json', 'application/octet-stream', 'text/plain']".format(content_type) ) - request = build_web_pub_sub_send_to_all_request( + request = build_send_to_all_request( hub=hub, content_type=content_type, excluded=excluded, @@ -287,7 +208,7 @@ async def connection_exists( error_map.update(kwargs.pop('error_map', {})) - request = build_web_pub_sub_connection_exists_request( + request = build_connection_exists_request( hub=hub, connection_id=connection_id, api_version=api_version, @@ -345,7 +266,7 @@ async def close_connection( error_map.update(kwargs.pop('error_map', {})) - request = build_web_pub_sub_close_connection_request( + request = build_close_connection_request( hub=hub, connection_id=connection_id, reason=reason, @@ -420,7 +341,7 @@ async def send_to_connection( "['application/json', 'application/octet-stream', 'text/plain']".format(content_type) ) - request = build_web_pub_sub_send_to_connection_request( + request = build_send_to_connection_request( hub=hub, connection_id=connection_id, content_type=content_type, @@ -478,7 +399,7 @@ async def group_exists( error_map.update(kwargs.pop('error_map', {})) - request = build_web_pub_sub_group_exists_request( + request = build_group_exists_request( hub=hub, group=group, api_version=api_version, @@ -555,7 +476,7 @@ async def send_to_group( "['application/json', 'application/octet-stream', 'text/plain']".format(content_type) ) - request = build_web_pub_sub_send_to_group_request( + request = build_send_to_group_request( hub=hub, group=group, content_type=content_type, @@ -617,7 +538,7 @@ async def add_connection_to_group( error_map.update(kwargs.pop('error_map', {})) - request = build_web_pub_sub_add_connection_to_group_request( + request = build_add_connection_to_group_request( hub=hub, group=group, connection_id=connection_id, @@ -676,7 +597,7 @@ async def remove_connection_from_group( error_map.update(kwargs.pop('error_map', {})) - request = build_web_pub_sub_remove_connection_from_group_request( + request = build_remove_connection_from_group_request( hub=hub, group=group, connection_id=connection_id, @@ -732,7 +653,7 @@ async def user_exists( error_map.update(kwargs.pop('error_map', {})) - request = build_web_pub_sub_user_exists_request( + request = build_user_exists_request( hub=hub, user_id=user_id, api_version=api_version, @@ -806,7 +727,7 @@ async def send_to_user( "['application/json', 'application/octet-stream', 'text/plain']".format(content_type) ) - request = build_web_pub_sub_send_to_user_request( + request = build_send_to_user_request( hub=hub, user_id=user_id, content_type=content_type, @@ -867,7 +788,7 @@ async def add_user_to_group( error_map.update(kwargs.pop('error_map', {})) - request = build_web_pub_sub_add_user_to_group_request( + request = build_add_user_to_group_request( hub=hub, group=group, user_id=user_id, @@ -926,7 +847,7 @@ async def remove_user_from_group( error_map.update(kwargs.pop('error_map', {})) - request = build_web_pub_sub_remove_user_from_group_request( + request = build_remove_user_from_group_request( hub=hub, group=group, user_id=user_id, @@ -982,7 +903,7 @@ async def remove_user_from_all_groups( error_map.update(kwargs.pop('error_map', {})) - request = build_web_pub_sub_remove_user_from_all_groups_request( + request = build_remove_user_from_all_groups_request( hub=hub, user_id=user_id, api_version=api_version, @@ -1045,7 +966,7 @@ async def grant_permission( error_map.update(kwargs.pop('error_map', {})) - request = build_web_pub_sub_grant_permission_request( + request = build_grant_permission_request( hub=hub, permission=permission, connection_id=connection_id, @@ -1110,7 +1031,7 @@ async def revoke_permission( error_map.update(kwargs.pop('error_map', {})) - request = build_web_pub_sub_revoke_permission_request( + request = build_revoke_permission_request( hub=hub, permission=permission, connection_id=connection_id, @@ -1175,7 +1096,7 @@ async def check_permission( error_map.update(kwargs.pop('error_map', {})) - request = build_web_pub_sub_check_permission_request( + request = build_check_permission_request( hub=hub, permission=permission, connection_id=connection_id, diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/__init__.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/__init__.py index a2ac5f07bd4f..af83bc4323b2 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/__init__.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/__init__.py @@ -6,10 +6,8 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from ._operations import HealthApiOperations -from ._operations import WebPubSubOperations +from ._operations import WebPubSubServiceClientOperationsMixin __all__ = [ - 'HealthApiOperations', - 'WebPubSubOperations', + 'WebPubSubServiceClientOperationsMixin', ] diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/_operations.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/_operations.py index af92a7a75292..f67786c1052d 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/_operations.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/operations/_operations.py @@ -27,29 +27,7 @@ _SERIALIZER = Serializer() # fmt: off -def build_health_api_get_service_status_request( - **kwargs # type: Any -): - # type: (...) -> HttpRequest - api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] - - # Construct URL - url = kwargs.pop("template_url", '/api/health') - - # Construct parameters - query_parameters = kwargs.pop("params", {}) # type: Dict[str, Any] - if api_version is not None: - query_parameters['api-version'] = _SERIALIZER.query("api_version", api_version, 'str') - - return HttpRequest( - method="HEAD", - url=url, - params=query_parameters, - **kwargs - ) - - -def build_web_pub_sub_generate_client_token_request( +def build_generate_client_token_request( hub, # type: str **kwargs # type: Any ): @@ -92,7 +70,7 @@ def build_web_pub_sub_generate_client_token_request( ) -def build_web_pub_sub_send_to_all_request( +def build_send_to_all_request( hub, # type: str **kwargs # type: Any ): @@ -130,7 +108,7 @@ def build_web_pub_sub_send_to_all_request( ) -def build_web_pub_sub_connection_exists_request( +def build_connection_exists_request( hub, # type: str connection_id, # type: str **kwargs # type: Any @@ -160,7 +138,7 @@ def build_web_pub_sub_connection_exists_request( ) -def build_web_pub_sub_close_connection_request( +def build_close_connection_request( hub, # type: str connection_id, # type: str **kwargs # type: Any @@ -193,7 +171,7 @@ def build_web_pub_sub_close_connection_request( ) -def build_web_pub_sub_send_to_connection_request( +def build_send_to_connection_request( hub, # type: str connection_id, # type: str **kwargs # type: Any @@ -230,7 +208,7 @@ def build_web_pub_sub_send_to_connection_request( ) -def build_web_pub_sub_group_exists_request( +def build_group_exists_request( hub, # type: str group, # type: str **kwargs # type: Any @@ -260,7 +238,7 @@ def build_web_pub_sub_group_exists_request( ) -def build_web_pub_sub_send_to_group_request( +def build_send_to_group_request( hub, # type: str group, # type: str **kwargs # type: Any @@ -300,7 +278,7 @@ def build_web_pub_sub_send_to_group_request( ) -def build_web_pub_sub_add_connection_to_group_request( +def build_add_connection_to_group_request( hub, # type: str group, # type: str connection_id, # type: str @@ -332,7 +310,7 @@ def build_web_pub_sub_add_connection_to_group_request( ) -def build_web_pub_sub_remove_connection_from_group_request( +def build_remove_connection_from_group_request( hub, # type: str group, # type: str connection_id, # type: str @@ -364,7 +342,7 @@ def build_web_pub_sub_remove_connection_from_group_request( ) -def build_web_pub_sub_user_exists_request( +def build_user_exists_request( hub, # type: str user_id, # type: str **kwargs # type: Any @@ -394,7 +372,7 @@ def build_web_pub_sub_user_exists_request( ) -def build_web_pub_sub_send_to_user_request( +def build_send_to_user_request( hub, # type: str user_id, # type: str **kwargs # type: Any @@ -431,7 +409,7 @@ def build_web_pub_sub_send_to_user_request( ) -def build_web_pub_sub_add_user_to_group_request( +def build_add_user_to_group_request( hub, # type: str group, # type: str user_id, # type: str @@ -463,7 +441,7 @@ def build_web_pub_sub_add_user_to_group_request( ) -def build_web_pub_sub_remove_user_from_group_request( +def build_remove_user_from_group_request( hub, # type: str group, # type: str user_id, # type: str @@ -495,7 +473,7 @@ def build_web_pub_sub_remove_user_from_group_request( ) -def build_web_pub_sub_remove_user_from_all_groups_request( +def build_remove_user_from_all_groups_request( hub, # type: str user_id, # type: str **kwargs # type: Any @@ -525,7 +503,7 @@ def build_web_pub_sub_remove_user_from_all_groups_request( ) -def build_web_pub_sub_grant_permission_request( +def build_grant_permission_request( hub, # type: str permission, # type: str connection_id, # type: str @@ -560,7 +538,7 @@ def build_web_pub_sub_grant_permission_request( ) -def build_web_pub_sub_revoke_permission_request( +def build_revoke_permission_request( hub, # type: str permission, # type: str connection_id, # type: str @@ -595,7 +573,7 @@ def build_web_pub_sub_revoke_permission_request( ) -def build_web_pub_sub_check_permission_request( +def build_check_permission_request( hub, # type: str permission, # type: str connection_id, # type: str @@ -630,87 +608,7 @@ def build_web_pub_sub_check_permission_request( ) # fmt: on -class HealthApiOperations(object): - """HealthApiOperations operations. - - You should not instantiate this class directly. Instead, you should create a Client instance that - instantiates it for you and attaches it as an attribute. - - :param client: Client for service requests. - :param config: Configuration of service client. - :param serializer: An object model serializer. - :param deserializer: An object model deserializer. - """ - - def __init__(self, client, config, serializer, deserializer): - self._client = client - self._serialize = serializer - self._deserialize = deserializer - self._config = config - - @distributed_trace - def get_service_status( - self, - **kwargs # type: Any - ): - # type: (...) -> None - """Get service health status. - - Get service health status. - - :keyword api_version: Api Version. - :paramtype api_version: str - :return: None - :rtype: None - :raises: ~azure.core.exceptions.HttpResponseError - """ - cls = kwargs.pop('cls', None) # type: ClsType[None] - error_map = { - 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError - } - error_map.update(kwargs.pop('error_map', {})) - - api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] - - - request = build_health_api_get_service_status_request( - api_version=api_version, - template_url=self.get_service_status.metadata['url'], - ) - path_format_arguments = { - "Endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), - } - request.url = self._client.format_url(request.url, **path_format_arguments) - - pipeline_response = self._client.send_request(request, stream=False, _return_pipeline_response=True, **kwargs) - response = pipeline_response.http_response - - if response.status_code not in [200]: - map_error(status_code=response.status_code, response=response, error_map=error_map) - raise HttpResponseError(response=response) - - if cls: - return cls(pipeline_response, None, {}) - - get_service_status.metadata = {'url': '/api/health'} # type: ignore - -class WebPubSubOperations(object): - """WebPubSubOperations operations. - - You should not instantiate this class directly. Instead, you should create a Client instance that - instantiates it for you and attaches it as an attribute. - - :param client: Client for service requests. - :param config: Configuration of service client. - :param serializer: An object model serializer. - :param deserializer: An object model deserializer. - """ - - def __init__(self, client, config, serializer, deserializer): - self._client = client - self._serialize = serializer - self._deserialize = deserializer - self._config = config +class WebPubSubServiceClientOperationsMixin(object): @distributed_trace def generate_client_token( @@ -758,7 +656,7 @@ def generate_client_token( api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] - request = build_web_pub_sub_generate_client_token_request( + request = build_generate_client_token_request( hub=hub, user_id=user_id, role=role, @@ -841,7 +739,7 @@ def send_to_all( "['application/json', 'application/octet-stream', 'text/plain']".format(content_type) ) - request = build_web_pub_sub_send_to_all_request( + request = build_send_to_all_request( hub=hub, content_type=content_type, excluded=excluded, @@ -900,7 +798,7 @@ def connection_exists( api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] - request = build_web_pub_sub_connection_exists_request( + request = build_connection_exists_request( hub=hub, connection_id=connection_id, api_version=api_version, @@ -959,7 +857,7 @@ def close_connection( api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] - request = build_web_pub_sub_close_connection_request( + request = build_close_connection_request( hub=hub, connection_id=connection_id, reason=reason, @@ -1034,7 +932,7 @@ def send_to_connection( "['application/json', 'application/octet-stream', 'text/plain']".format(content_type) ) - request = build_web_pub_sub_send_to_connection_request( + request = build_send_to_connection_request( hub=hub, connection_id=connection_id, content_type=content_type, @@ -1093,7 +991,7 @@ def group_exists( api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] - request = build_web_pub_sub_group_exists_request( + request = build_group_exists_request( hub=hub, group=group, api_version=api_version, @@ -1170,7 +1068,7 @@ def send_to_group( "['application/json', 'application/octet-stream', 'text/plain']".format(content_type) ) - request = build_web_pub_sub_send_to_group_request( + request = build_send_to_group_request( hub=hub, group=group, content_type=content_type, @@ -1233,7 +1131,7 @@ def add_connection_to_group( api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] - request = build_web_pub_sub_add_connection_to_group_request( + request = build_add_connection_to_group_request( hub=hub, group=group, connection_id=connection_id, @@ -1293,7 +1191,7 @@ def remove_connection_from_group( api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] - request = build_web_pub_sub_remove_connection_from_group_request( + request = build_remove_connection_from_group_request( hub=hub, group=group, connection_id=connection_id, @@ -1350,7 +1248,7 @@ def user_exists( api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] - request = build_web_pub_sub_user_exists_request( + request = build_user_exists_request( hub=hub, user_id=user_id, api_version=api_version, @@ -1424,7 +1322,7 @@ def send_to_user( "['application/json', 'application/octet-stream', 'text/plain']".format(content_type) ) - request = build_web_pub_sub_send_to_user_request( + request = build_send_to_user_request( hub=hub, user_id=user_id, content_type=content_type, @@ -1486,7 +1384,7 @@ def add_user_to_group( api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] - request = build_web_pub_sub_add_user_to_group_request( + request = build_add_user_to_group_request( hub=hub, group=group, user_id=user_id, @@ -1546,7 +1444,7 @@ def remove_user_from_group( api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] - request = build_web_pub_sub_remove_user_from_group_request( + request = build_remove_user_from_group_request( hub=hub, group=group, user_id=user_id, @@ -1603,7 +1501,7 @@ def remove_user_from_all_groups( api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] - request = build_web_pub_sub_remove_user_from_all_groups_request( + request = build_remove_user_from_all_groups_request( hub=hub, user_id=user_id, api_version=api_version, @@ -1667,7 +1565,7 @@ def grant_permission( api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] - request = build_web_pub_sub_grant_permission_request( + request = build_grant_permission_request( hub=hub, permission=permission, connection_id=connection_id, @@ -1733,7 +1631,7 @@ def revoke_permission( api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] - request = build_web_pub_sub_revoke_permission_request( + request = build_revoke_permission_request( hub=hub, permission=permission, connection_id=connection_id, @@ -1799,7 +1697,7 @@ def check_permission( api_version = kwargs.pop('api_version', "2021-08-01-preview") # type: Optional[str] - request = build_web_pub_sub_check_permission_request( + request = build_check_permission_request( hub=hub, permission=permission, connection_id=connection_id, diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad.py b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad.py index 0f37aeb83522..248f9d822ba8 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad.py @@ -49,7 +49,7 @@ # Send a json message to everybody on the given hub... try: # Raise an exception if the service rejected the call - client.web_pub_sub.send_to_all('Hub', message={'Hello': 'all'}) + client.send_to_all('Hub', message={'Hello': 'all'}) print('Successfully sent a JSON message') except HttpResponseError as e: print('Failed to send JSON message: {}'.format(e.response.json())) @@ -57,7 +57,7 @@ # Send a text message to everybody on the given hub... try: # Raise an exception if the service rejected the call - client.web_pub_sub.send_to_all('Hub', message='hello, text!', content_type='text/plain') + client.send_to_all('Hub', message='hello, text!', content_type='text/plain') print('Successfully sent a text message') except HttpResponseError as e: print('Failed to send text message: {}'.format(e.response.json())) @@ -66,7 +66,7 @@ # Send a json message from a stream to everybody on the given hub... try: # Raise an exception if the service rejected the call - client.web_pub_sub.send_to_all('Hub', message=io.BytesIO(b'{ "hello": "world" }'), content_type='application/json') + client.send_to_all('Hub', message=io.BytesIO(b'{ "hello": "world" }'), content_type='application/json') print('Successfully sent a JSON message') except HttpResponseError as e: print('Failed to send JSON message: {}'.format(e.response.json())) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad_apim_proxy.py b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad_apim_proxy.py index 3cb231fa7cf0..14a8e50bbd45 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad_apim_proxy.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad_apim_proxy.py @@ -50,7 +50,7 @@ # Send a json message to everybody on the given hub... try: # Raise an exception if the service rejected the call - client.web_pub_sub.send_to_all('Hub', message={'Hello': 'reverse_proxy_endpoint!'}) + client.send_to_all('Hub', message={'Hello': 'reverse_proxy_endpoint!'}) print('Successfully sent a JSON message') except HttpResponseError as e: print('Failed to send JSON message: {}'.format(e.response.json())) @@ -58,7 +58,7 @@ # Send a text message to everybody on the given hub... try: # Raise an exception if the service rejected the call - client.web_pub_sub.send_to_all('Hub', message='hello, reverse_proxy_endpoint!', content_type='text/plain') + client.send_to_all('Hub', message='hello, reverse_proxy_endpoint!', content_type='text/plain') print('Successfully sent a JSON message') except HttpResponseError as e: print('Failed to send JSON message: {}'.format(e.response.json())) @@ -67,7 +67,7 @@ # Send a json message from a stream to everybody on the given hub... try: # Raise an exception if the service rejected the call - client.web_pub_sub.send_to_all('Hub', message=io.BytesIO(b'{ "hello": "reverse_proxy_endpoint" }'), content_type='application/json') + client.send_to_all('Hub', message=io.BytesIO(b'{ "hello": "reverse_proxy_endpoint" }'), content_type='application/json') print('Successfully sent a JSON message') except HttpResponseError as e: print('Failed to send JSON message: {}'.format(e.response.json())) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string.py b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string.py index b5d4b47ee6ae..f39b1f182fa5 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string.py @@ -46,7 +46,7 @@ try: # Raise an exception if the service rejected the call - client.web_pub_sub.send_to_all('Hub', message={'Hello': 'all!'}) + client.send_to_all('Hub', message={'Hello': 'all!'}) print('Successfully sent a JSON message') except HttpResponseError as e: print('Failed to send JSON message: {}'.format(e.response.json())) @@ -54,7 +54,7 @@ # Send a text message to everybody on the given hub... try: # Raise an exception if the service rejected the call - client.web_pub_sub.send_to_all('Hub', message='hello, text!', content_type='text/plain') + client.send_to_all('Hub', message='hello, text!', content_type='text/plain') print('Successfully sent a JSON message') except HttpResponseError as e: print('Failed to send JSON message: {}'.format(e.response.json())) @@ -63,7 +63,7 @@ # Send a json message from a stream to everybody on the given hub... try: # Raise an exception if the service rejected the call - client.web_pub_sub.send_to_all('Hub', message=io.BytesIO(b'{ "hello": "world" }'), content_type='application/json') + client.send_to_all('Hub', message=io.BytesIO(b'{ "hello": "world" }'), content_type='application/json') print('Successfully sent a JSON message') except HttpResponseError as e: print('Failed to send JSON message: {}'.format(e.response.json())) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string_apim_proxy.py b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string_apim_proxy.py index a22723320831..16ffc5e65a8e 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string_apim_proxy.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string_apim_proxy.py @@ -47,7 +47,7 @@ try: # Raise an exception if the service rejected the call - client.web_pub_sub.send_to_all('Hub', message={'Hello': 'connection_string_reverse_proxy!'}) + client.send_to_all('Hub', message={'Hello': 'connection_string_reverse_proxy!'}) print('Successfully sent a JSON message') except HttpResponseError as e: print('Failed to send JSON message: {}'.format(e.response.json())) @@ -55,7 +55,7 @@ # Send a text message to everybody on the given hub... try: # Raise an exception if the service rejected the call - client.web_pub_sub.send_to_all('Hub', message='hello, connection_string_reverse_proxy!', content_type='text/plain') + client.send_to_all('Hub', message='hello, connection_string_reverse_proxy!', content_type='text/plain') print('Successfully sent a JSON message') except HttpResponseError as e: print('Failed to send JSON message: {}'.format(e.response.json())) @@ -64,7 +64,7 @@ # Send a json message from a stream to everybody on the given hub... try: # Raise an exception if the service rejected the call - client.web_pub_sub.send_to_all('Hub', message=io.BytesIO(b'{ "hello": "connection_string_reverse_proxy" }'), content_type='application/json') + client.send_to_all('Hub', message=io.BytesIO(b'{ "hello": "connection_string_reverse_proxy" }'), content_type='application/json') print('Successfully sent a JSON message') except HttpResponseError as e: print('Failed to send JSON message: {}'.format(e.response.json())) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/swagger/README.md b/sdk/webpubsub/azure-messaging-webpubsubservice/swagger/README.md index e8d43208ecdc..34e185dad628 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/swagger/README.md +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/swagger/README.md @@ -30,7 +30,33 @@ no-namespace-folders: true python: true title: WebPubSubServiceClient version-tolerant: true -package-version: 1.0.0b1 +package-version: 1.0.0b2 add-credential: true credential-scopes: https://webpubsub.azure.com/.default ``` + + +Here's the directive to delete the health api operation that we don't need / want +```yaml + +directive: + - from: swagger-document + where: $["paths"]["/api/health"] + transform: > + delete $["head"]; +``` + +Here's the directive to move the operations from the webpubsub operation group directly onto the client + +```yaml + +directive: + - from: swagger-document + where: $["paths"][*] + transform: > + for (var op of Object.values($)) { + if (op["operationId"].includes("WebPubSub_")) { + op["operationId"] = op["operationId"].replace("WebPubSub_", ""); + } + } +``` \ No newline at end of file diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml deleted file mode 100644 index 93df8ba8fac9..000000000000 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_health_api_status.yaml +++ /dev/null @@ -1,28 +0,0 @@ -interactions: -- request: - body: null - headers: - Accept: - - '*/*' - Accept-Encoding: - - gzip, deflate - Connection: - - keep-alive - User-Agent: - - azsdk-python-messaging-webpubsubservice/1.0.0b2 Python/3.7.3 (Windows-10-10.0.19041-SP0) - method: HEAD - uri: https://myservice.webpubsub.azure.com/api/health?api-version=2021-08-01-preview - response: - body: - string: '' - headers: - connection: - - keep-alive - date: - - Thu, 16 Sep 2021 07:55:30 GMT - strict-transport-security: - - max-age=15724800; includeSubDomains - status: - code: 200 - message: OK -version: 1 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_request.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_request.yaml index 567c090df450..3209b9003870 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_request.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_request.yaml @@ -25,7 +25,7 @@ interactions: content-length: - '0' date: - - Thu, 16 Sep 2021 07:55:32 GMT + - Fri, 17 Sep 2021 02:21:35 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml index f4bb578dfad0..3e374b336a17 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all.yaml @@ -25,7 +25,7 @@ interactions: content-length: - '0' date: - - Thu, 16 Sep 2021 07:55:35 GMT + - Fri, 17 Sep 2021 02:21:37 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml index 36bd0dcbec08..da76f03d1188 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml @@ -23,7 +23,7 @@ interactions: content-length: - '0' date: - - Thu, 16 Sep 2021 07:55:37 GMT + - Fri, 17 Sep 2021 02:21:40 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml deleted file mode 100644 index 904d9f7838f6..000000000000 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_health_api_status.yaml +++ /dev/null @@ -1,20 +0,0 @@ -interactions: -- request: - body: null - headers: - User-Agent: - - azsdk-python-messaging-webpubsubservice/1.0.0b2 Python/3.7.3 (Windows-10-10.0.19041-SP0) - method: HEAD - uri: https://myservice.webpubsub.azure.com/api/health?api-version=2021-08-01-preview - response: - body: - string: '' - headers: - connection: keep-alive - date: Thu, 16 Sep 2021 07:55:46 GMT - strict-transport-security: max-age=15724800; includeSubDomains - status: - code: 200 - message: OK - url: https://webpubsub-yyc.webpubsub.azure.com/api/health?api-version=2021-08-01-preview -version: 1 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml index 1011f41c7407..e8ce7e871950 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all.yaml @@ -16,7 +16,7 @@ interactions: headers: connection: keep-alive content-length: '0' - date: Thu, 16 Sep 2021 07:55:48 GMT + date: Fri, 17 Sep 2021 02:23:19 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 202 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml index 488c4dde2a16..6a03ef2584c6 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke_async.test_webpubsub_send_to_all_apim_proxy.yaml @@ -15,7 +15,7 @@ interactions: string: '' headers: content-length: '0' - date: Thu, 16 Sep 2021 07:55:50 GMT + date: Fri, 17 Sep 2021 02:23:21 GMT strict-transport-security: max-age=15724800; includeSubDomains status: code: 202 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py index 71cbcd06f4bd..89735d949c77 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py @@ -5,28 +5,24 @@ # license information. # ------------------------------------------------------------------------- from testcase import WebpubsubTest, WebpubsubPowerShellPreparer -from azure.messaging.webpubsubservice.operations._operations import build_web_pub_sub_send_to_all_request +from azure.messaging.webpubsubservice.operations._operations import build_send_to_all_request class WebpubsubSmokeTest(WebpubsubTest): - @WebpubsubPowerShellPreparer() - def test_health_api_status(self, webpubsub_endpoint): - client = self.create_client(endpoint=webpubsub_endpoint) - client.health_api.get_service_status() @WebpubsubPowerShellPreparer() def test_webpubsub_send_to_all(self, webpubsub_endpoint): client = self.create_client(endpoint=webpubsub_endpoint) - client.web_pub_sub.send_to_all('Hub', {'hello': 'test_webpubsub_send_to_all'}) + client.send_to_all('Hub', {'hello': 'test_webpubsub_send_to_all'}) @WebpubsubPowerShellPreparer() def test_webpubsub_send_to_all_api_management_proxy(self, webpubsub_endpoint, webpubsub_reverse_proxy_endpoint=None): client = self.create_client(endpoint=webpubsub_endpoint, reverse_proxy_endpoint=webpubsub_reverse_proxy_endpoint) - client.web_pub_sub.send_to_all('Hub', {'hello': 'test_webpubsub_send_to_all_api_management_proxy'}) + client.send_to_all('Hub', {'hello': 'test_webpubsub_send_to_all_api_management_proxy'}) @WebpubsubPowerShellPreparer() def test_webpubsub_send_request(self, webpubsub_endpoint): client = self.create_client(endpoint=webpubsub_endpoint) - request = build_web_pub_sub_send_to_all_request('Hub', content='test_webpubsub_send_request', content_type='text/plain') + request = build_send_to_all_request('Hub', content='test_webpubsub_send_request', content_type='text/plain') response = client.send_request(request) - assert response.status_code == 202 \ No newline at end of file + assert response.status_code == 202 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py index a91db336e36a..61544d89294a 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py @@ -10,17 +10,12 @@ class WebpubsubSmokeTestAsync(WebpubsubTestAsync): - @WebpubsubPowerShellPreparer() - async def test_health_api_status(self, webpubsub_endpoint): - client = self.create_client(endpoint=webpubsub_endpoint) - await client.health_api.get_service_status() - @WebpubsubPowerShellPreparer() async def test_webpubsub_send_to_all(self, webpubsub_endpoint): client = self.create_client(endpoint=webpubsub_endpoint) - await client.web_pub_sub.send_to_all('Hub', {'hello': 'test_webpubsub_send_to_all'}) + await client.send_to_all('Hub', {'hello': 'test_webpubsub_send_to_all'}) @WebpubsubPowerShellPreparer() async def test_webpubsub_send_to_all_apim_proxy(self, webpubsub_endpoint, webpubsub_reverse_proxy_endpoint=None): client = self.create_client(endpoint=webpubsub_endpoint, reverse_proxy_endpoint=webpubsub_reverse_proxy_endpoint) - await client.web_pub_sub.send_to_all('Hub', {'hello': 'test_webpubsub_send_to_all_apim_proxy'}) \ No newline at end of file + await client.send_to_all('Hub', {'hello': 'test_webpubsub_send_to_all_apim_proxy'}) \ No newline at end of file From 132f1bcef6cff060ca8e51121f7dd52434d7b281 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Wed, 22 Sep 2021 15:56:00 +0800 Subject: [PATCH 31/33] review --- .../azure-messaging-webpubsubservice/README.md | 4 ++-- .../azure/messaging/webpubsubservice/_patch.py | 10 +++++----- .../samples/send_messages_aad_apim_proxy.py | 2 +- ...est_webpubsub_send_to_all_api_management_proxy.yaml | 2 +- .../tests/test_smoke.py | 8 ++++++++ 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/README.md b/sdk/webpubsub/azure-messaging-webpubsubservice/README.md index 4daeaac475d1..bcea06b936c4 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/README.md +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/README.md @@ -99,7 +99,7 @@ Use the returned token credential to authenticate the client: >>> client = WebPubSubServiceClient(endpoint='', credential=DefaultAzureCredential()) >>> with open('file.json', 'r') as f: try: - client.web_pub_sub.send_to_all('ahub', content=f, content_type='application/json') + client.send_to_all('ahub', content=f, content_type='application/json') except HttpResponseError as e: print('service responds error: {}'.format(e.response.json())) @@ -159,7 +159,7 @@ Similarly, `logging_enable` can enable detailed logging for a single call, even when it isn't enabled for the client: ```python -result = client.web_pub_sub.send_to_all(..., logging_enable=True) +result = client.send_to_all(..., logging_enable=True) ``` Http request and response details are printed to stdout with this logging config. diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py index bf1f9b445225..fcd447fee38b 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/azure/messaging/webpubsubservice/_patch.py @@ -94,15 +94,15 @@ def build_authentication_token(endpoint, hub, **kwargs): """Build an authentication token for the given endpoint, hub using the provided key. :keyword endpoint: connetion string or HTTP or HTTPS endpoint for the WebPubSub service instance. - :type endpoint: ~str + :type endpoint: str :keyword hub: The hub to give access to. - :type hub: ~str + :type hub: str :keyword accesskey: Key to sign the token with. Required if endpoint is not a connection string - :type accesskey: ~str + :type accesskey: str :keyword ttl: Optional ttl timedelta for the token. Default is 1 hour. :type ttl: ~datetime.timedelta :keyword user: Optional user name (subject) for the token. Default is no user. - :type user: ~str + :type user: str :keyword roles: Roles for the token. :type roles: typing.List[str]. Default is no roles. :returns: ~dict containing the web socket endpoint, the token and a url with the generated access token. @@ -314,7 +314,7 @@ def from_connection_string(cls, connection_string, **kwargs): """Create a new WebPubSubServiceClient from a connection string. :param connection_string: Connection string - :type connection_string: ~str + :type connection_string: str :rtype: WebPubSubServiceClient """ kwargs = _parse_connection_string(connection_string, **kwargs) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad_apim_proxy.py b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad_apim_proxy.py index 14a8e50bbd45..7e7a191f754e 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad_apim_proxy.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad_apim_proxy.py @@ -39,7 +39,7 @@ # AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET, WEBPUBSUB_ENDPOINT try: endpoint = os.environ["WEBPUBSUB_ENDPOINT"] - reverse_proxy_endpoint = os.environ["WEBPUBSUB_REVERSE_RPOXY_ENDPOINT"] + reverse_proxy_endpoint = os.environ["WEBPUBSUB_REVERSE_PROXY_ENDPOINT"] except KeyError: LOG.error("Missing environment variable 'WEBPUBSUB_ENDPOINT' or 'WEBPUBSUB_REVERSE_RPOXY_ENDPOINT' - please set if before running the example") exit() diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml index da76f03d1188..2be7cda87237 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/recordings/test_smoke.test_webpubsub_send_to_all_api_management_proxy.yaml @@ -23,7 +23,7 @@ interactions: content-length: - '0' date: - - Fri, 17 Sep 2021 02:21:40 GMT + - Wed, 22 Sep 2021 07:54:54 GMT strict-transport-security: - max-age=15724800; includeSubDomains status: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py index 89735d949c77..7a1672964c05 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py @@ -4,8 +4,10 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # ------------------------------------------------------------------------- +import pytest from testcase import WebpubsubTest, WebpubsubPowerShellPreparer from azure.messaging.webpubsubservice.operations._operations import build_send_to_all_request +from azure.core.exceptions import ServiceRequestError class WebpubsubSmokeTest(WebpubsubTest): @@ -26,3 +28,9 @@ def test_webpubsub_send_request(self, webpubsub_endpoint): request = build_send_to_all_request('Hub', content='test_webpubsub_send_request', content_type='text/plain') response = client.send_request(request) assert response.status_code == 202 + + @WebpubsubPowerShellPreparer() + def test_webpubsub_send_to_all_api_management_proxy_counter_test(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, reverse_proxy_endpoint='https://example.azure-api.net') + with pytest.raises(ServiceRequestError): + client.send_to_all('Hub', {'hello': 'test_webpubsub_send_to_all_api_management_proxy_counter_test'}) \ No newline at end of file From 9534e0949c841215f9d554515fc947344ef72db1 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Wed, 22 Sep 2021 16:44:28 +0800 Subject: [PATCH 32/33] Update send_messages_connection_string_apim_proxy.py --- .../samples/send_messages_connection_string_apim_proxy.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string_apim_proxy.py b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string_apim_proxy.py index 16ffc5e65a8e..887ca39329d7 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string_apim_proxy.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string_apim_proxy.py @@ -42,7 +42,8 @@ exit() # Build a client from the connection string. And for this example, we have enabled debug -# tracing. For production code, this should be turned off. +# tracing. For production code, this should be turned off. +# If you want to know more about the effect of `reverse_proxy_endpoint`, please reference: https://github.com/Azure/azure-webpubsub/issues/194 client = WebPubSubServiceClient.from_connection_string(connection_string, logging_enable=True, reverse_proxy_endpoint=reverse_proxy_endpoint) try: From 3bf7b82d583d8decff423af6eb6a4e920d81f587 Mon Sep 17 00:00:00 2001 From: msyyc <70930885+msyyc@users.noreply.github.com> Date: Wed, 22 Sep 2021 16:46:37 +0800 Subject: [PATCH 33/33] Update send_messages_aad_apim_proxy.py --- .../samples/send_messages_aad_apim_proxy.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad_apim_proxy.py b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad_apim_proxy.py index 7e7a191f754e..40fb54b6645c 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad_apim_proxy.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad_apim_proxy.py @@ -45,6 +45,7 @@ exit() # Build a client through AAD +# If you want to know more about the effect of `reverse_proxy_endpoint`, please reference: https://github.com/Azure/azure-webpubsub/issues/194 client = WebPubSubServiceClient(credential=DefaultAzureCredential(), endpoint=endpoint, reverse_proxy_endpoint=reverse_proxy_endpoint) # Send a json message to everybody on the given hub...