Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update service client and client and add new api version #25865

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions sdk/communication/azure-communication-identity/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
# Release History

## 1.2.1 (Unreleased)
## 1.3.0 (Unreleased)

### Features Added

### Breaking Changes

### Bugs Fixed

### Other Changes
- Added support to customize the Communication Identity access token's validity period:
- `create_user_and_token` and `get_token` methods in both sync and async clients can now accept keyword argument `token_expires_in: ~datetime.timedelta` that provides the ability to create a Communication Identity access token with custom expiration.
- Added a new API version `ApiVersion.V2022_10_01` that is now the default API version.

## 1.2.0 (2022-08-24)

Expand Down
21 changes: 21 additions & 0 deletions sdk/communication/azure-communication-identity/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,17 @@ Pass in the user object as a parameter, and a list of `CommunicationTokenScope`.
tokenresponse = identity_client.get_token(user, scopes=[CommunicationTokenScope.CHAT])
print("Token issued with value: " + tokenresponse.token)
```

### Issuing or Refreshing an access token with custom expiration for a user

You can specify expiration time for the token. The token can be configured to expire in as little as one hour or as long as 24 hours. The default expiration time is 24 hours.

```python
token_expires_in = timedelta(hours=1)
tokenresponse = identity_client.get_token(user, scopes=[CommunicationTokenScope.CHAT], token_expires_in=token_expires_in)
print("Token issued with value: " + tokenresponse.token)
```

### Creating a user and a token in a single request
For convenience, use `create_user_and_token` to create a new user and issue a token with one function call. This translates into a single web request as opposed to creating a user first and then issuing a token.

Expand All @@ -85,6 +96,16 @@ print("User id:" + user.properties['id'])
print("Token issued with value: " + tokenresponse.token)
```

### Creating a user and a token with custom expiration in a single request

You can specify expiration time for the token. The token can be configured to expire in as little as one hour or as long as 24 hours. The default expiration time is 24 hours.
```python
token_expires_in = timedelta(hours=1)
user, tokenresponse = identity_client.create_user_and_token(scopes=[CommunicationTokenScope.CHAT], token_expires_in=token_expires_in)
print("User id:" + user.properties['id'])
print("Token issued with value: " + tokenresponse.token)
```

### Revoking a user's access tokens

Use `revoke_tokens` to revoke all access tokens for a user. Pass in the user object as a parameter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
class ApiVersion(str, Enum, metaclass=CaseInsensitiveEnumMeta):
V2021_03_07 = "2021-03-07"
V2022_06_01 = "2022-06-01"
V2022_10_01 = "2022-10-01"


DEFAULT_VERSION = ApiVersion.V2022_06_01
DEFAULT_VERSION = ApiVersion.V2022_10_01
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# Licensed under the MIT License.
# ------------------------------------

from typing import TYPE_CHECKING, Any, List, Union, Tuple
from typing import TYPE_CHECKING, Any, Tuple

from azure.core.tracing.decorator import distributed_trace
from azure.core.credentials import AccessToken
Expand All @@ -15,6 +15,7 @@
from ._shared.models import CommunicationUserIdentifier
from ._version import SDK_MONIKER
from ._api_versions import DEFAULT_VERSION
from ._utils import convert_timedelta_to_mins

if TYPE_CHECKING:
from azure.core.credentials import TokenCredential
Expand All @@ -35,6 +36,7 @@ class CommunicationIdentityClient(object): # pylint: disable=client-accepts-api-
:language: python
:dedent: 8
"""

def __init__(
self,
endpoint, # type: str
Expand Down Expand Up @@ -91,33 +93,37 @@ def create_user(self, **kwargs):
:return: CommunicationUserIdentifier
:rtype: ~azure.communication.identity.CommunicationUserIdentifier
"""
api_version = kwargs.pop("api_version", self._api_version)
return self._identity_service_client.communication_identity.create(
api_version=api_version,
cls=lambda pr, u, e: CommunicationUserIdentifier(u.identity.id, raw_id=u.identity.id),
cls=lambda pr, u, e: CommunicationUserIdentifier(u['identity']['id'], raw_id=u['identity']['id']),
AikoBB marked this conversation as resolved.
Show resolved Hide resolved
**kwargs)

@distributed_trace
def create_user_and_token(
self,
scopes, # type: List[Union[str, CommunicationTokenScope]]
scopes, # List[Union[str, CommunicationTokenScope]]
**kwargs # type: Any
):
# type: (...) -> Tuple[CommunicationUserIdentifier, AccessToken]
"""Create a single Communication user with an identity token.

:param scopes: List of scopes to be added to the token.
:type scopes: list[str or ~azure.communication.identity.CommunicationTokenScope]
:keyword token_expires_in: Custom validity period of the Communication Identity access token
within [1, 24] hours range. If not provided, the default value of 24 hours will be used.
:paramtype token_expires_in: ~datetime.timedelta
:return: A tuple of a CommunicationUserIdentifier and a AccessToken.
:rtype:
tuple of (~azure.communication.identity.CommunicationUserIdentifier, ~azure.core.credentials.AccessToken)
"""
api_version = kwargs.pop("api_version", self._api_version)
token_expires_in = kwargs.pop('token_expires_in', None)
request_body = {
'createTokenWithScopes': scopes,
'expiresInMinutes': convert_timedelta_to_mins(token_expires_in)
}
return self._identity_service_client.communication_identity.create(
cls=lambda pr, u, e: (CommunicationUserIdentifier(u.identity.id, raw_id=u.identity.id),
AccessToken(u.access_token.token, u.access_token.expires_on)),
create_token_with_scopes=scopes,
api_version=api_version,
cls=lambda pr, u, e: (CommunicationUserIdentifier(u['identity']['id'], raw_id=u['identity']['id']),
AccessToken(u['accessToken']['token'], u['accessToken']['expiresOn'])),
body=request_body,
**kwargs)

@distributed_trace
Expand All @@ -134,10 +140,8 @@ def delete_user(
:return: None
:rtype: None
"""
api_version = kwargs.pop("api_version", self._api_version)
self._identity_service_client.communication_identity.delete(
user.properties['id'],
api_version=api_version,
**kwargs)

@distributed_trace
Expand All @@ -154,15 +158,22 @@ def get_token(
:type user: ~azure.communication.identity.CommunicationUserIdentifier
:param scopes: List of scopes to be added to the token.
:type scopes: list[str or ~azure.communication.identity.CommunicationTokenScope]
:keyword token_expires_in: Custom validity period of the Communication Identity access token
within [1, 24] hours range. If not provided, the default value of 24 hours will be used.
:paramtype token_expires_in: ~datetime.timedelta
:return: AccessToken
:rtype: ~azure.core.credentials.AccessToken
"""
api_version = kwargs.pop("api_version", self._api_version)
token_expires_in = kwargs.pop('token_expires_in', None)
request_body = {
'scopes': scopes,
'expiresInMinutes': convert_timedelta_to_mins(token_expires_in)
}

return self._identity_service_client.communication_identity.issue_access_token(
user.properties['id'],
scopes,
api_version=api_version,
cls=lambda pr, u, e: AccessToken(u.token, u.expires_on),
body=request_body,
cls=lambda pr, u, e: AccessToken(u['token'], u['expiresOn']),
**kwargs)

@distributed_trace
Expand All @@ -179,10 +190,8 @@ def revoke_tokens(
:return: None
:rtype: None
"""
api_version = kwargs.pop("api_version", self._api_version)
return self._identity_service_client.communication_identity.revoke_access_tokens(
user.properties['id'] if user else None,
api_version=api_version,
**kwargs)

@distributed_trace
Expand All @@ -207,12 +216,15 @@ def get_token_for_teams_user(
:return: AccessToken
:rtype: ~azure.core.credentials.AccessToken
"""
api_version = kwargs.pop("api_version", self._api_version)

request_body = {
"token": aad_token,
"appId": client_id,
"userId": user_object_id
}

return self._identity_service_client.communication_identity.exchange_teams_user_access_token(
token=aad_token,
AikoBB marked this conversation as resolved.
Show resolved Hide resolved
app_id=client_id,
user_id=user_object_id,
api_version=api_version,
cls=lambda pr, u, e: AccessToken(u.token, u.expires_on),
body=request_body,
cls=lambda pr, u, e: AccessToken(u['token'], u['expiresOn']),
**kwargs)

Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,16 @@
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------

from ._communication_identity_client import CommunicationIdentityClient
__all__ = ['CommunicationIdentityClient']
from ._client import CommunicationIdentityClient

# `._patch.py` is used for handwritten extensions to the generated code
# Example: https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/customize_code/how-to-patch-sdk-code.md
from ._patch import patch_sdk
patch_sdk()
try:
from ._patch import __all__ as _patch_all
from ._patch import * # type: ignore # pylint: disable=unused-wildcard-import
except ImportError:
_patch_all = []
from ._patch import patch_sdk as _patch_sdk

__all__ = ["CommunicationIdentityClient"]
__all__.extend([p for p in _patch_all if p not in __all__])

_patch_sdk()
Original file line number Diff line number Diff line change
@@ -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, TYPE_CHECKING

from azure.core import PipelineClient
from azure.core.rest import HttpRequest, HttpResponse

from ._configuration import CommunicationIdentityClientConfiguration
from ._serialization import Deserializer, Serializer
from .operations import CommunicationIdentityOperations

if TYPE_CHECKING:
# pylint: disable=unused-import,ungrouped-imports
from typing import Dict


class CommunicationIdentityClient: # pylint: disable=client-accepts-api-version-keyword
"""Azure Communication Identity Service.

:ivar communication_identity: CommunicationIdentityOperations operations
:vartype communication_identity:
azure.communication.identity.operations.CommunicationIdentityOperations
:param endpoint: The communication resource, for example
https://my-resource.communication.azure.com. Required.
:type endpoint: str
:keyword api_version: Api Version. Default value is "2022-10-01". Note that overriding this
default value may result in unsupported behavior.
:paramtype api_version: str
"""

def __init__( # pylint: disable=missing-client-constructor-parameter-credential
self, endpoint: str, **kwargs: Any
) -> None:
_endpoint = "{endpoint}"
self._config = CommunicationIdentityClientConfiguration(endpoint=endpoint, **kwargs)
self._client = PipelineClient(base_url=_endpoint, config=self._config, **kwargs)

self._serialize = Serializer()
self._deserialize = Deserializer()
self._serialize.client_side_validation = False
self.communication_identity = CommunicationIdentityOperations(
self._client, self._config, self._serialize, self._deserialize
)

def send_request(self, request: HttpRequest, **kwargs: Any) -> HttpResponse:
"""Runs the network request through the client's chained policies.

>>> from azure.core.rest import HttpRequest
>>> request = HttpRequest("GET", "https://www.example.org/")
<HttpRequest [GET], url: 'https://www.example.org/'>
>>> response = client.send_request(request)
<HttpResponse: 200 OK>

For more information on this code flow, see https://aka.ms/azsdk/dpcodegen/python/send_request

: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)
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):
# type: () -> None
self._client.close()

def __enter__(self):
# type: () -> CommunicationIdentityClient
self._client.__enter__()
return self

def __exit__(self, *exc_details):
# type: (Any) -> None
self._client.__exit__(*exc_details)
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,31 @@
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------

from typing import TYPE_CHECKING
from typing import Any

from azure.core.configuration import Configuration
from azure.core.pipeline import policies

if TYPE_CHECKING:
# pylint: disable=unused-import,ungrouped-imports
from typing import Any

VERSION = "unknown"


class CommunicationIdentityClientConfiguration(Configuration): # pylint: disable=too-many-instance-attributes
"""Configuration for CommunicationIdentityClient.

Note that all parameters used to create this instance are saved as instance
attributes.

:param endpoint: The communication resource, for example
https://my-resource.communication.azure.com.
https://my-resource.communication.azure.com. Required.
:type endpoint: str
:keyword api_version: Api Version. Default value is "2022-06-01". Note that overriding this
:keyword api_version: Api Version. Default value is "2022-10-01". Note that overriding this
default value may result in unsupported behavior.
:paramtype api_version: str
"""

def __init__(
self,
endpoint, # type: str
**kwargs # type: Any
):
# type: (...) -> None
def __init__(self, endpoint: str, **kwargs: Any) -> None:
super(CommunicationIdentityClientConfiguration, self).__init__(**kwargs)
api_version = kwargs.pop('api_version', "2022-06-01") # type: str
api_version = kwargs.pop("api_version", "2022-10-01") # type: str

if endpoint is None:
raise ValueError("Parameter 'endpoint' must not be None.")
Expand Down
Loading