Skip to content

Commit ebe2d01

Browse files
MikeyMCZMichal Maternacatalinaperalta
authored
[Text Translation] Add support for AAD authentication (#34883)
* [Text Translation] Add support for AAD authentication * Fixing build * Fixing PR comments * Update sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_patch.py Co-authored-by: catalinaperalta <[email protected]> * Update sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_patch.py Co-authored-by: catalinaperalta <[email protected]> * Update sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_patch.py Co-authored-by: catalinaperalta <[email protected]> * Fix PR comments * Update sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_patch.py Co-authored-by: catalinaperalta <[email protected]> * Update sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_patch.py Co-authored-by: catalinaperalta <[email protected]> * fix types * Update sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_patch.py Co-authored-by: catalinaperalta <[email protected]> * Fix build --------- Co-authored-by: Michal Materna <[email protected]> Co-authored-by: catalinaperalta <[email protected]>
1 parent fcaa29d commit ebe2d01

File tree

14 files changed

+180
-17
lines changed

14 files changed

+180
-17
lines changed

sdk/translation/azure-ai-translation-text/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## 1.0.0b2 (Unreleased)
44

55
### Features Added
6+
- Added support for AAD authentication.
67

78
### Breaking Changes
89

sdk/translation/azure-ai-translation-text/assets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"AssetsRepo": "Azure/azure-sdk-assets",
33
"AssetsRepoPrefixPath": "python",
44
"TagPrefix": "python/translation/azure-ai-translation-text",
5-
"Tag": "python/translation/azure-ai-translation-text_498977d118"
5+
"Tag": "python/translation/azure-ai-translation-text_afde2bdc8c"
66
}

sdk/translation/azure-ai-translation-text/azure/ai/translation/text/__init__.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,16 @@
66
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
77
# --------------------------------------------------------------------------
88

9-
from ._patch import TextTranslationClient
9+
from ._patch import TextTranslationClient, TranslatorCredential, TranslatorAADCredential
1010
from ._version import VERSION
1111

1212
__version__ = VERSION
1313

14-
15-
from ._patch import TranslatorCredential
1614
from ._patch import patch_sdk as _patch_sdk
1715

1816
__all__ = [
1917
"TranslatorCredential",
18+
"TranslatorAADCredential",
2019
"TextTranslationClient",
2120
]
2221

sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_patch.py

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Licensed under the MIT License.
44
# ------------------------------------
55

6-
from typing import Union, Optional
6+
from typing import Union, Optional, Any
77
from azure.core.pipeline import PipelineRequest
88
from azure.core.pipeline.policies import SansIOHTTPPolicy, BearerTokenCredentialPolicy, AzureKeyCredentialPolicy
99
from azure.core.credentials import TokenCredential, AzureKeyCredential
@@ -56,6 +56,39 @@ def on_request(self, request: PipelineRequest) -> None:
5656
request.http_request.headers["Ocp-Apim-Subscription-Key"] = self.credential.key
5757
request.http_request.headers["Ocp-Apim-Subscription-Region"] = self.credential.region
5858

59+
class TranslatorAADCredential:
60+
"""Credential for Translator Service when using AAD authentication.
61+
62+
:param tokenCredential: An object which can provide an access token for the Translator Resource, such as a credential from
63+
:mod:`azure.identity`
64+
:type tokenCredential: ~azure.core.credentials.TokenCredential
65+
:param str resourceId: Azure Resource Id of the Translation Resource.
66+
:param str region: Azure Region of the Translation Resource.
67+
"""
68+
69+
def __init__(self, tokenCredential: TokenCredential, resourceId: str, region: str) -> None:
70+
self.tokenCredential = tokenCredential
71+
self.resourceId = resourceId
72+
self.region = region
73+
74+
class TranslatorAADAuthenticationPolicy(BearerTokenCredentialPolicy):
75+
"""Translator AAD Authentication Policy. Adds headers that are required by Translator Service
76+
when global endpoint is used with AAD policy.
77+
Ocp-Apim-Subscription-Region header contains region of the Translator resource.
78+
Ocp-Apim-ResourceId header contains Azure resource Id - Translator resource.
79+
80+
:param credential: Translator AAD Credentials used to access Translator Resource for global Translator endpoint.
81+
:type credential: ~azure.ai.translation.text.TranslatorAADCredential
82+
"""
83+
84+
def __init__(self, credential: TranslatorAADCredential, **kwargs: Any)-> None:
85+
super(TranslatorAADAuthenticationPolicy, self).__init__(credential.tokenCredential, "https://cognitiveservices.azure.com/.default", **kwargs)
86+
self.translatorCredential = credential
87+
88+
def on_request(self, request: PipelineRequest) -> None:
89+
request.http_request.headers["Ocp-Apim-ResourceId"] = self.translatorCredential.resourceId
90+
request.http_request.headers["Ocp-Apim-Subscription-Region"] = self.translatorCredential.region
91+
super().on_request(request)
5992

6093
def get_translation_endpoint(endpoint, api_version):
6194
if not endpoint:
@@ -74,6 +107,9 @@ def set_authentication_policy(credential, kwargs):
74107
if isinstance(credential, TranslatorCredential):
75108
if not kwargs.get("authentication_policy"):
76109
kwargs["authentication_policy"] = TranslatorAuthenticationPolicy(credential)
110+
elif isinstance(credential, TranslatorAADCredential):
111+
if not kwargs.get("authentication_policy"):
112+
kwargs["authentication_policy"] = TranslatorAADAuthenticationPolicy(credential)
77113
elif isinstance(credential, AzureKeyCredential):
78114
if not kwargs.get("authentication_policy"):
79115
kwargs["authentication_policy"] = AzureKeyCredentialPolicy(
@@ -122,7 +158,7 @@ class TextTranslationClient(ServiceClientGenerated):
122158
https://api.cognitive.microsofttranslator.com). Required.
123159
:type endpoint: str
124160
:param credential: Credential used to authenticate with the Translator service
125-
:type credential: Union[AzureKeyCredential , TokenCredential , TranslatorCredential]
161+
:type credential: Union[AzureKeyCredential , TokenCredential , TranslatorCredential, TranslatorAADCredential]
126162
:keyword api_version: Default value is "3.0". Note that overriding this default value may
127163
result in unsupported behavior.
128164
:paramtype api_version: str
@@ -131,7 +167,7 @@ class TextTranslationClient(ServiceClientGenerated):
131167
def __init__(
132168
self,
133169
*,
134-
credential: Optional[Union[AzureKeyCredential, TokenCredential, TranslatorCredential]] = None,
170+
credential: Optional[Union[AzureKeyCredential, TokenCredential, TranslatorCredential, TranslatorAADCredential]] = None,
135171
endpoint: Optional[str] = None,
136172
api_version="3.0",
137173
**kwargs
@@ -144,4 +180,4 @@ def __init__(
144180
super().__init__(endpoint=translation_endpoint, api_version=api_version, **kwargs)
145181

146182

147-
__all__ = ["TextTranslationClient", "TranslatorCredential"]
183+
__all__ = ["TextTranslationClient", "TranslatorCredential", "TranslatorAADCredential"]

sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
77
# --------------------------------------------------------------------------
88

9-
from ._patch import TextTranslationClient
9+
from ._patch import TextTranslationClient, AsyncTranslatorAADCredential
1010

1111

1212
from ._patch import patch_sdk as _patch_sdk
1313

1414
__all__ = [
1515
"TextTranslationClient",
16+
"AsyncTranslatorAADCredential"
1617
]
1718

1819

sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_patch.py

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
77
Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize
88
"""
9-
from typing import Union, Optional
9+
from typing import Union, Optional, Any
10+
from azure.core.pipeline import PipelineRequest
1011
from azure.core.pipeline.policies import AsyncBearerTokenCredentialPolicy, AzureKeyCredentialPolicy
1112
from azure.core.credentials import AzureKeyCredential
1213
from azure.core.credentials_async import AsyncTokenCredential
@@ -24,11 +25,48 @@ def patch_sdk():
2425
https://aka.ms/azsdk/python/dpcodegen/python/customize
2526
"""
2627

28+
class AsyncTranslatorAADCredential:
29+
"""Credential for Translator Service when using AAD authentication.
30+
31+
:param tokenCredential: An object which can provide an access token for the Translator Resource, such as a credential from
32+
:mod:`azure.identity`
33+
:type tokenCredential: ~azure.core.credentials.TokenCredential
34+
:param str resourceId: Azure Resource Id of the Translation Resource.
35+
:param str region: Azure Region of the Translation Resource.
36+
"""
37+
38+
def __init__(self, tokenCredential: AsyncTokenCredential, resourceId: str, region: str) -> None:
39+
self.tokenCredential = tokenCredential
40+
self.resourceId = resourceId
41+
self.region = region
42+
43+
class AsyncTranslatorAADAuthenticationPolicy(AsyncBearerTokenCredentialPolicy):
44+
"""Translator AAD Authentication Policy. Adds headers that are required by Translator Service
45+
when global endpoint is used with AAD policy.
46+
Ocp-Apim-Subscription-Region header contains region of the Translator resource.
47+
Ocp-Apim-ResourceId header contains Azure resource Id - Translator resource.
48+
49+
:param credential: Translator AAD Credentials used to access Translator Resource for global Translator endpoint.
50+
:type credential: ~azure.ai.translation.text.AsyncTranslatorAADCredential
51+
"""
52+
53+
def __init__(self, credential: AsyncTranslatorAADCredential, **kwargs: Any)-> None:
54+
super(AsyncTranslatorAADAuthenticationPolicy, self).__init__(credential.tokenCredential, "https://cognitiveservices.azure.com/.default", **kwargs)
55+
self.translatorCredential = credential
56+
57+
async def on_request(self, request: PipelineRequest) -> None:
58+
request.http_request.headers["Ocp-Apim-ResourceId"] = self.translatorCredential.resourceId
59+
request.http_request.headers["Ocp-Apim-Subscription-Region"] = self.translatorCredential.region
60+
await super().on_request(request)
61+
2762

2863
def set_authentication_policy(credential, kwargs):
2964
if isinstance(credential, TranslatorCredential):
3065
if not kwargs.get("authentication_policy"):
3166
kwargs["authentication_policy"] = TranslatorAuthenticationPolicy(credential)
67+
elif isinstance(credential, AsyncTranslatorAADCredential):
68+
if not kwargs.get("authentication_policy"):
69+
kwargs["authentication_policy"] = AsyncTranslatorAADAuthenticationPolicy(credential)
3270
elif isinstance(credential, AzureKeyCredential):
3371
if not kwargs.get("authentication_policy"):
3472
kwargs["authentication_policy"] = AzureKeyCredentialPolicy(
@@ -77,15 +115,15 @@ class TextTranslationClient(ServiceClientGenerated):
77115
https://api.cognitive.microsofttranslator.com). Required.
78116
:type endpoint: str
79117
:param credential: Credential used to authenticate with the Translator service
80-
:type credential: Union[AzureKeyCredential , AsyncTokenCredential , TranslatorCredential]
118+
:type credential: Union[AzureKeyCredential , AsyncTokenCredential , TranslatorCredential, AsyncTranslatorAADCredential]
81119
:keyword api_version: Default value is "3.0". Note that overriding this default value may
82120
result in unsupported behavior.
83121
:paramtype api_version: str
84122
"""
85123

86124
def __init__(
87125
self,
88-
credential: Union[AzureKeyCredential, AsyncTokenCredential, TranslatorCredential],
126+
credential: Union[AzureKeyCredential, AsyncTokenCredential, TranslatorCredential, AsyncTranslatorAADCredential],
89127
*,
90128
endpoint: Optional[str] = None,
91129
api_version="3.0",
@@ -99,4 +137,4 @@ def __init__(
99137
super().__init__(endpoint=translation_endpoint, api_version=api_version, **kwargs)
100138

101139

102-
__all__ = ["TextTranslationClient"]
140+
__all__ = ["TextTranslationClient", "AsyncTranslatorAADCredential"]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
-e ../../../tools/azure-sdk-tools
22
-e ../../../tools/azure-devtools
33
-e ../../core/azure-core
4+
-e ../../identity/azure-identity
5+
msrestazure
46
aiohttp>=3.0

sdk/translation/azure-ai-translation-text/tests/preparer.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,8 @@
1313
text_translation_custom_endpoint="https://fakeCustomEndpoint.cognitiveservices.azure.com",
1414
text_translation_apikey="fakeapikey",
1515
text_translation_region="fakeregion",
16+
text_translation_aadClientId="fakeAADClientId",
17+
text_translation_aadTenantId="fakeAADTenantId",
18+
text_translation_aadSecret="fakeAADSecret",
19+
text_translation_aadResourceId="fakeResourceId"
1620
)

sdk/translation/azure-ai-translation-text/tests/test_break_sentence.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def test_autodetect(self, **kwargs):
2121
response = client.find_sentence_boundaries(request_body=input_text_elements)
2222
assert response is not None
2323
assert response[0].detected_language.language == "en"
24-
assert response[0].detected_language.score == 1
24+
assert response[0].detected_language.score > 0.9
2525
assert response[0].sent_len[0] == 11
2626

2727
@TextTranslationPreparer()

sdk/translation/azure-ai-translation-text/tests/test_break_sentence_async.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ async def test_autodetect(self, **kwargs):
2222
response = await client.find_sentence_boundaries(request_body=input_text_elements)
2323
assert response is not None
2424
assert response[0].detected_language.language == "en"
25-
assert response[0].detected_language.score == 1
25+
assert response[0].detected_language.score > 0.9
2626
assert response[0].sent_len[0] == 11
2727

2828
@TextTranslationPreparer()

0 commit comments

Comments
 (0)