From dafceb2902764c0f751802ffb9b35f5dda149f05 Mon Sep 17 00:00:00 2001 From: Michal Materna Date: Thu, 6 Apr 2023 16:21:32 -0700 Subject: [PATCH] Adding Translation Text Service SDK (#29569) * Initial commit * Updates for async operations * Removing Detect, Fixing BreakSentence * Moving to correct location * Adding samples * Updating samples * Update names * Remove custom endpoint file * Update names according to APIView review * Trying to investigate failing tests * Investigation translate call failure * Fixing spelling issues * Spelling fixes * Links in MD files updated * Updating samples * Spelling fix * Readme file fix * Adding missing chapters to README * Commiting before syncing to main * Update version in the changelog * Add package_data to setup * exclude packages that would be excluded by pep420. * Adding description content type * Update setup.py * Removing license * Fixing setup file * Adding all test cases and recordings * Updated test-resources.json * Updated endpoint value for token test * Fixing mypy * Adding pyproject.toml * Testing translate with token test * Fixed translate token test and updated all recordings * Fixing linting * Fixing spelling in the test files * Fixing test errors found in pipeline (#4) Co-authored-by: Hamshavathi Munibyraiah (Murphy V-hmunibyrai Associates Inc) * Update sdk/translation/azure-ai-translation-text/README.md Co-authored-by: Krista Pratico * Update sdk/translation/azure-ai-translation-text/README.md Co-authored-by: Krista Pratico * Update sdk/translation/azure-ai-translation-text/README.md Co-authored-by: Krista Pratico * Update sdk/translation/azure-ai-translation-text/README.md Co-authored-by: Krista Pratico * Update sdk/translation/azure-ai-translation-text/README.md Co-authored-by: Krista Pratico * Update sdk/translation/azure-ai-translation-text/README.md Co-authored-by: Krista Pratico * Update sdk/translation/azure-ai-translation-text/samples/README.md Co-authored-by: Krista Pratico * Update sdk/translation/azure-ai-translation-text/setup.py Co-authored-by: Krista Pratico * Fixing PR comments * Fixing PR comments * Fixing PR comments * Fixing the links * Reference shared implementations * Sharing more implementation * Removing unused imports * Using hasattr instead of isinstance * Fix build * Sample update * Update sdk/translation/azure-ai-translation-text/setup.py Co-authored-by: Krista Pratico * Update sdk/translation/azure-ai-translation-text/README.md Co-authored-by: Krista Pratico * Update sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_patch.py Co-authored-by: Krista Pratico * Fixing PR comments * PR fixes * Passing default scope to the token policy * Fixing PR comments * Fixing the PR comments --------- Co-authored-by: Michal Materna Co-authored-by: Hamshavathi Munibyraiah (Murphy V-hmunibyrai Associates Inc) Co-authored-by: scbedd <45376673+scbedd@users.noreply.github.com> Co-authored-by: hamshavathimunibyraiah <125092972+hamshavathimunibyraiah@users.noreply.github.com> Co-authored-by: Krista Pratico --- .vscode/cspell.json | 19 + .../azure-ai-translation-text/CHANGELOG.md | 5 + .../azure-ai-translation-text/LICENSE | 21 + .../azure-ai-translation-text/MANIFEST.in | 8 + .../azure-ai-translation-text/README.md | 319 ++ .../azure/__init__.py | 1 + .../azure/ai/__init__.py | 1 + .../azure/ai/translation/__init__.py | 1 + .../azure/ai/translation/text/__init__.py | 26 + .../azure/ai/translation/text/_client.py | 97 + .../ai/translation/text/_configuration.py | 58 + .../azure/ai/translation/text/_model_base.py | 714 +++++ .../translation/text/_operations/__init__.py | 19 + .../text/_operations/_operations.py | 1420 +++++++++ .../ai/translation/text/_operations/_patch.py | 20 + .../azure/ai/translation/text/_patch.py | 138 + .../ai/translation/text/_serialization.py | 1996 ++++++++++++ .../azure/ai/translation/text/_vendor.py | 26 + .../azure/ai/translation/text/_version.py | 9 + .../azure/ai/translation/text/aio/__init__.py | 23 + .../azure/ai/translation/text/aio/_client.py | 97 + .../ai/translation/text/aio/_configuration.py | 58 + .../text/aio/_operations/__init__.py | 19 + .../text/aio/_operations/_operations.py | 1203 +++++++ .../text/aio/_operations/_patch.py | 20 + .../azure/ai/translation/text/aio/_patch.py | 103 + .../azure/ai/translation/text/aio/_vendor.py | 26 + .../ai/translation/text/models/__init__.py | 73 + .../ai/translation/text/models/_enums.py | 32 + .../ai/translation/text/models/_models.py | 1185 +++++++ .../ai/translation/text/models/_patch.py | 20 + .../azure/ai/translation/text/py.typed | 1 + .../dev_requirements.txt | 3 + .../azure-ai-translation-text/pyproject.toml | 3 + .../samples/README.md | 42 + .../samples/Sample1_GetLanguages.md | 116 + .../samples/Sample2_Translate.md | 327 ++ .../samples/Sample3_Transliterate.md | 38 + .../samples/Sample4_BreakSentence.md | 66 + .../samples/Sample5_DictionaryLookup.md | 38 + .../samples/Sample6_DictionaryExamples.md | 34 + .../sdk_packaging.toml | 2 + .../azure-ai-translation-text/setup.py | 75 + .../tests/conftest.py | 13 + .../tests/preparer.py | 16 + ...ce.pyTestBreakSentencetest_autodetect.json | 30 + ...pyTestBreakSentencetest_with_language.json | 30 + ...reakSentencetest_with_language_script.json | 30 + ...kSentencetest_with_multiple_languages.json | 30 + ...yExamplestest_multiple_input_elements.json | 35 + ...naryExamplestest_single_input_element.json | 35 + ...aryLookuptest_multiple_input_elements.json | 35 + ...ionaryLookuptest_single_input_element.json | 35 + ...ges.pyTestGetLanguagestest_all_scopes.json | 2800 ++++++++++++++++ ...test_dictionary_multiple_translations.json | 970 ++++++ ...TestGetLanguagestest_dictionary_scope.json | 970 ++++++ ...estGetLanguagestest_translation_scope.json | 652 ++++ ...test_transliteration_multiple_scripts.json | 1238 ++++++++ ...etLanguagestest_transliteration_scope.json | 1238 ++++++++ ...s.pyTestGetLanguagestest_with_culture.json | 2801 +++++++++++++++++ ...ation.pyTestTranslationtest_alignment.json | 35 + ...tion.pyTestTranslationtest_autodetect.json | 35 + ...pyTestTranslationtest_custom_endpoint.json | 34 + ....pyTestTranslationtest_dictionary_tag.json | 35 + ...stTranslationtest_different_texttypes.json | 35 + ...n.pyTestTranslationtest_from_to_latin.json | 35 + ....pyTestTranslationtest_multiple_input.json | 35 + ...slationtest_multiple_target_languages.json | 35 + ...yTestTranslationtest_no_translate_tag.json | 35 + ...ation.pyTestTranslationtest_profanity.json | 35 + ...pyTestTranslationtest_sentence_length.json | 35 + ...anslation.pyTestTranslationtest_token.json | 34 + ...ation.pyTestTranslationtest_translate.json | 35 + ...pyTestTranslationtest_transliteration.json | 35 + ...TestTransliterationtest_edit_distance.json | 34 + ...stTransliterationtest_multiple_inputs.json | 34 + ...stTransliterationtest_transliteration.json | 34 + .../tests/static_access_token_credential.py | 21 + .../tests/test_break_sentence.py | 77 + .../tests/test_dictionary_examples.py | 58 + .../tests/test_dictionary_lookup.py | 51 + .../tests/test_get_languages.py | 129 + .../tests/test_helper.py | 25 + .../tests/test_translation.py | 308 ++ .../tests/test_transliteration.py | 70 + .../tests/testcase.py | 27 + sdk/translation/ci.yml | 2 + sdk/translation/test-resources.json | 33 + 88 files changed, 20851 insertions(+) create mode 100644 sdk/translation/azure-ai-translation-text/CHANGELOG.md create mode 100644 sdk/translation/azure-ai-translation-text/LICENSE create mode 100644 sdk/translation/azure-ai-translation-text/MANIFEST.in create mode 100644 sdk/translation/azure-ai-translation-text/README.md create mode 100644 sdk/translation/azure-ai-translation-text/azure/__init__.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/__init__.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/__init__.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/__init__.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_client.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_configuration.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_model_base.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_operations/__init__.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_operations/_operations.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_operations/_patch.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_patch.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_serialization.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_vendor.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_version.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/__init__.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_client.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_configuration.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_operations/__init__.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_operations/_operations.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_operations/_patch.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_patch.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_vendor.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/models/__init__.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/models/_enums.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/models/_models.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/models/_patch.py create mode 100644 sdk/translation/azure-ai-translation-text/azure/ai/translation/text/py.typed create mode 100644 sdk/translation/azure-ai-translation-text/dev_requirements.txt create mode 100644 sdk/translation/azure-ai-translation-text/pyproject.toml create mode 100644 sdk/translation/azure-ai-translation-text/samples/README.md create mode 100644 sdk/translation/azure-ai-translation-text/samples/Sample1_GetLanguages.md create mode 100644 sdk/translation/azure-ai-translation-text/samples/Sample2_Translate.md create mode 100644 sdk/translation/azure-ai-translation-text/samples/Sample3_Transliterate.md create mode 100644 sdk/translation/azure-ai-translation-text/samples/Sample4_BreakSentence.md create mode 100644 sdk/translation/azure-ai-translation-text/samples/Sample5_DictionaryLookup.md create mode 100644 sdk/translation/azure-ai-translation-text/samples/Sample6_DictionaryExamples.md create mode 100644 sdk/translation/azure-ai-translation-text/sdk_packaging.toml create mode 100644 sdk/translation/azure-ai-translation-text/setup.py create mode 100644 sdk/translation/azure-ai-translation-text/tests/conftest.py create mode 100644 sdk/translation/azure-ai-translation-text/tests/preparer.py create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_break_sentence.pyTestBreakSentencetest_autodetect.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_break_sentence.pyTestBreakSentencetest_with_language.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_break_sentence.pyTestBreakSentencetest_with_language_script.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_break_sentence.pyTestBreakSentencetest_with_multiple_languages.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_dictionary_examples.pyTestDictionaryExamplestest_multiple_input_elements.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_dictionary_examples.pyTestDictionaryExamplestest_single_input_element.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_dictionary_lookup.pyTestDictionaryLookuptest_multiple_input_elements.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_dictionary_lookup.pyTestDictionaryLookuptest_single_input_element.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_all_scopes.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_dictionary_multiple_translations.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_dictionary_scope.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_translation_scope.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_transliteration_multiple_scripts.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_transliteration_scope.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_with_culture.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_alignment.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_autodetect.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_custom_endpoint.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_dictionary_tag.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_different_texttypes.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_from_to_latin.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_multiple_input.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_multiple_target_languages.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_no_translate_tag.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_profanity.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_sentence_length.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_token.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_translate.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_transliteration.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_transliteration.pyTestTransliterationtest_edit_distance.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_transliteration.pyTestTransliterationtest_multiple_inputs.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/recordings/test_transliteration.pyTestTransliterationtest_transliteration.json create mode 100644 sdk/translation/azure-ai-translation-text/tests/static_access_token_credential.py create mode 100644 sdk/translation/azure-ai-translation-text/tests/test_break_sentence.py create mode 100644 sdk/translation/azure-ai-translation-text/tests/test_dictionary_examples.py create mode 100644 sdk/translation/azure-ai-translation-text/tests/test_dictionary_lookup.py create mode 100644 sdk/translation/azure-ai-translation-text/tests/test_get_languages.py create mode 100644 sdk/translation/azure-ai-translation-text/tests/test_helper.py create mode 100644 sdk/translation/azure-ai-translation-text/tests/test_translation.py create mode 100644 sdk/translation/azure-ai-translation-text/tests/test_transliteration.py create mode 100644 sdk/translation/azure-ai-translation-text/tests/testcase.py diff --git a/.vscode/cspell.json b/.vscode/cspell.json index c0bc01c2029d..f98b805a58a9 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -91,6 +91,11 @@ "sdk/ml/azure-ai-ml/NOTICE.txt", "sdk/loadtestservice/azure-developer-loadtesting/**", "sdk/monitor/azure-monitor-ingestion/**", + "sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_serialization.py", + "sdk/translation/azure-ai-translation-text/tests/test_break_sentence.py", + "sdk/translation/azure-ai-translation-text/tests/test_translation.py", + "sdk/translation/azure-ai-translation-text/tests/test_transliteration.py", + "sdk/translation/test-resources.json", "eng/**/*.json", "eng/*.txt", "eng/tox/tox.ini", @@ -483,6 +488,20 @@ "myfoldername" ] }, + { + "filename": "sdk/translation/azure-ai-translation-text/**", + "words": [ + "akhtabar", + "deserializers", + "Esto", + "hudha", + "mosca", + "mros", + "NOACTION", + "prueba", + "wordomatic" + ] + }, { "filename": "sdk/textanalytics/azure-ai-textanalytics/**", "words": [ diff --git a/sdk/translation/azure-ai-translation-text/CHANGELOG.md b/sdk/translation/azure-ai-translation-text/CHANGELOG.md new file mode 100644 index 000000000000..f80bf0d6655d --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/CHANGELOG.md @@ -0,0 +1,5 @@ +# Release History + +## 1.0.0b1 (Unreleased) + + - Initial Release diff --git a/sdk/translation/azure-ai-translation-text/LICENSE b/sdk/translation/azure-ai-translation-text/LICENSE new file mode 100644 index 000000000000..b2f52a2bad4e --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) Microsoft Corporation. + +MIT License + +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. diff --git a/sdk/translation/azure-ai-translation-text/MANIFEST.in b/sdk/translation/azure-ai-translation-text/MANIFEST.in new file mode 100644 index 000000000000..2afc12475437 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/MANIFEST.in @@ -0,0 +1,8 @@ +recursive-include tests *.py +recursive-include samples *.py *.md +include *.md +include LICENSE +include azure/__init__.py +include azure/ai/__init__.py +include azure/ai/translation/__init__.py +include azure/ai/translation/text/py.typed diff --git a/sdk/translation/azure-ai-translation-text/README.md b/sdk/translation/azure-ai-translation-text/README.md new file mode 100644 index 000000000000..e5d77ff0a43c --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/README.md @@ -0,0 +1,319 @@ +# Azure Text Translation client library for Python + +Text Translation is a cloud-based REST API feature of the Translator service that uses neural machine translation technology to enable quick and accurate source-to-target text translation in real time across all supported languages. + +Use the Text Translation client library for Python to: + +* Return a list of languages supported by Translate, Transliterate, and Dictionary operations. + +* Render single source-language text to multiple target-language texts with a single request. + +* Convert text of a source language in letters of a different script. + +* Return equivalent words for the source term in the target language. + +* Return grammatical structure and context examples for the source term and target term pair. + +[Source code][python-dt-src] +| [Package (PyPI)][python-dt-pypi] +| [API reference documentation][python-dt-ref-docs] +| [Product documentation][python-dt-product-docs] +| [Samples][python-dt-samples] + +## Getting started + +### Prerequisites + +* Python 3.7 or later is required to use this package. +* An existing Translator service or Cognitive Services resource. + +### Install the package + +Install the Azure Text Translation client library for Python with [pip][pip]: + +```bash +pip install azure-ai-translation-text +``` + +#### Create a Translator service resource + +You can create Translator resource following [Create a Translator resource][translator_resource_create]. + +### Authenticate the client + +Interaction with the service using the client library begins with creating an instance of the [TextTranslationClient][translator_client_class] class. You will need an **API key** or ``TokenCredential`` to instantiate a client object. For more information regarding authenticating with cognitive services, see [Authenticate requests to Translator Service][translator_auth]. + +#### Get an API key + +You can get the `endpoint`, `API key` and `Region` from the Cognitive Services resource or Translator service resource information in the [Azure Portal][azure_portal]. + +Alternatively, use the [Azure CLI][azure_cli] snippet below to get the API key from the Translator service resource. + +```PowerShell +az cognitiveservices account keys list --resource-group --name +``` + +#### Create a `TextTranslationClient` using an API key and Region credential + +Once you have the value for the API key and Region, create an `TranslatorCredential`. This will allow you to +update the API key without creating a new client. + +With the value of the endpoint, `TranslatorCredential` and a `Region`, you can create the [TextTranslationClient][translator_client_class]: + +```Python +text_translator = TextTranslationClient(credential = TranslatorCredential("", "")); +``` + +## Key concepts + +### `TextTranslationClient` + +A `TextTranslationClient` is the primary interface for developers using the Text Translation client library. It provides both synchronous and asynchronous operations to access a specific use of text translator, such as get supported languages detection or text translation. + +### Input + +A **text element** (`string`), is a single unit of input to be processed by the translation models in the Translator service. Operations on `TextTranslationClient` may take a single text element or a collection of text elements. +For text element length limits, maximum requests size, and supported text encoding see [here][translator_limits]. + +## Examples + +The following section provides several code snippets using the `client` [created above](#create-a-texttranslationclient-using-an-api-key-and-region-credential), and covers the main features present in this client library. Although most of the snippets below make use of synchronous service calls, keep in mind that the Text Translation for Python library package supports both synchronous and asynchronous APIs. + +### Get Supported Languages + +Gets the set of languages currently supported by other operations of the Translator. + +```python +try: + response = text_translator.get_languages() + + print(f"Number of supported languages for translate operation: {len(response.translation) if response.translation is not None else 0}") + print(f"Number of supported languages for transliterate operation: {len(response.transliteration) if response.transliteration is not None else 0}") + print(f"Number of supported languages for dictionary operations: {len(response.dictionary) if response.dictionary is not None else 0}") + + if response.translation is not None: + print("Translation Languages:") + for key, value in response.translation.items(): + print(f"{key} -- name: {value.name} ({value.native_name})") + + if response.transliteration is not None: + print("Transliteration Languages:") + for key, value in response.transliteration.items(): + print(f"{key} -- name: {value.name}, supported script count: {len(value.scripts)}") + + if response.dictionary is not None: + print("Dictionary Languages:") + for key, value in response.dictionary.items(): + print(f"{key} -- name: {value.name}, supported target languages count: {len(value.translations)}") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +For samples on using the `languages` endpoint refer to more samples [here][languages_sample]. + +Please refer to the service documentation for a conceptual discussion of [languages][languages_doc]. + +### Translate + +Renders single source-language text to multiple target-language texts with a single request. + +```python +try: + source_language = "en" + target_languages = ["cs"] + input_text_elements = [ InputTextItem(text = "This is a test") ] + + response = text_translator.translate(content = input_text_elements, to = target_languages, from_parameter = source_language) + translation = response[0] if response else None + + if translation: + for translated_text in translation.translations: + print(f"Text was translated to: '{translated_text.to}' and the result is: '{translated_text.text}'.") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +For samples on using the `translate` endpoint refer to more samples [here][translate_sample]. + +Please refer to the service documentation for a conceptual discussion of [translate][translate_doc]. + +### Transliterate + +Converts characters or letters of a source language to the corresponding characters or letters of a target language. + +```python +try: + language = "zh-Hans" + from_script = "Hans" + to_script = "Latn" + input_text_elements = [ InputTextItem(text = "这是个测试。") ] + + response = text_translator.transliterate(content = input_text_elements, language = language, from_script = from_script, to_script = to_script) + transliteration = response[0] if response else None + + if transliteration: + print(f"Input text was transliterated to '{transliteration.script}' script. Transliterated text: '{transliteration.text}'.") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +For samples on using the `transliterate` endpoint refer to more samples [here][transliterate_sample]. + +Please refer to the service documentation for a conceptual discussion of [transliterate][transliterate_doc]. + +### Break Sentence + +Identifies the positioning of sentence boundaries in a piece of text. + +```python +try: + source_language = "zh-Hans" + source_script = "Latn" + input_text_elements = [ InputTextItem(text = "zhè shì gè cè shì。") ] + + response = text_translator.break_sentence(content = input_text_elements, language = source_language, script = source_script) + break_sentence = response[0] if response else None + + if break_sentence: + detected_language = break_sentence.detected_language + if detected_language: + print(f"Detected languages of the input text: {detected_language.language} with score: {detected_language.score}.") + print(f"The detected sentence boundaries:") + for boundary in break_sentence.sent_len: + print(boundary) + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +For samples on using the `break sentence` endpoint refer to more samples [here][breaksentence_sample]. + +Please refer to the service documentation for a conceptual discussion of [break sentence][breaksentence_doc]. + +### Dictionary Lookup + +Returns equivalent words for the source term in the target language. + +```python +try: + source_language = "en" + target_language = "es" + input_text_elements = [ InputTextItem(text = "fly") ] + + response = text_translator.dictionary_lookup(content = input_text_elements, from_parameter = source_language, to = target_language) + dictionary_entry = response[0] if response else None + + if dictionary_entry: + print(f"For the given input {len(dictionary_entry.translations)} entries were found in the dictionary.") + print(f"First entry: '{dictionary_entry.translations[0].display_target}', confidence: {dictionary_entry.translations[0].confidence}.") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +For samples on using the `dictionary lookup` endpoint refer to more samples [here][dictionarylookup_sample]. + +Please refer to the service documentation for a conceptual discussion of [dictionary lookup][dictionarylookup_doc]. + +### Dictionary Examples + +Returns grammatical structure and context examples for the source term and target term pair. + +```python +from azure.ai.translation.text.models import DictionaryExampleTextItem + +try: + source_language = "en" + target_language = "es" + input_text_elements = [ DictionaryExampleTextItem(text = "fly", translation = "volar") ] + + response = text_translator.dictionary_examples(content = input_text_elements, from_parameter = source_language, to = target_language) + dictionary_entry = response[0] if response else None + + if dictionary_entry: + print(f"For the given input {len(dictionary_entry.examples)} entries were found in the dictionary.") + print(f"First example: '{dictionary_entry.examples[0].target_prefix}{dictionary_entry.examples[0].target_term}{dictionary_entry.examples[0].target_suffix}'.") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +For samples on using the `dictionary examples` endpoint refer to more samples [here][dictionaryexamples_sample]. + +Please refer to the service documentation for a conceptual discussion of [dictionary examples][dictionaryexamples_doc]. + +## Troubleshooting + +When you interact with the Translator Service using the TextTranslator client library, errors returned by the Translator service correspond to the same HTTP status codes returned for REST API requests. + +For example, if you submit a translation request without a target translate language, a `400` error is returned, indicating "Bad Request". + +You can find the different error codes returned by the service in the [Service Documentation][service_errors]. + +## Provide Feedback + +If you encounter any bugs or have suggestions, please file an issue in the +[Issues](https://github.com/Azure/azure-sdk-for-python/issues) +section of the project. + +## Next steps + +More samples can be found under the [samples][samples] directory. + +## Contributing + +This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit [cla.microsoft.com][cla]. + +When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA. + +This project has adopted the [Microsoft Open Source Code of Conduct][code_of_conduct]. For more information see the [Code of Conduct FAQ][coc_faq] or contact [opencode@microsoft.com][coc_contact] with any additional questions or comments. + + + +[python-dt-src]: https://aka.ms/https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/translation/azure-ai-translation-text/azure/ai/translation/text +[python-dt-pypi]: https://aka.ms/azsdk/python/texttranslation/pypi +[python-dt-product-docs]: https://learn.microsoft.com/azure/cognitive-services/translator/ +[python-dt-ref-docs]: https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-reference +[python-dt-samples]: https://aka.ms/https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/translation/azure-ai-translation-text/samples + +[pip]: https://pypi.org/project/pip/ +[azure_cli]: https://docs.microsoft.com/cli/azure +[azure_portal]: https://portal.azure.com + +[translator_resource_create]: https://learn.microsoft.com/azure/cognitive-services/Translator/create-translator-resource + +[translator_client_class]: https://aka.ms/https://github.com/azure-sdk-for-python/blob/main/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_client.py + +[translator_auth]: https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-reference#authentication +[translator_limits]: https://learn.microsoft.com/azure/cognitive-services/translator/request-limits +[service_errors]: https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-reference#errors + +[languages_doc]: https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-languages +[translate_doc]: https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-translate +[transliterate_doc]: https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-transliterate +[breaksentence_doc]: https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-break-sentence +[dictionarylookup_doc]: https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-dictionary-lookup +[dictionaryexamples_doc]: https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-dictionary-examples + +[languages_sample]: https://aka.ms/https://github.com/azure-sdk-for-python/tree/main/sdk/translation/azure-ai-translation-text/samples/Sample1_GetLanguages.md +[translate_sample]: https://aka.ms/https://github.com/azure-sdk-for-python/tree/main/sdk/translation/azure-ai-translation-text/samples/Sample2_Translate.md +[transliterate_sample]: https://aka.ms/https://github.com/azure-sdk-for-python/tree/main/sdk/translation/azure-ai-translation-text/samples/Sample3_Transliterate.md +[breaksentence_sample]: https://aka.ms/https://github.com/azure-sdk-for-python/tree/main/sdk/translation/azure-ai-translation-text/samples/Sample4_BreakSentence.md +[dictionarylookup_sample]: https://aka.ms/https://github.com/azure-sdk-for-python/tree/main/sdk/translation/azure-ai-translation-text/samples/Sample5_DictionaryLookup.md +[dictionaryexamples_sample]: https://aka.ms/https://github.com/azure-sdk-for-python/tree/main/sdk/translation/azure-ai-translation-text/samples/Sample6_DictionaryExamples.md + +[samples]: https://aka.ms/https://github.com/azure-sdk-for-python/tree/main/sdk/translation/azure-ai-translation-text/samples + +[cla]: https://cla.microsoft.com +[code_of_conduct]: https://opensource.microsoft.com/codeofconduct/ +[coc_faq]: https://opensource.microsoft.com/codeofconduct/faq/ +[coc_contact]: mailto:opencode@microsoft.com diff --git a/sdk/translation/azure-ai-translation-text/azure/__init__.py b/sdk/translation/azure-ai-translation-text/azure/__init__.py new file mode 100644 index 000000000000..d55ccad1f573 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/__init__.py @@ -0,0 +1 @@ +__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/__init__.py b/sdk/translation/azure-ai-translation-text/azure/ai/__init__.py new file mode 100644 index 000000000000..d55ccad1f573 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/__init__.py @@ -0,0 +1 @@ +__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/__init__.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/__init__.py new file mode 100644 index 000000000000..d55ccad1f573 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/__init__.py @@ -0,0 +1 @@ +__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/__init__.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/__init__.py new file mode 100644 index 000000000000..dbfdf9d029a2 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/__init__.py @@ -0,0 +1,26 @@ +# 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) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._patch import TextTranslationClient +from ._version import VERSION + +__version__ = VERSION + +try: + from ._patch import __all__ as _patch_all + from ._patch import * # pylint: disable=unused-wildcard-import +except ImportError: + _patch_all = [] +from ._patch import patch_sdk as _patch_sdk + +__all__ = [ + "TextTranslationClient", +] +__all__.extend([p for p in _patch_all if p not in __all__]) + +_patch_sdk() diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_client.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_client.py new file mode 100644 index 000000000000..8b33807eebe0 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_client.py @@ -0,0 +1,97 @@ +# 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) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from copy import deepcopy +from typing import Any + +from azure.core import PipelineClient +from azure.core.rest import HttpRequest, HttpResponse + +from ._configuration import TextTranslationClientConfiguration +from ._operations import TextTranslationClientOperationsMixin +from ._serialization import Deserializer, Serializer + + +class TextTranslationClient(TextTranslationClientOperationsMixin): # pylint: disable=client-accepts-api-version-keyword + """Text translation is a cloud-based REST API feature of the Translator service that uses neural + machine translation technology to enable quick and accurate source-to-target text translation + in real time across all supported languages. + + The following methods are supported by the Text Translation feature: + + Languages. Returns a list of languages supported by Translate, Transliterate, and Dictionary + Lookup operations. + + Translate. Renders single source-language text to multiple target-language texts with a single + request. + + Transliterate. Converts characters or letters of a source language to the corresponding + characters or letters of a target language. + + Detect. Returns the source code language code and a boolean variable denoting whether the + detected language is supported for text translation and transliteration. + + Dictionary lookup. Returns equivalent words for the source term in the target language. + + Dictionary example Returns grammatical structure and context examples for the source term and + target term pair. + + :param endpoint: Supported Text Translation endpoints (protocol and hostname, for example: + https://api.cognitive.microsofttranslator.com). Required. + :type endpoint: str + :keyword api_version: Default value is "3.0". 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 = TextTranslationClientConfiguration(endpoint=endpoint, **kwargs) + self._client: PipelineClient = PipelineClient(base_url=_endpoint, config=self._config, **kwargs) + + self._serialize = Serializer() + self._deserialize = Deserializer() + self._serialize.client_side_validation = False + + 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/") + + >>> response = client.send_request(request) + + + 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) -> None: + self._client.close() + + def __enter__(self) -> "TextTranslationClient": + self._client.__enter__() + return self + + def __exit__(self, *exc_details: Any) -> None: + self._client.__exit__(*exc_details) diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_configuration.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_configuration.py new file mode 100644 index 000000000000..cc4411253fde --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_configuration.py @@ -0,0 +1,58 @@ +# 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) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +import sys +from typing import Any + +from azure.core.configuration import Configuration +from azure.core.pipeline import policies + +from ._version import VERSION + +if sys.version_info >= (3, 8): + from typing import Literal # pylint: disable=no-name-in-module, ungrouped-imports +else: + from typing_extensions import Literal # type: ignore # pylint: disable=ungrouped-imports + + +class TextTranslationClientConfiguration(Configuration): # pylint: disable=too-many-instance-attributes + """Configuration for TextTranslationClient. + + Note that all parameters used to create this instance are saved as instance + attributes. + + :param endpoint: Supported Text Translation endpoints (protocol and hostname, for example: + https://api.cognitive.microsofttranslator.com). Required. + :type endpoint: str + :keyword api_version: Default value is "3.0". Note that overriding this default value may + result in unsupported behavior. + :paramtype api_version: str + """ + + def __init__(self, endpoint: str, **kwargs: Any) -> None: + super(TextTranslationClientConfiguration, self).__init__(**kwargs) + api_version: Literal["3.0"] = kwargs.pop("api_version", "3.0") + + if endpoint is None: + raise ValueError("Parameter 'endpoint' must not be None.") + + self.endpoint = endpoint + self.api_version = api_version + kwargs.setdefault("sdk_moniker", "ai-translation-text/{}".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.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") diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_model_base.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_model_base.py new file mode 100644 index 000000000000..c37b9314ab90 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_model_base.py @@ -0,0 +1,714 @@ +# 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. +# -------------------------------------------------------------------------- +# pylint: disable=protected-access, arguments-differ, signature-differs, broad-except +# pyright: reportGeneralTypeIssues=false + +import functools +import sys +import logging +import base64 +import re +import copy +import typing +from datetime import datetime, date, time, timedelta, timezone +from json import JSONEncoder +import isodate +from azure.core.exceptions import DeserializationError +from azure.core import CaseInsensitiveEnumMeta +from azure.core.pipeline import PipelineResponse +from azure.core.serialization import NULL as AzureCoreNull + +if sys.version_info >= (3, 9): + from collections.abc import MutableMapping +else: + from typing import MutableMapping + +_LOGGER = logging.getLogger(__name__) + +__all__ = ["NULL", "AzureJSONEncoder", "Model", "rest_field", "rest_discriminator"] + + +class _Null(object): + """To create a Falsy object""" + + def __bool__(self): + return False + + __nonzero__ = __bool__ # Python2 compatibility + + +NULL = _Null() +""" +A falsy sentinel object which is supposed to be used to specify attributes +with no data. This gets serialized to `null` on the wire. +""" + +TZ_UTC = timezone.utc + + +def _timedelta_as_isostr(td: timedelta) -> str: + """Converts a datetime.timedelta object into an ISO 8601 formatted string, e.g. 'P4DT12H30M05S' + + Function adapted from the Tin Can Python project: https://github.com/RusticiSoftware/TinCanPython + + :param timedelta td: The timedelta to convert + :rtype: str + :return: ISO8601 version of this timedelta + """ + + # Split seconds to larger units + seconds = td.total_seconds() + minutes, seconds = divmod(seconds, 60) + hours, minutes = divmod(minutes, 60) + days, hours = divmod(hours, 24) + + days, hours, minutes = list(map(int, (days, hours, minutes))) + seconds = round(seconds, 6) + + # Build date + date_str = "" + if days: + date_str = "%sD" % days + + # Build time + time_str = "T" + + # Hours + bigger_exists = date_str or hours + if bigger_exists: + time_str += "{:02}H".format(hours) + + # Minutes + bigger_exists = bigger_exists or minutes + if bigger_exists: + time_str += "{:02}M".format(minutes) + + # Seconds + try: + if seconds.is_integer(): + seconds_string = "{:02}".format(int(seconds)) + else: + # 9 chars long w/ leading 0, 6 digits after decimal + seconds_string = "%09.6f" % seconds + # Remove trailing zeros + seconds_string = seconds_string.rstrip("0") + except AttributeError: # int.is_integer() raises + seconds_string = "{:02}".format(seconds) + + time_str += "{}S".format(seconds_string) + + return "P" + date_str + time_str + + +def _datetime_as_isostr(dt: typing.Union[datetime, date, time, timedelta]) -> str: + """Converts a datetime.(datetime|date|time|timedelta) object into an ISO 8601 formatted string + + :param timedelta dt: The date object to convert + :rtype: str + :return: ISO8601 version of this datetime + """ + # First try datetime.datetime + if hasattr(dt, "year") and hasattr(dt, "hour"): + dt = typing.cast(datetime, dt) + # astimezone() fails for naive times in Python 2.7, so make make sure dt is aware (tzinfo is set) + if not dt.tzinfo: + iso_formatted = dt.replace(tzinfo=TZ_UTC).isoformat() + else: + iso_formatted = dt.astimezone(TZ_UTC).isoformat() + # Replace the trailing "+00:00" UTC offset with "Z" (RFC 3339: https://www.ietf.org/rfc/rfc3339.txt) + return iso_formatted.replace("+00:00", "Z") + # Next try datetime.date or datetime.time + try: + dt = typing.cast(typing.Union[date, time], dt) + return dt.isoformat() + # Last, try datetime.timedelta + except AttributeError: + dt = typing.cast(timedelta, dt) + return _timedelta_as_isostr(dt) + + +def _serialize_bytes(o) -> str: + return base64.b64encode(o).decode() + + +def _serialize_datetime(o): + if hasattr(o, "year") and hasattr(o, "hour"): + # astimezone() fails for naive times in Python 2.7, so make make sure o is aware (tzinfo is set) + if not o.tzinfo: + iso_formatted = o.replace(tzinfo=TZ_UTC).isoformat() + else: + iso_formatted = o.astimezone(TZ_UTC).isoformat() + # Replace the trailing "+00:00" UTC offset with "Z" (RFC 3339: https://www.ietf.org/rfc/rfc3339.txt) + return iso_formatted.replace("+00:00", "Z") + # Next try datetime.date or datetime.time + return o.isoformat() + + +def _is_readonly(p): + try: + return p._readonly # pylint: disable=protected-access + except AttributeError: + return False + + +class AzureJSONEncoder(JSONEncoder): + """A JSON encoder that's capable of serializing datetime objects and bytes.""" + + def default(self, o): # pylint: disable=too-many-return-statements + if _is_model(o): + readonly_props = [ + p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p) + ] # pylint: disable=protected-access + return {k: v for k, v in o.items() if k not in readonly_props} + if isinstance(o, (bytes, bytearray)): + return base64.b64encode(o).decode() + if o is AzureCoreNull: + return None + try: + return super(AzureJSONEncoder, self).default(o) + except TypeError: + if isinstance(o, (bytes, bytearray)): + return _serialize_bytes(o) + try: + # First try datetime.datetime + return _serialize_datetime(o) + except AttributeError: + pass + # Last, try datetime.timedelta + try: + return _timedelta_as_isostr(o) + except AttributeError: + # This will be raised when it hits value.total_seconds in the method above + pass + return super(AzureJSONEncoder, self).default(o) + + +_VALID_DATE = re.compile(r"\d{4}[-]\d{2}[-]\d{2}T\d{2}:\d{2}:\d{2}" + r"\.?\d*Z?[-+]?[\d{2}]?:?[\d{2}]?") + + +def _deserialize_datetime(attr: typing.Union[str, datetime]) -> datetime: + """Deserialize ISO-8601 formatted string into Datetime object. + + :param str attr: response string to be deserialized. + :rtype: ~datetime.datetime + :returns: The datetime object from that input + """ + if isinstance(attr, datetime): + # i'm already deserialized + return attr + attr = attr.upper() + match = _VALID_DATE.match(attr) + if not match: + raise ValueError("Invalid datetime string: " + attr) + + check_decimal = attr.split(".") + if len(check_decimal) > 1: + decimal_str = "" + for digit in check_decimal[1]: + if digit.isdigit(): + decimal_str += digit + else: + break + if len(decimal_str) > 6: + attr = attr.replace(decimal_str, decimal_str[0:6]) + + date_obj = isodate.parse_datetime(attr) + test_utc = date_obj.utctimetuple() + if test_utc.tm_year > 9999 or test_utc.tm_year < 1: + raise OverflowError("Hit max or min date") + return date_obj + + +def _deserialize_date(attr: typing.Union[str, date]) -> date: + """Deserialize ISO-8601 formatted string into Date object. + :param str attr: response string to be deserialized. + :rtype: date + :returns: The date object from that input + """ + # This must NOT use defaultmonth/defaultday. Using None ensure this raises an exception. + if isinstance(attr, date): + return attr + return isodate.parse_date(attr, defaultmonth=None, defaultday=None) + + +def _deserialize_time(attr: typing.Union[str, time]) -> time: + """Deserialize ISO-8601 formatted string into time object. + + :param str attr: response string to be deserialized. + :rtype: datetime.time + :returns: The time object from that input + """ + if isinstance(attr, time): + return attr + return isodate.parse_time(attr) + + +def deserialize_bytes(attr): + if isinstance(attr, (bytes, bytearray)): + return attr + return bytes(base64.b64decode(attr)) + + +def deserialize_duration(attr): + if isinstance(attr, timedelta): + return attr + return isodate.parse_duration(attr) + + +_DESERIALIZE_MAPPING = { + datetime: _deserialize_datetime, + date: _deserialize_date, + time: _deserialize_time, + bytes: deserialize_bytes, + timedelta: deserialize_duration, + typing.Any: lambda x: x, +} + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + module_end = module_name.rsplit(".", 1)[0] + module = sys.modules[module_end] + models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)}) + if isinstance(model_name, str): + model_name = model_name.split(".")[-1] + if model_name not in models: + return model_name + return models[model_name] + + +_UNSET = object() + + +class _MyMutableMapping(MutableMapping[str, typing.Any]): # pylint: disable=unsubscriptable-object + def __init__(self, data: typing.Dict[str, typing.Any]) -> None: + self._data = copy.deepcopy(data) + + def __contains__(self, key: typing.Any) -> bool: + return key in self._data + + def __getitem__(self, key: str) -> typing.Any: + return self._data.__getitem__(key) + + def __setitem__(self, key: str, value: typing.Any) -> None: + self._data.__setitem__(key, value) + + def __delitem__(self, key: str) -> None: + self._data.__delitem__(key) + + def __iter__(self) -> typing.Iterator[typing.Any]: + return self._data.__iter__() + + def __len__(self) -> int: + return self._data.__len__() + + def __ne__(self, other: typing.Any) -> bool: + return not self.__eq__(other) + + def keys(self) -> typing.KeysView[str]: + return self._data.keys() + + def values(self) -> typing.ValuesView[typing.Any]: + return self._data.values() + + def items(self) -> typing.ItemsView[str, typing.Any]: + return self._data.items() + + def get(self, key: str, default: typing.Any = None) -> typing.Any: + try: + return self[key] + except KeyError: + return default + + @typing.overload # type: ignore + def pop(self, key: str) -> typing.Any: # pylint: disable=no-member + ... + + @typing.overload + def pop(self, key: str, default: typing.Any) -> typing.Any: + ... + + def pop(self, key: str, default: typing.Any = _UNSET) -> typing.Any: + if default is _UNSET: + return self._data.pop(key) + return self._data.pop(key, default) + + def popitem(self) -> typing.Tuple[str, typing.Any]: + return self._data.popitem() + + def clear(self) -> None: + self._data.clear() + + def update(self, *args: typing.Any, **kwargs: typing.Any) -> None: + self._data.update(*args, **kwargs) + + @typing.overload # type: ignore + def setdefault(self, key: str) -> typing.Any: + ... + + @typing.overload + def setdefault(self, key: str, default: typing.Any) -> typing.Any: + ... + + def setdefault(self, key: str, default: typing.Any = _UNSET) -> typing.Any: + if default is _UNSET: + return self._data.setdefault(key) + return self._data.setdefault(key, default) + + def __eq__(self, other: typing.Any) -> bool: + try: + other_model = self.__class__(other) + except Exception: + return False + return self._data == other_model._data + + def __repr__(self) -> str: + return str(self._data) + + +def _is_model(obj: typing.Any) -> bool: + return getattr(obj, "_is_model", False) + + +def _serialize(o): + if isinstance(o, (bytes, bytearray)): + return _serialize_bytes(o) + try: + # First try datetime.datetime + return _serialize_datetime(o) + except AttributeError: + pass + # Last, try datetime.timedelta + try: + return _timedelta_as_isostr(o) + except AttributeError: + # This will be raised when it hits value.total_seconds in the method above + pass + return o + + +def _get_rest_field( + attr_to_rest_field: typing.Dict[str, "_RestField"], rest_name: str +) -> typing.Optional["_RestField"]: + try: + return next(rf for rf in attr_to_rest_field.values() if rf._rest_name == rest_name) + except StopIteration: + return None + + +def _create_value(rf: typing.Optional["_RestField"], value: typing.Any) -> typing.Any: + return _deserialize(rf._type, value) if (rf and rf._is_model) else _serialize(value) + + +class Model(_MyMutableMapping): + _is_model = True + + def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: + class_name = self.__class__.__name__ + if len(args) > 1: + raise TypeError(f"{class_name}.__init__() takes 2 positional arguments but {len(args) + 1} were given") + dict_to_pass = { + rest_field._rest_name: rest_field._default + for rest_field in self._attr_to_rest_field.values() + if rest_field._default is not _UNSET + } + if args: + dict_to_pass.update( + {k: _create_value(_get_rest_field(self._attr_to_rest_field, k), v) for k, v in args[0].items()} + ) + else: + non_attr_kwargs = [k for k in kwargs if k not in self._attr_to_rest_field] + if non_attr_kwargs: + # actual type errors only throw the first wrong keyword arg they see, so following that. + raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") + dict_to_pass.update({self._attr_to_rest_field[k]._rest_name: _serialize(v) for k, v in kwargs.items()}) + super().__init__(dict_to_pass) + + def copy(self) -> "Model": + return Model(self.__dict__) + + def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> "Model": # pylint: disable=unused-argument + # we know the last three classes in mro are going to be 'Model', 'dict', and 'object' + mros = cls.__mro__[:-3][::-1] # ignore model, dict, and object parents, and reverse the mro order + attr_to_rest_field: typing.Dict[str, _RestField] = { # map attribute name to rest_field property + k: v for mro_class in mros for k, v in mro_class.__dict__.items() if k[0] != "_" and hasattr(v, "_type") + } + annotations = { + k: v + for mro_class in mros + if hasattr(mro_class, "__annotations__") # pylint: disable=no-member + for k, v in mro_class.__annotations__.items() # pylint: disable=no-member + } + for attr, rf in attr_to_rest_field.items(): + rf._module = cls.__module__ + if not rf._type: + rf._type = rf._get_deserialize_callable_from_annotation(annotations.get(attr, None)) + if not rf._rest_name_input: + rf._rest_name_input = attr + cls._attr_to_rest_field: typing.Dict[str, _RestField] = dict(attr_to_rest_field.items()) + + return super().__new__(cls) # pylint: disable=no-value-for-parameter + + def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: + for base in cls.__bases__: + if hasattr(base, "__mapping__"): # pylint: disable=no-member + base.__mapping__[discriminator or cls.__name__] = cls # type: ignore # pylint: disable=no-member + + @classmethod + def _get_discriminator(cls) -> typing.Optional[str]: + for v in cls.__dict__.values(): + if isinstance(v, _RestField) and v._is_discriminator: # pylint: disable=protected-access + return v._rest_name # pylint: disable=protected-access + return None + + @classmethod + def _deserialize(cls, data): + if not hasattr(cls, "__mapping__"): # pylint: disable=no-member + return cls(data) + discriminator = cls._get_discriminator() + mapped_cls = cls.__mapping__.get(data.get(discriminator), cls) # pylint: disable=no-member + if mapped_cls == cls: + return cls(data) + return mapped_cls._deserialize(data) # pylint: disable=protected-access + + +def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-statements + annotation: typing.Any, module: typing.Optional[str], rf: typing.Optional["_RestField"] = None +) -> typing.Optional[typing.Callable[[typing.Any], typing.Any]]: + if not annotation or annotation in [int, float]: + return None + + try: + if module and _is_model(_get_model(module, annotation)): + if rf: + rf._is_model = True + + def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj): + if _is_model(obj): + return obj + return _deserialize(model_deserializer, obj) + + return functools.partial(_deserialize_model, _get_model(module, annotation)) + except Exception: + pass + + # is it a literal? + try: + if sys.version_info >= (3, 8): + from typing import Literal # pylint: disable=no-name-in-module, ungrouped-imports + else: + from typing_extensions import Literal # type: ignore # pylint: disable=ungrouped-imports + + if annotation.__origin__ == Literal: + return None + except AttributeError: + pass + + if getattr(annotation, "__origin__", None) is typing.Union: + + def _deserialize_with_union(union_annotation, obj): + for t in union_annotation.__args__: + try: + return _deserialize(t, obj, module) + except DeserializationError: + pass + raise DeserializationError() + + return functools.partial(_deserialize_with_union, annotation) + + # is it optional? + try: + # right now, assuming we don't have unions, since we're getting rid of the only + # union we used to have in msrest models, which was union of str and enum + if any(a for a in annotation.__args__ if a == type(None)): + + if_obj_deserializer = _get_deserialize_callable_from_annotation( + next(a for a in annotation.__args__ if a != type(None)), module, rf + ) + + def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Callable], obj): + if obj is None: + return obj + return _deserialize_with_callable(if_obj_deserializer, obj) + + return functools.partial(_deserialize_with_optional, if_obj_deserializer) + except AttributeError: + pass + + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) + + try: + if annotation._name == "Dict": + key_deserializer = _get_deserialize_callable_from_annotation(annotation.__args__[0], module, rf) + value_deserializer = _get_deserialize_callable_from_annotation(annotation.__args__[1], module, rf) + + def _deserialize_dict( + key_deserializer: typing.Optional[typing.Callable], + value_deserializer: typing.Optional[typing.Callable], + obj: typing.Dict[typing.Any, typing.Any], + ): + if obj is None: + return obj + return { + _deserialize(key_deserializer, k, module): _deserialize(value_deserializer, v, module) + for k, v in obj.items() + } + + return functools.partial( + _deserialize_dict, + key_deserializer, + value_deserializer, + ) + except (AttributeError, IndexError): + pass + try: + if annotation._name in ["List", "Set", "Tuple", "Sequence"]: + if len(annotation.__args__) > 1: + + def _deserialize_multiple_sequence( + entry_deserializers: typing.List[typing.Optional[typing.Callable]], obj + ): + if obj is None: + return obj + return type(obj)( + _deserialize(deserializer, entry, module) + for entry, deserializer in zip(obj, entry_deserializers) + ) + + entry_deserializers = [ + _get_deserialize_callable_from_annotation(dt, module, rf) for dt in annotation.__args__ + ] + return functools.partial(_deserialize_multiple_sequence, entry_deserializers) + deserializer = _get_deserialize_callable_from_annotation(annotation.__args__[0], module, rf) + + def _deserialize_sequence( + deserializer: typing.Optional[typing.Callable], + obj, + ): + if obj is None: + return obj + return type(obj)(_deserialize(deserializer, entry, module) for entry in obj) + + return functools.partial(_deserialize_sequence, deserializer) + except (TypeError, IndexError, AttributeError, SyntaxError): + pass + + def _deserialize_default( + annotation, + deserializer_from_mapping, + obj, + ): + if obj is None: + return obj + try: + return _deserialize_with_callable(annotation, obj) + except Exception: + pass + return _deserialize_with_callable(deserializer_from_mapping, obj) + + return functools.partial(_deserialize_default, annotation, _DESERIALIZE_MAPPING.get(annotation)) + + +def _deserialize_with_callable( + deserializer: typing.Optional[typing.Callable[[typing.Any], typing.Any]], value: typing.Any +): + try: + if value is None: + return None + if deserializer is None: + return value + if isinstance(deserializer, CaseInsensitiveEnumMeta): + try: + return deserializer(value) + except ValueError: + # for unknown value, return raw value + return value + if isinstance(deserializer, type) and issubclass(deserializer, Model): + return deserializer._deserialize(value) + return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) + except Exception as e: + raise DeserializationError() from e + + +def _deserialize(deserializer: typing.Any, value: typing.Any, module: typing.Optional[str] = None) -> typing.Any: + if isinstance(value, PipelineResponse): + value = value.http_response.json() + deserializer = _get_deserialize_callable_from_annotation(deserializer, module) + return _deserialize_with_callable(deserializer, value) + + +class _RestField: + def __init__( + self, + *, + name: typing.Optional[str] = None, + type: typing.Optional[typing.Callable] = None, + is_discriminator: bool = False, + readonly: bool = False, + default: typing.Any = _UNSET, + ): + self._type = type + self._rest_name_input = name + self._module: typing.Optional[str] = None + self._is_discriminator = is_discriminator + self._readonly = readonly + self._is_model = False + self._default = default + + @property + def _rest_name(self) -> str: + if self._rest_name_input is None: + raise ValueError("Rest name was never set") + return self._rest_name_input + + def __get__(self, obj: Model, type=None): + # by this point, type and rest_name will have a value bc we default + # them in __new__ of the Model class + item = obj.get(self._rest_name) + if item is None: + return item + return _deserialize(self._type, _serialize(item)) + + def __set__(self, obj: Model, value) -> None: + if value is None: + # we want to wipe out entries if users set attr to None + try: + obj.__delitem__(self._rest_name) + except KeyError: + pass + return + if self._is_model and not _is_model(value): + obj.__setitem__(self._rest_name, _deserialize(self._type, value)) + obj.__setitem__(self._rest_name, _serialize(value)) + + def _get_deserialize_callable_from_annotation( + self, annotation: typing.Any + ) -> typing.Optional[typing.Callable[[typing.Any], typing.Any]]: + return _get_deserialize_callable_from_annotation(annotation, self._module, self) + + +def rest_field( + *, + name: typing.Optional[str] = None, + type: typing.Optional[typing.Callable] = None, + readonly: bool = False, + default: typing.Any = _UNSET, +) -> typing.Any: + return _RestField(name=name, type=type, readonly=readonly, default=default) + + +def rest_discriminator( + *, name: typing.Optional[str] = None, type: typing.Optional[typing.Callable] = None +) -> typing.Any: + return _RestField(name=name, type=type, is_discriminator=True) diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_operations/__init__.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_operations/__init__.py new file mode 100644 index 000000000000..7317dd9ada4d --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_operations/__init__.py @@ -0,0 +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. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._operations import TextTranslationClientOperationsMixin + +from ._patch import __all__ as _patch_all +from ._patch import * # pylint: disable=unused-wildcard-import +from ._patch import patch_sdk as _patch_sdk + +__all__ = [ + "TextTranslationClientOperationsMixin", +] +__all__.extend([p for p in _patch_all if p not in __all__]) +_patch_sdk() diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_operations/_operations.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_operations/_operations.py new file mode 100644 index 000000000000..4a62611f0559 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_operations/_operations.py @@ -0,0 +1,1420 @@ +# pylint: disable=too-many-lines +# 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) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +import json +import sys +from typing import Any, Callable, Dict, IO, List, Optional, TypeVar, Union, overload + +from azure.core.exceptions import ( + ClientAuthenticationError, + HttpResponseError, + ResourceExistsError, + ResourceNotFoundError, + ResourceNotModifiedError, + map_error, +) +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import HttpResponse +from azure.core.rest import HttpRequest +from azure.core.tracing.decorator import distributed_trace +from azure.core.utils import case_insensitive_dict + +from .. import models as _models +from .._model_base import AzureJSONEncoder, _deserialize +from .._serialization import Serializer +from .._vendor import TextTranslationClientMixinABC + +if sys.version_info >= (3, 8): + from typing import Literal # pylint: disable=no-name-in-module, ungrouped-imports +else: + from typing_extensions import Literal # type: ignore # pylint: disable=ungrouped-imports +T = TypeVar("T") +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] + +_SERIALIZER = Serializer() +_SERIALIZER.client_side_validation = False + + +def build_text_translation_get_languages_request( + *, + client_trace_id: Optional[str] = None, + scope: Optional[str] = None, + accept_language: Optional[str] = None, + if_none_match: Optional[str] = None, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: Literal["3.0"] = kwargs.pop("api_version", _params.pop("api-version", "3.0")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/languages" + + # Construct parameters + if scope is not None: + _params["scope"] = _SERIALIZER.query("scope", scope, "str") + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + if client_trace_id is not None: + _headers["X-ClientTraceId"] = _SERIALIZER.header("client_trace_id", client_trace_id, "str") + if accept_language is not None: + _headers["Accept-Language"] = _SERIALIZER.header("accept_language", accept_language, "str") + if if_none_match is not None: + _headers["If-None-Match"] = _SERIALIZER.header("if_none_match", if_none_match, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_text_translation_translate_request( + *, + to: List[str], + client_trace_id: Optional[str] = None, + from_parameter: Optional[str] = None, + text_type: Optional[Union[str, _models.TextType]] = None, + category: Optional[str] = None, + profanity_action: Optional[Union[str, _models.ProfanityAction]] = None, + profanity_marker: Optional[Union[str, _models.ProfanityMarker]] = None, + include_alignment: Optional[bool] = None, + include_sentence_length: Optional[bool] = None, + suggested_from: Optional[str] = None, + from_script: Optional[str] = None, + to_script: Optional[str] = None, + allow_fallback: Optional[bool] = None, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: Literal["3.0"] = kwargs.pop("api_version", _params.pop("api-version", "3.0")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/translate" + + # Construct parameters + _params["to"] = [_SERIALIZER.query("to", q, "str") if q is not None else "" for q in to] + if from_parameter is not None: + _params["from"] = _SERIALIZER.query("from_parameter", from_parameter, "str") + if text_type is not None: + _params["textType"] = _SERIALIZER.query("text_type", text_type, "str") + if category is not None: + _params["category"] = _SERIALIZER.query("category", category, "str") + if profanity_action is not None: + _params["profanityAction"] = _SERIALIZER.query("profanity_action", profanity_action, "str") + if profanity_marker is not None: + _params["profanityMarker"] = _SERIALIZER.query("profanity_marker", profanity_marker, "str") + if include_alignment is not None: + _params["includeAlignment"] = _SERIALIZER.query("include_alignment", include_alignment, "bool") + if include_sentence_length is not None: + _params["includeSentenceLength"] = _SERIALIZER.query("include_sentence_length", include_sentence_length, "bool") + if suggested_from is not None: + _params["suggestedFrom"] = _SERIALIZER.query("suggested_from", suggested_from, "str") + if from_script is not None: + _params["fromScript"] = _SERIALIZER.query("from_script", from_script, "str") + if to_script is not None: + _params["toScript"] = _SERIALIZER.query("to_script", to_script, "str") + if allow_fallback is not None: + _params["allowFallback"] = _SERIALIZER.query("allow_fallback", allow_fallback, "bool") + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + if client_trace_id is not None: + _headers["X-ClientTraceId"] = _SERIALIZER.header("client_trace_id", client_trace_id, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_text_translation_transliterate_request( + *, language: str, from_script: str, to_script: str, client_trace_id: Optional[str] = None, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: Literal["3.0"] = kwargs.pop("api_version", _params.pop("api-version", "3.0")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/transliterate" + + # Construct parameters + _params["language"] = _SERIALIZER.query("language", language, "str") + _params["fromScript"] = _SERIALIZER.query("from_script", from_script, "str") + _params["toScript"] = _SERIALIZER.query("to_script", to_script, "str") + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + if client_trace_id is not None: + _headers["X-ClientTraceId"] = _SERIALIZER.header("client_trace_id", client_trace_id, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_text_translation_find_sentence_boundaries_request( + *, + client_trace_id: Optional[str] = None, + language: Optional[str] = None, + script: Optional[str] = None, + **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: Literal["3.0"] = kwargs.pop("api_version", _params.pop("api-version", "3.0")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/breaksentence" + + # Construct parameters + if language is not None: + _params["language"] = _SERIALIZER.query("language", language, "str") + if script is not None: + _params["script"] = _SERIALIZER.query("script", script, "str") + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + if client_trace_id is not None: + _headers["X-ClientTraceId"] = _SERIALIZER.header("client_trace_id", client_trace_id, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_text_translation_lookup_dictionary_entries_request( + *, from_parameter: str, to: str, client_trace_id: Optional[str] = None, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: Literal["3.0"] = kwargs.pop("api_version", _params.pop("api-version", "3.0")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/dictionary/lookup" + + # Construct parameters + _params["from"] = _SERIALIZER.query("from_parameter", from_parameter, "str") + _params["to"] = _SERIALIZER.query("to", to, "str") + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + if client_trace_id is not None: + _headers["X-ClientTraceId"] = _SERIALIZER.header("client_trace_id", client_trace_id, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_text_translation_lookup_dictionary_examples_request( + *, from_parameter: str, to: str, client_trace_id: Optional[str] = None, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: Literal["3.0"] = kwargs.pop("api_version", _params.pop("api-version", "3.0")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/dictionary/examples" + + # Construct parameters + _params["from"] = _SERIALIZER.query("from_parameter", from_parameter, "str") + _params["to"] = _SERIALIZER.query("to", to, "str") + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + if client_trace_id is not None: + _headers["X-ClientTraceId"] = _SERIALIZER.header("client_trace_id", client_trace_id, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + + +class TextTranslationClientOperationsMixin(TextTranslationClientMixinABC): + @distributed_trace + def get_languages( + self, + *, + client_trace_id: Optional[str] = None, + scope: Optional[str] = None, + accept_language: Optional[str] = None, + if_none_match: Optional[str] = None, + **kwargs: Any + ) -> _models.GetLanguagesResult: + """Gets the set of languages currently supported by other operations of the Translator. + + Gets the set of languages currently supported by other operations of the Translator. + + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword scope: A comma-separated list of names defining the group of languages to return. + Allowed group names are: ``translation``\ , ``transliteration`` and ``dictionary``. + If no scope is given, then all groups are returned, which is equivalent to passing + ``scope=translation,transliteration,dictionary``. To decide which set of supported languages + is appropriate for your scenario, see the description of the `response object + <#response-body>`_. Default value is None. + :paramtype scope: str + :keyword accept_language: The language to use for user interface strings. Some of the fields in + the response are names of languages or + names of regions. Use this parameter to define the language in which these names are returned. + The language is specified by providing a well-formed BCP 47 language tag. For instance, use + the value ``fr`` + to request names in French or use the value ``zh-Hant`` to request names in Chinese + Traditional. + Names are provided in the English language when a target language is not specified or when + localization + is not available. Default value is None. + :paramtype accept_language: str + :keyword if_none_match: Passing the value of the ETag response header in an If-None-Match field + will allow the service to optimize the response. + If the resource has not been modified, the service will return status code 304 and an empty + response body. Default value is None. + :paramtype if_none_match: str + :return: GetLanguagesResult. The GetLanguagesResult is compatible with MutableMapping + :rtype: ~azure.ai.translation.text.models.GetLanguagesResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.GetLanguagesResult] = kwargs.pop("cls", None) + + request = build_text_translation_get_languages_request( + client_trace_id=client_trace_id, + scope=scope, + accept_language=accept_language, + if_none_match=if_none_match, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + 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) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + request, stream=_stream, **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) + error = _deserialize(_models.ErrorResponse, response.json()) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["X-RequestId"] = self._deserialize("str", response.headers.get("X-RequestId")) + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + + deserialized = _deserialize(_models.GetLanguagesResult, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + def translate( + self, + content: List[_models.InputTextItem], + *, + to: List[str], + client_trace_id: Optional[str] = None, + from_parameter: Optional[str] = None, + text_type: Optional[Union[str, _models.TextType]] = None, + category: Optional[str] = None, + profanity_action: Optional[Union[str, _models.ProfanityAction]] = None, + profanity_marker: Optional[Union[str, _models.ProfanityMarker]] = None, + include_alignment: Optional[bool] = None, + include_sentence_length: Optional[bool] = None, + suggested_from: Optional[str] = None, + from_script: Optional[str] = None, + to_script: Optional[str] = None, + allow_fallback: Optional[bool] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.TranslatedTextItem]: + """Translate Text. + + Translate Text. + + :param content: Array of the text to be translated. Required. + :type content: list[~azure.ai.translation.text.models.InputTextItem] + :keyword to: Specifies the language of the output text. The target language must be one of the + supported languages included + in the translation scope. For example, use to=de to translate to German. + It's possible to translate to multiple languages simultaneously by repeating the parameter in + the query string. + For example, use to=de&to=it to translate to German and Italian. Required. + :paramtype to: list[str] + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword from_parameter: Specifies the language of the input text. Find which languages are + available to translate from by + looking up supported languages using the translation scope. If the from parameter isn't + specified, + automatic language detection is applied to determine the source language. + + You must use the from parameter rather than autodetection when using the dynamic dictionary + feature. + Note: the dynamic dictionary feature is case-sensitive. Default value is None. + :paramtype from_parameter: str + :keyword text_type: Defines whether the text being translated is plain text or HTML text. Any + HTML needs to be a well-formed, + complete element. Possible values are: plain (default) or html. Known values are: "plain" and + "html". Default value is None. + :paramtype text_type: str or ~azure.ai.translation.text.models.TextType + :keyword category: A string specifying the category (domain) of the translation. This parameter + is used to get translations + from a customized system built with Custom Translator. Add the Category ID from your Custom + Translator + project details to this parameter to use your deployed customized system. Default value is: + general. Default value is None. + :paramtype category: str + :keyword profanity_action: Specifies how profanities should be treated in translations. + Possible values are: NoAction (default), Marked or Deleted. Known values are: "NoAction", + "Marked", and "Deleted". Default value is None. + :paramtype profanity_action: str or ~azure.ai.translation.text.models.ProfanityAction + :keyword profanity_marker: Specifies how profanities should be marked in translations. + Possible values are: Asterisk (default) or Tag. Known values are: "Asterisk" and "Tag". + Default value is None. + :paramtype profanity_marker: str or ~azure.ai.translation.text.models.ProfanityMarker + :keyword include_alignment: Specifies whether to include alignment projection from source text + to translated text. + Possible values are: true or false (default). Default value is None. + :paramtype include_alignment: bool + :keyword include_sentence_length: Specifies whether to include sentence boundaries for the + input text and the translated text. + Possible values are: true or false (default). Default value is None. + :paramtype include_sentence_length: bool + :keyword suggested_from: Specifies a fallback language if the language of the input text can't + be identified. + Language autodetection is applied when the from parameter is omitted. If detection fails, + the suggestedFrom language will be assumed. Default value is None. + :paramtype suggested_from: str + :keyword from_script: Specifies the script of the input text. Default value is None. + :paramtype from_script: str + :keyword to_script: Specifies the script of the translated text. Default value is None. + :paramtype to_script: str + :keyword allow_fallback: Specifies that the service is allowed to fall back to a general system + when a custom system doesn't exist. + Possible values are: true (default) or false. + + allowFallback=false specifies that the translation should only use systems trained for the + category specified + by the request. If a translation for language X to language Y requires chaining through a + pivot language E, + then all the systems in the chain (X → E and E → Y) will need to be custom and have the same + category. + If no system is found with the specific category, the request will return a 400 status code. + allowFallback=true + specifies that the service is allowed to fall back to a general system when a custom system + doesn't exist. Default value is None. + :paramtype allow_fallback: bool + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: list of TranslatedTextItem + :rtype: list[~azure.ai.translation.text.models.TranslatedTextItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def translate( + self, + content: IO, + *, + to: List[str], + client_trace_id: Optional[str] = None, + from_parameter: Optional[str] = None, + text_type: Optional[Union[str, _models.TextType]] = None, + category: Optional[str] = None, + profanity_action: Optional[Union[str, _models.ProfanityAction]] = None, + profanity_marker: Optional[Union[str, _models.ProfanityMarker]] = None, + include_alignment: Optional[bool] = None, + include_sentence_length: Optional[bool] = None, + suggested_from: Optional[str] = None, + from_script: Optional[str] = None, + to_script: Optional[str] = None, + allow_fallback: Optional[bool] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.TranslatedTextItem]: + """Translate Text. + + Translate Text. + + :param content: Array of the text to be translated. Required. + :type content: IO + :keyword to: Specifies the language of the output text. The target language must be one of the + supported languages included + in the translation scope. For example, use to=de to translate to German. + It's possible to translate to multiple languages simultaneously by repeating the parameter in + the query string. + For example, use to=de&to=it to translate to German and Italian. Required. + :paramtype to: list[str] + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword from_parameter: Specifies the language of the input text. Find which languages are + available to translate from by + looking up supported languages using the translation scope. If the from parameter isn't + specified, + automatic language detection is applied to determine the source language. + + You must use the from parameter rather than autodetection when using the dynamic dictionary + feature. + Note: the dynamic dictionary feature is case-sensitive. Default value is None. + :paramtype from_parameter: str + :keyword text_type: Defines whether the text being translated is plain text or HTML text. Any + HTML needs to be a well-formed, + complete element. Possible values are: plain (default) or html. Known values are: "plain" and + "html". Default value is None. + :paramtype text_type: str or ~azure.ai.translation.text.models.TextType + :keyword category: A string specifying the category (domain) of the translation. This parameter + is used to get translations + from a customized system built with Custom Translator. Add the Category ID from your Custom + Translator + project details to this parameter to use your deployed customized system. Default value is: + general. Default value is None. + :paramtype category: str + :keyword profanity_action: Specifies how profanities should be treated in translations. + Possible values are: NoAction (default), Marked or Deleted. Known values are: "NoAction", + "Marked", and "Deleted". Default value is None. + :paramtype profanity_action: str or ~azure.ai.translation.text.models.ProfanityAction + :keyword profanity_marker: Specifies how profanities should be marked in translations. + Possible values are: Asterisk (default) or Tag. Known values are: "Asterisk" and "Tag". + Default value is None. + :paramtype profanity_marker: str or ~azure.ai.translation.text.models.ProfanityMarker + :keyword include_alignment: Specifies whether to include alignment projection from source text + to translated text. + Possible values are: true or false (default). Default value is None. + :paramtype include_alignment: bool + :keyword include_sentence_length: Specifies whether to include sentence boundaries for the + input text and the translated text. + Possible values are: true or false (default). Default value is None. + :paramtype include_sentence_length: bool + :keyword suggested_from: Specifies a fallback language if the language of the input text can't + be identified. + Language autodetection is applied when the from parameter is omitted. If detection fails, + the suggestedFrom language will be assumed. Default value is None. + :paramtype suggested_from: str + :keyword from_script: Specifies the script of the input text. Default value is None. + :paramtype from_script: str + :keyword to_script: Specifies the script of the translated text. Default value is None. + :paramtype to_script: str + :keyword allow_fallback: Specifies that the service is allowed to fall back to a general system + when a custom system doesn't exist. + Possible values are: true (default) or false. + + allowFallback=false specifies that the translation should only use systems trained for the + category specified + by the request. If a translation for language X to language Y requires chaining through a + pivot language E, + then all the systems in the chain (X → E and E → Y) will need to be custom and have the same + category. + If no system is found with the specific category, the request will return a 400 status code. + allowFallback=true + specifies that the service is allowed to fall back to a general system when a custom system + doesn't exist. Default value is None. + :paramtype allow_fallback: bool + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: list of TranslatedTextItem + :rtype: list[~azure.ai.translation.text.models.TranslatedTextItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def translate( + self, + content: Union[List[_models.InputTextItem], IO], + *, + to: List[str], + client_trace_id: Optional[str] = None, + from_parameter: Optional[str] = None, + text_type: Optional[Union[str, _models.TextType]] = None, + category: Optional[str] = None, + profanity_action: Optional[Union[str, _models.ProfanityAction]] = None, + profanity_marker: Optional[Union[str, _models.ProfanityMarker]] = None, + include_alignment: Optional[bool] = None, + include_sentence_length: Optional[bool] = None, + suggested_from: Optional[str] = None, + from_script: Optional[str] = None, + to_script: Optional[str] = None, + allow_fallback: Optional[bool] = None, + **kwargs: Any + ) -> List[_models.TranslatedTextItem]: + """Translate Text. + + Translate Text. + + :param content: Array of the text to be translated. Is either a [InputTextItem] type or a IO + type. Required. + :type content: list[~azure.ai.translation.text.models.InputTextItem] or IO + :keyword to: Specifies the language of the output text. The target language must be one of the + supported languages included + in the translation scope. For example, use to=de to translate to German. + It's possible to translate to multiple languages simultaneously by repeating the parameter in + the query string. + For example, use to=de&to=it to translate to German and Italian. Required. + :paramtype to: list[str] + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword from_parameter: Specifies the language of the input text. Find which languages are + available to translate from by + looking up supported languages using the translation scope. If the from parameter isn't + specified, + automatic language detection is applied to determine the source language. + + You must use the from parameter rather than autodetection when using the dynamic dictionary + feature. + Note: the dynamic dictionary feature is case-sensitive. Default value is None. + :paramtype from_parameter: str + :keyword text_type: Defines whether the text being translated is plain text or HTML text. Any + HTML needs to be a well-formed, + complete element. Possible values are: plain (default) or html. Known values are: "plain" and + "html". Default value is None. + :paramtype text_type: str or ~azure.ai.translation.text.models.TextType + :keyword category: A string specifying the category (domain) of the translation. This parameter + is used to get translations + from a customized system built with Custom Translator. Add the Category ID from your Custom + Translator + project details to this parameter to use your deployed customized system. Default value is: + general. Default value is None. + :paramtype category: str + :keyword profanity_action: Specifies how profanities should be treated in translations. + Possible values are: NoAction (default), Marked or Deleted. Known values are: "NoAction", + "Marked", and "Deleted". Default value is None. + :paramtype profanity_action: str or ~azure.ai.translation.text.models.ProfanityAction + :keyword profanity_marker: Specifies how profanities should be marked in translations. + Possible values are: Asterisk (default) or Tag. Known values are: "Asterisk" and "Tag". + Default value is None. + :paramtype profanity_marker: str or ~azure.ai.translation.text.models.ProfanityMarker + :keyword include_alignment: Specifies whether to include alignment projection from source text + to translated text. + Possible values are: true or false (default). Default value is None. + :paramtype include_alignment: bool + :keyword include_sentence_length: Specifies whether to include sentence boundaries for the + input text and the translated text. + Possible values are: true or false (default). Default value is None. + :paramtype include_sentence_length: bool + :keyword suggested_from: Specifies a fallback language if the language of the input text can't + be identified. + Language autodetection is applied when the from parameter is omitted. If detection fails, + the suggestedFrom language will be assumed. Default value is None. + :paramtype suggested_from: str + :keyword from_script: Specifies the script of the input text. Default value is None. + :paramtype from_script: str + :keyword to_script: Specifies the script of the translated text. Default value is None. + :paramtype to_script: str + :keyword allow_fallback: Specifies that the service is allowed to fall back to a general system + when a custom system doesn't exist. + Possible values are: true (default) or false. + + allowFallback=false specifies that the translation should only use systems trained for the + category specified + by the request. If a translation for language X to language Y requires chaining through a + pivot language E, + then all the systems in the chain (X → E and E → Y) will need to be custom and have the same + category. + If no system is found with the specific category, the request will return a 400 status code. + allowFallback=true + specifies that the service is allowed to fall back to a general system when a custom system + doesn't exist. Default value is None. + :paramtype allow_fallback: bool + :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default + value is None. + :paramtype content_type: str + :return: list of TranslatedTextItem + :rtype: list[~azure.ai.translation.text.models.TranslatedTextItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[List[_models.TranslatedTextItem]] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(content, (IO, bytes)): + _content = content + else: + _content = json.dumps(content, cls=AzureJSONEncoder) # type: ignore + + request = build_text_translation_translate_request( + to=to, + client_trace_id=client_trace_id, + from_parameter=from_parameter, + text_type=text_type, + category=category, + profanity_action=profanity_action, + profanity_marker=profanity_marker, + include_alignment=include_alignment, + include_sentence_length=include_sentence_length, + suggested_from=suggested_from, + from_script=from_script, + to_script=to_script, + allow_fallback=allow_fallback, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + 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) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + request, stream=_stream, **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) + error = _deserialize(_models.ErrorResponse, response.json()) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["X-RequestId"] = self._deserialize("str", response.headers.get("X-RequestId")) + response_headers["x-mt-system"] = self._deserialize("str", response.headers.get("x-mt-system")) + response_headers["x-metered-usage"] = self._deserialize("int", response.headers.get("x-metered-usage")) + + deserialized = _deserialize(List[_models.TranslatedTextItem], response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + def transliterate( + self, + content: List[_models.InputTextItem], + *, + language: str, + from_script: str, + to_script: str, + client_trace_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.TransliteratedText]: + """Transliterate Text. + + Transliterate Text. + + :param content: Array of the text to be transliterated. Required. + :type content: list[~azure.ai.translation.text.models.InputTextItem] + :keyword language: Specifies the language of the text to convert from one script to another. + Possible languages are listed in the transliteration scope obtained by querying the service + for its supported languages. Required. + :paramtype language: str + :keyword from_script: Specifies the script used by the input text. Look up supported languages + using the transliteration scope, + to find input scripts available for the selected language. Required. + :paramtype from_script: str + :keyword to_script: Specifies the output script. Look up supported languages using the + transliteration scope, to find output + scripts available for the selected combination of input language and input script. Required. + :paramtype to_script: str + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: list of TransliteratedText + :rtype: list[~azure.ai.translation.text.models.TransliteratedText] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def transliterate( + self, + content: IO, + *, + language: str, + from_script: str, + to_script: str, + client_trace_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.TransliteratedText]: + """Transliterate Text. + + Transliterate Text. + + :param content: Array of the text to be transliterated. Required. + :type content: IO + :keyword language: Specifies the language of the text to convert from one script to another. + Possible languages are listed in the transliteration scope obtained by querying the service + for its supported languages. Required. + :paramtype language: str + :keyword from_script: Specifies the script used by the input text. Look up supported languages + using the transliteration scope, + to find input scripts available for the selected language. Required. + :paramtype from_script: str + :keyword to_script: Specifies the output script. Look up supported languages using the + transliteration scope, to find output + scripts available for the selected combination of input language and input script. Required. + :paramtype to_script: str + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: list of TransliteratedText + :rtype: list[~azure.ai.translation.text.models.TransliteratedText] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def transliterate( + self, + content: Union[List[_models.InputTextItem], IO], + *, + language: str, + from_script: str, + to_script: str, + client_trace_id: Optional[str] = None, + **kwargs: Any + ) -> List[_models.TransliteratedText]: + """Transliterate Text. + + Transliterate Text. + + :param content: Array of the text to be transliterated. Is either a [InputTextItem] type or a + IO type. Required. + :type content: list[~azure.ai.translation.text.models.InputTextItem] or IO + :keyword language: Specifies the language of the text to convert from one script to another. + Possible languages are listed in the transliteration scope obtained by querying the service + for its supported languages. Required. + :paramtype language: str + :keyword from_script: Specifies the script used by the input text. Look up supported languages + using the transliteration scope, + to find input scripts available for the selected language. Required. + :paramtype from_script: str + :keyword to_script: Specifies the output script. Look up supported languages using the + transliteration scope, to find output + scripts available for the selected combination of input language and input script. Required. + :paramtype to_script: str + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default + value is None. + :paramtype content_type: str + :return: list of TransliteratedText + :rtype: list[~azure.ai.translation.text.models.TransliteratedText] + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[List[_models.TransliteratedText]] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(content, (IO, bytes)): + _content = content + else: + _content = json.dumps(content, cls=AzureJSONEncoder) # type: ignore + + request = build_text_translation_transliterate_request( + language=language, + from_script=from_script, + to_script=to_script, + client_trace_id=client_trace_id, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + 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) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + request, stream=_stream, **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) + error = _deserialize(_models.ErrorResponse, response.json()) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["X-RequestId"] = self._deserialize("str", response.headers.get("X-RequestId")) + + deserialized = _deserialize(List[_models.TransliteratedText], response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + def find_sentence_boundaries( + self, + content: List[_models.InputTextItem], + *, + client_trace_id: Optional[str] = None, + language: Optional[str] = None, + script: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.BreakSentenceItem]: + """Find Sentence Boundaries. + + Find Sentence Boundaries. + + :param content: Array of the text for which values the sentence boundaries will be calculated. + Required. + :type content: list[~azure.ai.translation.text.models.InputTextItem] + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword language: Language tag identifying the language of the input text. + If a code isn't specified, automatic language detection will be applied. Default value is + None. + :paramtype language: str + :keyword script: Script tag identifying the script used by the input text. + If a script isn't specified, the default script of the language will be assumed. Default value + is None. + :paramtype script: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: list of BreakSentenceItem + :rtype: list[~azure.ai.translation.text.models.BreakSentenceItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def find_sentence_boundaries( + self, + content: IO, + *, + client_trace_id: Optional[str] = None, + language: Optional[str] = None, + script: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.BreakSentenceItem]: + """Find Sentence Boundaries. + + Find Sentence Boundaries. + + :param content: Array of the text for which values the sentence boundaries will be calculated. + Required. + :type content: IO + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword language: Language tag identifying the language of the input text. + If a code isn't specified, automatic language detection will be applied. Default value is + None. + :paramtype language: str + :keyword script: Script tag identifying the script used by the input text. + If a script isn't specified, the default script of the language will be assumed. Default value + is None. + :paramtype script: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: list of BreakSentenceItem + :rtype: list[~azure.ai.translation.text.models.BreakSentenceItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def find_sentence_boundaries( + self, + content: Union[List[_models.InputTextItem], IO], + *, + client_trace_id: Optional[str] = None, + language: Optional[str] = None, + script: Optional[str] = None, + **kwargs: Any + ) -> List[_models.BreakSentenceItem]: + """Find Sentence Boundaries. + + Find Sentence Boundaries. + + :param content: Array of the text for which values the sentence boundaries will be calculated. + Is either a [InputTextItem] type or a IO type. Required. + :type content: list[~azure.ai.translation.text.models.InputTextItem] or IO + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword language: Language tag identifying the language of the input text. + If a code isn't specified, automatic language detection will be applied. Default value is + None. + :paramtype language: str + :keyword script: Script tag identifying the script used by the input text. + If a script isn't specified, the default script of the language will be assumed. Default value + is None. + :paramtype script: str + :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default + value is None. + :paramtype content_type: str + :return: list of BreakSentenceItem + :rtype: list[~azure.ai.translation.text.models.BreakSentenceItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[List[_models.BreakSentenceItem]] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(content, (IO, bytes)): + _content = content + else: + _content = json.dumps(content, cls=AzureJSONEncoder) # type: ignore + + request = build_text_translation_find_sentence_boundaries_request( + client_trace_id=client_trace_id, + language=language, + script=script, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + 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) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + request, stream=_stream, **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) + error = _deserialize(_models.ErrorResponse, response.json()) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["X-RequestId"] = self._deserialize("str", response.headers.get("X-RequestId")) + + deserialized = _deserialize(List[_models.BreakSentenceItem], response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + def lookup_dictionary_entries( + self, + content: List[_models.InputTextItem], + *, + from_parameter: str, + to: str, + client_trace_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.DictionaryLookupItem]: + """Lookup Dictionary Entries. + + Lookup Dictionary Entries. + + :param content: Array of the text to be sent to dictionary. Required. + :type content: list[~azure.ai.translation.text.models.InputTextItem] + :keyword from_parameter: Specifies the language of the input text. + The source language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype from_parameter: str + :keyword to: Specifies the language of the output text. + The target language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype to: str + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: list of DictionaryLookupItem + :rtype: list[~azure.ai.translation.text.models.DictionaryLookupItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def lookup_dictionary_entries( + self, + content: IO, + *, + from_parameter: str, + to: str, + client_trace_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.DictionaryLookupItem]: + """Lookup Dictionary Entries. + + Lookup Dictionary Entries. + + :param content: Array of the text to be sent to dictionary. Required. + :type content: IO + :keyword from_parameter: Specifies the language of the input text. + The source language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype from_parameter: str + :keyword to: Specifies the language of the output text. + The target language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype to: str + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: list of DictionaryLookupItem + :rtype: list[~azure.ai.translation.text.models.DictionaryLookupItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def lookup_dictionary_entries( + self, + content: Union[List[_models.InputTextItem], IO], + *, + from_parameter: str, + to: str, + client_trace_id: Optional[str] = None, + **kwargs: Any + ) -> List[_models.DictionaryLookupItem]: + """Lookup Dictionary Entries. + + Lookup Dictionary Entries. + + :param content: Array of the text to be sent to dictionary. Is either a [InputTextItem] type or + a IO type. Required. + :type content: list[~azure.ai.translation.text.models.InputTextItem] or IO + :keyword from_parameter: Specifies the language of the input text. + The source language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype from_parameter: str + :keyword to: Specifies the language of the output text. + The target language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype to: str + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default + value is None. + :paramtype content_type: str + :return: list of DictionaryLookupItem + :rtype: list[~azure.ai.translation.text.models.DictionaryLookupItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[List[_models.DictionaryLookupItem]] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(content, (IO, bytes)): + _content = content + else: + _content = json.dumps(content, cls=AzureJSONEncoder) # type: ignore + + request = build_text_translation_lookup_dictionary_entries_request( + from_parameter=from_parameter, + to=to, + client_trace_id=client_trace_id, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + 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) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + request, stream=_stream, **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) + error = _deserialize(_models.ErrorResponse, response.json()) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["X-RequestId"] = self._deserialize("str", response.headers.get("X-RequestId")) + + deserialized = _deserialize(List[_models.DictionaryLookupItem], response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + def lookup_dictionary_examples( + self, + content: List[_models.DictionaryExampleTextItem], + *, + from_parameter: str, + to: str, + client_trace_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.DictionaryExampleItem]: + """Lookup Dictionary Examples. + + Lookup Dictionary Examples. + + :param content: Array of the text to be sent to dictionary. Required. + :type content: list[~azure.ai.translation.text.models.DictionaryExampleTextItem] + :keyword from_parameter: Specifies the language of the input text. + The source language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype from_parameter: str + :keyword to: Specifies the language of the output text. + The target language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype to: str + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: list of DictionaryExampleItem + :rtype: list[~azure.ai.translation.text.models.DictionaryExampleItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def lookup_dictionary_examples( + self, + content: IO, + *, + from_parameter: str, + to: str, + client_trace_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.DictionaryExampleItem]: + """Lookup Dictionary Examples. + + Lookup Dictionary Examples. + + :param content: Array of the text to be sent to dictionary. Required. + :type content: IO + :keyword from_parameter: Specifies the language of the input text. + The source language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype from_parameter: str + :keyword to: Specifies the language of the output text. + The target language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype to: str + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: list of DictionaryExampleItem + :rtype: list[~azure.ai.translation.text.models.DictionaryExampleItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def lookup_dictionary_examples( + self, + content: Union[List[_models.DictionaryExampleTextItem], IO], + *, + from_parameter: str, + to: str, + client_trace_id: Optional[str] = None, + **kwargs: Any + ) -> List[_models.DictionaryExampleItem]: + """Lookup Dictionary Examples. + + Lookup Dictionary Examples. + + :param content: Array of the text to be sent to dictionary. Is either a + [DictionaryExampleTextItem] type or a IO type. Required. + :type content: list[~azure.ai.translation.text.models.DictionaryExampleTextItem] or IO + :keyword from_parameter: Specifies the language of the input text. + The source language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype from_parameter: str + :keyword to: Specifies the language of the output text. + The target language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype to: str + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default + value is None. + :paramtype content_type: str + :return: list of DictionaryExampleItem + :rtype: list[~azure.ai.translation.text.models.DictionaryExampleItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[List[_models.DictionaryExampleItem]] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(content, (IO, bytes)): + _content = content + else: + _content = json.dumps(content, cls=AzureJSONEncoder) # type: ignore + + request = build_text_translation_lookup_dictionary_examples_request( + from_parameter=from_parameter, + to=to, + client_trace_id=client_trace_id, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + 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) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + request, stream=_stream, **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) + error = _deserialize(_models.ErrorResponse, response.json()) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["X-RequestId"] = self._deserialize("str", response.headers.get("X-RequestId")) + + deserialized = _deserialize(List[_models.DictionaryExampleItem], response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_operations/_patch.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_operations/_patch.py new file mode 100644 index 000000000000..f7dd32510333 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_operations/_patch.py @@ -0,0 +1,20 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +"""Customize generated code here. + +Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize +""" +from typing import List + +__all__: List[str] = [] # Add all objects you want publicly available to users at this package level + + +def patch_sdk(): + """Do not remove from this file. + + `patch_sdk` is a last resort escape hatch that allows you to do customizations + you can't accomplish using the techniques described in + https://aka.ms/azsdk/python/dpcodegen/python/customize + """ diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_patch.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_patch.py new file mode 100644 index 000000000000..a0c1bdce7cae --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_patch.py @@ -0,0 +1,138 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +from typing import ( Union, Optional ) +from azure.core.pipeline import PipelineRequest +from azure.core.pipeline.policies import ( SansIOHTTPPolicy, BearerTokenCredentialPolicy, AzureKeyCredentialPolicy ) +from azure.core.credentials import ( TokenCredential, AzureKeyCredential ) + +from ._client import TextTranslationClient as ServiceClientGenerated + +DEFAULT_TOKEN_SCOPE = "https://api.microsofttranslator.com/" + +def patch_sdk(): + """Do not remove from this file. + + `patch_sdk` is a last resort escape hatch that allows you to do customizations + you can't accomplish using the techniques described in + https://aka.ms/azsdk/python/dpcodegen/python/customize + """ + +class TranslatorCredential: + """ Credential for Translator Service. It is using combination of Resource key and region. + """ + def __init__(self, key: str, region: str) -> None: + self.key = key + self.region = region + + def update(self, key: str) -> None: + """Update the key. + This can be used when you've regenerated your service key and want + to update long-lived clients. + :param str key: The key used to authenticate to an Azure service + :raises: ValueError or TypeError + """ + if not key: + raise ValueError("The key used for updating can not be None or empty") + if not isinstance(key, str): + raise TypeError("The key used for updating must be a string.") + self.key = key + +class TranslatorAuthenticationPolicy(SansIOHTTPPolicy): + """ Translator Authentication Policy. Adds both authentication headers that are required. + Ocp-Apim-Subscription-Region header contains region of the Translator resource. + Ocp-Apim-Subscription-Key header contains API key of the Translator resource. + """ + def __init__(self, credential: TranslatorCredential): + self.credential = credential + + def on_request(self, request: PipelineRequest) -> None: + request.http_request.headers["Ocp-Apim-Subscription-Key"] = self.credential.key + request.http_request.headers["Ocp-Apim-Subscription-Region"] = self.credential.region + +def get_translation_endpoint(endpoint, api_version): + if not endpoint: + endpoint = "https://api.cognitive.microsofttranslator.com" + + translator_endpoint: str = "" + if "cognitiveservices" in endpoint: + translator_endpoint = endpoint + "/translator/text/v" + api_version + else: + translator_endpoint = endpoint + + return translator_endpoint + +def set_authentication_policy(credential, kwargs): + if isinstance(credential, TranslatorCredential): + if not kwargs.get("authentication_policy"): + kwargs["authentication_policy"] = TranslatorAuthenticationPolicy(credential) + elif isinstance(credential, AzureKeyCredential): + if not kwargs.get("authentication_policy"): + kwargs["authentication_policy"] = AzureKeyCredentialPolicy( + name="Ocp-Apim-Subscription-Key", credential=credential) + elif hasattr(credential, "get_token"): + if not kwargs.get("authentication_policy"): + kwargs["authentication_policy"] = BearerTokenCredentialPolicy(credential, *kwargs.pop("credential_scopes", [DEFAULT_TOKEN_SCOPE]), kwargs) + +class TextTranslationClient(ServiceClientGenerated): + """Text translation is a cloud-based REST API feature of the Translator service that uses neural + machine translation technology to enable quick and accurate source-to-target text translation + in real time across all supported languages. + + The following methods are supported by the Text Translation feature: + + Languages. Returns a list of languages supported by Translate, Transliterate, and Dictionary + Lookup operations. + + Translate. Renders single source-language text to multiple target-language texts with a single + request. + + Transliterate. Converts characters or letters of a source language to the corresponding + characters or letters of a target language. + + Detect. Returns the source code language code and a boolean variable denoting whether the + detected language is supported for text translation and transliteration. + + Dictionary lookup. Returns equivalent words for the source term in the target language. + + Dictionary example Returns grammatical structure and context examples for the source term and + target term pair. + + Combinations of endpoint and credential values: + str + AzureKeyCredential - used custom domain translator endpoint + str + TokenCredential - used for regional endpoint with token authentication + str + TranslatorCredential - used for National Clouds + None + AzureKeyCredential - used for global translator endpoint with global Translator resource + None + Token - general translator endpoint with token authentication + None + TranslatorCredential - general translator endpoint with regional Translator resource + + :param endpoint: Supported Text Translation endpoints (protocol and hostname, for example: + https://api.cognitive.microsofttranslator.com). Required. + :type endpoint: str + :param credential: Credential used to authenticate with the Translator service + :type credential: Union[AzureKeyCredential , TokenCredential , TranslatorCredential] + :keyword api_version: Default value is "3.0". Note that overriding this default value may + result in unsupported behavior. + :paramtype api_version: str + """ + def __init__( + self, + credential: Union[AzureKeyCredential , TokenCredential , TranslatorCredential], + *, + endpoint: Optional[str] = None, + api_version = "3.0", + **kwargs): + + set_authentication_policy(credential, kwargs) + + translation_endpoint = get_translation_endpoint(endpoint, api_version) + + super().__init__( + endpoint=translation_endpoint, + api_version=api_version, + **kwargs + ) + +__all__ = ["TextTranslationClient", "TranslatorCredential"] diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_serialization.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_serialization.py new file mode 100644 index 000000000000..842ae727fbbc --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_serialization.py @@ -0,0 +1,1996 @@ +# -------------------------------------------------------------------------- +# +# 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: skip-file +# pyright: reportUnnecessaryTypeIgnoreComment=false + +from base64 import b64decode, b64encode +import calendar +import datetime +import decimal +import email +from enum import Enum +import json +import logging +import re +import sys +import codecs +from typing import ( + Dict, + Any, + cast, + Optional, + Union, + AnyStr, + IO, + Mapping, + Callable, + TypeVar, + MutableMapping, + Type, + List, + Mapping, +) + +try: + from urllib import quote # type: ignore +except ImportError: + from urllib.parse import quote +import xml.etree.ElementTree as ET + +import isodate # type: ignore + +from azure.core.exceptions import DeserializationError, SerializationError, raise_with_traceback +from azure.core.serialization import NULL as AzureCoreNull + +_BOM = codecs.BOM_UTF8.decode(encoding="utf-8") + +ModelType = TypeVar("ModelType", bound="Model") +JSON = MutableMapping[str, Any] + + +class RawDeserializer: + + # Accept "text" because we're open minded people... + JSON_REGEXP = re.compile(r"^(application|text)/([a-z+.]+\+)?json$") + + # Name used in context + CONTEXT_NAME = "deserialized_data" + + @classmethod + def deserialize_from_text(cls, data: Optional[Union[AnyStr, IO]], content_type: Optional[str] = None) -> Any: + """Decode data according to content-type. + + Accept a stream of data as well, but will be load at once in memory for now. + + If no content-type, will return the string version (not bytes, not stream) + + :param data: Input, could be bytes or stream (will be decoded with UTF8) or text + :type data: str or bytes or IO + :param str content_type: The content type. + """ + if hasattr(data, "read"): + # Assume a stream + data = cast(IO, data).read() + + if isinstance(data, bytes): + data_as_str = data.decode(encoding="utf-8-sig") + else: + # Explain to mypy the correct type. + data_as_str = cast(str, data) + + # Remove Byte Order Mark if present in string + data_as_str = data_as_str.lstrip(_BOM) + + if content_type is None: + return data + + if cls.JSON_REGEXP.match(content_type): + try: + return json.loads(data_as_str) + except ValueError as err: + raise DeserializationError("JSON is invalid: {}".format(err), err) + elif "xml" in (content_type or []): + try: + + try: + if isinstance(data, unicode): # type: ignore + # If I'm Python 2.7 and unicode XML will scream if I try a "fromstring" on unicode string + data_as_str = data_as_str.encode(encoding="utf-8") # type: ignore + except NameError: + pass + + return ET.fromstring(data_as_str) # nosec + except ET.ParseError: + # It might be because the server has an issue, and returned JSON with + # content-type XML.... + # So let's try a JSON load, and if it's still broken + # let's flow the initial exception + def _json_attemp(data): + try: + return True, json.loads(data) + except ValueError: + return False, None # Don't care about this one + + success, json_result = _json_attemp(data) + if success: + return json_result + # If i'm here, it's not JSON, it's not XML, let's scream + # and raise the last context in this block (the XML exception) + # The function hack is because Py2.7 messes up with exception + # context otherwise. + _LOGGER.critical("Wasn't XML not JSON, failing") + raise_with_traceback(DeserializationError, "XML is invalid") + raise DeserializationError("Cannot deserialize content-type: {}".format(content_type)) + + @classmethod + def deserialize_from_http_generics(cls, body_bytes: Optional[Union[AnyStr, IO]], headers: Mapping) -> Any: + """Deserialize from HTTP response. + + Use bytes and headers to NOT use any requests/aiohttp or whatever + specific implementation. + Headers will tested for "content-type" + """ + # Try to use content-type from headers if available + content_type = None + if "content-type" in headers: + content_type = headers["content-type"].split(";")[0].strip().lower() + # Ouch, this server did not declare what it sent... + # Let's guess it's JSON... + # Also, since Autorest was considering that an empty body was a valid JSON, + # need that test as well.... + else: + content_type = "application/json" + + if body_bytes: + return cls.deserialize_from_text(body_bytes, content_type) + return None + + +try: + basestring # type: ignore + unicode_str = unicode # type: ignore +except NameError: + basestring = str + unicode_str = str + +_LOGGER = logging.getLogger(__name__) + +try: + _long_type = long # type: ignore +except NameError: + _long_type = int + + +class UTC(datetime.tzinfo): + """Time Zone info for handling UTC""" + + def utcoffset(self, dt): + """UTF offset for UTC is 0.""" + return datetime.timedelta(0) + + def tzname(self, dt): + """Timestamp representation.""" + return "Z" + + def dst(self, dt): + """No daylight saving for UTC.""" + return datetime.timedelta(hours=1) + + +try: + from datetime import timezone as _FixedOffset # type: ignore +except ImportError: # Python 2.7 + + class _FixedOffset(datetime.tzinfo): # type: ignore + """Fixed offset in minutes east from UTC. + Copy/pasted from Python doc + :param datetime.timedelta offset: offset in timedelta format + """ + + def __init__(self, offset): + self.__offset = offset + + def utcoffset(self, dt): + return self.__offset + + def tzname(self, dt): + return str(self.__offset.total_seconds() / 3600) + + def __repr__(self): + return "".format(self.tzname(None)) + + def dst(self, dt): + return datetime.timedelta(0) + + def __getinitargs__(self): + return (self.__offset,) + + +try: + from datetime import timezone + + TZ_UTC = timezone.utc +except ImportError: + TZ_UTC = UTC() # type: ignore + +_FLATTEN = re.compile(r"(? None: + self.additional_properties: Dict[str, Any] = {} + for k in kwargs: + if k not in self._attribute_map: + _LOGGER.warning("%s is not a known attribute of class %s and will be ignored", k, self.__class__) + elif k in self._validation and self._validation[k].get("readonly", False): + _LOGGER.warning("Readonly attribute %s will be ignored in class %s", k, self.__class__) + else: + setattr(self, k, kwargs[k]) + + def __eq__(self, other: Any) -> bool: + """Compare objects by comparing all attributes.""" + if isinstance(other, self.__class__): + return self.__dict__ == other.__dict__ + return False + + def __ne__(self, other: Any) -> bool: + """Compare objects by comparing all attributes.""" + return not self.__eq__(other) + + def __str__(self) -> str: + return str(self.__dict__) + + @classmethod + def enable_additional_properties_sending(cls) -> None: + cls._attribute_map["additional_properties"] = {"key": "", "type": "{object}"} + + @classmethod + def is_xml_model(cls) -> bool: + try: + cls._xml_map # type: ignore + except AttributeError: + return False + return True + + @classmethod + def _create_xml_node(cls): + """Create XML node.""" + try: + xml_map = cls._xml_map # type: ignore + except AttributeError: + xml_map = {} + + return _create_xml_node(xml_map.get("name", cls.__name__), xml_map.get("prefix", None), xml_map.get("ns", None)) + + def serialize(self, keep_readonly: bool = False, **kwargs: Any) -> JSON: + """Return the JSON that would be sent to azure from this model. + + This is an alias to `as_dict(full_restapi_key_transformer, keep_readonly=False)`. + + If you want XML serialization, you can pass the kwargs is_xml=True. + + :param bool keep_readonly: If you want to serialize the readonly attributes + :returns: A dict JSON compatible object + :rtype: dict + """ + serializer = Serializer(self._infer_class_models()) + return serializer._serialize(self, keep_readonly=keep_readonly, **kwargs) + + def as_dict( + self, + keep_readonly: bool = True, + key_transformer: Callable[[str, Dict[str, Any], Any], Any] = attribute_transformer, + **kwargs: Any + ) -> JSON: + """Return a dict that can be serialized using json.dump. + + Advanced usage might optionally use a callback as parameter: + + .. code::python + + def my_key_transformer(key, attr_desc, value): + return key + + Key is the attribute name used in Python. Attr_desc + is a dict of metadata. Currently contains 'type' with the + msrest type and 'key' with the RestAPI encoded key. + Value is the current value in this object. + + The string returned will be used to serialize the key. + If the return type is a list, this is considered hierarchical + result dict. + + See the three examples in this file: + + - attribute_transformer + - full_restapi_key_transformer + - last_restapi_key_transformer + + If you want XML serialization, you can pass the kwargs is_xml=True. + + :param function key_transformer: A key transformer function. + :returns: A dict JSON compatible object + :rtype: dict + """ + serializer = Serializer(self._infer_class_models()) + return serializer._serialize(self, key_transformer=key_transformer, keep_readonly=keep_readonly, **kwargs) + + @classmethod + def _infer_class_models(cls): + try: + str_models = cls.__module__.rsplit(".", 1)[0] + models = sys.modules[str_models] + client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)} + if cls.__name__ not in client_models: + raise ValueError("Not Autorest generated code") + except Exception: + # Assume it's not Autorest generated (tests?). Add ourselves as dependencies. + client_models = {cls.__name__: cls} + return client_models + + @classmethod + def deserialize(cls: Type[ModelType], data: Any, content_type: Optional[str] = None) -> ModelType: + """Parse a str using the RestAPI syntax and return a model. + + :param str data: A str using RestAPI structure. JSON by default. + :param str content_type: JSON by default, set application/xml if XML. + :returns: An instance of this model + :raises: DeserializationError if something went wrong + """ + deserializer = Deserializer(cls._infer_class_models()) + return deserializer(cls.__name__, data, content_type=content_type) + + @classmethod + def from_dict( + cls: Type[ModelType], + data: Any, + key_extractors: Optional[Callable[[str, Dict[str, Any], Any], Any]] = None, + content_type: Optional[str] = None, + ) -> ModelType: + """Parse a dict using given key extractor return a model. + + By default consider key + extractors (rest_key_case_insensitive_extractor, attribute_key_case_insensitive_extractor + and last_rest_key_case_insensitive_extractor) + + :param dict data: A dict using RestAPI structure + :param str content_type: JSON by default, set application/xml if XML. + :returns: An instance of this model + :raises: DeserializationError if something went wrong + """ + deserializer = Deserializer(cls._infer_class_models()) + deserializer.key_extractors = ( # type: ignore + [ # type: ignore + attribute_key_case_insensitive_extractor, + rest_key_case_insensitive_extractor, + last_rest_key_case_insensitive_extractor, + ] + if key_extractors is None + else key_extractors + ) + return deserializer(cls.__name__, data, content_type=content_type) + + @classmethod + def _flatten_subtype(cls, key, objects): + if "_subtype_map" not in cls.__dict__: + return {} + result = dict(cls._subtype_map[key]) + for valuetype in cls._subtype_map[key].values(): + result.update(objects[valuetype]._flatten_subtype(key, objects)) + return result + + @classmethod + def _classify(cls, response, objects): + """Check the class _subtype_map for any child classes. + We want to ignore any inherited _subtype_maps. + Remove the polymorphic key from the initial data. + """ + for subtype_key in cls.__dict__.get("_subtype_map", {}).keys(): + subtype_value = None + + if not isinstance(response, ET.Element): + rest_api_response_key = cls._get_rest_key_parts(subtype_key)[-1] + subtype_value = response.pop(rest_api_response_key, None) or response.pop(subtype_key, None) + else: + subtype_value = xml_key_extractor(subtype_key, cls._attribute_map[subtype_key], response) + if subtype_value: + # Try to match base class. Can be class name only + # (bug to fix in Autorest to support x-ms-discriminator-name) + if cls.__name__ == subtype_value: + return cls + flatten_mapping_type = cls._flatten_subtype(subtype_key, objects) + try: + return objects[flatten_mapping_type[subtype_value]] # type: ignore + except KeyError: + _LOGGER.warning( + "Subtype value %s has no mapping, use base class %s.", + subtype_value, + cls.__name__, + ) + break + else: + _LOGGER.warning("Discriminator %s is absent or null, use base class %s.", subtype_key, cls.__name__) + break + return cls + + @classmethod + def _get_rest_key_parts(cls, attr_key): + """Get the RestAPI key of this attr, split it and decode part + :param str attr_key: Attribute key must be in attribute_map. + :returns: A list of RestAPI part + :rtype: list + """ + rest_split_key = _FLATTEN.split(cls._attribute_map[attr_key]["key"]) + return [_decode_attribute_map_key(key_part) for key_part in rest_split_key] + + +def _decode_attribute_map_key(key): + """This decode a key in an _attribute_map to the actual key we want to look at + inside the received data. + + :param str key: A key string from the generated code + """ + return key.replace("\\.", ".") + + +class Serializer(object): + """Request object model serializer.""" + + basic_types = {str: "str", int: "int", bool: "bool", float: "float"} + + _xml_basic_types_serializers = {"bool": lambda x: str(x).lower()} + days = {0: "Mon", 1: "Tue", 2: "Wed", 3: "Thu", 4: "Fri", 5: "Sat", 6: "Sun"} + months = { + 1: "Jan", + 2: "Feb", + 3: "Mar", + 4: "Apr", + 5: "May", + 6: "Jun", + 7: "Jul", + 8: "Aug", + 9: "Sep", + 10: "Oct", + 11: "Nov", + 12: "Dec", + } + validation = { + "min_length": lambda x, y: len(x) < y, + "max_length": lambda x, y: len(x) > y, + "minimum": lambda x, y: x < y, + "maximum": lambda x, y: x > y, + "minimum_ex": lambda x, y: x <= y, + "maximum_ex": lambda x, y: x >= y, + "min_items": lambda x, y: len(x) < y, + "max_items": lambda x, y: len(x) > y, + "pattern": lambda x, y: not re.match(y, x, re.UNICODE), + "unique": lambda x, y: len(x) != len(set(x)), + "multiple": lambda x, y: x % y != 0, + } + + def __init__(self, classes: Optional[Mapping[str, Type[ModelType]]] = None): + self.serialize_type = { + "iso-8601": Serializer.serialize_iso, + "rfc-1123": Serializer.serialize_rfc, + "unix-time": Serializer.serialize_unix, + "duration": Serializer.serialize_duration, + "date": Serializer.serialize_date, + "time": Serializer.serialize_time, + "decimal": Serializer.serialize_decimal, + "long": Serializer.serialize_long, + "bytearray": Serializer.serialize_bytearray, + "base64": Serializer.serialize_base64, + "object": self.serialize_object, + "[]": self.serialize_iter, + "{}": self.serialize_dict, + } + self.dependencies: Dict[str, Type[ModelType]] = dict(classes) if classes else {} + self.key_transformer = full_restapi_key_transformer + self.client_side_validation = True + + def _serialize(self, target_obj, data_type=None, **kwargs): + """Serialize data into a string according to type. + + :param target_obj: The data to be serialized. + :param str data_type: The type to be serialized from. + :rtype: str, dict + :raises: SerializationError if serialization fails. + """ + key_transformer = kwargs.get("key_transformer", self.key_transformer) + keep_readonly = kwargs.get("keep_readonly", False) + if target_obj is None: + return None + + attr_name = None + class_name = target_obj.__class__.__name__ + + if data_type: + return self.serialize_data(target_obj, data_type, **kwargs) + + if not hasattr(target_obj, "_attribute_map"): + data_type = type(target_obj).__name__ + if data_type in self.basic_types.values(): + return self.serialize_data(target_obj, data_type, **kwargs) + + # Force "is_xml" kwargs if we detect a XML model + try: + is_xml_model_serialization = kwargs["is_xml"] + except KeyError: + is_xml_model_serialization = kwargs.setdefault("is_xml", target_obj.is_xml_model()) + + serialized = {} + if is_xml_model_serialization: + serialized = target_obj._create_xml_node() + try: + attributes = target_obj._attribute_map + for attr, attr_desc in attributes.items(): + attr_name = attr + if not keep_readonly and target_obj._validation.get(attr_name, {}).get("readonly", False): + continue + + if attr_name == "additional_properties" and attr_desc["key"] == "": + if target_obj.additional_properties is not None: + serialized.update(target_obj.additional_properties) + continue + try: + + orig_attr = getattr(target_obj, attr) + if is_xml_model_serialization: + pass # Don't provide "transformer" for XML for now. Keep "orig_attr" + else: # JSON + keys, orig_attr = key_transformer(attr, attr_desc.copy(), orig_attr) + keys = keys if isinstance(keys, list) else [keys] + + kwargs["serialization_ctxt"] = attr_desc + new_attr = self.serialize_data(orig_attr, attr_desc["type"], **kwargs) + + if is_xml_model_serialization: + xml_desc = attr_desc.get("xml", {}) + xml_name = xml_desc.get("name", attr_desc["key"]) + xml_prefix = xml_desc.get("prefix", None) + xml_ns = xml_desc.get("ns", None) + if xml_desc.get("attr", False): + if xml_ns: + ET.register_namespace(xml_prefix, xml_ns) + xml_name = "{{{}}}{}".format(xml_ns, xml_name) + serialized.set(xml_name, new_attr) # type: ignore + continue + if xml_desc.get("text", False): + serialized.text = new_attr # type: ignore + continue + if isinstance(new_attr, list): + serialized.extend(new_attr) # type: ignore + elif isinstance(new_attr, ET.Element): + # If the down XML has no XML/Name, we MUST replace the tag with the local tag. But keeping the namespaces. + if "name" not in getattr(orig_attr, "_xml_map", {}): + splitted_tag = new_attr.tag.split("}") + if len(splitted_tag) == 2: # Namespace + new_attr.tag = "}".join([splitted_tag[0], xml_name]) + else: + new_attr.tag = xml_name + serialized.append(new_attr) # type: ignore + else: # That's a basic type + # Integrate namespace if necessary + local_node = _create_xml_node(xml_name, xml_prefix, xml_ns) + local_node.text = unicode_str(new_attr) + serialized.append(local_node) # type: ignore + else: # JSON + for k in reversed(keys): # type: ignore + new_attr = {k: new_attr} + + _new_attr = new_attr + _serialized = serialized + for k in keys: # type: ignore + if k not in _serialized: + _serialized.update(_new_attr) # type: ignore + _new_attr = _new_attr[k] # type: ignore + _serialized = _serialized[k] + except ValueError: + continue + + except (AttributeError, KeyError, TypeError) as err: + msg = "Attribute {} in object {} cannot be serialized.\n{}".format(attr_name, class_name, str(target_obj)) + raise_with_traceback(SerializationError, msg, err) + else: + return serialized + + def body(self, data, data_type, **kwargs): + """Serialize data intended for a request body. + + :param data: The data to be serialized. + :param str data_type: The type to be serialized from. + :rtype: dict + :raises: SerializationError if serialization fails. + :raises: ValueError if data is None + """ + + # Just in case this is a dict + internal_data_type_str = data_type.strip("[]{}") + internal_data_type = self.dependencies.get(internal_data_type_str, None) + try: + is_xml_model_serialization = kwargs["is_xml"] + except KeyError: + if internal_data_type and issubclass(internal_data_type, Model): + is_xml_model_serialization = kwargs.setdefault("is_xml", internal_data_type.is_xml_model()) + else: + is_xml_model_serialization = False + if internal_data_type and not isinstance(internal_data_type, Enum): + try: + deserializer = Deserializer(self.dependencies) + # Since it's on serialization, it's almost sure that format is not JSON REST + # We're not able to deal with additional properties for now. + deserializer.additional_properties_detection = False + if is_xml_model_serialization: + deserializer.key_extractors = [ # type: ignore + attribute_key_case_insensitive_extractor, + ] + else: + deserializer.key_extractors = [ + rest_key_case_insensitive_extractor, + attribute_key_case_insensitive_extractor, + last_rest_key_case_insensitive_extractor, + ] + data = deserializer._deserialize(data_type, data) + except DeserializationError as err: + raise_with_traceback(SerializationError, "Unable to build a model: " + str(err), err) + + return self._serialize(data, data_type, **kwargs) + + def url(self, name, data, data_type, **kwargs): + """Serialize data intended for a URL path. + + :param data: The data to be serialized. + :param str data_type: The type to be serialized from. + :rtype: str + :raises: TypeError if serialization fails. + :raises: ValueError if data is None + """ + try: + output = self.serialize_data(data, data_type, **kwargs) + if data_type == "bool": + output = json.dumps(output) + + if kwargs.get("skip_quote") is True: + output = str(output) + else: + output = quote(str(output), safe="") + except SerializationError: + raise TypeError("{} must be type {}.".format(name, data_type)) + else: + return output + + def query(self, name, data, data_type, **kwargs): + """Serialize data intended for a URL query. + + :param data: The data to be serialized. + :param str data_type: The type to be serialized from. + :rtype: str + :raises: TypeError if serialization fails. + :raises: ValueError if data is None + """ + try: + # Treat the list aside, since we don't want to encode the div separator + if data_type.startswith("["): + internal_data_type = data_type[1:-1] + data = [self.serialize_data(d, internal_data_type, **kwargs) if d is not None else "" for d in data] + if not kwargs.get("skip_quote", False): + data = [quote(str(d), safe="") for d in data] + return str(self.serialize_iter(data, internal_data_type, **kwargs)) + + # Not a list, regular serialization + output = self.serialize_data(data, data_type, **kwargs) + if data_type == "bool": + output = json.dumps(output) + if kwargs.get("skip_quote") is True: + output = str(output) + else: + output = quote(str(output), safe="") + except SerializationError: + raise TypeError("{} must be type {}.".format(name, data_type)) + else: + return str(output) + + def header(self, name, data, data_type, **kwargs): + """Serialize data intended for a request header. + + :param data: The data to be serialized. + :param str data_type: The type to be serialized from. + :rtype: str + :raises: TypeError if serialization fails. + :raises: ValueError if data is None + """ + try: + if data_type in ["[str]"]: + data = ["" if d is None else d for d in data] + + output = self.serialize_data(data, data_type, **kwargs) + if data_type == "bool": + output = json.dumps(output) + except SerializationError: + raise TypeError("{} must be type {}.".format(name, data_type)) + else: + return str(output) + + def serialize_data(self, data, data_type, **kwargs): + """Serialize generic data according to supplied data type. + + :param data: The data to be serialized. + :param str data_type: The type to be serialized from. + :param bool required: Whether it's essential that the data not be + empty or None + :raises: AttributeError if required data is None. + :raises: ValueError if data is None + :raises: SerializationError if serialization fails. + """ + if data is None: + raise ValueError("No value for given attribute") + + try: + if data is AzureCoreNull: + return None + if data_type in self.basic_types.values(): + return self.serialize_basic(data, data_type, **kwargs) + + elif data_type in self.serialize_type: + return self.serialize_type[data_type](data, **kwargs) + + # If dependencies is empty, try with current data class + # It has to be a subclass of Enum anyway + enum_type = self.dependencies.get(data_type, data.__class__) + if issubclass(enum_type, Enum): + return Serializer.serialize_enum(data, enum_obj=enum_type) + + iter_type = data_type[0] + data_type[-1] + if iter_type in self.serialize_type: + return self.serialize_type[iter_type](data, data_type[1:-1], **kwargs) + + except (ValueError, TypeError) as err: + msg = "Unable to serialize value: {!r} as type: {!r}." + raise_with_traceback(SerializationError, msg.format(data, data_type), err) + else: + return self._serialize(data, **kwargs) + + @classmethod + def _get_custom_serializers(cls, data_type, **kwargs): + custom_serializer = kwargs.get("basic_types_serializers", {}).get(data_type) + if custom_serializer: + return custom_serializer + if kwargs.get("is_xml", False): + return cls._xml_basic_types_serializers.get(data_type) + + @classmethod + def serialize_basic(cls, data, data_type, **kwargs): + """Serialize basic builting data type. + Serializes objects to str, int, float or bool. + + Possible kwargs: + - basic_types_serializers dict[str, callable] : If set, use the callable as serializer + - is_xml bool : If set, use xml_basic_types_serializers + + :param data: Object to be serialized. + :param str data_type: Type of object in the iterable. + """ + custom_serializer = cls._get_custom_serializers(data_type, **kwargs) + if custom_serializer: + return custom_serializer(data) + if data_type == "str": + return cls.serialize_unicode(data) + return eval(data_type)(data) # nosec + + @classmethod + def serialize_unicode(cls, data): + """Special handling for serializing unicode strings in Py2. + Encode to UTF-8 if unicode, otherwise handle as a str. + + :param data: Object to be serialized. + :rtype: str + """ + try: # If I received an enum, return its value + return data.value + except AttributeError: + pass + + try: + if isinstance(data, unicode): # type: ignore + # Don't change it, JSON and XML ElementTree are totally able + # to serialize correctly u'' strings + return data + except NameError: + return str(data) + else: + return str(data) + + def serialize_iter(self, data, iter_type, div=None, **kwargs): + """Serialize iterable. + + Supported kwargs: + - serialization_ctxt dict : The current entry of _attribute_map, or same format. + serialization_ctxt['type'] should be same as data_type. + - is_xml bool : If set, serialize as XML + + :param list attr: Object to be serialized. + :param str iter_type: Type of object in the iterable. + :param bool required: Whether the objects in the iterable must + not be None or empty. + :param str div: If set, this str will be used to combine the elements + in the iterable into a combined string. Default is 'None'. + :rtype: list, str + """ + if isinstance(data, str): + raise SerializationError("Refuse str type as a valid iter type.") + + serialization_ctxt = kwargs.get("serialization_ctxt", {}) + is_xml = kwargs.get("is_xml", False) + + serialized = [] + for d in data: + try: + serialized.append(self.serialize_data(d, iter_type, **kwargs)) + except ValueError: + serialized.append(None) + + if div: + serialized = ["" if s is None else str(s) for s in serialized] + serialized = div.join(serialized) + + if "xml" in serialization_ctxt or is_xml: + # XML serialization is more complicated + xml_desc = serialization_ctxt.get("xml", {}) + xml_name = xml_desc.get("name") + if not xml_name: + xml_name = serialization_ctxt["key"] + + # Create a wrap node if necessary (use the fact that Element and list have "append") + is_wrapped = xml_desc.get("wrapped", False) + node_name = xml_desc.get("itemsName", xml_name) + if is_wrapped: + final_result = _create_xml_node(xml_name, xml_desc.get("prefix", None), xml_desc.get("ns", None)) + else: + final_result = [] + # All list elements to "local_node" + for el in serialized: + if isinstance(el, ET.Element): + el_node = el + else: + el_node = _create_xml_node(node_name, xml_desc.get("prefix", None), xml_desc.get("ns", None)) + if el is not None: # Otherwise it writes "None" :-p + el_node.text = str(el) + final_result.append(el_node) + return final_result + return serialized + + def serialize_dict(self, attr, dict_type, **kwargs): + """Serialize a dictionary of objects. + + :param dict attr: Object to be serialized. + :param str dict_type: Type of object in the dictionary. + :param bool required: Whether the objects in the dictionary must + not be None or empty. + :rtype: dict + """ + serialization_ctxt = kwargs.get("serialization_ctxt", {}) + serialized = {} + for key, value in attr.items(): + try: + serialized[self.serialize_unicode(key)] = self.serialize_data(value, dict_type, **kwargs) + except ValueError: + serialized[self.serialize_unicode(key)] = None + + if "xml" in serialization_ctxt: + # XML serialization is more complicated + xml_desc = serialization_ctxt["xml"] + xml_name = xml_desc["name"] + + final_result = _create_xml_node(xml_name, xml_desc.get("prefix", None), xml_desc.get("ns", None)) + for key, value in serialized.items(): + ET.SubElement(final_result, key).text = value + return final_result + + return serialized + + def serialize_object(self, attr, **kwargs): + """Serialize a generic object. + This will be handled as a dictionary. If object passed in is not + a basic type (str, int, float, dict, list) it will simply be + cast to str. + + :param dict attr: Object to be serialized. + :rtype: dict or str + """ + if attr is None: + return None + if isinstance(attr, ET.Element): + return attr + obj_type = type(attr) + if obj_type in self.basic_types: + return self.serialize_basic(attr, self.basic_types[obj_type], **kwargs) + if obj_type is _long_type: + return self.serialize_long(attr) + if obj_type is unicode_str: + return self.serialize_unicode(attr) + if obj_type is datetime.datetime: + return self.serialize_iso(attr) + if obj_type is datetime.date: + return self.serialize_date(attr) + if obj_type is datetime.time: + return self.serialize_time(attr) + if obj_type is datetime.timedelta: + return self.serialize_duration(attr) + if obj_type is decimal.Decimal: + return self.serialize_decimal(attr) + + # If it's a model or I know this dependency, serialize as a Model + elif obj_type in self.dependencies.values() or isinstance(attr, Model): + return self._serialize(attr) + + if obj_type == dict: + serialized = {} + for key, value in attr.items(): + try: + serialized[self.serialize_unicode(key)] = self.serialize_object(value, **kwargs) + except ValueError: + serialized[self.serialize_unicode(key)] = None + return serialized + + if obj_type == list: + serialized = [] + for obj in attr: + try: + serialized.append(self.serialize_object(obj, **kwargs)) + except ValueError: + pass + return serialized + return str(attr) + + @staticmethod + def serialize_enum(attr, enum_obj=None): + try: + result = attr.value + except AttributeError: + result = attr + try: + enum_obj(result) # type: ignore + return result + except ValueError: + for enum_value in enum_obj: # type: ignore + if enum_value.value.lower() == str(attr).lower(): + return enum_value.value + error = "{!r} is not valid value for enum {!r}" + raise SerializationError(error.format(attr, enum_obj)) + + @staticmethod + def serialize_bytearray(attr, **kwargs): + """Serialize bytearray into base-64 string. + + :param attr: Object to be serialized. + :rtype: str + """ + return b64encode(attr).decode() + + @staticmethod + def serialize_base64(attr, **kwargs): + """Serialize str into base-64 string. + + :param attr: Object to be serialized. + :rtype: str + """ + encoded = b64encode(attr).decode("ascii") + return encoded.strip("=").replace("+", "-").replace("/", "_") + + @staticmethod + def serialize_decimal(attr, **kwargs): + """Serialize Decimal object to float. + + :param attr: Object to be serialized. + :rtype: float + """ + return float(attr) + + @staticmethod + def serialize_long(attr, **kwargs): + """Serialize long (Py2) or int (Py3). + + :param attr: Object to be serialized. + :rtype: int/long + """ + return _long_type(attr) + + @staticmethod + def serialize_date(attr, **kwargs): + """Serialize Date object into ISO-8601 formatted string. + + :param Date attr: Object to be serialized. + :rtype: str + """ + if isinstance(attr, str): + attr = isodate.parse_date(attr) + t = "{:04}-{:02}-{:02}".format(attr.year, attr.month, attr.day) + return t + + @staticmethod + def serialize_time(attr, **kwargs): + """Serialize Time object into ISO-8601 formatted string. + + :param datetime.time attr: Object to be serialized. + :rtype: str + """ + if isinstance(attr, str): + attr = isodate.parse_time(attr) + t = "{:02}:{:02}:{:02}".format(attr.hour, attr.minute, attr.second) + if attr.microsecond: + t += ".{:02}".format(attr.microsecond) + return t + + @staticmethod + def serialize_duration(attr, **kwargs): + """Serialize TimeDelta object into ISO-8601 formatted string. + + :param TimeDelta attr: Object to be serialized. + :rtype: str + """ + if isinstance(attr, str): + attr = isodate.parse_duration(attr) + return isodate.duration_isoformat(attr) + + @staticmethod + def serialize_rfc(attr, **kwargs): + """Serialize Datetime object into RFC-1123 formatted string. + + :param Datetime attr: Object to be serialized. + :rtype: str + :raises: TypeError if format invalid. + """ + try: + if not attr.tzinfo: + _LOGGER.warning("Datetime with no tzinfo will be considered UTC.") + utc = attr.utctimetuple() + except AttributeError: + raise TypeError("RFC1123 object must be valid Datetime object.") + + return "{}, {:02} {} {:04} {:02}:{:02}:{:02} GMT".format( + Serializer.days[utc.tm_wday], + utc.tm_mday, + Serializer.months[utc.tm_mon], + utc.tm_year, + utc.tm_hour, + utc.tm_min, + utc.tm_sec, + ) + + @staticmethod + def serialize_iso(attr, **kwargs): + """Serialize Datetime object into ISO-8601 formatted string. + + :param Datetime attr: Object to be serialized. + :rtype: str + :raises: SerializationError if format invalid. + """ + if isinstance(attr, str): + attr = isodate.parse_datetime(attr) + try: + if not attr.tzinfo: + _LOGGER.warning("Datetime with no tzinfo will be considered UTC.") + utc = attr.utctimetuple() + if utc.tm_year > 9999 or utc.tm_year < 1: + raise OverflowError("Hit max or min date") + + microseconds = str(attr.microsecond).rjust(6, "0").rstrip("0").ljust(3, "0") + if microseconds: + microseconds = "." + microseconds + date = "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}".format( + utc.tm_year, utc.tm_mon, utc.tm_mday, utc.tm_hour, utc.tm_min, utc.tm_sec + ) + return date + microseconds + "Z" + except (ValueError, OverflowError) as err: + msg = "Unable to serialize datetime object." + raise_with_traceback(SerializationError, msg, err) + except AttributeError as err: + msg = "ISO-8601 object must be valid Datetime object." + raise_with_traceback(TypeError, msg, err) + + @staticmethod + def serialize_unix(attr, **kwargs): + """Serialize Datetime object into IntTime format. + This is represented as seconds. + + :param Datetime attr: Object to be serialized. + :rtype: int + :raises: SerializationError if format invalid + """ + if isinstance(attr, int): + return attr + try: + if not attr.tzinfo: + _LOGGER.warning("Datetime with no tzinfo will be considered UTC.") + return int(calendar.timegm(attr.utctimetuple())) + except AttributeError: + raise TypeError("Unix time object must be valid Datetime object.") + + +def rest_key_extractor(attr, attr_desc, data): + key = attr_desc["key"] + working_data = data + + while "." in key: + # Need the cast, as for some reasons "split" is typed as list[str | Any] + dict_keys = cast(List[str], _FLATTEN.split(key)) + if len(dict_keys) == 1: + key = _decode_attribute_map_key(dict_keys[0]) + break + working_key = _decode_attribute_map_key(dict_keys[0]) + working_data = working_data.get(working_key, data) + if working_data is None: + # If at any point while following flatten JSON path see None, it means + # that all properties under are None as well + # https://github.com/Azure/msrest-for-python/issues/197 + return None + key = ".".join(dict_keys[1:]) + + return working_data.get(key) + + +def rest_key_case_insensitive_extractor(attr, attr_desc, data): + key = attr_desc["key"] + working_data = data + + while "." in key: + dict_keys = _FLATTEN.split(key) + if len(dict_keys) == 1: + key = _decode_attribute_map_key(dict_keys[0]) + break + working_key = _decode_attribute_map_key(dict_keys[0]) + working_data = attribute_key_case_insensitive_extractor(working_key, None, working_data) + if working_data is None: + # If at any point while following flatten JSON path see None, it means + # that all properties under are None as well + # https://github.com/Azure/msrest-for-python/issues/197 + return None + key = ".".join(dict_keys[1:]) + + if working_data: + return attribute_key_case_insensitive_extractor(key, None, working_data) + + +def last_rest_key_extractor(attr, attr_desc, data): + """Extract the attribute in "data" based on the last part of the JSON path key.""" + key = attr_desc["key"] + dict_keys = _FLATTEN.split(key) + return attribute_key_extractor(dict_keys[-1], None, data) + + +def last_rest_key_case_insensitive_extractor(attr, attr_desc, data): + """Extract the attribute in "data" based on the last part of the JSON path key. + + This is the case insensitive version of "last_rest_key_extractor" + """ + key = attr_desc["key"] + dict_keys = _FLATTEN.split(key) + return attribute_key_case_insensitive_extractor(dict_keys[-1], None, data) + + +def attribute_key_extractor(attr, _, data): + return data.get(attr) + + +def attribute_key_case_insensitive_extractor(attr, _, data): + found_key = None + lower_attr = attr.lower() + for key in data: + if lower_attr == key.lower(): + found_key = key + break + + return data.get(found_key) + + +def _extract_name_from_internal_type(internal_type): + """Given an internal type XML description, extract correct XML name with namespace. + + :param dict internal_type: An model type + :rtype: tuple + :returns: A tuple XML name + namespace dict + """ + internal_type_xml_map = getattr(internal_type, "_xml_map", {}) + xml_name = internal_type_xml_map.get("name", internal_type.__name__) + xml_ns = internal_type_xml_map.get("ns", None) + if xml_ns: + xml_name = "{{{}}}{}".format(xml_ns, xml_name) + return xml_name + + +def xml_key_extractor(attr, attr_desc, data): + if isinstance(data, dict): + return None + + # Test if this model is XML ready first + if not isinstance(data, ET.Element): + return None + + xml_desc = attr_desc.get("xml", {}) + xml_name = xml_desc.get("name", attr_desc["key"]) + + # Look for a children + is_iter_type = attr_desc["type"].startswith("[") + is_wrapped = xml_desc.get("wrapped", False) + internal_type = attr_desc.get("internalType", None) + internal_type_xml_map = getattr(internal_type, "_xml_map", {}) + + # Integrate namespace if necessary + xml_ns = xml_desc.get("ns", internal_type_xml_map.get("ns", None)) + if xml_ns: + xml_name = "{{{}}}{}".format(xml_ns, xml_name) + + # If it's an attribute, that's simple + if xml_desc.get("attr", False): + return data.get(xml_name) + + # If it's x-ms-text, that's simple too + if xml_desc.get("text", False): + return data.text + + # Scenario where I take the local name: + # - Wrapped node + # - Internal type is an enum (considered basic types) + # - Internal type has no XML/Name node + if is_wrapped or (internal_type and (issubclass(internal_type, Enum) or "name" not in internal_type_xml_map)): + children = data.findall(xml_name) + # If internal type has a local name and it's not a list, I use that name + elif not is_iter_type and internal_type and "name" in internal_type_xml_map: + xml_name = _extract_name_from_internal_type(internal_type) + children = data.findall(xml_name) + # That's an array + else: + if internal_type: # Complex type, ignore itemsName and use the complex type name + items_name = _extract_name_from_internal_type(internal_type) + else: + items_name = xml_desc.get("itemsName", xml_name) + children = data.findall(items_name) + + if len(children) == 0: + if is_iter_type: + if is_wrapped: + return None # is_wrapped no node, we want None + else: + return [] # not wrapped, assume empty list + return None # Assume it's not there, maybe an optional node. + + # If is_iter_type and not wrapped, return all found children + if is_iter_type: + if not is_wrapped: + return children + else: # Iter and wrapped, should have found one node only (the wrap one) + if len(children) != 1: + raise DeserializationError( + "Tried to deserialize an array not wrapped, and found several nodes '{}'. Maybe you should declare this array as wrapped?".format( + xml_name + ) + ) + return list(children[0]) # Might be empty list and that's ok. + + # Here it's not a itertype, we should have found one element only or empty + if len(children) > 1: + raise DeserializationError("Find several XML '{}' where it was not expected".format(xml_name)) + return children[0] + + +class Deserializer(object): + """Response object model deserializer. + + :param dict classes: Class type dictionary for deserializing complex types. + :ivar list key_extractors: Ordered list of extractors to be used by this deserializer. + """ + + basic_types = {str: "str", int: "int", bool: "bool", float: "float"} + + valid_date = re.compile(r"\d{4}[-]\d{2}[-]\d{2}T\d{2}:\d{2}:\d{2}" r"\.?\d*Z?[-+]?[\d{2}]?:?[\d{2}]?") + + def __init__(self, classes: Optional[Mapping[str, Type[ModelType]]] = None): + self.deserialize_type = { + "iso-8601": Deserializer.deserialize_iso, + "rfc-1123": Deserializer.deserialize_rfc, + "unix-time": Deserializer.deserialize_unix, + "duration": Deserializer.deserialize_duration, + "date": Deserializer.deserialize_date, + "time": Deserializer.deserialize_time, + "decimal": Deserializer.deserialize_decimal, + "long": Deserializer.deserialize_long, + "bytearray": Deserializer.deserialize_bytearray, + "base64": Deserializer.deserialize_base64, + "object": self.deserialize_object, + "[]": self.deserialize_iter, + "{}": self.deserialize_dict, + } + self.deserialize_expected_types = { + "duration": (isodate.Duration, datetime.timedelta), + "iso-8601": (datetime.datetime), + } + self.dependencies: Dict[str, Type[ModelType]] = dict(classes) if classes else {} + self.key_extractors = [rest_key_extractor, xml_key_extractor] + # Additional properties only works if the "rest_key_extractor" is used to + # extract the keys. Making it to work whatever the key extractor is too much + # complicated, with no real scenario for now. + # So adding a flag to disable additional properties detection. This flag should be + # used if your expect the deserialization to NOT come from a JSON REST syntax. + # Otherwise, result are unexpected + self.additional_properties_detection = True + + def __call__(self, target_obj, response_data, content_type=None): + """Call the deserializer to process a REST response. + + :param str target_obj: Target data type to deserialize to. + :param requests.Response response_data: REST response object. + :param str content_type: Swagger "produces" if available. + :raises: DeserializationError if deserialization fails. + :return: Deserialized object. + """ + data = self._unpack_content(response_data, content_type) + return self._deserialize(target_obj, data) + + def _deserialize(self, target_obj, data): + """Call the deserializer on a model. + + Data needs to be already deserialized as JSON or XML ElementTree + + :param str target_obj: Target data type to deserialize to. + :param object data: Object to deserialize. + :raises: DeserializationError if deserialization fails. + :return: Deserialized object. + """ + # This is already a model, go recursive just in case + if hasattr(data, "_attribute_map"): + constants = [name for name, config in getattr(data, "_validation", {}).items() if config.get("constant")] + try: + for attr, mapconfig in data._attribute_map.items(): + if attr in constants: + continue + value = getattr(data, attr) + if value is None: + continue + local_type = mapconfig["type"] + internal_data_type = local_type.strip("[]{}") + if internal_data_type not in self.dependencies or isinstance(internal_data_type, Enum): + continue + setattr(data, attr, self._deserialize(local_type, value)) + return data + except AttributeError: + return + + response, class_name = self._classify_target(target_obj, data) + + if isinstance(response, basestring): + return self.deserialize_data(data, response) + elif isinstance(response, type) and issubclass(response, Enum): + return self.deserialize_enum(data, response) + + if data is None: + return data + try: + attributes = response._attribute_map # type: ignore + d_attrs = {} + for attr, attr_desc in attributes.items(): + # Check empty string. If it's not empty, someone has a real "additionalProperties"... + if attr == "additional_properties" and attr_desc["key"] == "": + continue + raw_value = None + # Enhance attr_desc with some dynamic data + attr_desc = attr_desc.copy() # Do a copy, do not change the real one + internal_data_type = attr_desc["type"].strip("[]{}") + if internal_data_type in self.dependencies: + attr_desc["internalType"] = self.dependencies[internal_data_type] + + for key_extractor in self.key_extractors: + found_value = key_extractor(attr, attr_desc, data) + if found_value is not None: + if raw_value is not None and raw_value != found_value: + msg = ( + "Ignoring extracted value '%s' from %s for key '%s'" + " (duplicate extraction, follow extractors order)" + ) + _LOGGER.warning(msg, found_value, key_extractor, attr) + continue + raw_value = found_value + + value = self.deserialize_data(raw_value, attr_desc["type"]) + d_attrs[attr] = value + except (AttributeError, TypeError, KeyError) as err: + msg = "Unable to deserialize to object: " + class_name # type: ignore + raise_with_traceback(DeserializationError, msg, err) + else: + additional_properties = self._build_additional_properties(attributes, data) + return self._instantiate_model(response, d_attrs, additional_properties) + + def _build_additional_properties(self, attribute_map, data): + if not self.additional_properties_detection: + return None + if "additional_properties" in attribute_map and attribute_map.get("additional_properties", {}).get("key") != "": + # Check empty string. If it's not empty, someone has a real "additionalProperties" + return None + if isinstance(data, ET.Element): + data = {el.tag: el.text for el in data} + + known_keys = { + _decode_attribute_map_key(_FLATTEN.split(desc["key"])[0]) + for desc in attribute_map.values() + if desc["key"] != "" + } + present_keys = set(data.keys()) + missing_keys = present_keys - known_keys + return {key: data[key] for key in missing_keys} + + def _classify_target(self, target, data): + """Check to see whether the deserialization target object can + be classified into a subclass. + Once classification has been determined, initialize object. + + :param str target: The target object type to deserialize to. + :param str/dict data: The response data to deserialize. + """ + if target is None: + return None, None + + if isinstance(target, basestring): + try: + target = self.dependencies[target] + except KeyError: + return target, target + + try: + target = target._classify(data, self.dependencies) + except AttributeError: + pass # Target is not a Model, no classify + return target, target.__class__.__name__ # type: ignore + + def failsafe_deserialize(self, target_obj, data, content_type=None): + """Ignores any errors encountered in deserialization, + and falls back to not deserializing the object. Recommended + for use in error deserialization, as we want to return the + HttpResponseError to users, and not have them deal with + a deserialization error. + + :param str target_obj: The target object type to deserialize to. + :param str/dict data: The response data to deserialize. + :param str content_type: Swagger "produces" if available. + """ + try: + return self(target_obj, data, content_type=content_type) + except: + _LOGGER.debug( + "Ran into a deserialization error. Ignoring since this is failsafe deserialization", exc_info=True + ) + return None + + @staticmethod + def _unpack_content(raw_data, content_type=None): + """Extract the correct structure for deserialization. + + If raw_data is a PipelineResponse, try to extract the result of RawDeserializer. + if we can't, raise. Your Pipeline should have a RawDeserializer. + + If not a pipeline response and raw_data is bytes or string, use content-type + to decode it. If no content-type, try JSON. + + If raw_data is something else, bypass all logic and return it directly. + + :param raw_data: Data to be processed. + :param content_type: How to parse if raw_data is a string/bytes. + :raises JSONDecodeError: If JSON is requested and parsing is impossible. + :raises UnicodeDecodeError: If bytes is not UTF8 + """ + # Assume this is enough to detect a Pipeline Response without importing it + context = getattr(raw_data, "context", {}) + if context: + if RawDeserializer.CONTEXT_NAME in context: + return context[RawDeserializer.CONTEXT_NAME] + raise ValueError("This pipeline didn't have the RawDeserializer policy; can't deserialize") + + # Assume this is enough to recognize universal_http.ClientResponse without importing it + if hasattr(raw_data, "body"): + return RawDeserializer.deserialize_from_http_generics(raw_data.text(), raw_data.headers) + + # Assume this enough to recognize requests.Response without importing it. + if hasattr(raw_data, "_content_consumed"): + return RawDeserializer.deserialize_from_http_generics(raw_data.text, raw_data.headers) + + if isinstance(raw_data, (basestring, bytes)) or hasattr(raw_data, "read"): + return RawDeserializer.deserialize_from_text(raw_data, content_type) # type: ignore + return raw_data + + def _instantiate_model(self, response, attrs, additional_properties=None): + """Instantiate a response model passing in deserialized args. + + :param response: The response model class. + :param d_attrs: The deserialized response attributes. + """ + if callable(response): + subtype = getattr(response, "_subtype_map", {}) + try: + readonly = [k for k, v in response._validation.items() if v.get("readonly")] + const = [k for k, v in response._validation.items() if v.get("constant")] + kwargs = {k: v for k, v in attrs.items() if k not in subtype and k not in readonly + const} + response_obj = response(**kwargs) + for attr in readonly: + setattr(response_obj, attr, attrs.get(attr)) + if additional_properties: + response_obj.additional_properties = additional_properties + return response_obj + except TypeError as err: + msg = "Unable to deserialize {} into model {}. ".format(kwargs, response) # type: ignore + raise DeserializationError(msg + str(err)) + else: + try: + for attr, value in attrs.items(): + setattr(response, attr, value) + return response + except Exception as exp: + msg = "Unable to populate response model. " + msg += "Type: {}, Error: {}".format(type(response), exp) + raise DeserializationError(msg) + + def deserialize_data(self, data, data_type): + """Process data for deserialization according to data type. + + :param str data: The response string to be deserialized. + :param str data_type: The type to deserialize to. + :raises: DeserializationError if deserialization fails. + :return: Deserialized object. + """ + if data is None: + return data + + try: + if not data_type: + return data + if data_type in self.basic_types.values(): + return self.deserialize_basic(data, data_type) + if data_type in self.deserialize_type: + if isinstance(data, self.deserialize_expected_types.get(data_type, tuple())): + return data + + is_a_text_parsing_type = lambda x: x not in ["object", "[]", r"{}"] + if isinstance(data, ET.Element) and is_a_text_parsing_type(data_type) and not data.text: + return None + data_val = self.deserialize_type[data_type](data) + return data_val + + iter_type = data_type[0] + data_type[-1] + if iter_type in self.deserialize_type: + return self.deserialize_type[iter_type](data, data_type[1:-1]) + + obj_type = self.dependencies[data_type] + if issubclass(obj_type, Enum): + if isinstance(data, ET.Element): + data = data.text + return self.deserialize_enum(data, obj_type) + + except (ValueError, TypeError, AttributeError) as err: + msg = "Unable to deserialize response data." + msg += " Data: {}, {}".format(data, data_type) + raise_with_traceback(DeserializationError, msg, err) + else: + return self._deserialize(obj_type, data) + + def deserialize_iter(self, attr, iter_type): + """Deserialize an iterable. + + :param list attr: Iterable to be deserialized. + :param str iter_type: The type of object in the iterable. + :rtype: list + """ + if attr is None: + return None + if isinstance(attr, ET.Element): # If I receive an element here, get the children + attr = list(attr) + if not isinstance(attr, (list, set)): + raise DeserializationError("Cannot deserialize as [{}] an object of type {}".format(iter_type, type(attr))) + return [self.deserialize_data(a, iter_type) for a in attr] + + def deserialize_dict(self, attr, dict_type): + """Deserialize a dictionary. + + :param dict/list attr: Dictionary to be deserialized. Also accepts + a list of key, value pairs. + :param str dict_type: The object type of the items in the dictionary. + :rtype: dict + """ + if isinstance(attr, list): + return {x["key"]: self.deserialize_data(x["value"], dict_type) for x in attr} + + if isinstance(attr, ET.Element): + # Transform value into {"Key": "value"} + attr = {el.tag: el.text for el in attr} + return {k: self.deserialize_data(v, dict_type) for k, v in attr.items()} + + def deserialize_object(self, attr, **kwargs): + """Deserialize a generic object. + This will be handled as a dictionary. + + :param dict attr: Dictionary to be deserialized. + :rtype: dict + :raises: TypeError if non-builtin datatype encountered. + """ + if attr is None: + return None + if isinstance(attr, ET.Element): + # Do no recurse on XML, just return the tree as-is + return attr + if isinstance(attr, basestring): + return self.deserialize_basic(attr, "str") + obj_type = type(attr) + if obj_type in self.basic_types: + return self.deserialize_basic(attr, self.basic_types[obj_type]) + if obj_type is _long_type: + return self.deserialize_long(attr) + + if obj_type == dict: + deserialized = {} + for key, value in attr.items(): + try: + deserialized[key] = self.deserialize_object(value, **kwargs) + except ValueError: + deserialized[key] = None + return deserialized + + if obj_type == list: + deserialized = [] + for obj in attr: + try: + deserialized.append(self.deserialize_object(obj, **kwargs)) + except ValueError: + pass + return deserialized + + else: + error = "Cannot deserialize generic object with type: " + raise TypeError(error + str(obj_type)) + + def deserialize_basic(self, attr, data_type): + """Deserialize basic builtin data type from string. + Will attempt to convert to str, int, float and bool. + This function will also accept '1', '0', 'true' and 'false' as + valid bool values. + + :param str attr: response string to be deserialized. + :param str data_type: deserialization data type. + :rtype: str, int, float or bool + :raises: TypeError if string format is not valid. + """ + # If we're here, data is supposed to be a basic type. + # If it's still an XML node, take the text + if isinstance(attr, ET.Element): + attr = attr.text + if not attr: + if data_type == "str": + # None or '', node is empty string. + return "" + else: + # None or '', node with a strong type is None. + # Don't try to model "empty bool" or "empty int" + return None + + if data_type == "bool": + if attr in [True, False, 1, 0]: + return bool(attr) + elif isinstance(attr, basestring): + if attr.lower() in ["true", "1"]: + return True + elif attr.lower() in ["false", "0"]: + return False + raise TypeError("Invalid boolean value: {}".format(attr)) + + if data_type == "str": + return self.deserialize_unicode(attr) + return eval(data_type)(attr) # nosec + + @staticmethod + def deserialize_unicode(data): + """Preserve unicode objects in Python 2, otherwise return data + as a string. + + :param str data: response string to be deserialized. + :rtype: str or unicode + """ + # We might be here because we have an enum modeled as string, + # and we try to deserialize a partial dict with enum inside + if isinstance(data, Enum): + return data + + # Consider this is real string + try: + if isinstance(data, unicode): # type: ignore + return data + except NameError: + return str(data) + else: + return str(data) + + @staticmethod + def deserialize_enum(data, enum_obj): + """Deserialize string into enum object. + + If the string is not a valid enum value it will be returned as-is + and a warning will be logged. + + :param str data: Response string to be deserialized. If this value is + None or invalid it will be returned as-is. + :param Enum enum_obj: Enum object to deserialize to. + :rtype: Enum + """ + if isinstance(data, enum_obj) or data is None: + return data + if isinstance(data, Enum): + data = data.value + if isinstance(data, int): + # Workaround. We might consider remove it in the future. + # https://github.com/Azure/azure-rest-api-specs/issues/141 + try: + return list(enum_obj.__members__.values())[data] + except IndexError: + error = "{!r} is not a valid index for enum {!r}" + raise DeserializationError(error.format(data, enum_obj)) + try: + return enum_obj(str(data)) + except ValueError: + for enum_value in enum_obj: + if enum_value.value.lower() == str(data).lower(): + return enum_value + # We don't fail anymore for unknown value, we deserialize as a string + _LOGGER.warning("Deserializer is not able to find %s as valid enum in %s", data, enum_obj) + return Deserializer.deserialize_unicode(data) + + @staticmethod + def deserialize_bytearray(attr): + """Deserialize string into bytearray. + + :param str attr: response string to be deserialized. + :rtype: bytearray + :raises: TypeError if string format invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + return bytearray(b64decode(attr)) # type: ignore + + @staticmethod + def deserialize_base64(attr): + """Deserialize base64 encoded string into string. + + :param str attr: response string to be deserialized. + :rtype: bytearray + :raises: TypeError if string format invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + padding = "=" * (3 - (len(attr) + 3) % 4) # type: ignore + attr = attr + padding # type: ignore + encoded = attr.replace("-", "+").replace("_", "/") + return b64decode(encoded) + + @staticmethod + def deserialize_decimal(attr): + """Deserialize string into Decimal object. + + :param str attr: response string to be deserialized. + :rtype: Decimal + :raises: DeserializationError if string format invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + try: + return decimal.Decimal(attr) # type: ignore + except decimal.DecimalException as err: + msg = "Invalid decimal {}".format(attr) + raise_with_traceback(DeserializationError, msg, err) + + @staticmethod + def deserialize_long(attr): + """Deserialize string into long (Py2) or int (Py3). + + :param str attr: response string to be deserialized. + :rtype: long or int + :raises: ValueError if string format invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + return _long_type(attr) # type: ignore + + @staticmethod + def deserialize_duration(attr): + """Deserialize ISO-8601 formatted string into TimeDelta object. + + :param str attr: response string to be deserialized. + :rtype: TimeDelta + :raises: DeserializationError if string format invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + try: + duration = isodate.parse_duration(attr) + except (ValueError, OverflowError, AttributeError) as err: + msg = "Cannot deserialize duration object." + raise_with_traceback(DeserializationError, msg, err) + else: + return duration + + @staticmethod + def deserialize_date(attr): + """Deserialize ISO-8601 formatted string into Date object. + + :param str attr: response string to be deserialized. + :rtype: Date + :raises: DeserializationError if string format invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + if re.search(r"[^\W\d_]", attr, re.I + re.U): # type: ignore + raise DeserializationError("Date must have only digits and -. Received: %s" % attr) + # This must NOT use defaultmonth/defaultday. Using None ensure this raises an exception. + return isodate.parse_date(attr, defaultmonth=None, defaultday=None) + + @staticmethod + def deserialize_time(attr): + """Deserialize ISO-8601 formatted string into time object. + + :param str attr: response string to be deserialized. + :rtype: datetime.time + :raises: DeserializationError if string format invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + if re.search(r"[^\W\d_]", attr, re.I + re.U): # type: ignore + raise DeserializationError("Date must have only digits and -. Received: %s" % attr) + return isodate.parse_time(attr) + + @staticmethod + def deserialize_rfc(attr): + """Deserialize RFC-1123 formatted string into Datetime object. + + :param str attr: response string to be deserialized. + :rtype: Datetime + :raises: DeserializationError if string format invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + try: + parsed_date = email.utils.parsedate_tz(attr) # type: ignore + date_obj = datetime.datetime( + *parsed_date[:6], tzinfo=_FixedOffset(datetime.timedelta(minutes=(parsed_date[9] or 0) / 60)) + ) + if not date_obj.tzinfo: + date_obj = date_obj.astimezone(tz=TZ_UTC) + except ValueError as err: + msg = "Cannot deserialize to rfc datetime object." + raise_with_traceback(DeserializationError, msg, err) + else: + return date_obj + + @staticmethod + def deserialize_iso(attr): + """Deserialize ISO-8601 formatted string into Datetime object. + + :param str attr: response string to be deserialized. + :rtype: Datetime + :raises: DeserializationError if string format invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + try: + attr = attr.upper() # type: ignore + match = Deserializer.valid_date.match(attr) + if not match: + raise ValueError("Invalid datetime string: " + attr) + + check_decimal = attr.split(".") + if len(check_decimal) > 1: + decimal_str = "" + for digit in check_decimal[1]: + if digit.isdigit(): + decimal_str += digit + else: + break + if len(decimal_str) > 6: + attr = attr.replace(decimal_str, decimal_str[0:6]) + + date_obj = isodate.parse_datetime(attr) + test_utc = date_obj.utctimetuple() + if test_utc.tm_year > 9999 or test_utc.tm_year < 1: + raise OverflowError("Hit max or min date") + except (ValueError, OverflowError, AttributeError) as err: + msg = "Cannot deserialize datetime object." + raise_with_traceback(DeserializationError, msg, err) + else: + return date_obj + + @staticmethod + def deserialize_unix(attr): + """Serialize Datetime object into IntTime format. + This is represented as seconds. + + :param int attr: Object to be serialized. + :rtype: Datetime + :raises: DeserializationError if format invalid + """ + if isinstance(attr, ET.Element): + attr = int(attr.text) # type: ignore + try: + date_obj = datetime.datetime.fromtimestamp(attr, TZ_UTC) + except ValueError as err: + msg = "Cannot deserialize to unix datetime object." + raise_with_traceback(DeserializationError, msg, err) + else: + return date_obj diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_vendor.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_vendor.py new file mode 100644 index 000000000000..0b9dda2df268 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_vendor.py @@ -0,0 +1,26 @@ +# -------------------------------------------------------------------------- +# 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) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from abc import ABC +from typing import TYPE_CHECKING + +from ._configuration import TextTranslationClientConfiguration + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from azure.core import PipelineClient + + from ._serialization import Deserializer, Serializer + + +class TextTranslationClientMixinABC(ABC): + """DO NOT use this class. It is for internal typing use only.""" + + _client: "PipelineClient" + _config: TextTranslationClientConfiguration + _serialize: "Serializer" + _deserialize: "Deserializer" diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_version.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_version.py new file mode 100644 index 000000000000..be71c81bd282 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_version.py @@ -0,0 +1,9 @@ +# 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) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +VERSION = "1.0.0b1" diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/__init__.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/__init__.py new file mode 100644 index 000000000000..b968ebfb1f5c --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/__init__.py @@ -0,0 +1,23 @@ +# 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) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._client import TextTranslationClient + +try: + from ._patch import __all__ as _patch_all + from ._patch import * # pylint: disable=unused-wildcard-import +except ImportError: + _patch_all = [] +from ._patch import patch_sdk as _patch_sdk + +__all__ = [ + "TextTranslationClient", +] +__all__.extend([p for p in _patch_all if p not in __all__]) + +_patch_sdk() diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_client.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_client.py new file mode 100644 index 000000000000..4293b6f55358 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_client.py @@ -0,0 +1,97 @@ +# 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) Python 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 + +from azure.core import AsyncPipelineClient +from azure.core.rest import AsyncHttpResponse, HttpRequest + +from .._serialization import Deserializer, Serializer +from ._configuration import TextTranslationClientConfiguration +from ._operations import TextTranslationClientOperationsMixin + + +class TextTranslationClient(TextTranslationClientOperationsMixin): # pylint: disable=client-accepts-api-version-keyword + """Text translation is a cloud-based REST API feature of the Translator service that uses neural + machine translation technology to enable quick and accurate source-to-target text translation + in real time across all supported languages. + + The following methods are supported by the Text Translation feature: + + Languages. Returns a list of languages supported by Translate, Transliterate, and Dictionary + Lookup operations. + + Translate. Renders single source-language text to multiple target-language texts with a single + request. + + Transliterate. Converts characters or letters of a source language to the corresponding + characters or letters of a target language. + + Detect. Returns the source code language code and a boolean variable denoting whether the + detected language is supported for text translation and transliteration. + + Dictionary lookup. Returns equivalent words for the source term in the target language. + + Dictionary example Returns grammatical structure and context examples for the source term and + target term pair. + + :param endpoint: Supported Text Translation endpoints (protocol and hostname, for example: + https://api.cognitive.microsofttranslator.com). Required. + :type endpoint: str + :keyword api_version: Default value is "3.0". 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 = TextTranslationClientConfiguration(endpoint=endpoint, **kwargs) + self._client: AsyncPipelineClient = AsyncPipelineClient(base_url=_endpoint, config=self._config, **kwargs) + + self._serialize = Serializer() + self._deserialize = Deserializer() + self._serialize.client_side_validation = False + + 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/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.AsyncHttpResponse + """ + + 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) + + async def close(self) -> None: + await self._client.close() + + async def __aenter__(self) -> "TextTranslationClient": + await self._client.__aenter__() + return self + + async def __aexit__(self, *exc_details: Any) -> None: + await self._client.__aexit__(*exc_details) diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_configuration.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_configuration.py new file mode 100644 index 000000000000..2ff232a4e5b2 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_configuration.py @@ -0,0 +1,58 @@ +# 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) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +import sys +from typing import Any + +from azure.core.configuration import Configuration +from azure.core.pipeline import policies + +from .._version import VERSION + +if sys.version_info >= (3, 8): + from typing import Literal # pylint: disable=no-name-in-module, ungrouped-imports +else: + from typing_extensions import Literal # type: ignore # pylint: disable=ungrouped-imports + + +class TextTranslationClientConfiguration(Configuration): # pylint: disable=too-many-instance-attributes + """Configuration for TextTranslationClient. + + Note that all parameters used to create this instance are saved as instance + attributes. + + :param endpoint: Supported Text Translation endpoints (protocol and hostname, for example: + https://api.cognitive.microsofttranslator.com). Required. + :type endpoint: str + :keyword api_version: Default value is "3.0". Note that overriding this default value may + result in unsupported behavior. + :paramtype api_version: str + """ + + def __init__(self, endpoint: str, **kwargs: Any) -> None: + super(TextTranslationClientConfiguration, self).__init__(**kwargs) + api_version: Literal["3.0"] = kwargs.pop("api_version", "3.0") + + if endpoint is None: + raise ValueError("Parameter 'endpoint' must not be None.") + + self.endpoint = endpoint + self.api_version = api_version + kwargs.setdefault("sdk_moniker", "ai-translation-text/{}".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") diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_operations/__init__.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_operations/__init__.py new file mode 100644 index 000000000000..7317dd9ada4d --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_operations/__init__.py @@ -0,0 +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. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._operations import TextTranslationClientOperationsMixin + +from ._patch import __all__ as _patch_all +from ._patch import * # pylint: disable=unused-wildcard-import +from ._patch import patch_sdk as _patch_sdk + +__all__ = [ + "TextTranslationClientOperationsMixin", +] +__all__.extend([p for p in _patch_all if p not in __all__]) +_patch_sdk() diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_operations/_operations.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_operations/_operations.py new file mode 100644 index 000000000000..196edc43292d --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_operations/_operations.py @@ -0,0 +1,1203 @@ +# pylint: disable=too-many-lines +# 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) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +import json +from typing import Any, Callable, Dict, IO, List, Optional, TypeVar, Union, overload + +from azure.core.exceptions import ( + ClientAuthenticationError, + HttpResponseError, + ResourceExistsError, + ResourceNotFoundError, + ResourceNotModifiedError, + 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 azure.core.utils import case_insensitive_dict + +from ... import models as _models +from ..._model_base import AzureJSONEncoder, _deserialize +from ..._operations._operations import ( + build_text_translation_find_sentence_boundaries_request, + build_text_translation_get_languages_request, + build_text_translation_lookup_dictionary_entries_request, + build_text_translation_lookup_dictionary_examples_request, + build_text_translation_translate_request, + build_text_translation_transliterate_request, +) +from .._vendor import TextTranslationClientMixinABC + +T = TypeVar("T") +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] + + +class TextTranslationClientOperationsMixin(TextTranslationClientMixinABC): + @distributed_trace_async + async def get_languages( + self, + *, + client_trace_id: Optional[str] = None, + scope: Optional[str] = None, + accept_language: Optional[str] = None, + if_none_match: Optional[str] = None, + **kwargs: Any + ) -> _models.GetLanguagesResult: + """Gets the set of languages currently supported by other operations of the Translator. + + Gets the set of languages currently supported by other operations of the Translator. + + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword scope: A comma-separated list of names defining the group of languages to return. + Allowed group names are: ``translation``\ , ``transliteration`` and ``dictionary``. + If no scope is given, then all groups are returned, which is equivalent to passing + ``scope=translation,transliteration,dictionary``. To decide which set of supported languages + is appropriate for your scenario, see the description of the `response object + <#response-body>`_. Default value is None. + :paramtype scope: str + :keyword accept_language: The language to use for user interface strings. Some of the fields in + the response are names of languages or + names of regions. Use this parameter to define the language in which these names are returned. + The language is specified by providing a well-formed BCP 47 language tag. For instance, use + the value ``fr`` + to request names in French or use the value ``zh-Hant`` to request names in Chinese + Traditional. + Names are provided in the English language when a target language is not specified or when + localization + is not available. Default value is None. + :paramtype accept_language: str + :keyword if_none_match: Passing the value of the ETag response header in an If-None-Match field + will allow the service to optimize the response. + If the resource has not been modified, the service will return status code 304 and an empty + response body. Default value is None. + :paramtype if_none_match: str + :return: GetLanguagesResult. The GetLanguagesResult is compatible with MutableMapping + :rtype: ~azure.ai.translation.text.models.GetLanguagesResult + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.GetLanguagesResult] = kwargs.pop("cls", None) + + request = build_text_translation_get_languages_request( + client_trace_id=client_trace_id, + scope=scope, + accept_language=accept_language, + if_none_match=if_none_match, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + 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) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + request, stream=_stream, **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) + error = _deserialize(_models.ErrorResponse, response.json()) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["X-RequestId"] = self._deserialize("str", response.headers.get("X-RequestId")) + response_headers["ETag"] = self._deserialize("str", response.headers.get("ETag")) + + deserialized = _deserialize(_models.GetLanguagesResult, response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + async def translate( + self, + content: List[_models.InputTextItem], + *, + to: List[str], + client_trace_id: Optional[str] = None, + from_parameter: Optional[str] = None, + text_type: Optional[Union[str, _models.TextType]] = None, + category: Optional[str] = None, + profanity_action: Optional[Union[str, _models.ProfanityAction]] = None, + profanity_marker: Optional[Union[str, _models.ProfanityMarker]] = None, + include_alignment: Optional[bool] = None, + include_sentence_length: Optional[bool] = None, + suggested_from: Optional[str] = None, + from_script: Optional[str] = None, + to_script: Optional[str] = None, + allow_fallback: Optional[bool] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.TranslatedTextItem]: + """Translate Text. + + Translate Text. + + :param content: Array of the text to be translated. Required. + :type content: list[~azure.ai.translation.text.models.InputTextItem] + :keyword to: Specifies the language of the output text. The target language must be one of the + supported languages included + in the translation scope. For example, use to=de to translate to German. + It's possible to translate to multiple languages simultaneously by repeating the parameter in + the query string. + For example, use to=de&to=it to translate to German and Italian. Required. + :paramtype to: list[str] + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword from_parameter: Specifies the language of the input text. Find which languages are + available to translate from by + looking up supported languages using the translation scope. If the from parameter isn't + specified, + automatic language detection is applied to determine the source language. + + You must use the from parameter rather than autodetection when using the dynamic dictionary + feature. + Note: the dynamic dictionary feature is case-sensitive. Default value is None. + :paramtype from_parameter: str + :keyword text_type: Defines whether the text being translated is plain text or HTML text. Any + HTML needs to be a well-formed, + complete element. Possible values are: plain (default) or html. Known values are: "plain" and + "html". Default value is None. + :paramtype text_type: str or ~azure.ai.translation.text.models.TextType + :keyword category: A string specifying the category (domain) of the translation. This parameter + is used to get translations + from a customized system built with Custom Translator. Add the Category ID from your Custom + Translator + project details to this parameter to use your deployed customized system. Default value is: + general. Default value is None. + :paramtype category: str + :keyword profanity_action: Specifies how profanities should be treated in translations. + Possible values are: NoAction (default), Marked or Deleted. Known values are: "NoAction", + "Marked", and "Deleted". Default value is None. + :paramtype profanity_action: str or ~azure.ai.translation.text.models.ProfanityAction + :keyword profanity_marker: Specifies how profanities should be marked in translations. + Possible values are: Asterisk (default) or Tag. Known values are: "Asterisk" and "Tag". + Default value is None. + :paramtype profanity_marker: str or ~azure.ai.translation.text.models.ProfanityMarker + :keyword include_alignment: Specifies whether to include alignment projection from source text + to translated text. + Possible values are: true or false (default). Default value is None. + :paramtype include_alignment: bool + :keyword include_sentence_length: Specifies whether to include sentence boundaries for the + input text and the translated text. + Possible values are: true or false (default). Default value is None. + :paramtype include_sentence_length: bool + :keyword suggested_from: Specifies a fallback language if the language of the input text can't + be identified. + Language autodetection is applied when the from parameter is omitted. If detection fails, + the suggestedFrom language will be assumed. Default value is None. + :paramtype suggested_from: str + :keyword from_script: Specifies the script of the input text. Default value is None. + :paramtype from_script: str + :keyword to_script: Specifies the script of the translated text. Default value is None. + :paramtype to_script: str + :keyword allow_fallback: Specifies that the service is allowed to fall back to a general system + when a custom system doesn't exist. + Possible values are: true (default) or false. + + allowFallback=false specifies that the translation should only use systems trained for the + category specified + by the request. If a translation for language X to language Y requires chaining through a + pivot language E, + then all the systems in the chain (X → E and E → Y) will need to be custom and have the same + category. + If no system is found with the specific category, the request will return a 400 status code. + allowFallback=true + specifies that the service is allowed to fall back to a general system when a custom system + doesn't exist. Default value is None. + :paramtype allow_fallback: bool + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: list of TranslatedTextItem + :rtype: list[~azure.ai.translation.text.models.TranslatedTextItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def translate( + self, + content: IO, + *, + to: List[str], + client_trace_id: Optional[str] = None, + from_parameter: Optional[str] = None, + text_type: Optional[Union[str, _models.TextType]] = None, + category: Optional[str] = None, + profanity_action: Optional[Union[str, _models.ProfanityAction]] = None, + profanity_marker: Optional[Union[str, _models.ProfanityMarker]] = None, + include_alignment: Optional[bool] = None, + include_sentence_length: Optional[bool] = None, + suggested_from: Optional[str] = None, + from_script: Optional[str] = None, + to_script: Optional[str] = None, + allow_fallback: Optional[bool] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.TranslatedTextItem]: + """Translate Text. + + Translate Text. + + :param content: Array of the text to be translated. Required. + :type content: IO + :keyword to: Specifies the language of the output text. The target language must be one of the + supported languages included + in the translation scope. For example, use to=de to translate to German. + It's possible to translate to multiple languages simultaneously by repeating the parameter in + the query string. + For example, use to=de&to=it to translate to German and Italian. Required. + :paramtype to: list[str] + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword from_parameter: Specifies the language of the input text. Find which languages are + available to translate from by + looking up supported languages using the translation scope. If the from parameter isn't + specified, + automatic language detection is applied to determine the source language. + + You must use the from parameter rather than autodetection when using the dynamic dictionary + feature. + Note: the dynamic dictionary feature is case-sensitive. Default value is None. + :paramtype from_parameter: str + :keyword text_type: Defines whether the text being translated is plain text or HTML text. Any + HTML needs to be a well-formed, + complete element. Possible values are: plain (default) or html. Known values are: "plain" and + "html". Default value is None. + :paramtype text_type: str or ~azure.ai.translation.text.models.TextType + :keyword category: A string specifying the category (domain) of the translation. This parameter + is used to get translations + from a customized system built with Custom Translator. Add the Category ID from your Custom + Translator + project details to this parameter to use your deployed customized system. Default value is: + general. Default value is None. + :paramtype category: str + :keyword profanity_action: Specifies how profanities should be treated in translations. + Possible values are: NoAction (default), Marked or Deleted. Known values are: "NoAction", + "Marked", and "Deleted". Default value is None. + :paramtype profanity_action: str or ~azure.ai.translation.text.models.ProfanityAction + :keyword profanity_marker: Specifies how profanities should be marked in translations. + Possible values are: Asterisk (default) or Tag. Known values are: "Asterisk" and "Tag". + Default value is None. + :paramtype profanity_marker: str or ~azure.ai.translation.text.models.ProfanityMarker + :keyword include_alignment: Specifies whether to include alignment projection from source text + to translated text. + Possible values are: true or false (default). Default value is None. + :paramtype include_alignment: bool + :keyword include_sentence_length: Specifies whether to include sentence boundaries for the + input text and the translated text. + Possible values are: true or false (default). Default value is None. + :paramtype include_sentence_length: bool + :keyword suggested_from: Specifies a fallback language if the language of the input text can't + be identified. + Language autodetection is applied when the from parameter is omitted. If detection fails, + the suggestedFrom language will be assumed. Default value is None. + :paramtype suggested_from: str + :keyword from_script: Specifies the script of the input text. Default value is None. + :paramtype from_script: str + :keyword to_script: Specifies the script of the translated text. Default value is None. + :paramtype to_script: str + :keyword allow_fallback: Specifies that the service is allowed to fall back to a general system + when a custom system doesn't exist. + Possible values are: true (default) or false. + + allowFallback=false specifies that the translation should only use systems trained for the + category specified + by the request. If a translation for language X to language Y requires chaining through a + pivot language E, + then all the systems in the chain (X → E and E → Y) will need to be custom and have the same + category. + If no system is found with the specific category, the request will return a 400 status code. + allowFallback=true + specifies that the service is allowed to fall back to a general system when a custom system + doesn't exist. Default value is None. + :paramtype allow_fallback: bool + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: list of TranslatedTextItem + :rtype: list[~azure.ai.translation.text.models.TranslatedTextItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def translate( + self, + content: Union[List[_models.InputTextItem], IO], + *, + to: List[str], + client_trace_id: Optional[str] = None, + from_parameter: Optional[str] = None, + text_type: Optional[Union[str, _models.TextType]] = None, + category: Optional[str] = None, + profanity_action: Optional[Union[str, _models.ProfanityAction]] = None, + profanity_marker: Optional[Union[str, _models.ProfanityMarker]] = None, + include_alignment: Optional[bool] = None, + include_sentence_length: Optional[bool] = None, + suggested_from: Optional[str] = None, + from_script: Optional[str] = None, + to_script: Optional[str] = None, + allow_fallback: Optional[bool] = None, + **kwargs: Any + ) -> List[_models.TranslatedTextItem]: + """Translate Text. + + Translate Text. + + :param content: Array of the text to be translated. Is either a [InputTextItem] type or a IO + type. Required. + :type content: list[~azure.ai.translation.text.models.InputTextItem] or IO + :keyword to: Specifies the language of the output text. The target language must be one of the + supported languages included + in the translation scope. For example, use to=de to translate to German. + It's possible to translate to multiple languages simultaneously by repeating the parameter in + the query string. + For example, use to=de&to=it to translate to German and Italian. Required. + :paramtype to: list[str] + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword from_parameter: Specifies the language of the input text. Find which languages are + available to translate from by + looking up supported languages using the translation scope. If the from parameter isn't + specified, + automatic language detection is applied to determine the source language. + + You must use the from parameter rather than autodetection when using the dynamic dictionary + feature. + Note: the dynamic dictionary feature is case-sensitive. Default value is None. + :paramtype from_parameter: str + :keyword text_type: Defines whether the text being translated is plain text or HTML text. Any + HTML needs to be a well-formed, + complete element. Possible values are: plain (default) or html. Known values are: "plain" and + "html". Default value is None. + :paramtype text_type: str or ~azure.ai.translation.text.models.TextType + :keyword category: A string specifying the category (domain) of the translation. This parameter + is used to get translations + from a customized system built with Custom Translator. Add the Category ID from your Custom + Translator + project details to this parameter to use your deployed customized system. Default value is: + general. Default value is None. + :paramtype category: str + :keyword profanity_action: Specifies how profanities should be treated in translations. + Possible values are: NoAction (default), Marked or Deleted. Known values are: "NoAction", + "Marked", and "Deleted". Default value is None. + :paramtype profanity_action: str or ~azure.ai.translation.text.models.ProfanityAction + :keyword profanity_marker: Specifies how profanities should be marked in translations. + Possible values are: Asterisk (default) or Tag. Known values are: "Asterisk" and "Tag". + Default value is None. + :paramtype profanity_marker: str or ~azure.ai.translation.text.models.ProfanityMarker + :keyword include_alignment: Specifies whether to include alignment projection from source text + to translated text. + Possible values are: true or false (default). Default value is None. + :paramtype include_alignment: bool + :keyword include_sentence_length: Specifies whether to include sentence boundaries for the + input text and the translated text. + Possible values are: true or false (default). Default value is None. + :paramtype include_sentence_length: bool + :keyword suggested_from: Specifies a fallback language if the language of the input text can't + be identified. + Language autodetection is applied when the from parameter is omitted. If detection fails, + the suggestedFrom language will be assumed. Default value is None. + :paramtype suggested_from: str + :keyword from_script: Specifies the script of the input text. Default value is None. + :paramtype from_script: str + :keyword to_script: Specifies the script of the translated text. Default value is None. + :paramtype to_script: str + :keyword allow_fallback: Specifies that the service is allowed to fall back to a general system + when a custom system doesn't exist. + Possible values are: true (default) or false. + + allowFallback=false specifies that the translation should only use systems trained for the + category specified + by the request. If a translation for language X to language Y requires chaining through a + pivot language E, + then all the systems in the chain (X → E and E → Y) will need to be custom and have the same + category. + If no system is found with the specific category, the request will return a 400 status code. + allowFallback=true + specifies that the service is allowed to fall back to a general system when a custom system + doesn't exist. Default value is None. + :paramtype allow_fallback: bool + :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default + value is None. + :paramtype content_type: str + :return: list of TranslatedTextItem + :rtype: list[~azure.ai.translation.text.models.TranslatedTextItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[List[_models.TranslatedTextItem]] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(content, (IO, bytes)): + _content = content + else: + _content = json.dumps(content, cls=AzureJSONEncoder) # type: ignore + + request = build_text_translation_translate_request( + to=to, + client_trace_id=client_trace_id, + from_parameter=from_parameter, + text_type=text_type, + category=category, + profanity_action=profanity_action, + profanity_marker=profanity_marker, + include_alignment=include_alignment, + include_sentence_length=include_sentence_length, + suggested_from=suggested_from, + from_script=from_script, + to_script=to_script, + allow_fallback=allow_fallback, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + 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) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + request, stream=_stream, **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) + error = _deserialize(_models.ErrorResponse, response.json()) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["X-RequestId"] = self._deserialize("str", response.headers.get("X-RequestId")) + response_headers["x-mt-system"] = self._deserialize("str", response.headers.get("x-mt-system")) + response_headers["x-metered-usage"] = self._deserialize("int", response.headers.get("x-metered-usage")) + + deserialized = _deserialize(List[_models.TranslatedTextItem], response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + async def transliterate( + self, + content: List[_models.InputTextItem], + *, + language: str, + from_script: str, + to_script: str, + client_trace_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.TransliteratedText]: + """Transliterate Text. + + Transliterate Text. + + :param content: Array of the text to be transliterated. Required. + :type content: list[~azure.ai.translation.text.models.InputTextItem] + :keyword language: Specifies the language of the text to convert from one script to another. + Possible languages are listed in the transliteration scope obtained by querying the service + for its supported languages. Required. + :paramtype language: str + :keyword from_script: Specifies the script used by the input text. Look up supported languages + using the transliteration scope, + to find input scripts available for the selected language. Required. + :paramtype from_script: str + :keyword to_script: Specifies the output script. Look up supported languages using the + transliteration scope, to find output + scripts available for the selected combination of input language and input script. Required. + :paramtype to_script: str + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: list of TransliteratedText + :rtype: list[~azure.ai.translation.text.models.TransliteratedText] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def transliterate( + self, + content: IO, + *, + language: str, + from_script: str, + to_script: str, + client_trace_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.TransliteratedText]: + """Transliterate Text. + + Transliterate Text. + + :param content: Array of the text to be transliterated. Required. + :type content: IO + :keyword language: Specifies the language of the text to convert from one script to another. + Possible languages are listed in the transliteration scope obtained by querying the service + for its supported languages. Required. + :paramtype language: str + :keyword from_script: Specifies the script used by the input text. Look up supported languages + using the transliteration scope, + to find input scripts available for the selected language. Required. + :paramtype from_script: str + :keyword to_script: Specifies the output script. Look up supported languages using the + transliteration scope, to find output + scripts available for the selected combination of input language and input script. Required. + :paramtype to_script: str + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: list of TransliteratedText + :rtype: list[~azure.ai.translation.text.models.TransliteratedText] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def transliterate( + self, + content: Union[List[_models.InputTextItem], IO], + *, + language: str, + from_script: str, + to_script: str, + client_trace_id: Optional[str] = None, + **kwargs: Any + ) -> List[_models.TransliteratedText]: + """Transliterate Text. + + Transliterate Text. + + :param content: Array of the text to be transliterated. Is either a [InputTextItem] type or a + IO type. Required. + :type content: list[~azure.ai.translation.text.models.InputTextItem] or IO + :keyword language: Specifies the language of the text to convert from one script to another. + Possible languages are listed in the transliteration scope obtained by querying the service + for its supported languages. Required. + :paramtype language: str + :keyword from_script: Specifies the script used by the input text. Look up supported languages + using the transliteration scope, + to find input scripts available for the selected language. Required. + :paramtype from_script: str + :keyword to_script: Specifies the output script. Look up supported languages using the + transliteration scope, to find output + scripts available for the selected combination of input language and input script. Required. + :paramtype to_script: str + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default + value is None. + :paramtype content_type: str + :return: list of TransliteratedText + :rtype: list[~azure.ai.translation.text.models.TransliteratedText] + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[List[_models.TransliteratedText]] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(content, (IO, bytes)): + _content = content + else: + _content = json.dumps(content, cls=AzureJSONEncoder) # type: ignore + + request = build_text_translation_transliterate_request( + language=language, + from_script=from_script, + to_script=to_script, + client_trace_id=client_trace_id, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + 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) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + request, stream=_stream, **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) + error = _deserialize(_models.ErrorResponse, response.json()) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["X-RequestId"] = self._deserialize("str", response.headers.get("X-RequestId")) + + deserialized = _deserialize(List[_models.TransliteratedText], response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + async def find_sentence_boundaries( + self, + content: List[_models.InputTextItem], + *, + client_trace_id: Optional[str] = None, + language: Optional[str] = None, + script: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.BreakSentenceItem]: + """Find Sentence Boundaries. + + Find Sentence Boundaries. + + :param content: Array of the text for which values the sentence boundaries will be calculated. + Required. + :type content: list[~azure.ai.translation.text.models.InputTextItem] + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword language: Language tag identifying the language of the input text. + If a code isn't specified, automatic language detection will be applied. Default value is + None. + :paramtype language: str + :keyword script: Script tag identifying the script used by the input text. + If a script isn't specified, the default script of the language will be assumed. Default value + is None. + :paramtype script: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: list of BreakSentenceItem + :rtype: list[~azure.ai.translation.text.models.BreakSentenceItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def find_sentence_boundaries( + self, + content: IO, + *, + client_trace_id: Optional[str] = None, + language: Optional[str] = None, + script: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.BreakSentenceItem]: + """Find Sentence Boundaries. + + Find Sentence Boundaries. + + :param content: Array of the text for which values the sentence boundaries will be calculated. + Required. + :type content: IO + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword language: Language tag identifying the language of the input text. + If a code isn't specified, automatic language detection will be applied. Default value is + None. + :paramtype language: str + :keyword script: Script tag identifying the script used by the input text. + If a script isn't specified, the default script of the language will be assumed. Default value + is None. + :paramtype script: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: list of BreakSentenceItem + :rtype: list[~azure.ai.translation.text.models.BreakSentenceItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def find_sentence_boundaries( + self, + content: Union[List[_models.InputTextItem], IO], + *, + client_trace_id: Optional[str] = None, + language: Optional[str] = None, + script: Optional[str] = None, + **kwargs: Any + ) -> List[_models.BreakSentenceItem]: + """Find Sentence Boundaries. + + Find Sentence Boundaries. + + :param content: Array of the text for which values the sentence boundaries will be calculated. + Is either a [InputTextItem] type or a IO type. Required. + :type content: list[~azure.ai.translation.text.models.InputTextItem] or IO + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword language: Language tag identifying the language of the input text. + If a code isn't specified, automatic language detection will be applied. Default value is + None. + :paramtype language: str + :keyword script: Script tag identifying the script used by the input text. + If a script isn't specified, the default script of the language will be assumed. Default value + is None. + :paramtype script: str + :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default + value is None. + :paramtype content_type: str + :return: list of BreakSentenceItem + :rtype: list[~azure.ai.translation.text.models.BreakSentenceItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[List[_models.BreakSentenceItem]] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(content, (IO, bytes)): + _content = content + else: + _content = json.dumps(content, cls=AzureJSONEncoder) # type: ignore + + request = build_text_translation_find_sentence_boundaries_request( + client_trace_id=client_trace_id, + language=language, + script=script, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + 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) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + request, stream=_stream, **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) + error = _deserialize(_models.ErrorResponse, response.json()) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["X-RequestId"] = self._deserialize("str", response.headers.get("X-RequestId")) + + deserialized = _deserialize(List[_models.BreakSentenceItem], response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + async def lookup_dictionary_entries( + self, + content: List[_models.InputTextItem], + *, + from_parameter: str, + to: str, + client_trace_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.DictionaryLookupItem]: + """Lookup Dictionary Entries. + + Lookup Dictionary Entries. + + :param content: Array of the text to be sent to dictionary. Required. + :type content: list[~azure.ai.translation.text.models.InputTextItem] + :keyword from_parameter: Specifies the language of the input text. + The source language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype from_parameter: str + :keyword to: Specifies the language of the output text. + The target language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype to: str + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: list of DictionaryLookupItem + :rtype: list[~azure.ai.translation.text.models.DictionaryLookupItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def lookup_dictionary_entries( + self, + content: IO, + *, + from_parameter: str, + to: str, + client_trace_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.DictionaryLookupItem]: + """Lookup Dictionary Entries. + + Lookup Dictionary Entries. + + :param content: Array of the text to be sent to dictionary. Required. + :type content: IO + :keyword from_parameter: Specifies the language of the input text. + The source language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype from_parameter: str + :keyword to: Specifies the language of the output text. + The target language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype to: str + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: list of DictionaryLookupItem + :rtype: list[~azure.ai.translation.text.models.DictionaryLookupItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def lookup_dictionary_entries( + self, + content: Union[List[_models.InputTextItem], IO], + *, + from_parameter: str, + to: str, + client_trace_id: Optional[str] = None, + **kwargs: Any + ) -> List[_models.DictionaryLookupItem]: + """Lookup Dictionary Entries. + + Lookup Dictionary Entries. + + :param content: Array of the text to be sent to dictionary. Is either a [InputTextItem] type or + a IO type. Required. + :type content: list[~azure.ai.translation.text.models.InputTextItem] or IO + :keyword from_parameter: Specifies the language of the input text. + The source language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype from_parameter: str + :keyword to: Specifies the language of the output text. + The target language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype to: str + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default + value is None. + :paramtype content_type: str + :return: list of DictionaryLookupItem + :rtype: list[~azure.ai.translation.text.models.DictionaryLookupItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[List[_models.DictionaryLookupItem]] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(content, (IO, bytes)): + _content = content + else: + _content = json.dumps(content, cls=AzureJSONEncoder) # type: ignore + + request = build_text_translation_lookup_dictionary_entries_request( + from_parameter=from_parameter, + to=to, + client_trace_id=client_trace_id, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + 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) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + request, stream=_stream, **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) + error = _deserialize(_models.ErrorResponse, response.json()) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["X-RequestId"] = self._deserialize("str", response.headers.get("X-RequestId")) + + deserialized = _deserialize(List[_models.DictionaryLookupItem], response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore + + @overload + async def lookup_dictionary_examples( + self, + content: List[_models.DictionaryExampleTextItem], + *, + from_parameter: str, + to: str, + client_trace_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.DictionaryExampleItem]: + """Lookup Dictionary Examples. + + Lookup Dictionary Examples. + + :param content: Array of the text to be sent to dictionary. Required. + :type content: list[~azure.ai.translation.text.models.DictionaryExampleTextItem] + :keyword from_parameter: Specifies the language of the input text. + The source language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype from_parameter: str + :keyword to: Specifies the language of the output text. + The target language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype to: str + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: list of DictionaryExampleItem + :rtype: list[~azure.ai.translation.text.models.DictionaryExampleItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def lookup_dictionary_examples( + self, + content: IO, + *, + from_parameter: str, + to: str, + client_trace_id: Optional[str] = None, + content_type: str = "application/json", + **kwargs: Any + ) -> List[_models.DictionaryExampleItem]: + """Lookup Dictionary Examples. + + Lookup Dictionary Examples. + + :param content: Array of the text to be sent to dictionary. Required. + :type content: IO + :keyword from_parameter: Specifies the language of the input text. + The source language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype from_parameter: str + :keyword to: Specifies the language of the output text. + The target language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype to: str + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: list of DictionaryExampleItem + :rtype: list[~azure.ai.translation.text.models.DictionaryExampleItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def lookup_dictionary_examples( + self, + content: Union[List[_models.DictionaryExampleTextItem], IO], + *, + from_parameter: str, + to: str, + client_trace_id: Optional[str] = None, + **kwargs: Any + ) -> List[_models.DictionaryExampleItem]: + """Lookup Dictionary Examples. + + Lookup Dictionary Examples. + + :param content: Array of the text to be sent to dictionary. Is either a + [DictionaryExampleTextItem] type or a IO type. Required. + :type content: list[~azure.ai.translation.text.models.DictionaryExampleTextItem] or IO + :keyword from_parameter: Specifies the language of the input text. + The source language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype from_parameter: str + :keyword to: Specifies the language of the output text. + The target language must be one of the supported languages included in the dictionary scope. + Required. + :paramtype to: str + :keyword client_trace_id: A client-generated GUID to uniquely identify the request. Default + value is None. + :paramtype client_trace_id: str + :keyword content_type: Body parameter Content-Type. Known values are: application/json. Default + value is None. + :paramtype content_type: str + :return: list of DictionaryExampleItem + :rtype: list[~azure.ai.translation.text.models.DictionaryExampleItem] + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[List[_models.DictionaryExampleItem]] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(content, (IO, bytes)): + _content = content + else: + _content = json.dumps(content, cls=AzureJSONEncoder) # type: ignore + + request = build_text_translation_lookup_dictionary_examples_request( + from_parameter=from_parameter, + to=to, + client_trace_id=client_trace_id, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + 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) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + request, stream=_stream, **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) + error = _deserialize(_models.ErrorResponse, response.json()) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["X-RequestId"] = self._deserialize("str", response.headers.get("X-RequestId")) + + deserialized = _deserialize(List[_models.DictionaryExampleItem], response.json()) + + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + + return deserialized # type: ignore diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_operations/_patch.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_operations/_patch.py new file mode 100644 index 000000000000..f7dd32510333 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_operations/_patch.py @@ -0,0 +1,20 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +"""Customize generated code here. + +Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize +""" +from typing import List + +__all__: List[str] = [] # Add all objects you want publicly available to users at this package level + + +def patch_sdk(): + """Do not remove from this file. + + `patch_sdk` is a last resort escape hatch that allows you to do customizations + you can't accomplish using the techniques described in + https://aka.ms/azsdk/python/dpcodegen/python/customize + """ diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_patch.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_patch.py new file mode 100644 index 000000000000..dc0163493ef8 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_patch.py @@ -0,0 +1,103 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +"""Customize generated code here. + +Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize +""" +from typing import ( Union, Optional ) +from azure.core.pipeline.policies import ( AsyncBearerTokenCredentialPolicy, AzureKeyCredentialPolicy ) +from azure.core.credentials import AzureKeyCredential +from azure.core.credentials_async import AsyncTokenCredential + +from .._patch import ( + DEFAULT_TOKEN_SCOPE, + get_translation_endpoint, + TranslatorAuthenticationPolicy, + TranslatorCredential +) + +from ._client import TextTranslationClient as ServiceClientGenerated + +def patch_sdk(): + """Do not remove from this file. + + `patch_sdk` is a last resort escape hatch that allows you to do customizations + you can't accomplish using the techniques described in + https://aka.ms/azsdk/python/dpcodegen/python/customize + """ + +def set_authentication_policy(credential, kwargs): + if isinstance(credential, TranslatorCredential): + if not kwargs.get("authentication_policy"): + kwargs["authentication_policy"] = TranslatorAuthenticationPolicy(credential) + elif isinstance(credential, AzureKeyCredential): + if not kwargs.get("authentication_policy"): + kwargs["authentication_policy"] = AzureKeyCredentialPolicy( + name="Ocp-Apim-Subscription-Key", credential=credential) + elif hasattr(credential, "get_token"): + if not kwargs.get("authentication_policy"): + kwargs["authentication_policy"] = AsyncBearerTokenCredentialPolicy(credential, *kwargs.pop("credential_scopes", [DEFAULT_TOKEN_SCOPE]), kwargs) + +class TextTranslationClient(ServiceClientGenerated): + """Text translation is a cloud-based REST API feature of the Translator service that uses neural + machine translation technology to enable quick and accurate source-to-target text translation + in real time across all supported languages. + + The following methods are supported by the Text Translation feature: + + Languages. Returns a list of languages supported by Translate, Transliterate, and Dictionary + Lookup operations. + + Translate. Renders single source-language text to multiple target-language texts with a single + request. + + Transliterate. Converts characters or letters of a source language to the corresponding + characters or letters of a target language. + + Detect. Returns the source code language code and a boolean variable denoting whether the + detected language is supported for text translation and transliteration. + + Dictionary lookup. Returns equivalent words for the source term in the target language. + + Dictionary example Returns grammatical structure and context examples for the source term and + target term pair. + + Combinations of endpoint and credential values: + str + AzureKeyCredential - used custom domain translator endpoint + str + TokenCredential - used for regional endpoint with token authentication + str + TranslatorCredential - used for National Clouds + None + AzureKeyCredential - used for global translator endpoint with global Translator resource + None + Token - general translator endpoint with token authentication + None + TranslatorCredential - general translator endpoint with regional Translator resource + + :param endpoint: Supported Text Translation endpoints (protocol and hostname, for example: + https://api.cognitive.microsofttranslator.com). Required. + :type endpoint: str + :param credential: Credential used to authenticate with the Translator service + :type credential: Union[AzureKeyCredential , AsyncTokenCredential , TranslatorCredential] + :keyword api_version: Default value is "3.0". Note that overriding this default value may + result in unsupported behavior. + :paramtype api_version: str + """ + def __init__( + self, + credential: Union[AzureKeyCredential , AsyncTokenCredential , TranslatorCredential], + *, + endpoint: Optional[str] = None, + api_version = "3.0", + **kwargs): + + set_authentication_policy(credential, kwargs) + + translation_endpoint = get_translation_endpoint(endpoint, api_version) + + super().__init__( + endpoint=translation_endpoint, + api_version=api_version, + **kwargs + ) + + +__all__ = ["TextTranslationClient"] diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_vendor.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_vendor.py new file mode 100644 index 000000000000..8b610f67bd27 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/aio/_vendor.py @@ -0,0 +1,26 @@ +# -------------------------------------------------------------------------- +# 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) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from abc import ABC +from typing import TYPE_CHECKING + +from ._configuration import TextTranslationClientConfiguration + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from azure.core import AsyncPipelineClient + + from .._serialization import Deserializer, Serializer + + +class TextTranslationClientMixinABC(ABC): + """DO NOT use this class. It is for internal typing use only.""" + + _client: "AsyncPipelineClient" + _config: TextTranslationClientConfiguration + _serialize: "Serializer" + _deserialize: "Deserializer" diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/models/__init__.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/models/__init__.py new file mode 100644 index 000000000000..3f7702d81681 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/models/__init__.py @@ -0,0 +1,73 @@ +# 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) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._models import BackTranslation +from ._models import BreakSentenceItem +from ._models import CommonScriptModel +from ._models import DetectedLanguage +from ._models import DictionaryExample +from ._models import DictionaryExampleItem +from ._models import DictionaryExampleTextItem +from ._models import DictionaryLookupItem +from ._models import DictionaryTranslation +from ._models import ErrorDetails +from ._models import ErrorResponse +from ._models import GetLanguagesResult +from ._models import InputTextItem +from ._models import SentenceLength +from ._models import SourceDictionaryLanguage +from ._models import SourceText +from ._models import TargetDictionaryLanguage +from ._models import TranslatedTextAlignment +from ._models import TranslatedTextItem +from ._models import Translation +from ._models import TranslationLanguage +from ._models import TransliterableScript +from ._models import TransliteratedText +from ._models import Transliteration +from ._models import TransliterationLanguage + +from ._enums import ProfanityAction +from ._enums import ProfanityMarker +from ._enums import TextType +from ._patch import __all__ as _patch_all +from ._patch import * # pylint: disable=unused-wildcard-import +from ._patch import patch_sdk as _patch_sdk + +__all__ = [ + "BackTranslation", + "BreakSentenceItem", + "CommonScriptModel", + "DetectedLanguage", + "DictionaryExample", + "DictionaryExampleItem", + "DictionaryExampleTextItem", + "DictionaryLookupItem", + "DictionaryTranslation", + "ErrorDetails", + "ErrorResponse", + "GetLanguagesResult", + "InputTextItem", + "SentenceLength", + "SourceDictionaryLanguage", + "SourceText", + "TargetDictionaryLanguage", + "TranslatedTextAlignment", + "TranslatedTextItem", + "Translation", + "TranslationLanguage", + "TransliterableScript", + "TransliteratedText", + "Transliteration", + "TransliterationLanguage", + "ProfanityAction", + "ProfanityMarker", + "TextType", +] +__all__.extend([p for p in _patch_all if p not in __all__]) +_patch_sdk() diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/models/_enums.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/models/_enums.py new file mode 100644 index 000000000000..13da2925e220 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/models/_enums.py @@ -0,0 +1,32 @@ +# 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) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from enum import Enum +from azure.core import CaseInsensitiveEnumMeta + + +class ProfanityAction(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Translator profanity actions.""" + + NO_ACTION = "NoAction" + MARKED = "Marked" + DELETED = "Deleted" + + +class ProfanityMarker(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Translator profanity markers.""" + + ASTERISK = "Asterisk" + TAG = "Tag" + + +class TextType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """Translation text type.""" + + PLAIN = "plain" + HTML = "html" diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/models/_models.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/models/_models.py new file mode 100644 index 000000000000..98ad4345885c --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/models/_models.py @@ -0,0 +1,1185 @@ +# coding=utf-8 +# pylint: disable=too-many-lines +# -------------------------------------------------------------------------- +# 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) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import Any, Dict, List, Mapping, Optional, TYPE_CHECKING, overload + +from .. import _model_base +from .._model_base import rest_field + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from .. import models as _models + + +class BackTranslation(_model_base.Model): + """Back Translation. + + All required parameters must be populated in order to send to Azure. + + :ivar normalized_text: A string giving the normalized form of the source term that is a + back-translation of the target. + This value should be used as input to lookup examples. Required. + :vartype normalized_text: str + :ivar display_text: A string giving the source term that is a back-translation of the target in + a form best + suited for end-user display. Required. + :vartype display_text: str + :ivar num_examples: An integer representing the number of examples that are available for this + translation pair. + Actual examples must be retrieved with a separate call to lookup examples. The number is + mostly + intended to facilitate display in a UX. For example, a user interface may add a hyperlink + to the back-translation if the number of examples is greater than zero and show the + back-translation + as plain text if there are no examples. Note that the actual number of examples returned + by a call to lookup examples may be less than numExamples, because additional filtering may be + applied on the fly to remove "bad" examples. Required. + :vartype num_examples: int + :ivar frequency_count: An integer representing the frequency of this translation pair in the + data. The main purpose of this + field is to provide a user interface with a means to sort back-translations so the most + frequent terms are first. Required. + :vartype frequency_count: int + """ + + normalized_text: str = rest_field(name="normalizedText") + """A string giving the normalized form of the source term that is a back-translation of the target. +This value should be used as input to lookup examples. Required. """ + display_text: str = rest_field(name="displayText") + """A string giving the source term that is a back-translation of the target in a form best +suited for end-user display. Required. """ + num_examples: int = rest_field(name="numExamples") + """An integer representing the number of examples that are available for this translation pair. +Actual examples must be retrieved with a separate call to lookup examples. The number is mostly +intended to facilitate display in a UX. For example, a user interface may add a hyperlink +to the back-translation if the number of examples is greater than zero and show the back-translation +as plain text if there are no examples. Note that the actual number of examples returned +by a call to lookup examples may be less than numExamples, because additional filtering may be +applied on the fly to remove \"bad\" examples. Required. """ + frequency_count: int = rest_field(name="frequencyCount") + """An integer representing the frequency of this translation pair in the data. The main purpose of this +field is to provide a user interface with a means to sort back-translations so the most frequent terms are first. Required. """ + + @overload + def __init__( + self, + *, + normalized_text: str, + display_text: str, + num_examples: int, + frequency_count: int, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class BreakSentenceItem(_model_base.Model): + """Item containing break sentence result. + + All required parameters must be populated in order to send to Azure. + + :ivar detected_language: The detectedLanguage property is only present in the result object + when language auto-detection is requested. + :vartype detected_language: ~azure.ai.translation.text.models.DetectedLanguage + :ivar sent_len: An integer array representing the lengths of the sentences in the input text. + The length of the array is the number of sentences, and the values are the length of each + sentence. Required. + :vartype sent_len: list[int] + """ + + detected_language: Optional["_models.DetectedLanguage"] = rest_field(name="detectedLanguage") + """The detectedLanguage property is only present in the result object when language auto-detection is requested. """ + sent_len: List[int] = rest_field(name="sentLen") + """An integer array representing the lengths of the sentences in the input text. +The length of the array is the number of sentences, and the values are the length of each sentence. Required. """ + + @overload + def __init__( + self, + *, + sent_len: List[int], + detected_language: Optional["_models.DetectedLanguage"] = None, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class CommonScriptModel(_model_base.Model): + """Common properties of language script. + + All required parameters must be populated in order to send to Azure. + + :ivar code: Code identifying the script. Required. + :vartype code: str + :ivar name: Display name of the script in the locale requested via Accept-Language header. + Required. + :vartype name: str + :ivar native_name: Display name of the language in the locale native for the language. + Required. + :vartype native_name: str + :ivar dir: Directionality, which is rtl for right-to-left languages or ltr for left-to-right + languages. Required. + :vartype dir: str + """ + + code: str = rest_field() + """Code identifying the script. Required. """ + name: str = rest_field() + """Display name of the script in the locale requested via Accept-Language header. Required. """ + native_name: str = rest_field(name="nativeName") + """Display name of the language in the locale native for the language. Required. """ + dir: str = rest_field() + """Directionality, which is rtl for right-to-left languages or ltr for left-to-right languages. Required. """ + + @overload + def __init__( + self, + *, + code: str, + name: str, + native_name: str, + dir: str, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class DetectedLanguage(_model_base.Model): + """An object describing the detected language. + + All required parameters must be populated in order to send to Azure. + + :ivar language: A string representing the code of the detected language. Required. + :vartype language: str + :ivar score: A float value indicating the confidence in the result. + The score is between zero and one and a low score indicates a low confidence. Required. + :vartype score: float + """ + + language: str = rest_field() + """A string representing the code of the detected language. Required. """ + score: float = rest_field() + """A float value indicating the confidence in the result. +The score is between zero and one and a low score indicates a low confidence. Required. """ + + @overload + def __init__( + self, + *, + language: str, + score: float, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class DictionaryExample(_model_base.Model): + """Dictionary Example. + + All required parameters must be populated in order to send to Azure. + + :ivar source_prefix: The string to concatenate before the value of sourceTerm to form a + complete example. + Do not add a space character, since it is already there when it should be. + This value may be an empty string. Required. + :vartype source_prefix: str + :ivar source_term: A string equal to the actual term looked up. The string is added with + sourcePrefix + and sourceSuffix to form the complete example. Its value is separated so it can be + marked in a user interface, e.g., by bolding it. Required. + :vartype source_term: str + :ivar source_suffix: The string to concatenate after the value of sourceTerm to form a complete + example. + Do not add a space character, since it is already there when it should be. + This value may be an empty string. Required. + :vartype source_suffix: str + :ivar target_prefix: A string similar to sourcePrefix but for the target. Required. + :vartype target_prefix: str + :ivar target_term: A string similar to sourceTerm but for the target. Required. + :vartype target_term: str + :ivar target_suffix: A string similar to sourceSuffix but for the target. Required. + :vartype target_suffix: str + """ + + source_prefix: str = rest_field(name="sourcePrefix") + """The string to concatenate before the value of sourceTerm to form a complete example. +Do not add a space character, since it is already there when it should be. +This value may be an empty string. Required. """ + source_term: str = rest_field(name="sourceTerm") + """A string equal to the actual term looked up. The string is added with sourcePrefix +and sourceSuffix to form the complete example. Its value is separated so it can be +marked in a user interface, e.g., by bolding it. Required. """ + source_suffix: str = rest_field(name="sourceSuffix") + """The string to concatenate after the value of sourceTerm to form a complete example. +Do not add a space character, since it is already there when it should be. +This value may be an empty string. Required. """ + target_prefix: str = rest_field(name="targetPrefix") + """A string similar to sourcePrefix but for the target. Required. """ + target_term: str = rest_field(name="targetTerm") + """A string similar to sourceTerm but for the target. Required. """ + target_suffix: str = rest_field(name="targetSuffix") + """A string similar to sourceSuffix but for the target. Required. """ + + @overload + def __init__( + self, + *, + source_prefix: str, + source_term: str, + source_suffix: str, + target_prefix: str, + target_term: str, + target_suffix: str, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class DictionaryExampleItem(_model_base.Model): + """Dictionary Example element. + + All required parameters must be populated in order to send to Azure. + + :ivar normalized_source: A string giving the normalized form of the source term. Generally, + this should be identical + to the value of the Text field at the matching list index in the body of the request. + Required. + :vartype normalized_source: str + :ivar normalized_target: A string giving the normalized form of the target term. Generally, + this should be identical + to the value of the Translation field at the matching list index in the body of the request. + Required. + :vartype normalized_target: str + :ivar examples: A list of examples for the (source term, target term) pair. Required. + :vartype examples: list[~azure.ai.translation.text.models.DictionaryExample] + """ + + normalized_source: str = rest_field(name="normalizedSource") + """A string giving the normalized form of the source term. Generally, this should be identical +to the value of the Text field at the matching list index in the body of the request. Required. """ + normalized_target: str = rest_field(name="normalizedTarget") + """A string giving the normalized form of the target term. Generally, this should be identical +to the value of the Translation field at the matching list index in the body of the request. Required. """ + examples: List["_models.DictionaryExample"] = rest_field() + """A list of examples for the (source term, target term) pair. Required. """ + + @overload + def __init__( + self, + *, + normalized_source: str, + normalized_target: str, + examples: List["_models.DictionaryExample"], + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class InputTextItem(_model_base.Model): + """Element containing the text for translation. + + All required parameters must be populated in order to send to Azure. + + :ivar text: Text to translate. Required. + :vartype text: str + """ + + text: str = rest_field() + """Text to translate. Required. """ + + @overload + def __init__( + self, + *, + text: str, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class DictionaryExampleTextItem(InputTextItem): + """Element containing the text with translation. + + All required parameters must be populated in order to send to Azure. + + :ivar text: Text to translate. Required. + :vartype text: str + :ivar translation: A string specifying the translated text previously returned by the + Dictionary lookup operation. + This should be the value from the normalizedTarget field in the translations list of the + Dictionary + lookup response. The service will return examples for the specific source-target word-pair. + Required. + :vartype translation: str + """ + + translation: str = rest_field() + """A string specifying the translated text previously returned by the Dictionary lookup operation. +This should be the value from the normalizedTarget field in the translations list of the Dictionary +lookup response. The service will return examples for the specific source-target word-pair. Required. """ + + @overload + def __init__( + self, + *, + text: str, + translation: str, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class DictionaryLookupItem(_model_base.Model): + """Dictionary Lookup Element. + + All required parameters must be populated in order to send to Azure. + + :ivar normalized_source: A string giving the normalized form of the source term. + For example, if the request is "JOHN", the normalized form will be "john". + The content of this field becomes the input to lookup examples. Required. + :vartype normalized_source: str + :ivar display_source: A string giving the source term in a form best suited for end-user + display. + For example, if the input is "JOHN", the display form will reflect the usual + spelling of the name: "John". Required. + :vartype display_source: str + :ivar translations: A list of translations for the source term. Required. + :vartype translations: list[~azure.ai.translation.text.models.DictionaryTranslation] + """ + + normalized_source: str = rest_field(name="normalizedSource") + """A string giving the normalized form of the source term. +For example, if the request is \"JOHN\", the normalized form will be \"john\". +The content of this field becomes the input to lookup examples. Required. """ + display_source: str = rest_field(name="displaySource") + """A string giving the source term in a form best suited for end-user display. +For example, if the input is \"JOHN\", the display form will reflect the usual +spelling of the name: \"John\". Required. """ + translations: List["_models.DictionaryTranslation"] = rest_field() + """A list of translations for the source term. Required. """ + + @overload + def __init__( + self, + *, + normalized_source: str, + display_source: str, + translations: List["_models.DictionaryTranslation"], + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class DictionaryTranslation(_model_base.Model): + """Translation source term. + + All required parameters must be populated in order to send to Azure. + + :ivar normalized_target: A string giving the normalized form of this term in the target + language. + This value should be used as input to lookup examples. Required. + :vartype normalized_target: str + :ivar display_target: A string giving the term in the target language and in a form best suited + for end-user display. Generally, this will only differ from the normalizedTarget + in terms of capitalization. For example, a proper noun like "Juan" will have + normalizedTarget = "juan" and displayTarget = "Juan". Required. + :vartype display_target: str + :ivar pos_tag: A string associating this term with a part-of-speech tag. Required. + :vartype pos_tag: str + :ivar confidence: A value between 0.0 and 1.0 which represents the "confidence" + (or perhaps more accurately, "probability in the training data") of that translation pair. + The sum of confidence scores for one source word may or may not sum to 1.0. Required. + :vartype confidence: float + :ivar prefix_word: A string giving the word to display as a prefix of the translation. + Currently, + this is the gendered determiner of nouns, in languages that have gendered determiners. + For example, the prefix of the Spanish word "mosca" is "la", since "mosca" is a feminine noun + in Spanish. + This is only dependent on the translation, and not on the source. + If there is no prefix, it will be the empty string. Required. + :vartype prefix_word: str + :ivar back_translations: A list of "back translations" of the target. For example, source words + that the target can translate to. + The list is guaranteed to contain the source word that was requested (e.g., if the source word + being + looked up is "fly", then it is guaranteed that "fly" will be in the backTranslations list). + However, it is not guaranteed to be in the first position, and often will not be. Required. + :vartype back_translations: list[~azure.ai.translation.text.models.BackTranslation] + """ + + normalized_target: str = rest_field(name="normalizedTarget") + """A string giving the normalized form of this term in the target language. +This value should be used as input to lookup examples. Required. """ + display_target: str = rest_field(name="displayTarget") + """A string giving the term in the target language and in a form best suited +for end-user display. Generally, this will only differ from the normalizedTarget +in terms of capitalization. For example, a proper noun like \"Juan\" will have +normalizedTarget = \"juan\" and displayTarget = \"Juan\". Required. """ + pos_tag: str = rest_field(name="posTag") + """A string associating this term with a part-of-speech tag. Required. """ + confidence: float = rest_field() + """A value between 0.0 and 1.0 which represents the \"confidence\" +(or perhaps more accurately, \"probability in the training data\") of that translation pair. +The sum of confidence scores for one source word may or may not sum to 1.0. Required. """ + prefix_word: str = rest_field(name="prefixWord") + """A string giving the word to display as a prefix of the translation. Currently, +this is the gendered determiner of nouns, in languages that have gendered determiners. +For example, the prefix of the Spanish word \"mosca\" is \"la\", since \"mosca\" is a feminine noun in Spanish. +This is only dependent on the translation, and not on the source. +If there is no prefix, it will be the empty string. Required. """ + back_translations: List["_models.BackTranslation"] = rest_field(name="backTranslations") + """A list of \"back translations\" of the target. For example, source words that the target can translate to. +The list is guaranteed to contain the source word that was requested (e.g., if the source word being +looked up is \"fly\", then it is guaranteed that \"fly\" will be in the backTranslations list). +However, it is not guaranteed to be in the first position, and often will not be. Required. """ + + @overload + def __init__( + self, + *, + normalized_target: str, + display_target: str, + pos_tag: str, + confidence: float, + prefix_word: str, + back_translations: List["_models.BackTranslation"], + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class ErrorDetails(_model_base.Model): + """Error details as returned by Translator Service. + + All required parameters must be populated in order to send to Azure. + + :ivar code: Number identifier of the error. Required. + :vartype code: int + :ivar message: Human readable error description. Required. + :vartype message: str + """ + + code: int = rest_field() + """Number identifier of the error. Required. """ + message: str = rest_field() + """Human readable error description. Required. """ + + @overload + def __init__( + self, + *, + code: int, + message: str, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class ErrorResponse(_model_base.Model): + """Representation of the Error Response from Translator Service. + + All required parameters must be populated in order to send to Azure. + + :ivar error: Error details. Required. + :vartype error: ~azure.ai.translation.text.models.ErrorDetails + """ + + error: "_models.ErrorDetails" = rest_field() + """Error details. Required. """ + + @overload + def __init__( + self, + *, + error: "_models.ErrorDetails", + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class GetLanguagesResult(_model_base.Model): + """Response for the languages API. + + :ivar translation: Languages that support translate API. + :vartype translation: dict[str, ~azure.ai.translation.text.models.TranslationLanguage] + :ivar transliteration: Languages that support transliteration API. + :vartype transliteration: dict[str, ~azure.ai.translation.text.models.TransliterationLanguage] + :ivar dictionary: Languages that support dictionary API. + :vartype dictionary: dict[str, ~azure.ai.translation.text.models.SourceDictionaryLanguage] + """ + + translation: Optional[Dict[str, "_models.TranslationLanguage"]] = rest_field() + """Languages that support translate API. """ + transliteration: Optional[Dict[str, "_models.TransliterationLanguage"]] = rest_field() + """Languages that support transliteration API. """ + dictionary: Optional[Dict[str, "_models.SourceDictionaryLanguage"]] = rest_field() + """Languages that support dictionary API. """ + + @overload + def __init__( + self, + *, + translation: Optional[Dict[str, "_models.TranslationLanguage"]] = None, + transliteration: Optional[Dict[str, "_models.TransliterationLanguage"]] = None, + dictionary: Optional[Dict[str, "_models.SourceDictionaryLanguage"]] = None, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class SentenceLength(_model_base.Model): + """An object returning sentence boundaries in the input and output texts. + + All required parameters must be populated in order to send to Azure. + + :ivar src_sent_len: An integer array representing the lengths of the sentences in the input + text. + The length of the array is the number of sentences, and the values are the length of each + sentence. Required. + :vartype src_sent_len: list[int] + :ivar trans_sent_len: An integer array representing the lengths of the sentences in the + translated text. + The length of the array is the number of sentences, and the values are the length of each + sentence. Required. + :vartype trans_sent_len: list[int] + """ + + src_sent_len: List[int] = rest_field(name="srcSentLen") + """An integer array representing the lengths of the sentences in the input text. +The length of the array is the number of sentences, and the values are the length of each sentence. Required. """ + trans_sent_len: List[int] = rest_field(name="transSentLen") + """An integer array representing the lengths of the sentences in the translated text. +The length of the array is the number of sentences, and the values are the length of each sentence. Required. """ + + @overload + def __init__( + self, + *, + src_sent_len: List[int], + trans_sent_len: List[int], + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class SourceDictionaryLanguage(_model_base.Model): + """Properties ot the source dictionary language. + + All required parameters must be populated in order to send to Azure. + + :ivar name: Display name of the language in the locale requested via Accept-Language header. + Required. + :vartype name: str + :ivar native_name: Display name of the language in the locale native for this language. + Required. + :vartype native_name: str + :ivar dir: Directionality, which is rtl for right-to-left languages or ltr for left-to-right + languages. Required. + :vartype dir: str + :ivar translations: List of languages with alterative translations and examples for the query + expressed in the source language. Required. + :vartype translations: list[~azure.ai.translation.text.models.TargetDictionaryLanguage] + """ + + name: str = rest_field() + """Display name of the language in the locale requested via Accept-Language header. Required. """ + native_name: str = rest_field(name="nativeName") + """Display name of the language in the locale native for this language. Required. """ + dir: str = rest_field() + """Directionality, which is rtl for right-to-left languages or ltr for left-to-right languages. Required. """ + translations: List["_models.TargetDictionaryLanguage"] = rest_field() + """List of languages with alterative translations and examples for the query expressed in the source language. Required. """ + + @overload + def __init__( + self, + *, + name: str, + native_name: str, + dir: str, + translations: List["_models.TargetDictionaryLanguage"], + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class SourceText(_model_base.Model): + """Input text in the default script of the source language. + + All required parameters must be populated in order to send to Azure. + + :ivar text: Input text in the default script of the source language. Required. + :vartype text: str + """ + + text: str = rest_field() + """Input text in the default script of the source language. Required. """ + + @overload + def __init__( + self, + *, + text: str, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class TargetDictionaryLanguage(_model_base.Model): + """Properties of the target dictionary language. + + All required parameters must be populated in order to send to Azure. + + :ivar name: Display name of the language in the locale requested via Accept-Language header. + Required. + :vartype name: str + :ivar native_name: Display name of the language in the locale native for this language. + Required. + :vartype native_name: str + :ivar dir: Directionality, which is rtl for right-to-left languages or ltr for left-to-right + languages. Required. + :vartype dir: str + :ivar code: Language code identifying the target language. Required. + :vartype code: str + """ + + name: str = rest_field() + """Display name of the language in the locale requested via Accept-Language header. Required. """ + native_name: str = rest_field(name="nativeName") + """Display name of the language in the locale native for this language. Required. """ + dir: str = rest_field() + """Directionality, which is rtl for right-to-left languages or ltr for left-to-right languages. Required. """ + code: str = rest_field() + """Language code identifying the target language. Required. """ + + @overload + def __init__( + self, + *, + name: str, + native_name: str, + dir: str, + code: str, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class TranslatedTextAlignment(_model_base.Model): + """Alignment information object. + + All required parameters must be populated in order to send to Azure. + + :ivar proj: Maps input text to translated text. The alignment information is only provided when + the request + parameter includeAlignment is true. Alignment is returned as a string value of the following + format: [[SourceTextStartIndex]:[SourceTextEndIndex]–[TgtTextStartIndex]:[TgtTextEndIndex]]. + The colon separates start and end index, the dash separates the languages, and space separates + the words. + One word may align with zero, one, or multiple words in the other language, and the aligned + words may + be non-contiguous. When no alignment information is available, the alignment element will be + empty. Required. + :vartype proj: str + """ + + proj: str = rest_field() + """Maps input text to translated text. The alignment information is only provided when the request +parameter includeAlignment is true. Alignment is returned as a string value of the following +format: [[SourceTextStartIndex]:[SourceTextEndIndex]–[TgtTextStartIndex]:[TgtTextEndIndex]]. +The colon separates start and end index, the dash separates the languages, and space separates the words. +One word may align with zero, one, or multiple words in the other language, and the aligned words may +be non-contiguous. When no alignment information is available, the alignment element will be empty. Required. """ + + @overload + def __init__( + self, + *, + proj: str, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class TranslatedTextItem(_model_base.Model): + """Element containing the translated text. + + All required parameters must be populated in order to send to Azure. + + :ivar detected_language: The detectedLanguage property is only present in the result object + when language auto-detection is requested. + :vartype detected_language: ~azure.ai.translation.text.models.DetectedLanguage + :ivar translations: An array of translation results. The size of the array matches the number + of target + languages specified through the to query parameter. Required. + :vartype translations: list[~azure.ai.translation.text.models.Translation] + :ivar source_text: Input text in the default script of the source language. sourceText property + is present only when + the input is expressed in a script that's not the usual script for the language. For example, + if the input were Arabic written in Latin script, then sourceText.text would be the same + Arabic text + converted into Arab script. + :vartype source_text: ~azure.ai.translation.text.models.SourceText + """ + + detected_language: Optional["_models.DetectedLanguage"] = rest_field(name="detectedLanguage") + """The detectedLanguage property is only present in the result object when language auto-detection is requested. """ + translations: List["_models.Translation"] = rest_field() + """An array of translation results. The size of the array matches the number of target +languages specified through the to query parameter. Required. """ + source_text: Optional["_models.SourceText"] = rest_field(name="sourceText") + """Input text in the default script of the source language. sourceText property is present only when +the input is expressed in a script that's not the usual script for the language. For example, +if the input were Arabic written in Latin script, then sourceText.text would be the same Arabic text +converted into Arab script. """ + + @overload + def __init__( + self, + *, + translations: List["_models.Translation"], + detected_language: Optional["_models.DetectedLanguage"] = None, + source_text: Optional["_models.SourceText"] = None, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class Translation(_model_base.Model): + """Translation result. + + All required parameters must be populated in order to send to Azure. + + :ivar to: A string representing the language code of the target language. Required. + :vartype to: str + :ivar text: A string giving the translated text. Required. + :vartype text: str + :ivar transliteration: An object giving the translated text in the script specified by the + toScript parameter. + :vartype transliteration: ~azure.ai.translation.text.models.Transliteration + :ivar alignment: Alignment information. + :vartype alignment: ~azure.ai.translation.text.models.TranslatedTextAlignment + :ivar sent_len: Sentence boundaries in the input and output texts. + :vartype sent_len: ~azure.ai.translation.text.models.SentenceLength + """ + + to: str = rest_field() + """A string representing the language code of the target language. Required. """ + text: str = rest_field() + """A string giving the translated text. Required. """ + transliteration: Optional["_models.Transliteration"] = rest_field() + """An object giving the translated text in the script specified by the toScript parameter. """ + alignment: Optional["_models.TranslatedTextAlignment"] = rest_field() + """Alignment information. """ + sent_len: Optional["_models.SentenceLength"] = rest_field(name="sentLen") + """Sentence boundaries in the input and output texts. """ + + @overload + def __init__( + self, + *, + to: str, + text: str, + transliteration: Optional["_models.Transliteration"] = None, + alignment: Optional["_models.TranslatedTextAlignment"] = None, + sent_len: Optional["_models.SentenceLength"] = None, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class TranslationLanguage(_model_base.Model): + """The value of the translation property is a dictionary of (key, value) pairs. Each key is a BCP + 47 language tag. + A key identifies a language for which text can be translated to or translated from. + + All required parameters must be populated in order to send to Azure. + + :ivar name: Display name of the language in the locale requested via Accept-Language header. + Required. + :vartype name: str + :ivar native_name: Display name of the language in the locale native for this language. + Required. + :vartype native_name: str + :ivar dir: Directionality, which is rtl for right-to-left languages or ltr for left-to-right + languages. Required. + :vartype dir: str + """ + + name: str = rest_field() + """Display name of the language in the locale requested via Accept-Language header. Required. """ + native_name: str = rest_field(name="nativeName") + """Display name of the language in the locale native for this language. Required. """ + dir: str = rest_field() + """Directionality, which is rtl for right-to-left languages or ltr for left-to-right languages. Required. """ + + @overload + def __init__( + self, + *, + name: str, + native_name: str, + dir: str, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class TransliterableScript(CommonScriptModel): + """Script definition with list of script into which given script can be translitered. + + All required parameters must be populated in order to send to Azure. + + :ivar code: Code identifying the script. Required. + :vartype code: str + :ivar name: Display name of the script in the locale requested via Accept-Language header. + Required. + :vartype name: str + :ivar native_name: Display name of the language in the locale native for the language. + Required. + :vartype native_name: str + :ivar dir: Directionality, which is rtl for right-to-left languages or ltr for left-to-right + languages. Required. + :vartype dir: str + :ivar to_scripts: List of scripts available to convert text to. Required. + :vartype to_scripts: list[~azure.ai.translation.text.models.CommonScriptModel] + """ + + to_scripts: List["_models.CommonScriptModel"] = rest_field(name="toScripts") + """List of scripts available to convert text to. Required. """ + + @overload + def __init__( + self, + *, + code: str, + name: str, + native_name: str, + dir: str, + to_scripts: List["_models.CommonScriptModel"], + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class TransliteratedText(_model_base.Model): + """Transliterated text element. + + All required parameters must be populated in order to send to Azure. + + :ivar text: A string which is the result of converting the input string to the output script. + Required. + :vartype text: str + :ivar script: A string specifying the script used in the output. Required. + :vartype script: str + """ + + text: str = rest_field() + """A string which is the result of converting the input string to the output script. Required. """ + script: str = rest_field() + """A string specifying the script used in the output. Required. """ + + @overload + def __init__( + self, + *, + text: str, + script: str, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class Transliteration(_model_base.Model): + """An object giving the translated text in the script specified by the toScript parameter. + + All required parameters must be populated in order to send to Azure. + + :ivar script: A string specifying the target script. Required. + :vartype script: str + :ivar text: A string giving the translated text in the target script. Required. + :vartype text: str + """ + + script: str = rest_field() + """A string specifying the target script. Required. """ + text: str = rest_field() + """A string giving the translated text in the target script. Required. """ + + @overload + def __init__( + self, + *, + script: str, + text: str, + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) + + +class TransliterationLanguage(_model_base.Model): + """The value of the transliteration property is a dictionary of (key, value) pairs. + Each key is a BCP 47 language tag. A key identifies a language for which text can be converted + from one script + to another script. + + All required parameters must be populated in order to send to Azure. + + :ivar name: Display name of the language in the locale requested via Accept-Language header. + Required. + :vartype name: str + :ivar native_name: Display name of the language in the locale native for this language. + Required. + :vartype native_name: str + :ivar scripts: List of scripts to convert from. Required. + :vartype scripts: list[~azure.ai.translation.text.models.TransliterableScript] + """ + + name: str = rest_field() + """Display name of the language in the locale requested via Accept-Language header. Required. """ + native_name: str = rest_field(name="nativeName") + """Display name of the language in the locale native for this language. Required. """ + scripts: List["_models.TransliterableScript"] = rest_field() + """List of scripts to convert from. Required. """ + + @overload + def __init__( + self, + *, + name: str, + native_name: str, + scripts: List["_models.TransliterableScript"], + ): + ... + + @overload + def __init__(self, mapping: Mapping[str, Any]): + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: # pylint: disable=useless-super-delegation + super().__init__(*args, **kwargs) diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/models/_patch.py b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/models/_patch.py new file mode 100644 index 000000000000..f7dd32510333 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/models/_patch.py @@ -0,0 +1,20 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ +"""Customize generated code here. + +Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize +""" +from typing import List + +__all__: List[str] = [] # Add all objects you want publicly available to users at this package level + + +def patch_sdk(): + """Do not remove from this file. + + `patch_sdk` is a last resort escape hatch that allows you to do customizations + you can't accomplish using the techniques described in + https://aka.ms/azsdk/python/dpcodegen/python/customize + """ diff --git a/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/py.typed b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/py.typed new file mode 100644 index 000000000000..e5aff4f83af8 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/azure/ai/translation/text/py.typed @@ -0,0 +1 @@ +# Marker file for PEP 561. \ No newline at end of file diff --git a/sdk/translation/azure-ai-translation-text/dev_requirements.txt b/sdk/translation/azure-ai-translation-text/dev_requirements.txt new file mode 100644 index 000000000000..36b863ce4e32 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/dev_requirements.txt @@ -0,0 +1,3 @@ +-e ../../../tools/azure-sdk-tools +-e ../../../tools/azure-devtools +azure-core \ No newline at end of file diff --git a/sdk/translation/azure-ai-translation-text/pyproject.toml b/sdk/translation/azure-ai-translation-text/pyproject.toml new file mode 100644 index 000000000000..c576244cfde6 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/pyproject.toml @@ -0,0 +1,3 @@ +[tool.azure-sdk-build] +mypy = false +pylint = false diff --git a/sdk/translation/azure-ai-translation-text/samples/README.md b/sdk/translation/azure-ai-translation-text/samples/README.md new file mode 100644 index 000000000000..714588a2f159 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/samples/README.md @@ -0,0 +1,42 @@ +--- +page_type: sample +languages: +- python +products: +- azure +- cognitive-services +- azure-text-translator +name: azure.ai.translation.text samples for Python +description: Samples for the azure.ai.translation.text client library. +--- + +# Azure Text Translator client library for Python + +Translator Service is a cloud-based neural machine translation service that is part of the Azure Cognitive Services family of REST APIs and can be used with any operating system. This client library offers the following features: + +* Get Supported Languages +* Translate +* Transliterate +* Break Sentence +* Dictionary Lookup +* Dictionary Examples + +See the [README][README] of the Text Translator client library for more information, including useful links and instructions. + +## Common scenarios samples + +* [Get Languages][languages_sample] +* [Translate][translate_sample] +* [Transliterate][transliterate_sample] +* [Break Sentence][breaksentence_sample] +* [Dictionary Lookup][dictionarylookup_sample] +* [Dictionary Examples][dictionaryexamples_sample] + +[README]: https://aka.ms/https://github.com/azure-sdk-for-python/blob/main/sdk/translation/azure-ai-translation-text/README.md + +[languages_sample]: https://aka.ms/https://github.com/azure-sdk-for-python/blob/main/sdk/translation/azure-ai-translation-text/samples/Sample1_GetLanguages.md +[translate_sample]: https://aka.ms/https://github.com/azure-sdk-for-python/blob/main/sdk/translation/azure-ai-translation-text/samples/Sample2_Translate.md +[transliterate_sample]: https://aka.ms/https://github.com/azure-sdk-for-python/blob/main/sdk/translation/azure-ai-translation-text/samples/Sample3_Transliterate.md +[breaksentence_sample]: https://aka.ms/https://github.com/azure-sdk-for-python/blob/main/sdk/translation/azure-ai-translation-text/samples/Sample4_BreakSentence.md +[dictionarylookup_sample]: https://aka.ms/https://github.com/azure-sdk-for-python/blob/main/sdk/translation/azure-ai-translation-text/samples/Sample5_DictionaryLookup.md +[dictionaryexamples_sample]: https://aka.ms/https://github.com/azure-sdk-for-python/blob/main/sdk/translation/azure-ai-translation-text/samples/Sample6_DictionaryExamples.md diff --git a/sdk/translation/azure-ai-translation-text/samples/Sample1_GetLanguages.md b/sdk/translation/azure-ai-translation-text/samples/Sample1_GetLanguages.md new file mode 100644 index 000000000000..6a1fcf1d4dad --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/samples/Sample1_GetLanguages.md @@ -0,0 +1,116 @@ +# Get Languages + +This sample demonstrates how to get languages that are supported by other operations. + +## Create a `TextTranslationClient` + +For this operation you can create a new `TextTranslationClient` without any authentication. You will only need your endpoint: + +```Python +translator_client = TextTranslationClient(endpoint="") +``` + +The values of the `endpoint` variable can be retrieved from environment variables, configuration settings, or any other secure approach that works for your application. + +## Get Supported Languages for ALL other operations + +This will return language metadata from all supported scopes. + +```Python +try: + response = response = text_translator.get_languages() + + print(f"Number of supported languages for translate operation: {len(response.translation) if response.translation is not None else 0}") + print(f"Number of supported languages for transliterate operation: {len(response.transliteration) if response.transliteration is not None else 0}") + print(f"Number of supported languages for dictionary operations: {len(response.dictionary) if response.dictionary is not None else 0}") + + if response.translation is not None: + print("Translation Languages:") + for key, value in response.translation.items(): + print(f"{key} -- name: {value.name} ({value.native_name})") + + if response.transliteration is not None: + print("Transliteration Languages:") + for key, value in response.transliteration.items(): + print(f"{key} -- name: {value.name}, supported script count: {len(value.scripts)}") + + if response.dictionary is not None: + print("Dictionary Languages:") + for key, value in response.dictionary.items(): + print(f"{key} -- name: {value.name}, supported target languages count: {len(value.translations)}") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +### Get Supported Languages for a given scope + +You can limit the scope of the response of the languages API by providing the optional parameter `scope`. A comma-separated list of names defining the group of languages to return. Allowed group names are: `translation`, `transliteration` and `dictionary`. If no scope is given, then all groups are returned, which is equivalent to passing `translation,transliteration,dictionary`. + +```Python +try: + scope = "translation" + response = response = text_translator.get_languages(scope=scope) + + print(f"Number of supported languages for translate operation: {len(response.translation) if response.translation is not None else 0}") + print(f"Number of supported languages for transliterate operation: {len(response.transliteration) if response.transliteration is not None else 0}") + print(f"Number of supported languages for dictionary operations: {len(response.dictionary) if response.dictionary is not None else 0}") + + if response.translation is not None: + print("Translation Languages:") + for key, value in response.translation.items(): + print(f"{key} -- name: {value.name} ({value.native_name})") + + if response.transliteration is not None: + print("Transliteration Languages:") + for key, value in response.transliteration.items(): + print(f"{key} -- name: {value.name}, supported script count: {len(value.scripts)}") + + if response.dictionary is not None: + print("Dictionary Languages:") + for key, value in response.dictionary.items(): + print(f"{key} -- name: {value.name}, supported target languages count: {len(value.translations)}") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +### Get Languages in a given culture + +You can select the language to use for user interface strings. Some of the fields in the response are names of languages or names of regions. Use this parameter to define the language in which these names are returned. The language is specified by providing a well-formed BCP 47 language tag. For instance, use the value `fr` to request names in French or use the value `zh-Hant` to request names in Chinese Traditional. +Names are provided in the English language when a target language is not specified or when localization is not available. + +```Python +try: + accept_language = "es" + response = response = text_translator.get_languages(accept_language=accept_language) + + print(f"Number of supported languages for translate operation: {len(response.translation) if response.translation is not None else 0}") + print(f"Number of supported languages for transliterate operation: {len(response.transliteration) if response.transliteration is not None else 0}") + print(f"Number of supported languages for dictionary operations: {len(response.dictionary) if response.dictionary is not None else 0}") + + if response.translation is not None: + print("Translation Languages:") + for key, value in response.translation.items(): + print(f"{key} -- name: {value.name} ({value.native_name})") + + if response.transliteration is not None: + print("Transliteration Languages:") + for key, value in response.transliteration.items(): + print(f"{key} -- name: {value.name}, supported script count: {len(value.scripts)}") + + if response.dictionary is not None: + print("Dictionary Languages:") + for key, value in response.dictionary.items(): + print(f"{key} -- name: {value.name}, supported target languages count: {len(value.translations)}") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +See the [README] of the Text Translator client library for more information, including useful links and instructions. + +[README]: https://aka.ms/https://github.com/azure-sdk-for-python/blob/main/sdk/translation/azure-ai-translation-text/README.md diff --git a/sdk/translation/azure-ai-translation-text/samples/Sample2_Translate.md b/sdk/translation/azure-ai-translation-text/samples/Sample2_Translate.md new file mode 100644 index 000000000000..a1f29db042ea --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/samples/Sample2_Translate.md @@ -0,0 +1,327 @@ +# Translate + +## Create a `TextTranslationClient` + +To create a new `TextTranslationClient`, you will need the service endpoint and credentials of your Translator resource. In this sample, you will use an `TranslatorCredential`, which you can create with an API key and region. + +```Python +credential = TranslatorCredential("", "") +text_translator = TextTranslationClient(endpoint="", credential=credential) +``` + +The values of the `endpoint`, `apiKey` and `region` variables can be retrieved from environment variables, configuration settings, or any other secure approach that works for your application. + +### Translate text + +Translate text from known source language to target language. + +```Python +try: + source_language = "en" + target_languages = ["cs"] + input_text_elements = [ InputTextItem(text = "This is a test") ] + + response = text_translator.translate(content = input_text_elements, to = target_languages, from_parameter = source_language) + translation = response[0] if response else None + + if translation: + for translated_text in translation.translations: + print(f"Text was translated to: '{translated_text.to}' and the result is: '{translated_text.text}'.") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +### Translate with auto-detection + +You can omit source language of the input text. In this case, API will try to auto-detect the language. + +> Note that you must provide the source language rather than autodetection when using the dynamic dictionary feature. + +> Note you can use `suggestedFrom` parameter that specifies a fallback language if the language of the input text can't be identified. Language autodetection is applied when the from parameter is omitted. If detection fails, the suggestedFrom language will be assumed. + +```Python +try: + target_languages = ["cs"] + input_text_elements = [ InputTextItem(text = "This is a test") ] + + response = text_translator.translate(content = input_text_elements, to = target_languages) + translation = response[0] if response else None + + if translation: + detected_language = translation.detected_language + if detected_language: + print(f"Detected languages of the input text: {detected_language.language} with score: {detected_language.score}.") + for translated_text in translation.translations: + print(f"Text was translated to: '{translated_text.to}' and the result is: '{translated_text.text}'.") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +### Translate with Transliteration + +You can combine both Translation and Transliteration in one Translate call. Your source Text can be in non-standard Script of a language as well as you can ask for non-standard Script of a target language. + +```Python +try: + from_script = "Latn" + from_language = "ar" + to_script = "Latn" + target_languages = ["zh-Hans"] + input_text_elements = [ InputTextItem(text = "hudha akhtabar.") ] + + response = text_translator.translate(content = input_text_elements, to = target_languages, from_script=from_script, from_parameter=from_language, to_script=to_script) + translation = response[0] if response else None + + if translation: + if translation.source_text: + print(f"Source Text: {translation.source_text.text}") + first_translation = translation.translations[0] + if first_translation: + print(f"Translation: '{first_translation.text}'.") + transliteration = first_translation.transliteration + if transliteration: + print(f"Transliterated text ({transliteration.script}): {transliteration.text}") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +### Translate multiple input texts + +You can translate multiple text elements with a various length. Each input element can be in different language (source language parameter needs to be omitted and language auto-detection is used). Refer to [Request limits for Translator](https://learn.microsoft.com/azure/cognitive-services/translator/request-limits) for current limits. + +```Python +try: + target_languages = ["cs"] + input_text_elements = [ + InputTextItem(text = "This is a test."), + InputTextItem(text = "Esto es una prueba."), + InputTextItem(text = "Dies ist ein Test.")] + + translations = text_translator.translate(content = input_text_elements, to = target_languages) + + for translation in translations: + print(f"Detected languages of the input text: {translation.detected_language.language if translation.detected_language else None} with score: {translation.detected_language.score if translation.detected_language else None}.") + print(f"Text was translated to: '{translation.translations[0].to if translation.translations else None}' and the result is: '{translation.translations[0].text if translation.translations else None}'.") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +### Translate multiple target languages + +You can provide multiple target languages which results to each input element be translated to all target languages. + +```Python +try: + target_languages = ["cs", "es", "de"] + input_text_elements = [ InputTextItem(text = "This is a test") ] + + response = text_translator.translate(content = input_text_elements, to = target_languages) + translation = response[0] if response else None + + if translation: + detected_language = translation.detected_language + if detected_language: + print(f"Detected languages of the input text: {detected_language.language} with score: {detected_language.score}.") + for translated_text in translation.translations: + print(f"Text was translated to: '{translated_text.to}' and the result is: '{translated_text.text}'.") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +### Translate different text types + +You can select whether the translated text is plain text or HTML text. Any HTML needs to be a well-formed, complete element. Possible values are: plain (default) or html. + +```Python +try: + text_type = TextTypes.HTML + target_languages = ["cs"] + input_text_elements = [ InputTextItem(text = "This is a test.") ] + + response = text_translator.translate(content = input_text_elements, to = target_languages, text_type=text_type) + translation = response[0] if response else None + + if translation: + detected_language = translation.detected_language + if detected_language: + print(f"Detected languages of the input text: {detected_language.language} with score: {detected_language.score}.") + for translated_text in translation.translations: + print(f"Text was translated to: '{translated_text.to}' and the result is: '{translated_text.text}'.") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +### Don’t translate specific entity name in a text + +It's sometimes useful to exclude specific content from translation. You can use the attribute class=notranslate to specify content that should remain in its original language. In the following example, the content inside the first div element won't be translated, while the content in the second div element will be translated. + +```Python +try: + text_type = TextTypes.HTML + source_language = "en" + target_languages = ["cs"] + input_text_elements = [ InputTextItem(text = "
This will not be translated.
This will be translated.
") ] + + response = text_translator.translate(content = input_text_elements, to = target_languages, from_parameter = source_language, text_type=text_type) + translation = response[0] if response else None + + if translation: + for translated_text in translation.translations: + print(f"Text was translated to: '{translated_text.to}' and the result is: '{translated_text.text}'.") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +### Translate specific entity name in a text applying a dictionary + +If you already know the translation you want to apply to a word or a phrase, you can supply it as markup within the request. The dynamic dictionary is safe only for compound nouns like proper names and product names. + +> Note You must include the From parameter in your API translation request instead of using the autodetect feature. + +```Python +try: + source_language = "en" + target_languages = ["cs"] + input_text_elements = [ InputTextItem(text = "The word wordomatic is a dictionary entry.") ] + + response = text_translator.translate(content = input_text_elements, to = target_languages, from_parameter = source_language) + translation = response[0] if response else None + + if translation: + for translated_text in translation.translations: + print(f"Text was translated to: '{translated_text.to}' and the result is: '{translated_text.text}'.") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +### Profanity handling + +[Profanity handling](https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-translate#handle-profanity). Normally the Translator service will retain profanity that is present in the source in the translation. The degree of profanity and the context that makes words profane differ between cultures, and as a result the degree of profanity in the target language may be amplified or reduced. + +If you want to avoid getting profanity in the translation, regardless of the presence of profanity in the source text, you can use the profanity filtering option. The option allows you to choose whether you want to see profanity deleted, whether you want to mark profanities with appropriate tags (giving you the option to add your own post-processing), or you want no action taken. The accepted values of `ProfanityAction` are `DELETED`, `MARKED` and `NOACTION` (default). + +```Python +try: + profanity_action = ProfanityActions.MARKED + profanity_maker = ProfanityMarkers.ASTERISK + target_languages = ["cs"] + input_text_elements = [ InputTextItem(text = "This is ***.") ] + + response = text_translator.translate(content = input_text_elements, to = target_languages, profanity_action=profanity_action, profanity_marker=profanity_maker) + translation = response[0] if response else None + + if translation: + detected_language = translation.detected_language + if detected_language: + print(f"Detected languages of the input text: {detected_language.language} with score: {detected_language.score}.") + for translated_text in translation.translations: + print(f"Text was translated to: '{translated_text.to}' and the result is: '{translated_text.text}'.") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +### Include alignments into translations + +You can ask translation service to include alignment projection from source text to translated text. + +```Python +try: + include_alignment = True + target_languages = ["cs"] + input_text_elements = [ InputTextItem(text = "The answer lies in machine translation.") ] + + response = text_translator.translate(content = input_text_elements, to = target_languages, include_alignment = include_alignment) + translation = response[0] if response else None + + if translation: + detected_language = translation.detected_language + if detected_language: + print(f"Detected languages of the input text: {detected_language.language} with score: {detected_language.score}.") + for translated_text in translation.translations: + print(f"Text was translated to: '{translated_text.to}' and the result is: '{translated_text.text}'.") + if (translated_text.alignment): + print(f"Alignments: {translated_text.alignment.proj}") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +### Include sentence length + +You can ask translator service to include sentence boundaries for the input text and the translated text. + +```Python +try: + include_sentence_length = True + target_languages = ["cs"] + input_text_elements = [ InputTextItem(text = "The answer lies in machine translation. This is a test.") ] + + response = text_translator.translate(content = input_text_elements, to = target_languages, include_sentence_length=include_sentence_length) + translation = response[0] if response else None + + if translation: + detected_language = translation.detected_language + if detected_language: + print(f"Detected languages of the input text: {detected_language.language} with score: {detected_language.score}.") + for translated_text in translation.translations: + print(f"Text was translated to: '{translated_text.to}' and the result is: '{translated_text.text}'.") + if (translated_text.sent_len): + print(f"Source Sentence length: {translated_text.sent_len.src_sent_len}") + print(f"Translated Sentence length: {translated_text.sent_len.trans_sent_len}") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +### Custom Translator + +You can get translations from a customized system built with [Custom Translator](https://learn.microsoft.com/azure/cognitive-services/translator/customization). Add the Category ID from your Custom Translator [project details](https://learn.microsoft.com/azure/cognitive-services/translator/custom-translator/how-to-create-project#view-project-details) to this parameter to use your deployed customized system. + +It is possible to set `allow_fallback` parameter. It specifies that the service is allowed to fall back to a general system when a custom system doesn't exist. Possible values are: `True` (default) or `False`. + +`allow_fallback=False` specifies that the translation should only use systems trained for the category specified by the request. If a translation for language X to language Y requires chaining through a pivot language E, then all the systems in the chain (X → E and E → Y) will need to be custom and have the same category. If no system is found with the specific category, the request will return a 400 status code. `allow_fallback=True` specifies that the service is allowed to fall back to a general system when a custom system doesn't exist. + +```Python +try: + category = "<>" + target_languages = ["cs"] + input_text_elements = [ InputTextItem(text = "This is a test") ] + + response = text_translator.translate(content = input_text_elements, to = target_languages, category = category) + translation = response[0] if response else None + + if translation: + detected_language = translation.detected_language + if detected_language: + print(f"Detected languages of the input text: {detected_language.language} with score: {detected_language.score}.") + for translated_text in translation.translations: + print(f"Text was translated to: '{translated_text.to}' and the result is: '{translated_text.text}'.") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +See the [README] of the Text Translator client library for more information, including useful links and instructions. + +[README]: https://aka.ms/https://github.com/azure-sdk-for-python/blob/main/sdk/translation/azure-ai-translation-text/README.md diff --git a/sdk/translation/azure-ai-translation-text/samples/Sample3_Transliterate.md b/sdk/translation/azure-ai-translation-text/samples/Sample3_Transliterate.md new file mode 100644 index 000000000000..6579d7e16529 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/samples/Sample3_Transliterate.md @@ -0,0 +1,38 @@ +# Transliterate + +## Create a `TextTranslationClient` + +To create a new `TextTranslationClient`, you will need the service endpoint and credentials of your Translator resource. In this sample, you will use an `TranslatorCredential`, which you can create with an API key and region. + +```Python +credential = TranslatorCredential("", "") +text_translator = TextTranslationClient(endpoint="", credential=credential) +``` + +The values of the `endpoint`, `apiKey` and `region` variables can be retrieved from environment variables, configuration settings, or any other secure approach that works for your application. + +### Transliterate Text + +Converts characters or letters of a source language to the corresponding characters or letters of a target language. + +```Python +try: + language = "zh-Hans" + from_script = "Hans" + to_script = "Latn" + input_text_elements = [ InputTextItem(text = "这是个测试。") ] + + response = text_translator.transliterate(content = input_text_elements, language = language, from_script = from_script, to_script = to_script) + transliteration = response[0] if response else None + + if transliteration: + print(f"Input text was transliterated to '{transliteration.script}' script. Transliterated text: '{transliteration.text}'.") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +See the [README] of the Text Translator client library for more information, including useful links and instructions. + +[README]: https://aka.ms/https://github.com/azure-sdk-for-python/blob/main/sdk/translation/azure-ai-translation-text/README.md diff --git a/sdk/translation/azure-ai-translation-text/samples/Sample4_BreakSentence.md b/sdk/translation/azure-ai-translation-text/samples/Sample4_BreakSentence.md new file mode 100644 index 000000000000..35c9be26ee79 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/samples/Sample4_BreakSentence.md @@ -0,0 +1,66 @@ +# Break Sentence + +## Create a `TextTranslationClient` + +To create a new `TextTranslationClient`, you will need the service endpoint and credentials of your Translator resource. In this sample, you will use an `TranslatorCredential`, which you can create with an API key and region. + +```Python +credential = TranslatorCredential("", "") +text_translator = TextTranslationClient(endpoint="", credential=credential) +``` + +The values of the `endpoint`, `apiKey` and `region` variables can be retrieved from environment variables, configuration settings, or any other secure approach that works for your application. + +### Break Sentence with language and script parameters + +When the input language is known, you can provide those to the service call. + +```Python +try: + source_language = "zh-Hans" + source_script = "Latn" + input_text_elements = [ InputTextItem(text = "zhè shì gè cè shì。") ] + + response = text_translator.break_sentence(content = input_text_elements, language = source_language, script = source_script) + break_sentence = response[0] if response else None + + if break_sentence: + detected_language = break_sentence.detected_language + if detected_language: + print(f"Detected languages of the input text: {detected_language.language} with score: {detected_language.score}.") + print(f"The detected sentence boundaries:") + for boundary in break_sentence.sent_len: + print(boundary) + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +### Break Sentence with auto-detection + +You can omit source language of the input text. In this case, API will try to auto-detect the language. + +```Python +try: + input_text_elements = [ InputTextItem(text = "This is a test. This is the second sentence.") ] + + response = text_translator.break_sentence(content = input_text_elements) + break_sentence = response[0] if response else None + + if break_sentence: + detected_language = break_sentence.detected_language + if detected_language: + print(f"Detected languages of the input text: {detected_language.language} with score: {detected_language.score}.") + print(f"The detected sentence boundaries:") + for boundary in break_sentence.sent_len: + print(boundary) + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +See the [README] of the Text Translator client library for more information, including useful links and instructions. + +[README]: https://aka.ms/https://github.com/azure-sdk-for-python/blob/main/sdk/translation/azure-ai-translation-text/README.md diff --git a/sdk/translation/azure-ai-translation-text/samples/Sample5_DictionaryLookup.md b/sdk/translation/azure-ai-translation-text/samples/Sample5_DictionaryLookup.md new file mode 100644 index 000000000000..a4b4a90aee20 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/samples/Sample5_DictionaryLookup.md @@ -0,0 +1,38 @@ +# Dictionary Lookup + +## Create a `TextTranslationClient` + +To create a new `TextTranslationClient`, you will need the service endpoint and credentials of your Translator resource. In this sample, you will use an `TranslatorCredential`, which you can create with an API key and region. + +```Python +credential = TranslatorCredential("", "") +text_translator = TextTranslationClient(endpoint="", credential=credential) +``` + +The values of the `endpoint`, `apiKey` and `region` variables can be retrieved from environment variables, configuration settings, or any other secure approach that works for your application. + +### Lookup Dictionary Entries + +Returns equivalent words for the source term in the target language. + +```Python +try: + source_language = "en" + target_language = "es" + input_text_elements = [ InputTextItem(text = "fly") ] + + response = text_translator.dictionary_lookup(content = input_text_elements, from_parameter = source_language, to = target_language) + dictionary_entry = response[0] if response else None + + if dictionary_entry: + print(f"For the given input {len(dictionary_entry.translations)} entries were found in the dictionary.") + print(f"First entry: '{dictionary_entry.translations[0].display_target}', confidence: {dictionary_entry.translations[0].confidence}.") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +See the [README] of the Text Translator client library for more information, including useful links and instructions. + +[README]: https://aka.ms/https://github.com/azure-sdk-for-python/blob/main/sdk/translation/azure-ai-translation-text/README.md diff --git a/sdk/translation/azure-ai-translation-text/samples/Sample6_DictionaryExamples.md b/sdk/translation/azure-ai-translation-text/samples/Sample6_DictionaryExamples.md new file mode 100644 index 000000000000..8d337bf61fed --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/samples/Sample6_DictionaryExamples.md @@ -0,0 +1,34 @@ +# Dictionary Examples + +## Create a `TextTranslationClient` + +To create a new `TextTranslationClient`, you will need the service endpoint and credentials of your Translator resource. In this sample, you will use an `TranslatorCredential`, which you can create with an API key and region. + +```Python +credential = TranslatorCredential("", "") +text_translator = TextTranslationClient(endpoint="", credential=credential) +``` + +The values of the `endpoint`, `apiKey` and `region` variables can be retrieved from environment variables, configuration settings, or any other secure approach that works for your application. + +```Python +try: + source_language = "en" + target_language = "es" + input_text_elements = [ DictionaryExampleTextItem(text = "fly", translation = "volar") ] + + response = text_translator.dictionary_examples(content = input_text_elements, from_parameter = source_language, to = target_language) + dictionary_entry = response[0] if response else None + + if dictionary_entry: + print(f"For the given input {len(dictionary_entry.examples)} entries were found in the dictionary.") + print(f"First example: '{dictionary_entry.examples[0].target_prefix}{dictionary_entry.examples[0].target_term}{dictionary_entry.examples[0].target_suffix}'.") + +except HttpResponseError as exception: + print(f"Error Code: {exception.error.code}") + print(f"Message: {exception.error.message}") +``` + +See the [README] of the Text Translator client library for more information, including useful links and instructions. + +[README]: https://aka.ms/https://github.com/azure-sdk-for-python/blob/main/sdk/translation/azure-ai-translation-text/README.md diff --git a/sdk/translation/azure-ai-translation-text/sdk_packaging.toml b/sdk/translation/azure-ai-translation-text/sdk_packaging.toml new file mode 100644 index 000000000000..901bc8ccbfa6 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/sdk_packaging.toml @@ -0,0 +1,2 @@ +[packaging] +auto_update = false diff --git a/sdk/translation/azure-ai-translation-text/setup.py b/sdk/translation/azure-ai-translation-text/setup.py new file mode 100644 index 000000000000..ef927847157a --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/setup.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python + +#------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +#-------------------------------------------------------------------------- + +from io import open +import os +from setuptools import setup, find_packages +import re + + +PACKAGE_NAME = "azure-ai-translation-text" +PACKAGE_PPRINT_NAME = "Text Translation" + +# a-b-c => a/b/c +package_folder_path = PACKAGE_NAME.replace('-', '/') +# a-b-c => a.b.c +namespace_name = PACKAGE_NAME.replace('-', '.') + +# Version extraction inspired from 'requests' +with open(os.path.join(package_folder_path, '_version.py'), 'r') as fd: + version = re.search(r'^VERSION\s*=\s*[\'"]([^\'"]*)[\'"]', + fd.read(), re.MULTILINE).group(1) +if not version: + raise RuntimeError('Cannot find version information') + +with open('README.md', encoding='utf-8') as f: + readme = f.read() +with open('CHANGELOG.md', encoding='utf-8') as f: + changelog = f.read() + +setup( + name=PACKAGE_NAME, + version=version, + description="Azure Text Translation Client Library for Python", + author_email='azpysdkhelp@microsoft.com', + url='https://github.com/Azure/azure-sdk-for-python', + long_description=readme + '\n\n' + changelog, + long_description_content_type='text/markdown', + license='MIT License', + author='Microsoft Corporation', + keywords="azure, azure sdk", + classifiers=[ + 'Development Status :: 4 - Beta', + 'Programming Language :: Python', + 'Programming Language :: Python :: 3 :: Only', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'License :: OSI Approved :: MIT License', + ], + zip_safe=False, + packages=find_packages(exclude=[ + # Exclude packages that will be covered by PEP420 or nspkg + 'azure', + 'azure.ai', + 'azure.ai.translation' + ]), + include_package_data=True, + package_data={ + 'azure.ai.translation.text': ['py.typed'], + }, + install_requires=[ + "msrest>=0.7.1", + "azure-core<2.0.0,>=1.24.0", + "typing-extensions>=4.3.0", + ], + python_requires=">=3.7" +) diff --git a/sdk/translation/azure-ai-translation-text/tests/conftest.py b/sdk/translation/azure-ai-translation-text/tests/conftest.py new file mode 100644 index 000000000000..cd8fc782df18 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/conftest.py @@ -0,0 +1,13 @@ +import pytest +from devtools_testutils import ( + test_proxy, + add_remove_header_sanitizer +) + +# autouse=True will trigger this fixture on each pytest run, even if it's not explicitly used by a test method +#def start_proxy(test_proxy): + # return + +@pytest.fixture(scope="session", autouse=True) +def add_sanitizers(test_proxy): + add_remove_header_sanitizer(headers="Ocp-Apim-Subscription-Key") \ No newline at end of file diff --git a/sdk/translation/azure-ai-translation-text/tests/preparer.py b/sdk/translation/azure-ai-translation-text/tests/preparer.py new file mode 100644 index 000000000000..9eb9a58abd4b --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/preparer.py @@ -0,0 +1,16 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +import functools +from devtools_testutils import EnvironmentVariableLoader + +TextTranslationPreparer = functools.partial( + EnvironmentVariableLoader, + 'text_translation', + text_translation_endpoint="https://fakeEndpoint.cognitive.microsofttranslator.com", + text_translation_custom_endpoint="https://fakeCustomEndpoint.cognitiveservices.azure.com", + text_translation_apikey="fakeapikey", + text_translation_region="fakeregion", +) \ No newline at end of file diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_break_sentence.pyTestBreakSentencetest_autodetect.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_break_sentence.pyTestBreakSentencetest_autodetect.json new file mode 100644 index 000000000000..b8759aae8089 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_break_sentence.pyTestBreakSentencetest_autodetect.json @@ -0,0 +1,30 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/breaksentence?api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "25", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022Hello world\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": "X-RequestId", + "Content-Length": "67", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:51 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-RequestId": "BKST.MW1P.99BE.0403T2149.2FCA415" + }, + "ResponseBody": "[{\u0022detectedLanguage\u0022:{\u0022language\u0022:\u0022en\u0022,\u0022score\u0022:1.0},\u0022sentLen\u0022:[11]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_break_sentence.pyTestBreakSentencetest_with_language.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_break_sentence.pyTestBreakSentencetest_with_language.json new file mode 100644 index 000000000000..f47ef52d28ce --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_break_sentence.pyTestBreakSentencetest_with_language.json @@ -0,0 +1,30 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/breaksentence?language=th\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "1589", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022\\u0e23\\u0e27\\u0e1a\\u0e23\\u0e27\\u0e21\\u0e41\\u0e1c\\u0e48\\u0e19\\u0e04\\u0e33\\u0e15\\u0e2d\\u0e1a \\u0e23\\u0e30\\u0e22\\u0e30\\u0e40\\u0e27\\u0e25\\u0e32\\u0e02\\u0e2d\\u0e07\\u0e42\\u0e04\\u0e23\\u0e07\\u0e01\\u0e32\\u0e23 \\u0e27\\u0e34\\u0e18\\u0e35\\u0e40\\u0e25\\u0e37\\u0e2d\\u0e01\\u0e0a\\u0e32\\u0e22\\u0e43\\u0e19\\u0e1d\\u0e31\\u0e19 \\u0e2b\\u0e21\\u0e32\\u0e22\\u0e40\\u0e25\\u0e02\\u0e0b\\u0e35\\u0e40\\u0e23\\u0e35\\u0e22\\u0e25\\u0e02\\u0e2d\\u0e07\\u0e23\\u0e30\\u0e40\\u0e1a\\u0e35\\u0e22\\u0e19 \\u0e27\\u0e31\\u0e19\\u0e17\\u0e35\\u0e48\\u0e2a\\u0e34\\u0e49\\u0e19\\u0e2a\\u0e38\\u0e14\\u0e02\\u0e2d\\u0e07\\u0e42\\u0e04\\u0e23\\u0e07\\u0e01\\u0e32\\u0e23\\u0e40\\u0e21\\u0e37\\u0e48\\u0e2d\\u0e40\\u0e2a\\u0e23\\u0e47\\u0e08\\u0e2a\\u0e21\\u0e1a\\u0e39\\u0e23\\u0e13\\u0e4c \\u0e1b\\u0e35\\u0e17\\u0e35\\u0e48\\u0e21\\u0e35\\u0e01\\u0e32\\u0e23\\u0e23\\u0e27\\u0e1a\\u0e23\\u0e27\\u0e21 \\u0e17\\u0e38\\u0e01\\u0e04\\u0e19\\u0e21\\u0e35\\u0e27\\u0e31\\u0e12\\u0e19\\u0e18\\u0e23\\u0e23\\u0e21\\u0e41\\u0e25\\u0e30\\u0e27\\u0e34\\u0e18\\u0e35\\u0e04\\u0e34\\u0e14\\u0e40\\u0e2b\\u0e21\\u0e37\\u0e2d\\u0e19\\u0e01\\u0e31\\u0e19 \\u0e44\\u0e14\\u0e49\\u0e23\\u0e31\\u0e1a\\u0e42\\u0e17\\u0e29\\u0e08\\u0e33\\u0e04\\u0e38\\u0e01\\u0e15\\u0e25\\u0e2d\\u0e14\\u0e0a\\u0e35\\u0e27\\u0e34\\u0e15\\u0e43\\u0e19 \\u0e09\\u0e31\\u0e19\\u0e25\\u0e14\\u0e44\\u0e14\\u0e49\\u0e16\\u0e36\\u0e07 55 \\u0e1b\\u0e2d\\u0e19\\u0e14\\u0e4c\\u0e44\\u0e14\\u0e49\\u0e2d\\u0e22\\u0e48\\u0e32\\u0e07\\u0e44\\u0e23 \\u0e09\\u0e31\\u0e19\\u0e04\\u0e34\\u0e14\\u0e27\\u0e48\\u0e32\\u0e43\\u0e04\\u0e23\\u0e46 \\u0e01\\u0e47\\u0e15\\u0e49\\u0e2d\\u0e07\\u0e01\\u0e32\\u0e23\\u0e01\\u0e33\\u0e2b\\u0e19\\u0e14\\u0e40\\u0e21\\u0e19\\u0e39\\u0e2d\\u0e32\\u0e2b\\u0e32\\u0e23\\u0e2a\\u0e48\\u0e27\\u0e19\\u0e1a\\u0e38\\u0e04\\u0e04\\u0e25\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": "X-RequestId", + "Content-Length": "28", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:51 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-RequestId": "BKST.MW1P.99BE.0403T2149.2FCA480" + }, + "ResponseBody": "[{\u0022sentLen\u0022:[78,41,110,46]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_break_sentence.pyTestBreakSentencetest_with_language_script.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_break_sentence.pyTestBreakSentencetest_with_language_script.json new file mode 100644 index 000000000000..f0c2813396f8 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_break_sentence.pyTestBreakSentencetest_with_language_script.json @@ -0,0 +1,30 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/breaksentence?language=zh-Hans\u0026script=Latn\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "62", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022zh\\u00e8 sh\\u00ec g\\u00e8 c\\u00e8 sh\\u00ec\\u3002\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": "X-RequestId", + "Content-Length": "18", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:51 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-RequestId": "BKST.MW1P.99BE.0403T2149.2FCA48E" + }, + "ResponseBody": "[{\u0022sentLen\u0022:[18]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_break_sentence.pyTestBreakSentencetest_with_multiple_languages.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_break_sentence.pyTestBreakSentencetest_with_multiple_languages.json new file mode 100644 index 000000000000..939f386e6d44 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_break_sentence.pyTestBreakSentencetest_with_multiple_languages.json @@ -0,0 +1,30 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/breaksentence?api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "206", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022hello world\u0022}, {\u0022text\u0022: \u0022\\u0627\\u0644\\u0639\\u0627\\u0644\\u0645 \\u0647\\u0648 \\u0645\\u0643\\u0627\\u0646 \\u0645\\u062b\\u064a\\u0631 \\u062c\\u062f\\u0627 \\u0644\\u0644\\u0627\\u0647\\u062a\\u0645\\u0627\\u0645\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": "X-RequestId", + "Content-Length": "133", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:51 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-RequestId": "BKST.MW1P.99BE.0403T2149.2FCA4A6" + }, + "ResponseBody": "[{\u0022detectedLanguage\u0022:{\u0022language\u0022:\u0022en\u0022,\u0022score\u0022:1.0},\u0022sentLen\u0022:[11]},{\u0022detectedLanguage\u0022:{\u0022language\u0022:\u0022ar\u0022,\u0022score\u0022:1.0},\u0022sentLen\u0022:[32]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_dictionary_examples.pyTestDictionaryExamplestest_multiple_input_elements.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_dictionary_examples.pyTestDictionaryExamplestest_multiple_input_elements.json new file mode 100644 index 000000000000..c7a98d618a29 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_dictionary_examples.pyTestDictionaryExamplestest_multiple_input_elements.json @@ -0,0 +1,35 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/dictionary/examples?from=en\u0026to=es\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "82", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022fly\u0022, \u0022translation\u0022: \u0022volar\u0022}, {\u0022text\u0022: \u0022beef\u0022, \u0022translation\u0022: \u0022came\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Encoding": "gzip", + "Content-Length": "2704", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:52 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "16", + "X-RequestId": "DTEX.MW1P.99BE.0403T2149.2FCA4C7" + }, + "ResponseBody": "[{\u0022normalizedSource\u0022:\u0022fly\u0022,\u0022normalizedTarget\u0022:\u0022volar\u0022,\u0022examples\u0022:[{\u0022sourcePrefix\u0022:\u0022I mean, for a guy who could \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Quiero decir, para un tipo que pod\u00EDa \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022Now it\u0027s time to make you \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Ahora es hora de que te haga \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022One happy thought will make you \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Uno solo te har\u00E1 \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022They need machines to \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Necesitan m\u00E1quinas para \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022That should really \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Eso realmente debe \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022It sure takes longer when you can\u0027t \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Lleva m\u00E1s tiempo cuando no puedes \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022I have to \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022 home in the morning.\u0022,\u0022targetPrefix\u0022:\u0022Tengo que \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022 a casa por la ma\u00F1ana.\u0022},{\u0022sourcePrefix\u0022:\u0022You taught me to \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Me ense\u00F1aste a \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022I think you should \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022 with the window closed.\u0022,\u0022targetPrefix\u0022:\u0022Creo que debemos \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022 con la ventana cerrada.\u0022},{\u0022sourcePrefix\u0022:\u0022They look like they could \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Parece que pudieran \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022But you can \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022, for instance?\u0022,\u0022targetPrefix\u0022:\u0022Que puedes \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022, por ejemplo.\u0022},{\u0022sourcePrefix\u0022:\u0022At least until her kids can be able to \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Al menos hasta que sus hijos sean capaces de \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022I thought you could \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Pens\u00E9 que pod\u00EDas \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022I was wondering what it would be like to \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Me preguntaba c\u00F3mo ser\u00EDa \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022But nobody else can \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Pero nadie puede \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022}]},{\u0022normalizedSource\u0022:\u0022beef\u0022,\u0022normalizedTarget\u0022:\u0022came\u0022,\u0022examples\u0022:[]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_dictionary_examples.pyTestDictionaryExamplestest_single_input_element.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_dictionary_examples.pyTestDictionaryExamplestest_single_input_element.json new file mode 100644 index 000000000000..aae6218cd333 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_dictionary_examples.pyTestDictionaryExamplestest_single_input_element.json @@ -0,0 +1,35 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/dictionary/examples?from=en\u0026to=es\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "41", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022fly\u0022, \u0022translation\u0022: \u0022volar\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Encoding": "gzip", + "Content-Length": "2636", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:52 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "8", + "X-RequestId": "DTEX.MW1P.99BE.0403T2149.2FCA4B8" + }, + "ResponseBody": "[{\u0022normalizedSource\u0022:\u0022fly\u0022,\u0022normalizedTarget\u0022:\u0022volar\u0022,\u0022examples\u0022:[{\u0022sourcePrefix\u0022:\u0022I mean, for a guy who could \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Quiero decir, para un tipo que pod\u00EDa \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022Now it\u0027s time to make you \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Ahora es hora de que te haga \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022One happy thought will make you \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Uno solo te har\u00E1 \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022They need machines to \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Necesitan m\u00E1quinas para \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022That should really \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Eso realmente debe \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022It sure takes longer when you can\u0027t \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Lleva m\u00E1s tiempo cuando no puedes \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022I have to \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022 home in the morning.\u0022,\u0022targetPrefix\u0022:\u0022Tengo que \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022 a casa por la ma\u00F1ana.\u0022},{\u0022sourcePrefix\u0022:\u0022You taught me to \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Me ense\u00F1aste a \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022I think you should \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022 with the window closed.\u0022,\u0022targetPrefix\u0022:\u0022Creo que debemos \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022 con la ventana cerrada.\u0022},{\u0022sourcePrefix\u0022:\u0022They look like they could \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Parece que pudieran \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022But you can \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022, for instance?\u0022,\u0022targetPrefix\u0022:\u0022Que puedes \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022, por ejemplo.\u0022},{\u0022sourcePrefix\u0022:\u0022At least until her kids can be able to \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Al menos hasta que sus hijos sean capaces de \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022I thought you could \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Pens\u00E9 que pod\u00EDas \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022I was wondering what it would be like to \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Me preguntaba c\u00F3mo ser\u00EDa \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022},{\u0022sourcePrefix\u0022:\u0022But nobody else can \u0022,\u0022sourceTerm\u0022:\u0022fly\u0022,\u0022sourceSuffix\u0022:\u0022.\u0022,\u0022targetPrefix\u0022:\u0022Pero nadie puede \u0022,\u0022targetTerm\u0022:\u0022volar\u0022,\u0022targetSuffix\u0022:\u0022.\u0022}]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_dictionary_lookup.pyTestDictionaryLookuptest_multiple_input_elements.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_dictionary_lookup.pyTestDictionaryLookuptest_multiple_input_elements.json new file mode 100644 index 000000000000..0a14235154b0 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_dictionary_lookup.pyTestDictionaryLookuptest_multiple_input_elements.json @@ -0,0 +1,35 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/dictionary/lookup?from=en\u0026to=es\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "34", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022fly\u0022}, {\u0022text\u0022: \u0022fox\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Encoding": "gzip", + "Content-Length": "3045", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:52 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "6", + "X-RequestId": "DTLK.MW1P.99BE.0403T2149.2FCA4E7" + }, + "ResponseBody": "[{\u0022normalizedSource\u0022:\u0022fly\u0022,\u0022displaySource\u0022:\u0022fly\u0022,\u0022translations\u0022:[{\u0022normalizedTarget\u0022:\u0022volar\u0022,\u0022displayTarget\u0022:\u0022volar\u0022,\u0022posTag\u0022:\u0022VERB\u0022,\u0022confidence\u0022:0.4081,\u0022prefixWord\u0022:\u0022\u0022,\u0022backTranslations\u0022:[{\u0022normalizedText\u0022:\u0022fly\u0022,\u0022displayText\u0022:\u0022fly\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:4637},{\u0022normalizedText\u0022:\u0022flying\u0022,\u0022displayText\u0022:\u0022flying\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:1365},{\u0022normalizedText\u0022:\u0022blow\u0022,\u0022displayText\u0022:\u0022blow\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:503},{\u0022normalizedText\u0022:\u0022flight\u0022,\u0022displayText\u0022:\u0022flight\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:135}]},{\u0022normalizedTarget\u0022:\u0022mosca\u0022,\u0022displayTarget\u0022:\u0022mosca\u0022,\u0022posTag\u0022:\u0022NOUN\u0022,\u0022confidence\u0022:0.2668,\u0022prefixWord\u0022:\u0022\u0022,\u0022backTranslations\u0022:[{\u0022normalizedText\u0022:\u0022fly\u0022,\u0022displayText\u0022:\u0022fly\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:1697},{\u0022normalizedText\u0022:\u0022flyweight\u0022,\u0022displayText\u0022:\u0022flyweight\u0022,\u0022numExamples\u0022:0,\u0022frequencyCount\u0022:48},{\u0022normalizedText\u0022:\u0022flies\u0022,\u0022displayText\u0022:\u0022flies\u0022,\u0022numExamples\u0022:9,\u0022frequencyCount\u0022:34}]},{\u0022normalizedTarget\u0022:\u0022operan\u0022,\u0022displayTarget\u0022:\u0022operan\u0022,\u0022posTag\u0022:\u0022VERB\u0022,\u0022confidence\u0022:0.1144,\u0022prefixWord\u0022:\u0022\u0022,\u0022backTranslations\u0022:[{\u0022normalizedText\u0022:\u0022operate\u0022,\u0022displayText\u0022:\u0022operate\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:1344},{\u0022normalizedText\u0022:\u0022fly\u0022,\u0022displayText\u0022:\u0022fly\u0022,\u0022numExamples\u0022:1,\u0022frequencyCount\u0022:422}]},{\u0022normalizedTarget\u0022:\u0022pilotar\u0022,\u0022displayTarget\u0022:\u0022pilotar\u0022,\u0022posTag\u0022:\u0022VERB\u0022,\u0022confidence\u0022:0.095,\u0022prefixWord\u0022:\u0022\u0022,\u0022backTranslations\u0022:[{\u0022normalizedText\u0022:\u0022fly\u0022,\u0022displayText\u0022:\u0022fly\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:104},{\u0022normalizedText\u0022:\u0022pilot\u0022,\u0022displayText\u0022:\u0022pilot\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:61}]},{\u0022normalizedTarget\u0022:\u0022moscas\u0022,\u0022displayTarget\u0022:\u0022moscas\u0022,\u0022posTag\u0022:\u0022VERB\u0022,\u0022confidence\u0022:0.0644,\u0022prefixWord\u0022:\u0022\u0022,\u0022backTranslations\u0022:[{\u0022normalizedText\u0022:\u0022flies\u0022,\u0022displayText\u0022:\u0022flies\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:1219},{\u0022normalizedText\u0022:\u0022fly\u0022,\u0022displayText\u0022:\u0022fly\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:143}]},{\u0022normalizedTarget\u0022:\u0022marcha\u0022,\u0022displayTarget\u0022:\u0022marcha\u0022,\u0022posTag\u0022:\u0022NOUN\u0022,\u0022confidence\u0022:0.0514,\u0022prefixWord\u0022:\u0022\u0022,\u0022backTranslations\u0022:[{\u0022normalizedText\u0022:\u0022march\u0022,\u0022displayText\u0022:\u0022March\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:5355},{\u0022normalizedText\u0022:\u0022up\u0022,\u0022displayText\u0022:\u0022up\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:1277},{\u0022normalizedText\u0022:\u0022running\u0022,\u0022displayText\u0022:\u0022running\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:752},{\u0022normalizedText\u0022:\u0022going\u0022,\u0022displayText\u0022:\u0022going\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:570},{\u0022normalizedText\u0022:\u0022fly\u0022,\u0022displayText\u0022:\u0022fly\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:253}]}]},{\u0022normalizedSource\u0022:\u0022fox\u0022,\u0022displaySource\u0022:\u0022fox\u0022,\u0022translations\u0022:[{\u0022normalizedTarget\u0022:\u0022fox\u0022,\u0022displayTarget\u0022:\u0022Fox\u0022,\u0022posTag\u0022:\u0022NOUN\u0022,\u0022confidence\u0022:0.5333,\u0022prefixWord\u0022:\u0022\u0022,\u0022backTranslations\u0022:[{\u0022normalizedText\u0022:\u0022fox\u0022,\u0022displayText\u0022:\u0022fox\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:2888}]},{\u0022normalizedTarget\u0022:\u0022zorro\u0022,\u0022displayTarget\u0022:\u0022zorro\u0022,\u0022posTag\u0022:\u0022NOUN\u0022,\u0022confidence\u0022:0.4667,\u0022prefixWord\u0022:\u0022\u0022,\u0022backTranslations\u0022:[{\u0022normalizedText\u0022:\u0022fox\u0022,\u0022displayText\u0022:\u0022fox\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:1984},{\u0022normalizedText\u0022:\u0022thresher\u0022,\u0022displayText\u0022:\u0022thresher\u0022,\u0022numExamples\u0022:0,\u0022frequencyCount\u0022:16},{\u0022normalizedText\u0022:\u0022foxes\u0022,\u0022displayText\u0022:\u0022foxes\u0022,\u0022numExamples\u0022:5,\u0022frequencyCount\u0022:15}]}]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_dictionary_lookup.pyTestDictionaryLookuptest_single_input_element.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_dictionary_lookup.pyTestDictionaryLookuptest_single_input_element.json new file mode 100644 index 000000000000..469d5a8f8592 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_dictionary_lookup.pyTestDictionaryLookuptest_single_input_element.json @@ -0,0 +1,35 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/dictionary/lookup?from=en\u0026to=es\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "17", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022fly\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Encoding": "gzip", + "Content-Length": "2387", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:52 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "3", + "X-RequestId": "DTLK.MW1P.99BE.0403T2149.2FCA4D7" + }, + "ResponseBody": "[{\u0022normalizedSource\u0022:\u0022fly\u0022,\u0022displaySource\u0022:\u0022fly\u0022,\u0022translations\u0022:[{\u0022normalizedTarget\u0022:\u0022volar\u0022,\u0022displayTarget\u0022:\u0022volar\u0022,\u0022posTag\u0022:\u0022VERB\u0022,\u0022confidence\u0022:0.4081,\u0022prefixWord\u0022:\u0022\u0022,\u0022backTranslations\u0022:[{\u0022normalizedText\u0022:\u0022fly\u0022,\u0022displayText\u0022:\u0022fly\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:4637},{\u0022normalizedText\u0022:\u0022flying\u0022,\u0022displayText\u0022:\u0022flying\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:1365},{\u0022normalizedText\u0022:\u0022blow\u0022,\u0022displayText\u0022:\u0022blow\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:503},{\u0022normalizedText\u0022:\u0022flight\u0022,\u0022displayText\u0022:\u0022flight\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:135}]},{\u0022normalizedTarget\u0022:\u0022mosca\u0022,\u0022displayTarget\u0022:\u0022mosca\u0022,\u0022posTag\u0022:\u0022NOUN\u0022,\u0022confidence\u0022:0.2668,\u0022prefixWord\u0022:\u0022\u0022,\u0022backTranslations\u0022:[{\u0022normalizedText\u0022:\u0022fly\u0022,\u0022displayText\u0022:\u0022fly\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:1697},{\u0022normalizedText\u0022:\u0022flyweight\u0022,\u0022displayText\u0022:\u0022flyweight\u0022,\u0022numExamples\u0022:0,\u0022frequencyCount\u0022:48},{\u0022normalizedText\u0022:\u0022flies\u0022,\u0022displayText\u0022:\u0022flies\u0022,\u0022numExamples\u0022:9,\u0022frequencyCount\u0022:34}]},{\u0022normalizedTarget\u0022:\u0022operan\u0022,\u0022displayTarget\u0022:\u0022operan\u0022,\u0022posTag\u0022:\u0022VERB\u0022,\u0022confidence\u0022:0.1144,\u0022prefixWord\u0022:\u0022\u0022,\u0022backTranslations\u0022:[{\u0022normalizedText\u0022:\u0022operate\u0022,\u0022displayText\u0022:\u0022operate\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:1344},{\u0022normalizedText\u0022:\u0022fly\u0022,\u0022displayText\u0022:\u0022fly\u0022,\u0022numExamples\u0022:1,\u0022frequencyCount\u0022:422}]},{\u0022normalizedTarget\u0022:\u0022pilotar\u0022,\u0022displayTarget\u0022:\u0022pilotar\u0022,\u0022posTag\u0022:\u0022VERB\u0022,\u0022confidence\u0022:0.095,\u0022prefixWord\u0022:\u0022\u0022,\u0022backTranslations\u0022:[{\u0022normalizedText\u0022:\u0022fly\u0022,\u0022displayText\u0022:\u0022fly\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:104},{\u0022normalizedText\u0022:\u0022pilot\u0022,\u0022displayText\u0022:\u0022pilot\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:61}]},{\u0022normalizedTarget\u0022:\u0022moscas\u0022,\u0022displayTarget\u0022:\u0022moscas\u0022,\u0022posTag\u0022:\u0022VERB\u0022,\u0022confidence\u0022:0.0644,\u0022prefixWord\u0022:\u0022\u0022,\u0022backTranslations\u0022:[{\u0022normalizedText\u0022:\u0022flies\u0022,\u0022displayText\u0022:\u0022flies\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:1219},{\u0022normalizedText\u0022:\u0022fly\u0022,\u0022displayText\u0022:\u0022fly\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:143}]},{\u0022normalizedTarget\u0022:\u0022marcha\u0022,\u0022displayTarget\u0022:\u0022marcha\u0022,\u0022posTag\u0022:\u0022NOUN\u0022,\u0022confidence\u0022:0.0514,\u0022prefixWord\u0022:\u0022\u0022,\u0022backTranslations\u0022:[{\u0022normalizedText\u0022:\u0022march\u0022,\u0022displayText\u0022:\u0022March\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:5355},{\u0022normalizedText\u0022:\u0022up\u0022,\u0022displayText\u0022:\u0022up\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:1277},{\u0022normalizedText\u0022:\u0022running\u0022,\u0022displayText\u0022:\u0022running\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:752},{\u0022normalizedText\u0022:\u0022going\u0022,\u0022displayText\u0022:\u0022going\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:570},{\u0022normalizedText\u0022:\u0022fly\u0022,\u0022displayText\u0022:\u0022fly\u0022,\u0022numExamples\u0022:15,\u0022frequencyCount\u0022:253}]}]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_all_scopes.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_all_scopes.json new file mode 100644 index 000000000000..9ee39218c4a4 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_all_scopes.json @@ -0,0 +1,2800 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/languages?api-version=3.0", + "RequestMethod": "GET", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": "X-RequestId", + "Content-Encoding": "gzip", + "Content-Length": "33050", + "Content-Type": "application/json", + "Date": "Mon, 03 Apr 2023 21:49:52 GMT", + "ETag": "\u0022E9kr19NI7myV5cMR0slywl7KhNj9otulW0prhqt43w8=\u0022", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-RequestId": "LANG.MW1P.99BE.0403T2149.2FCA4F8" + }, + "ResponseBody": { + "translation": { + "af": { + "name": "Afrikaans", + "nativeName": "Afrikaans", + "dir": "ltr" + }, + "am": { + "name": "Amharic", + "nativeName": "\u12A0\u121B\u122D\u129B", + "dir": "ltr" + }, + "ar": { + "name": "Arabic", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "dir": "rtl" + }, + "as": { + "name": "Assamese", + "nativeName": "\u0985\u09B8\u09AE\u09C0\u09AF\u09BC\u09BE", + "dir": "ltr" + }, + "az": { + "name": "Azerbaijani", + "nativeName": "Az\u0259rbaycan", + "dir": "ltr" + }, + "ba": { + "name": "Bashkir", + "nativeName": "Bashkir", + "dir": "ltr" + }, + "bg": { + "name": "Bulgarian", + "nativeName": "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438", + "dir": "ltr" + }, + "bn": { + "name": "Bangla", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr" + }, + "bo": { + "name": "Tibetan", + "nativeName": "\u0F56\u0F7C\u0F51\u0F0B\u0F66\u0F90\u0F51\u0F0B", + "dir": "ltr" + }, + "bs": { + "name": "Bosnian", + "nativeName": "Bosnian", + "dir": "ltr" + }, + "ca": { + "name": "Catalan", + "nativeName": "Catal\u00E0", + "dir": "ltr" + }, + "cs": { + "name": "Czech", + "nativeName": "\u010Ce\u0161tina", + "dir": "ltr" + }, + "cy": { + "name": "Welsh", + "nativeName": "Cymraeg", + "dir": "ltr" + }, + "da": { + "name": "Danish", + "nativeName": "Dansk", + "dir": "ltr" + }, + "de": { + "name": "German", + "nativeName": "Deutsch", + "dir": "ltr" + }, + "dv": { + "name": "Divehi", + "nativeName": "\u078B\u07A8\u0788\u07AC\u0780\u07A8\u0784\u07A6\u0790\u07B0", + "dir": "rtl" + }, + "el": { + "name": "Greek", + "nativeName": "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC", + "dir": "ltr" + }, + "en": { + "name": "English", + "nativeName": "English", + "dir": "ltr" + }, + "es": { + "name": "Spanish", + "nativeName": "Espa\u00F1ol", + "dir": "ltr" + }, + "et": { + "name": "Estonian", + "nativeName": "Eesti", + "dir": "ltr" + }, + "eu": { + "name": "Basque", + "nativeName": "Euskara", + "dir": "ltr" + }, + "fa": { + "name": "Persian", + "nativeName": "\u0641\u0627\u0631\u0633\u06CC", + "dir": "rtl" + }, + "fi": { + "name": "Finnish", + "nativeName": "Suomi", + "dir": "ltr" + }, + "fil": { + "name": "Filipino", + "nativeName": "Filipino", + "dir": "ltr" + }, + "fj": { + "name": "Fijian", + "nativeName": "Na Vosa Vakaviti", + "dir": "ltr" + }, + "fo": { + "name": "Faroese", + "nativeName": "F\u00F8royskt", + "dir": "ltr" + }, + "fr": { + "name": "French", + "nativeName": "Fran\u00E7ais", + "dir": "ltr" + }, + "fr-CA": { + "name": "French (Canada)", + "nativeName": "Fran\u00E7ais (Canada)", + "dir": "ltr" + }, + "ga": { + "name": "Irish", + "nativeName": "Gaeilge", + "dir": "ltr" + }, + "gl": { + "name": "Galician", + "nativeName": "Galego", + "dir": "ltr" + }, + "gu": { + "name": "Gujarati", + "nativeName": "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0", + "dir": "ltr" + }, + "ha": { + "name": "Hausa", + "nativeName": "Hausa", + "dir": "ltr" + }, + "he": { + "name": "Hebrew", + "nativeName": "\u05E2\u05D1\u05E8\u05D9\u05EA", + "dir": "rtl" + }, + "hi": { + "name": "Hindi", + "nativeName": "\u0939\u093F\u0928\u094D\u0926\u0940", + "dir": "ltr" + }, + "hr": { + "name": "Croatian", + "nativeName": "Hrvatski", + "dir": "ltr" + }, + "hsb": { + "name": "Upper Sorbian", + "nativeName": "Hornjoserb\u0161\u0107ina", + "dir": "ltr" + }, + "ht": { + "name": "Haitian Creole", + "nativeName": "Haitian Creole", + "dir": "ltr" + }, + "hu": { + "name": "Hungarian", + "nativeName": "Magyar", + "dir": "ltr" + }, + "hy": { + "name": "Armenian", + "nativeName": "\u0540\u0561\u0575\u0565\u0580\u0565\u0576", + "dir": "ltr" + }, + "id": { + "name": "Indonesian", + "nativeName": "Indonesia", + "dir": "ltr" + }, + "ig": { + "name": "Igbo", + "nativeName": "\u00C1s\u1EE5\u0300s\u1EE5\u0301 \u00CCgb\u00F2", + "dir": "ltr" + }, + "ikt": { + "name": "Inuinnaqtun", + "nativeName": "Inuinnaqtun", + "dir": "ltr" + }, + "is": { + "name": "Icelandic", + "nativeName": "\u00CDslenska", + "dir": "ltr" + }, + "it": { + "name": "Italian", + "nativeName": "Italiano", + "dir": "ltr" + }, + "iu": { + "name": "Inuktitut", + "nativeName": "\u1403\u14C4\u1483\u144E\u1450\u1466", + "dir": "ltr" + }, + "iu-Latn": { + "name": "Inuktitut (Latin)", + "nativeName": "Inuktitut (Latin)", + "dir": "ltr" + }, + "ja": { + "name": "Japanese", + "nativeName": "\u65E5\u672C\u8A9E", + "dir": "ltr" + }, + "ka": { + "name": "Georgian", + "nativeName": "\u10E5\u10D0\u10E0\u10D7\u10E3\u10DA\u10D8", + "dir": "ltr" + }, + "kk": { + "name": "Kazakh", + "nativeName": "\u049A\u0430\u0437\u0430\u049B \u0422\u0456\u043B\u0456", + "dir": "ltr" + }, + "km": { + "name": "Khmer", + "nativeName": "\u1781\u17D2\u1798\u17C2\u179A", + "dir": "ltr" + }, + "kmr": { + "name": "Kurdish (Northern)", + "nativeName": "Kurd\u00EE (Bakur)", + "dir": "ltr" + }, + "kn": { + "name": "Kannada", + "nativeName": "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1", + "dir": "ltr" + }, + "ko": { + "name": "Korean", + "nativeName": "\uD55C\uAD6D\uC5B4", + "dir": "ltr" + }, + "ku": { + "name": "Kurdish (Central)", + "nativeName": "Kurd\u00EE (Nav\u00EEn)", + "dir": "rtl" + }, + "ky": { + "name": "Kyrgyz", + "nativeName": "\u041A\u044B\u0440\u0433\u044B\u0437\u0447\u0430", + "dir": "ltr" + }, + "ln": { + "name": "Lingala", + "nativeName": "Ling\u00E1la", + "dir": "ltr" + }, + "lo": { + "name": "Lao", + "nativeName": "\u0EA5\u0EB2\u0EA7", + "dir": "ltr" + }, + "lt": { + "name": "Lithuanian", + "nativeName": "Lietuvi\u0173", + "dir": "ltr" + }, + "lug": { + "name": "Ganda", + "nativeName": "Ganda", + "dir": "ltr" + }, + "lv": { + "name": "Latvian", + "nativeName": "Latvie\u0161u", + "dir": "ltr" + }, + "lzh": { + "name": "Chinese (Literary)", + "nativeName": "\u4E2D\u6587 (\u6587\u8A00\u6587)", + "dir": "ltr" + }, + "mg": { + "name": "Malagasy", + "nativeName": "Malagasy", + "dir": "ltr" + }, + "mi": { + "name": "M\u0101ori", + "nativeName": "Te Reo M\u0101ori", + "dir": "ltr" + }, + "mk": { + "name": "Macedonian", + "nativeName": "\u041C\u0430\u043A\u0435\u0434\u043E\u043D\u0441\u043A\u0438", + "dir": "ltr" + }, + "ml": { + "name": "Malayalam", + "nativeName": "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02", + "dir": "ltr" + }, + "mn-Cyrl": { + "name": "Mongolian (Cyrillic)", + "nativeName": "Mongolian (Cyrillic)", + "dir": "ltr" + }, + "mn-Mong": { + "name": "Mongolian (Traditional)", + "nativeName": "\u182E\u1823\u1829\u182D\u1823\u182F \u182C\u1821\u182F\u1821", + "dir": "ltr" + }, + "mr": { + "name": "Marathi", + "nativeName": "\u092E\u0930\u093E\u0920\u0940", + "dir": "ltr" + }, + "ms": { + "name": "Malay", + "nativeName": "Melayu", + "dir": "ltr" + }, + "mt": { + "name": "Maltese", + "nativeName": "Malti", + "dir": "ltr" + }, + "mww": { + "name": "Hmong Daw", + "nativeName": "Hmong Daw", + "dir": "ltr" + }, + "my": { + "name": "Myanmar (Burmese)", + "nativeName": "\u1019\u103C\u1014\u103A\u1019\u102C", + "dir": "ltr" + }, + "nb": { + "name": "Norwegian", + "nativeName": "Norsk Bokm\u00E5l", + "dir": "ltr" + }, + "ne": { + "name": "Nepali", + "nativeName": "\u0928\u0947\u092A\u093E\u0932\u0940", + "dir": "ltr" + }, + "nl": { + "name": "Dutch", + "nativeName": "Nederlands", + "dir": "ltr" + }, + "nso": { + "name": "Sesotho sa Leboa", + "nativeName": "Sesotho sa Leboa", + "dir": "ltr" + }, + "nya": { + "name": "Nyanja", + "nativeName": "Nyanja", + "dir": "ltr" + }, + "or": { + "name": "Odia", + "nativeName": "\u0B13\u0B21\u0B3C\u0B3F\u0B06", + "dir": "ltr" + }, + "otq": { + "name": "Quer\u00E9taro Otomi", + "nativeName": "H\u00F1\u00E4h\u00F1u", + "dir": "ltr" + }, + "pa": { + "name": "Punjabi", + "nativeName": "\u0A2A\u0A70\u0A1C\u0A3E\u0A2C\u0A40", + "dir": "ltr" + }, + "pl": { + "name": "Polish", + "nativeName": "Polski", + "dir": "ltr" + }, + "prs": { + "name": "Dari", + "nativeName": "\u062F\u0631\u06CC", + "dir": "rtl" + }, + "ps": { + "name": "Pashto", + "nativeName": "\u067E\u069A\u062A\u0648", + "dir": "rtl" + }, + "pt": { + "name": "Portuguese (Brazil)", + "nativeName": "Portugu\u00EAs (Brasil)", + "dir": "ltr" + }, + "pt-PT": { + "name": "Portuguese (Portugal)", + "nativeName": "Portugu\u00EAs (Portugal)", + "dir": "ltr" + }, + "ro": { + "name": "Romanian", + "nativeName": "Rom\u00E2n\u0103", + "dir": "ltr" + }, + "ru": { + "name": "Russian", + "nativeName": "\u0420\u0443\u0441\u0441\u043A\u0438\u0439", + "dir": "ltr" + }, + "run": { + "name": "Rundi", + "nativeName": "Rundi", + "dir": "ltr" + }, + "rw": { + "name": "Kinyarwanda", + "nativeName": "Kinyarwanda", + "dir": "ltr" + }, + "sk": { + "name": "Slovak", + "nativeName": "Sloven\u010Dina", + "dir": "ltr" + }, + "sl": { + "name": "Slovenian", + "nativeName": "Sloven\u0161\u010Dina", + "dir": "ltr" + }, + "sm": { + "name": "Samoan", + "nativeName": "Gagana S\u0101moa", + "dir": "ltr" + }, + "sn": { + "name": "Shona", + "nativeName": "chiShona", + "dir": "ltr" + }, + "so": { + "name": "Somali", + "nativeName": "Soomaali", + "dir": "ltr" + }, + "sq": { + "name": "Albanian", + "nativeName": "Shqip", + "dir": "ltr" + }, + "sr-Cyrl": { + "name": "Serbian (Cyrillic)", + "nativeName": "\u0421\u0440\u043F\u0441\u043A\u0438 (\u045B\u0438\u0440\u0438\u043B\u0438\u0446\u0430)", + "dir": "ltr" + }, + "sr-Latn": { + "name": "Serbian (Latin)", + "nativeName": "Srpski (latinica)", + "dir": "ltr" + }, + "st": { + "name": "Sesotho", + "nativeName": "Sesotho", + "dir": "ltr" + }, + "sv": { + "name": "Swedish", + "nativeName": "Svenska", + "dir": "ltr" + }, + "sw": { + "name": "Swahili", + "nativeName": "Kiswahili", + "dir": "ltr" + }, + "ta": { + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "dir": "ltr" + }, + "te": { + "name": "Telugu", + "nativeName": "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41", + "dir": "ltr" + }, + "th": { + "name": "Thai", + "nativeName": "\u0E44\u0E17\u0E22", + "dir": "ltr" + }, + "ti": { + "name": "Tigrinya", + "nativeName": "\u1275\u130D\u122D", + "dir": "ltr" + }, + "tk": { + "name": "Turkmen", + "nativeName": "T\u00FCrkmen Dili", + "dir": "ltr" + }, + "tlh-Latn": { + "name": "Klingon (Latin)", + "nativeName": "Klingon (Latin)", + "dir": "ltr" + }, + "tlh-Piqd": { + "name": "Klingon (pIqaD)", + "nativeName": "Klingon (pIqaD)", + "dir": "ltr" + }, + "tn": { + "name": "Setswana", + "nativeName": "Setswana", + "dir": "ltr" + }, + "to": { + "name": "Tongan", + "nativeName": "Lea Fakatonga", + "dir": "ltr" + }, + "tr": { + "name": "Turkish", + "nativeName": "T\u00FCrk\u00E7e", + "dir": "ltr" + }, + "tt": { + "name": "Tatar", + "nativeName": "\u0422\u0430\u0442\u0430\u0440", + "dir": "ltr" + }, + "ty": { + "name": "Tahitian", + "nativeName": "Reo Tahiti", + "dir": "ltr" + }, + "ug": { + "name": "Uyghur", + "nativeName": "\u0626\u06C7\u064A\u063A\u06C7\u0631\u0686\u06D5", + "dir": "rtl" + }, + "uk": { + "name": "Ukrainian", + "nativeName": "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430", + "dir": "ltr" + }, + "ur": { + "name": "Urdu", + "nativeName": "\u0627\u0631\u062F\u0648", + "dir": "rtl" + }, + "uz": { + "name": "Uzbek (Latin)", + "nativeName": "Uzbek (Latin)", + "dir": "ltr" + }, + "vi": { + "name": "Vietnamese", + "nativeName": "Ti\u1EBFng Vi\u1EC7t", + "dir": "ltr" + }, + "xh": { + "name": "Xhosa", + "nativeName": "isiXhosa", + "dir": "ltr" + }, + "yo": { + "name": "Yoruba", + "nativeName": "\u00C8d\u00E8 Yor\u00F9b\u00E1", + "dir": "ltr" + }, + "yua": { + "name": "Yucatec Maya", + "nativeName": "Yucatec Maya", + "dir": "ltr" + }, + "yue": { + "name": "Cantonese (Traditional)", + "nativeName": "\u7CB5\u8A9E (\u7E41\u9AD4)", + "dir": "ltr" + }, + "zh-Hans": { + "name": "Chinese Simplified", + "nativeName": "\u4E2D\u6587 (\u7B80\u4F53)", + "dir": "ltr" + }, + "zh-Hant": { + "name": "Chinese Traditional", + "nativeName": "\u7E41\u9AD4\u4E2D\u6587 (\u7E41\u9AD4)", + "dir": "ltr" + }, + "zu": { + "name": "Zulu", + "nativeName": "Isi-Zulu", + "dir": "ltr" + } + }, + "transliteration": { + "ar": { + "name": "Arabic", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "scripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "dir": "rtl", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0627\u0644\u0644\u0627\u062A\u064A\u0646\u064A\u0629", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0627\u0644\u0644\u0627\u062A\u064A\u0646\u064A\u0629", + "dir": "ltr", + "toScripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "dir": "rtl" + } + ] + } + ] + }, + "as": { + "name": "Assamese", + "nativeName": "\u0985\u09B8\u09AE\u09C0\u09AF\u09BC\u09BE", + "scripts": [ + { + "code": "Beng", + "name": "Bengali", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u09B2\u09C7\u099F\u09BF\u09A8", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u09B2\u09C7\u099F\u09BF\u09A8", + "dir": "ltr", + "toScripts": [ + { + "code": "Beng", + "name": "Bangla", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr" + } + ] + } + ] + }, + "be": { + "name": "Belarusian", + "nativeName": "Belarusian", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "Cyrillic", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "Cyrillic", + "dir": "ltr" + } + ] + } + ] + }, + "bg": { + "name": "Bulgarian", + "nativeName": "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u0430", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0438\u0446\u0430", + "dir": "ltr" + } + ] + } + ] + }, + "bn": { + "name": "Bangla", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "scripts": [ + { + "code": "Beng", + "name": "Bengali", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u09B2\u09CD\u09AF\u09BE\u099F\u09BF\u09A8", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u09B2\u09CD\u09AF\u09BE\u099F\u09BF\u09A8", + "dir": "ltr", + "toScripts": [ + { + "code": "Beng", + "name": "Bangla", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr" + } + ] + } + ] + }, + "el": { + "name": "Greek", + "nativeName": "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC", + "scripts": [ + { + "code": "Grek", + "name": "Greek", + "nativeName": "\u03B5\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03CC", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u03BB\u03B1\u03C4\u03B9\u03BD\u03B9\u03BA\u03CC", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u03BB\u03B1\u03C4\u03B9\u03BD\u03B9\u03BA\u03CC", + "dir": "ltr", + "toScripts": [ + { + "code": "Grek", + "name": "Greek", + "nativeName": "\u03B5\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03CC", + "dir": "ltr" + } + ] + } + ] + }, + "fa": { + "name": "Persian", + "nativeName": "\u0641\u0627\u0631\u0633\u06CC", + "scripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0639\u0631\u0628\u06CC", + "dir": "rtl", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0644\u0627\u062A\u06CC\u0646", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0644\u0627\u062A\u06CC\u0646", + "dir": "ltr", + "toScripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0639\u0631\u0628\u06CC", + "dir": "rtl" + } + ] + } + ] + }, + "gu": { + "name": "Gujarati", + "nativeName": "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0", + "scripts": [ + { + "code": "Gujr", + "name": "Gujarati", + "nativeName": "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0AB2\u0AC7\u0A9F\u0ABF\u0AA8", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0AB2\u0AC7\u0A9F\u0ABF\u0AA8", + "dir": "ltr", + "toScripts": [ + { + "code": "Gujr", + "name": "Gujarati", + "nativeName": "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0", + "dir": "ltr" + } + ] + } + ] + }, + "he": { + "name": "Hebrew", + "nativeName": "\u05E2\u05D1\u05E8\u05D9\u05EA", + "scripts": [ + { + "code": "Hebr", + "name": "Hebrew", + "nativeName": "\u05E2\u05D1\u05E8\u05D9", + "dir": "rtl", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u05DC\u05D8\u05D9\u05E0\u05D9", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u05DC\u05D8\u05D9\u05E0\u05D9", + "dir": "ltr", + "toScripts": [ + { + "code": "Hebr", + "name": "Hebrew", + "nativeName": "\u05E2\u05D1\u05E8\u05D9", + "dir": "rtl" + } + ] + } + ] + }, + "hi": { + "name": "Hindi", + "nativeName": "\u0939\u093F\u0928\u094D\u0926\u0940", + "scripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u0948\u091F\u093F\u0928", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u0948\u091F\u093F\u0928", + "dir": "ltr", + "toScripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr" + } + ] + } + ] + }, + "ja": { + "name": "Japanese", + "nativeName": "\u65E5\u672C\u8A9E", + "scripts": [ + { + "code": "Jpan", + "name": "Japanese", + "nativeName": "\u65E5\u672C\u8A9E\u306E\u6587\u5B57", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u30E9\u30C6\u30F3\u6587\u5B57", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u30E9\u30C6\u30F3\u6587\u5B57", + "dir": "ltr", + "toScripts": [ + { + "code": "Jpan", + "name": "Japanese", + "nativeName": "\u65E5\u672C\u8A9E\u306E\u6587\u5B57", + "dir": "ltr" + } + ] + } + ] + }, + "kk": { + "name": "Kazakh", + "nativeName": "\u049A\u0430\u0437\u0430\u049B \u0422\u0456\u043B\u0456", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B \u0436\u0430\u0437\u0443\u044B", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u044B\u043D \u0436\u0430\u0437\u0443\u044B", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u044B\u043D \u0436\u0430\u0437\u0443\u044B", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B \u0436\u0430\u0437\u0443\u044B", + "dir": "ltr" + } + ] + } + ] + }, + "kn": { + "name": "Kannada", + "nativeName": "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1", + "scripts": [ + { + "code": "Knda", + "name": "Kannada", + "nativeName": "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0CB2\u0CCD\u0CAF\u0CBE\u0C9F\u0CBF\u0CA8\u0CCD", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0CB2\u0CCD\u0CAF\u0CBE\u0C9F\u0CBF\u0CA8\u0CCD", + "dir": "ltr", + "toScripts": [ + { + "code": "Knda", + "name": "Kannada", + "nativeName": "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1", + "dir": "ltr" + } + ] + } + ] + }, + "ko": { + "name": "Korean", + "nativeName": "\uD55C\uAD6D\uC5B4", + "scripts": [ + { + "code": "Kore", + "name": "Korean", + "nativeName": "\uD55C\uAD6D \uBB38\uC790", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\uB85C\uB9C8\uC790", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\uB85C\uB9C8\uC790", + "dir": "ltr", + "toScripts": [ + { + "code": "Kore", + "name": "Korean", + "nativeName": "\uD55C\uAD6D \uBB38\uC790", + "dir": "ltr" + } + ] + } + ] + }, + "ky": { + "name": "Kyrgyz", + "nativeName": "\u041A\u044B\u0440\u0433\u044B\u0437\u0447\u0430", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u044B\u043D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u044B\u043D", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr" + } + ] + } + ] + }, + "mk": { + "name": "Macedonian", + "nativeName": "\u041C\u0430\u043A\u0435\u0434\u043E\u043D\u0441\u043A\u0438", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0441\u043A\u043E \u043F\u0438\u0441\u043C\u043E", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0447\u043D\u043E \u043F\u0438\u0441\u043C\u043E", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0447\u043D\u043E \u043F\u0438\u0441\u043C\u043E", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0441\u043A\u043E \u043F\u0438\u0441\u043C\u043E", + "dir": "ltr" + } + ] + } + ] + }, + "ml": { + "name": "Malayalam", + "nativeName": "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02", + "scripts": [ + { + "code": "Mlym", + "name": "Malayalam", + "nativeName": "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0D32\u0D3E\u0D31\u0D4D\u0D31\u0D3F\u0D7B", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0D32\u0D3E\u0D31\u0D4D\u0D31\u0D3F\u0D7B", + "dir": "ltr", + "toScripts": [ + { + "code": "Mlym", + "name": "Malayalam", + "nativeName": "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02", + "dir": "ltr" + } + ] + } + ] + }, + "mn-Cyrl": { + "name": "Mongolian (Cyrillic)", + "nativeName": "Mongolian (Cyrillic)", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr" + } + ] + } + ] + }, + "mr": { + "name": "Marathi", + "nativeName": "\u092E\u0930\u093E\u0920\u0940", + "scripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u0945\u091F\u093F\u0928", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u0945\u091F\u093F\u0928", + "dir": "ltr", + "toScripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr" + } + ] + } + ] + }, + "ne": { + "name": "Nepali", + "nativeName": "\u0928\u0947\u092A\u093E\u0932\u0940", + "scripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u093E\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u094D\u092F\u093E\u091F\u093F\u0928", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u094D\u092F\u093E\u091F\u093F\u0928", + "dir": "ltr", + "toScripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u093E\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr" + } + ] + } + ] + }, + "or": { + "name": "Odia", + "nativeName": "\u0B13\u0B21\u0B3C\u0B3F\u0B06", + "scripts": [ + { + "code": "Orya", + "name": "Odia", + "nativeName": "\u0B13\u0B21\u0B3C\u0B3F\u0B06", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0B32\u0B3E\u0B1F\u0B3F\u0B28\u0B4D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0B32\u0B3E\u0B1F\u0B3F\u0B28\u0B4D", + "dir": "ltr", + "toScripts": [ + { + "code": "Orya", + "name": "Odia", + "nativeName": "\u0B13\u0B21\u0B3C\u0B3F\u0B06", + "dir": "ltr" + } + ] + } + ] + }, + "pa": { + "name": "Punjabi", + "nativeName": "\u0A2A\u0A70\u0A1C\u0A3E\u0A2C\u0A40", + "scripts": [ + { + "code": "Guru", + "name": "Gurmukhi", + "nativeName": "\u0A17\u0A41\u0A30\u0A2E\u0A41\u0A16\u0A40", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0A32\u0A3E\u0A24\u0A40\u0A28\u0A40", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0A32\u0A3E\u0A24\u0A40\u0A28\u0A40", + "dir": "ltr", + "toScripts": [ + { + "code": "Guru", + "name": "Gurmukhi", + "nativeName": "\u0A17\u0A41\u0A30\u0A2E\u0A41\u0A16\u0A40", + "dir": "ltr" + } + ] + } + ] + }, + "ru": { + "name": "Russian", + "nativeName": "\u0420\u0443\u0441\u0441\u043A\u0438\u0439", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u0430", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B\u0438\u0446\u0430", + "dir": "ltr" + } + ] + } + ] + }, + "sd": { + "name": "Sindhi", + "nativeName": "\u0633\u0646\u068C\u064A", + "scripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "Arabic", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr", + "toScripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "Arabic", + "dir": "ltr" + } + ] + } + ] + }, + "si": { + "name": "Sinhala", + "nativeName": "\u0DC3\u0DD2\u0D82\u0DC4\u0DBD", + "scripts": [ + { + "code": "Sinh", + "name": "Sinhala", + "nativeName": "Sinhala", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr", + "toScripts": [ + { + "code": "Sinh", + "name": "Sinhala", + "nativeName": "Sinhala", + "dir": "ltr" + } + ] + } + ] + }, + "sr-Cyrl": { + "name": "Serbian (Cyrillic)", + "nativeName": "\u0421\u0440\u043F\u0441\u043A\u0438 (\u045B\u0438\u0440\u0438\u043B\u0438\u0446\u0430)", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u045B\u0438\u0440\u0438\u043B\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "latinica", + "dir": "ltr" + } + ] + } + ] + }, + "sr-Latn": { + "name": "Serbian (Latin)", + "nativeName": "Srpski (latinica)", + "scripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "latinica", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u0107irilica", + "dir": "ltr" + } + ] + } + ] + }, + "ta": { + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "scripts": [ + { + "code": "Taml", + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0BB2\u0BA4\u0BCD\u0BA4\u0BBF\u0BA9\u0BCD", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0BB2\u0BA4\u0BCD\u0BA4\u0BBF\u0BA9\u0BCD", + "dir": "ltr", + "toScripts": [ + { + "code": "Taml", + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "dir": "ltr" + } + ] + } + ] + }, + "te": { + "name": "Telugu", + "nativeName": "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41", + "scripts": [ + { + "code": "Telu", + "name": "Telugu", + "nativeName": "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0C32\u0C3E\u0C1F\u0C3F\u0C28\u0C4D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0C32\u0C3E\u0C1F\u0C3F\u0C28\u0C4D", + "dir": "ltr", + "toScripts": [ + { + "code": "Telu", + "name": "Telugu", + "nativeName": "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41", + "dir": "ltr" + } + ] + } + ] + }, + "tg": { + "name": "Tajik", + "nativeName": "Tajik (Cyrillic)", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "Cyrillic", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "Cyrillic", + "dir": "ltr" + } + ] + } + ] + }, + "th": { + "name": "Thai", + "nativeName": "\u0E44\u0E17\u0E22", + "scripts": [ + { + "code": "Thai", + "name": "Thai", + "nativeName": "\u0E44\u0E17\u0E22", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0E25\u0E30\u0E15\u0E34\u0E19", + "dir": "ltr" + } + ] + } + ] + }, + "tt": { + "name": "Tatar", + "nativeName": "\u0422\u0430\u0442\u0430\u0440", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr" + } + ] + } + ] + }, + "uk": { + "name": "Ukrainian", + "nativeName": "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0438\u0446\u044F", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u044F", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u044F", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0438\u0446\u044F", + "dir": "ltr" + } + ] + } + ] + }, + "ur": { + "name": "Urdu", + "nativeName": "\u0627\u0631\u062F\u0648", + "scripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0639\u0631\u0628\u06CC", + "dir": "rtl", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0644\u0627\u0637\u06CC\u0646\u06CC", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0644\u0627\u0637\u06CC\u0646\u06CC", + "dir": "ltr", + "toScripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0639\u0631\u0628\u06CC", + "dir": "rtl" + } + ] + } + ] + }, + "zh-Hans": { + "name": "Chinese Simplified", + "nativeName": "\u4E2D\u6587 (\u7B80\u4F53)", + "scripts": [ + { + "code": "Hans", + "name": "Simplified", + "nativeName": "\u7B80\u4F53\u6C49\u8BED", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u62C9\u4E01\u8BED", + "dir": "ltr" + }, + { + "code": "Hant", + "name": "Hat", + "nativeName": "\u4F20\u7EDF", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u62C9\u4E01\u8BED", + "dir": "ltr", + "toScripts": [ + { + "code": "Hans", + "name": "Han", + "nativeName": "\u7B80\u4F53\u6C49\u8BED", + "dir": "ltr" + }, + { + "code": "Hant", + "name": "Hat", + "nativeName": "\u4F20\u7EDF", + "dir": "ltr" + } + ] + } + ] + }, + "zh-Hant": { + "name": "Chinese Traditional", + "nativeName": "\u7E41\u9AD4\u4E2D\u6587 (\u7E41\u9AD4)", + "scripts": [ + { + "code": "Hant", + "name": "Traditional", + "nativeName": "\u50B3\u7D71", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u62C9\u4E01\u8BED", + "dir": "ltr" + }, + { + "code": "Hans", + "name": "Han", + "nativeName": "\u7B80\u4F53\u6C49\u8BED", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u62C9\u4E01\u6587", + "dir": "ltr", + "toScripts": [ + { + "code": "Hans", + "name": "Han", + "nativeName": "\u7B80\u4F53\u6C49\u8BED", + "dir": "ltr" + }, + { + "code": "Hant", + "name": "Hat", + "nativeName": "\u4F20\u7EDF", + "dir": "ltr" + } + ] + } + ] + } + }, + "dictionary": { + "af": { + "name": "Afrikaans", + "nativeName": "Afrikaans", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ar": { + "name": "Arabic", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "dir": "rtl", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "bg": { + "name": "Bulgarian", + "nativeName": "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "bn": { + "name": "Bangla", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "bs": { + "name": "Bosnian", + "nativeName": "Bosnian", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ca": { + "name": "Catalan", + "nativeName": "Catal\u00E0", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "cs": { + "name": "Czech", + "nativeName": "\u010Ce\u0161tina", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "cy": { + "name": "Welsh", + "nativeName": "Cymraeg", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "da": { + "name": "Danish", + "nativeName": "Dansk", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "de": { + "name": "German", + "nativeName": "Deutsch", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "el": { + "name": "Greek", + "nativeName": "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "en": { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "translations": [ + { + "name": "Afrikaans", + "nativeName": "Afrikaans", + "dir": "ltr", + "code": "af" + }, + { + "name": "Arabic", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "dir": "rtl", + "code": "ar" + }, + { + "name": "Bulgarian", + "nativeName": "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438", + "dir": "ltr", + "code": "bg" + }, + { + "name": "Bangla", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr", + "code": "bn" + }, + { + "name": "Bosnian", + "nativeName": "Bosnian", + "dir": "ltr", + "code": "bs" + }, + { + "name": "Catalan", + "nativeName": "Catal\u00E0", + "dir": "ltr", + "code": "ca" + }, + { + "name": "Chinese Simplified", + "nativeName": "\u4E2D\u6587 (\u7B80\u4F53)", + "dir": "ltr", + "code": "zh-Hans" + }, + { + "name": "Czech", + "nativeName": "\u010Ce\u0161tina", + "dir": "ltr", + "code": "cs" + }, + { + "name": "Welsh", + "nativeName": "Cymraeg", + "dir": "ltr", + "code": "cy" + }, + { + "name": "Danish", + "nativeName": "Dansk", + "dir": "ltr", + "code": "da" + }, + { + "name": "German", + "nativeName": "Deutsch", + "dir": "ltr", + "code": "de" + }, + { + "name": "Greek", + "nativeName": "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC", + "dir": "ltr", + "code": "el" + }, + { + "name": "Spanish", + "nativeName": "Espa\u00F1ol", + "dir": "ltr", + "code": "es" + }, + { + "name": "Estonian", + "nativeName": "Eesti", + "dir": "ltr", + "code": "et" + }, + { + "name": "Persian", + "nativeName": "\u0641\u0627\u0631\u0633\u06CC", + "dir": "rtl", + "code": "fa" + }, + { + "name": "Finnish", + "nativeName": "Suomi", + "dir": "ltr", + "code": "fi" + }, + { + "name": "French", + "nativeName": "Fran\u00E7ais", + "dir": "ltr", + "code": "fr" + }, + { + "name": "Hebrew", + "nativeName": "\u05E2\u05D1\u05E8\u05D9\u05EA", + "dir": "rtl", + "code": "he" + }, + { + "name": "Hindi", + "nativeName": "\u0939\u093F\u0928\u094D\u0926\u0940", + "dir": "ltr", + "code": "hi" + }, + { + "name": "Croatian", + "nativeName": "Hrvatski", + "dir": "ltr", + "code": "hr" + }, + { + "name": "Hungarian", + "nativeName": "Magyar", + "dir": "ltr", + "code": "hu" + }, + { + "name": "Indonesian", + "nativeName": "Indonesia", + "dir": "ltr", + "code": "id" + }, + { + "name": "Icelandic", + "nativeName": "\u00CDslenska", + "dir": "ltr", + "code": "is" + }, + { + "name": "Italian", + "nativeName": "Italiano", + "dir": "ltr", + "code": "it" + }, + { + "name": "Japanese", + "nativeName": "\u65E5\u672C\u8A9E", + "dir": "ltr", + "code": "ja" + }, + { + "name": "Korean", + "nativeName": "\uD55C\uAD6D\uC5B4", + "dir": "ltr", + "code": "ko" + }, + { + "name": "Lithuanian", + "nativeName": "Lietuvi\u0173", + "dir": "ltr", + "code": "lt" + }, + { + "name": "Latvian", + "nativeName": "Latvie\u0161u", + "dir": "ltr", + "code": "lv" + }, + { + "name": "Maltese", + "nativeName": "Malti", + "dir": "ltr", + "code": "mt" + }, + { + "name": "Malay", + "nativeName": "Melayu", + "dir": "ltr", + "code": "ms" + }, + { + "name": "Hmong Daw", + "nativeName": "Hmong Daw", + "dir": "ltr", + "code": "mww" + }, + { + "name": "Dutch", + "nativeName": "Nederlands", + "dir": "ltr", + "code": "nl" + }, + { + "name": "Norwegian", + "nativeName": "Norsk Bokm\u00E5l", + "dir": "ltr", + "code": "nb" + }, + { + "name": "Polish", + "nativeName": "Polski", + "dir": "ltr", + "code": "pl" + }, + { + "name": "Portuguese (Brazil)", + "nativeName": "Portugu\u00EAs (Brasil)", + "dir": "ltr", + "code": "pt" + }, + { + "name": "Romanian", + "nativeName": "Rom\u00E2n\u0103", + "dir": "ltr", + "code": "ro" + }, + { + "name": "Russian", + "nativeName": "\u0420\u0443\u0441\u0441\u043A\u0438\u0439", + "dir": "ltr", + "code": "ru" + }, + { + "name": "Slovak", + "nativeName": "Sloven\u010Dina", + "dir": "ltr", + "code": "sk" + }, + { + "name": "Slovenian", + "nativeName": "Sloven\u0161\u010Dina", + "dir": "ltr", + "code": "sl" + }, + { + "name": "Serbian (Latin)", + "nativeName": "Srpski (latinica)", + "dir": "ltr", + "code": "sr-Latn" + }, + { + "name": "Swedish", + "nativeName": "Svenska", + "dir": "ltr", + "code": "sv" + }, + { + "name": "Swahili", + "nativeName": "Kiswahili", + "dir": "ltr", + "code": "sw" + }, + { + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "dir": "ltr", + "code": "ta" + }, + { + "name": "Thai", + "nativeName": "\u0E44\u0E17\u0E22", + "dir": "ltr", + "code": "th" + }, + { + "name": "Klingon (Latin)", + "nativeName": "Klingon (Latin)", + "dir": "ltr", + "code": "tlh-Latn" + }, + { + "name": "Turkish", + "nativeName": "T\u00FCrk\u00E7e", + "dir": "ltr", + "code": "tr" + }, + { + "name": "Ukrainian", + "nativeName": "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430", + "dir": "ltr", + "code": "uk" + }, + { + "name": "Urdu", + "nativeName": "\u0627\u0631\u062F\u0648", + "dir": "rtl", + "code": "ur" + }, + { + "name": "Vietnamese", + "nativeName": "Ti\u1EBFng Vi\u1EC7t", + "dir": "ltr", + "code": "vi" + } + ] + }, + "es": { + "name": "Spanish", + "nativeName": "Espa\u00F1ol", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "et": { + "name": "Estonian", + "nativeName": "Eesti", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "fa": { + "name": "Persian", + "nativeName": "\u0641\u0627\u0631\u0633\u06CC", + "dir": "rtl", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "fi": { + "name": "Finnish", + "nativeName": "Suomi", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "fr": { + "name": "French", + "nativeName": "Fran\u00E7ais", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "he": { + "name": "Hebrew", + "nativeName": "\u05E2\u05D1\u05E8\u05D9\u05EA", + "dir": "rtl", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "hi": { + "name": "Hindi", + "nativeName": "\u0939\u093F\u0928\u094D\u0926\u0940", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "hr": { + "name": "Croatian", + "nativeName": "Hrvatski", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "hu": { + "name": "Hungarian", + "nativeName": "Magyar", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "id": { + "name": "Indonesian", + "nativeName": "Indonesia", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "is": { + "name": "Icelandic", + "nativeName": "\u00CDslenska", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "it": { + "name": "Italian", + "nativeName": "Italiano", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ja": { + "name": "Japanese", + "nativeName": "\u65E5\u672C\u8A9E", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ko": { + "name": "Korean", + "nativeName": "\uD55C\uAD6D\uC5B4", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "lt": { + "name": "Lithuanian", + "nativeName": "Lietuvi\u0173", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "lv": { + "name": "Latvian", + "nativeName": "Latvie\u0161u", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ms": { + "name": "Malay", + "nativeName": "Melayu", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "mt": { + "name": "Maltese", + "nativeName": "Malti", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "mww": { + "name": "Hmong Daw", + "nativeName": "Hmong Daw", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "nb": { + "name": "Norwegian", + "nativeName": "Norsk Bokm\u00E5l", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "nl": { + "name": "Dutch", + "nativeName": "Nederlands", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "pl": { + "name": "Polish", + "nativeName": "Polski", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "pt": { + "name": "Portuguese (Brazil)", + "nativeName": "Portugu\u00EAs (Brasil)", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ro": { + "name": "Romanian", + "nativeName": "Rom\u00E2n\u0103", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ru": { + "name": "Russian", + "nativeName": "\u0420\u0443\u0441\u0441\u043A\u0438\u0439", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sk": { + "name": "Slovak", + "nativeName": "Sloven\u010Dina", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sl": { + "name": "Slovenian", + "nativeName": "Sloven\u0161\u010Dina", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sr-Latn": { + "name": "Serbian (Latin)", + "nativeName": "Srpski (latinica)", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sv": { + "name": "Swedish", + "nativeName": "Svenska", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sw": { + "name": "Swahili", + "nativeName": "Kiswahili", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ta": { + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "th": { + "name": "Thai", + "nativeName": "\u0E44\u0E17\u0E22", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "tlh-Latn": { + "name": "Klingon (Latin)", + "nativeName": "Klingon (Latin)", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "tr": { + "name": "Turkish", + "nativeName": "T\u00FCrk\u00E7e", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "uk": { + "name": "Ukrainian", + "nativeName": "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ur": { + "name": "Urdu", + "nativeName": "\u0627\u0631\u062F\u0648", + "dir": "rtl", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "vi": { + "name": "Vietnamese", + "nativeName": "Ti\u1EBFng Vi\u1EC7t", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "zh-Hans": { + "name": "Chinese Simplified", + "nativeName": "\u4E2D\u6587 (\u7B80\u4F53)", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + } + } + } + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_dictionary_multiple_translations.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_dictionary_multiple_translations.json new file mode 100644 index 000000000000..d0569b961dc5 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_dictionary_multiple_translations.json @@ -0,0 +1,970 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/languages?scope=dictionary\u0026api-version=3.0", + "RequestMethod": "GET", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": "X-RequestId", + "Content-Encoding": "gzip", + "Content-Length": "10722", + "Content-Type": "application/json", + "Date": "Mon, 03 Apr 2023 21:49:53 GMT", + "ETag": "\u0022O9/lTodTxeM22O9Zx2E5QRj\u002B2mdNnueZdwfjziTuhgI=\u0022", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-RequestId": "LANG.MW1P.99BE.0403T2149.2FCA5B6" + }, + "ResponseBody": { + "dictionary": { + "af": { + "name": "Afrikaans", + "nativeName": "Afrikaans", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ar": { + "name": "Arabic", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "dir": "rtl", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "bg": { + "name": "Bulgarian", + "nativeName": "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "bn": { + "name": "Bangla", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "bs": { + "name": "Bosnian", + "nativeName": "Bosnian", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ca": { + "name": "Catalan", + "nativeName": "Catal\u00E0", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "cs": { + "name": "Czech", + "nativeName": "\u010Ce\u0161tina", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "cy": { + "name": "Welsh", + "nativeName": "Cymraeg", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "da": { + "name": "Danish", + "nativeName": "Dansk", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "de": { + "name": "German", + "nativeName": "Deutsch", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "el": { + "name": "Greek", + "nativeName": "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "en": { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "translations": [ + { + "name": "Afrikaans", + "nativeName": "Afrikaans", + "dir": "ltr", + "code": "af" + }, + { + "name": "Arabic", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "dir": "rtl", + "code": "ar" + }, + { + "name": "Bulgarian", + "nativeName": "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438", + "dir": "ltr", + "code": "bg" + }, + { + "name": "Bangla", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr", + "code": "bn" + }, + { + "name": "Bosnian", + "nativeName": "Bosnian", + "dir": "ltr", + "code": "bs" + }, + { + "name": "Catalan", + "nativeName": "Catal\u00E0", + "dir": "ltr", + "code": "ca" + }, + { + "name": "Chinese Simplified", + "nativeName": "\u4E2D\u6587 (\u7B80\u4F53)", + "dir": "ltr", + "code": "zh-Hans" + }, + { + "name": "Czech", + "nativeName": "\u010Ce\u0161tina", + "dir": "ltr", + "code": "cs" + }, + { + "name": "Welsh", + "nativeName": "Cymraeg", + "dir": "ltr", + "code": "cy" + }, + { + "name": "Danish", + "nativeName": "Dansk", + "dir": "ltr", + "code": "da" + }, + { + "name": "German", + "nativeName": "Deutsch", + "dir": "ltr", + "code": "de" + }, + { + "name": "Greek", + "nativeName": "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC", + "dir": "ltr", + "code": "el" + }, + { + "name": "Spanish", + "nativeName": "Espa\u00F1ol", + "dir": "ltr", + "code": "es" + }, + { + "name": "Estonian", + "nativeName": "Eesti", + "dir": "ltr", + "code": "et" + }, + { + "name": "Persian", + "nativeName": "\u0641\u0627\u0631\u0633\u06CC", + "dir": "rtl", + "code": "fa" + }, + { + "name": "Finnish", + "nativeName": "Suomi", + "dir": "ltr", + "code": "fi" + }, + { + "name": "French", + "nativeName": "Fran\u00E7ais", + "dir": "ltr", + "code": "fr" + }, + { + "name": "Hebrew", + "nativeName": "\u05E2\u05D1\u05E8\u05D9\u05EA", + "dir": "rtl", + "code": "he" + }, + { + "name": "Hindi", + "nativeName": "\u0939\u093F\u0928\u094D\u0926\u0940", + "dir": "ltr", + "code": "hi" + }, + { + "name": "Croatian", + "nativeName": "Hrvatski", + "dir": "ltr", + "code": "hr" + }, + { + "name": "Hungarian", + "nativeName": "Magyar", + "dir": "ltr", + "code": "hu" + }, + { + "name": "Indonesian", + "nativeName": "Indonesia", + "dir": "ltr", + "code": "id" + }, + { + "name": "Icelandic", + "nativeName": "\u00CDslenska", + "dir": "ltr", + "code": "is" + }, + { + "name": "Italian", + "nativeName": "Italiano", + "dir": "ltr", + "code": "it" + }, + { + "name": "Japanese", + "nativeName": "\u65E5\u672C\u8A9E", + "dir": "ltr", + "code": "ja" + }, + { + "name": "Korean", + "nativeName": "\uD55C\uAD6D\uC5B4", + "dir": "ltr", + "code": "ko" + }, + { + "name": "Lithuanian", + "nativeName": "Lietuvi\u0173", + "dir": "ltr", + "code": "lt" + }, + { + "name": "Latvian", + "nativeName": "Latvie\u0161u", + "dir": "ltr", + "code": "lv" + }, + { + "name": "Maltese", + "nativeName": "Malti", + "dir": "ltr", + "code": "mt" + }, + { + "name": "Malay", + "nativeName": "Melayu", + "dir": "ltr", + "code": "ms" + }, + { + "name": "Hmong Daw", + "nativeName": "Hmong Daw", + "dir": "ltr", + "code": "mww" + }, + { + "name": "Dutch", + "nativeName": "Nederlands", + "dir": "ltr", + "code": "nl" + }, + { + "name": "Norwegian", + "nativeName": "Norsk Bokm\u00E5l", + "dir": "ltr", + "code": "nb" + }, + { + "name": "Polish", + "nativeName": "Polski", + "dir": "ltr", + "code": "pl" + }, + { + "name": "Portuguese (Brazil)", + "nativeName": "Portugu\u00EAs (Brasil)", + "dir": "ltr", + "code": "pt" + }, + { + "name": "Romanian", + "nativeName": "Rom\u00E2n\u0103", + "dir": "ltr", + "code": "ro" + }, + { + "name": "Russian", + "nativeName": "\u0420\u0443\u0441\u0441\u043A\u0438\u0439", + "dir": "ltr", + "code": "ru" + }, + { + "name": "Slovak", + "nativeName": "Sloven\u010Dina", + "dir": "ltr", + "code": "sk" + }, + { + "name": "Slovenian", + "nativeName": "Sloven\u0161\u010Dina", + "dir": "ltr", + "code": "sl" + }, + { + "name": "Serbian (Latin)", + "nativeName": "Srpski (latinica)", + "dir": "ltr", + "code": "sr-Latn" + }, + { + "name": "Swedish", + "nativeName": "Svenska", + "dir": "ltr", + "code": "sv" + }, + { + "name": "Swahili", + "nativeName": "Kiswahili", + "dir": "ltr", + "code": "sw" + }, + { + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "dir": "ltr", + "code": "ta" + }, + { + "name": "Thai", + "nativeName": "\u0E44\u0E17\u0E22", + "dir": "ltr", + "code": "th" + }, + { + "name": "Klingon (Latin)", + "nativeName": "Klingon (Latin)", + "dir": "ltr", + "code": "tlh-Latn" + }, + { + "name": "Turkish", + "nativeName": "T\u00FCrk\u00E7e", + "dir": "ltr", + "code": "tr" + }, + { + "name": "Ukrainian", + "nativeName": "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430", + "dir": "ltr", + "code": "uk" + }, + { + "name": "Urdu", + "nativeName": "\u0627\u0631\u062F\u0648", + "dir": "rtl", + "code": "ur" + }, + { + "name": "Vietnamese", + "nativeName": "Ti\u1EBFng Vi\u1EC7t", + "dir": "ltr", + "code": "vi" + } + ] + }, + "es": { + "name": "Spanish", + "nativeName": "Espa\u00F1ol", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "et": { + "name": "Estonian", + "nativeName": "Eesti", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "fa": { + "name": "Persian", + "nativeName": "\u0641\u0627\u0631\u0633\u06CC", + "dir": "rtl", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "fi": { + "name": "Finnish", + "nativeName": "Suomi", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "fr": { + "name": "French", + "nativeName": "Fran\u00E7ais", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "he": { + "name": "Hebrew", + "nativeName": "\u05E2\u05D1\u05E8\u05D9\u05EA", + "dir": "rtl", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "hi": { + "name": "Hindi", + "nativeName": "\u0939\u093F\u0928\u094D\u0926\u0940", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "hr": { + "name": "Croatian", + "nativeName": "Hrvatski", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "hu": { + "name": "Hungarian", + "nativeName": "Magyar", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "id": { + "name": "Indonesian", + "nativeName": "Indonesia", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "is": { + "name": "Icelandic", + "nativeName": "\u00CDslenska", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "it": { + "name": "Italian", + "nativeName": "Italiano", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ja": { + "name": "Japanese", + "nativeName": "\u65E5\u672C\u8A9E", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ko": { + "name": "Korean", + "nativeName": "\uD55C\uAD6D\uC5B4", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "lt": { + "name": "Lithuanian", + "nativeName": "Lietuvi\u0173", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "lv": { + "name": "Latvian", + "nativeName": "Latvie\u0161u", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ms": { + "name": "Malay", + "nativeName": "Melayu", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "mt": { + "name": "Maltese", + "nativeName": "Malti", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "mww": { + "name": "Hmong Daw", + "nativeName": "Hmong Daw", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "nb": { + "name": "Norwegian", + "nativeName": "Norsk Bokm\u00E5l", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "nl": { + "name": "Dutch", + "nativeName": "Nederlands", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "pl": { + "name": "Polish", + "nativeName": "Polski", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "pt": { + "name": "Portuguese (Brazil)", + "nativeName": "Portugu\u00EAs (Brasil)", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ro": { + "name": "Romanian", + "nativeName": "Rom\u00E2n\u0103", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ru": { + "name": "Russian", + "nativeName": "\u0420\u0443\u0441\u0441\u043A\u0438\u0439", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sk": { + "name": "Slovak", + "nativeName": "Sloven\u010Dina", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sl": { + "name": "Slovenian", + "nativeName": "Sloven\u0161\u010Dina", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sr-Latn": { + "name": "Serbian (Latin)", + "nativeName": "Srpski (latinica)", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sv": { + "name": "Swedish", + "nativeName": "Svenska", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sw": { + "name": "Swahili", + "nativeName": "Kiswahili", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ta": { + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "th": { + "name": "Thai", + "nativeName": "\u0E44\u0E17\u0E22", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "tlh-Latn": { + "name": "Klingon (Latin)", + "nativeName": "Klingon (Latin)", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "tr": { + "name": "Turkish", + "nativeName": "T\u00FCrk\u00E7e", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "uk": { + "name": "Ukrainian", + "nativeName": "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ur": { + "name": "Urdu", + "nativeName": "\u0627\u0631\u062F\u0648", + "dir": "rtl", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "vi": { + "name": "Vietnamese", + "nativeName": "Ti\u1EBFng Vi\u1EC7t", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "zh-Hans": { + "name": "Chinese Simplified", + "nativeName": "\u4E2D\u6587 (\u7B80\u4F53)", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + } + } + } + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_dictionary_scope.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_dictionary_scope.json new file mode 100644 index 000000000000..8fd6ecac9224 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_dictionary_scope.json @@ -0,0 +1,970 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/languages?scope=dictionary\u0026api-version=3.0", + "RequestMethod": "GET", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": "X-RequestId", + "Content-Encoding": "gzip", + "Content-Length": "10722", + "Content-Type": "application/json", + "Date": "Mon, 03 Apr 2023 21:49:52 GMT", + "ETag": "\u0022O9/lTodTxeM22O9Zx2E5QRj\u002B2mdNnueZdwfjziTuhgI=\u0022", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-RequestId": "LANG.MW1P.99BE.0403T2149.2FCA59A" + }, + "ResponseBody": { + "dictionary": { + "af": { + "name": "Afrikaans", + "nativeName": "Afrikaans", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ar": { + "name": "Arabic", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "dir": "rtl", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "bg": { + "name": "Bulgarian", + "nativeName": "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "bn": { + "name": "Bangla", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "bs": { + "name": "Bosnian", + "nativeName": "Bosnian", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ca": { + "name": "Catalan", + "nativeName": "Catal\u00E0", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "cs": { + "name": "Czech", + "nativeName": "\u010Ce\u0161tina", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "cy": { + "name": "Welsh", + "nativeName": "Cymraeg", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "da": { + "name": "Danish", + "nativeName": "Dansk", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "de": { + "name": "German", + "nativeName": "Deutsch", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "el": { + "name": "Greek", + "nativeName": "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "en": { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "translations": [ + { + "name": "Afrikaans", + "nativeName": "Afrikaans", + "dir": "ltr", + "code": "af" + }, + { + "name": "Arabic", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "dir": "rtl", + "code": "ar" + }, + { + "name": "Bulgarian", + "nativeName": "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438", + "dir": "ltr", + "code": "bg" + }, + { + "name": "Bangla", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr", + "code": "bn" + }, + { + "name": "Bosnian", + "nativeName": "Bosnian", + "dir": "ltr", + "code": "bs" + }, + { + "name": "Catalan", + "nativeName": "Catal\u00E0", + "dir": "ltr", + "code": "ca" + }, + { + "name": "Chinese Simplified", + "nativeName": "\u4E2D\u6587 (\u7B80\u4F53)", + "dir": "ltr", + "code": "zh-Hans" + }, + { + "name": "Czech", + "nativeName": "\u010Ce\u0161tina", + "dir": "ltr", + "code": "cs" + }, + { + "name": "Welsh", + "nativeName": "Cymraeg", + "dir": "ltr", + "code": "cy" + }, + { + "name": "Danish", + "nativeName": "Dansk", + "dir": "ltr", + "code": "da" + }, + { + "name": "German", + "nativeName": "Deutsch", + "dir": "ltr", + "code": "de" + }, + { + "name": "Greek", + "nativeName": "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC", + "dir": "ltr", + "code": "el" + }, + { + "name": "Spanish", + "nativeName": "Espa\u00F1ol", + "dir": "ltr", + "code": "es" + }, + { + "name": "Estonian", + "nativeName": "Eesti", + "dir": "ltr", + "code": "et" + }, + { + "name": "Persian", + "nativeName": "\u0641\u0627\u0631\u0633\u06CC", + "dir": "rtl", + "code": "fa" + }, + { + "name": "Finnish", + "nativeName": "Suomi", + "dir": "ltr", + "code": "fi" + }, + { + "name": "French", + "nativeName": "Fran\u00E7ais", + "dir": "ltr", + "code": "fr" + }, + { + "name": "Hebrew", + "nativeName": "\u05E2\u05D1\u05E8\u05D9\u05EA", + "dir": "rtl", + "code": "he" + }, + { + "name": "Hindi", + "nativeName": "\u0939\u093F\u0928\u094D\u0926\u0940", + "dir": "ltr", + "code": "hi" + }, + { + "name": "Croatian", + "nativeName": "Hrvatski", + "dir": "ltr", + "code": "hr" + }, + { + "name": "Hungarian", + "nativeName": "Magyar", + "dir": "ltr", + "code": "hu" + }, + { + "name": "Indonesian", + "nativeName": "Indonesia", + "dir": "ltr", + "code": "id" + }, + { + "name": "Icelandic", + "nativeName": "\u00CDslenska", + "dir": "ltr", + "code": "is" + }, + { + "name": "Italian", + "nativeName": "Italiano", + "dir": "ltr", + "code": "it" + }, + { + "name": "Japanese", + "nativeName": "\u65E5\u672C\u8A9E", + "dir": "ltr", + "code": "ja" + }, + { + "name": "Korean", + "nativeName": "\uD55C\uAD6D\uC5B4", + "dir": "ltr", + "code": "ko" + }, + { + "name": "Lithuanian", + "nativeName": "Lietuvi\u0173", + "dir": "ltr", + "code": "lt" + }, + { + "name": "Latvian", + "nativeName": "Latvie\u0161u", + "dir": "ltr", + "code": "lv" + }, + { + "name": "Maltese", + "nativeName": "Malti", + "dir": "ltr", + "code": "mt" + }, + { + "name": "Malay", + "nativeName": "Melayu", + "dir": "ltr", + "code": "ms" + }, + { + "name": "Hmong Daw", + "nativeName": "Hmong Daw", + "dir": "ltr", + "code": "mww" + }, + { + "name": "Dutch", + "nativeName": "Nederlands", + "dir": "ltr", + "code": "nl" + }, + { + "name": "Norwegian", + "nativeName": "Norsk Bokm\u00E5l", + "dir": "ltr", + "code": "nb" + }, + { + "name": "Polish", + "nativeName": "Polski", + "dir": "ltr", + "code": "pl" + }, + { + "name": "Portuguese (Brazil)", + "nativeName": "Portugu\u00EAs (Brasil)", + "dir": "ltr", + "code": "pt" + }, + { + "name": "Romanian", + "nativeName": "Rom\u00E2n\u0103", + "dir": "ltr", + "code": "ro" + }, + { + "name": "Russian", + "nativeName": "\u0420\u0443\u0441\u0441\u043A\u0438\u0439", + "dir": "ltr", + "code": "ru" + }, + { + "name": "Slovak", + "nativeName": "Sloven\u010Dina", + "dir": "ltr", + "code": "sk" + }, + { + "name": "Slovenian", + "nativeName": "Sloven\u0161\u010Dina", + "dir": "ltr", + "code": "sl" + }, + { + "name": "Serbian (Latin)", + "nativeName": "Srpski (latinica)", + "dir": "ltr", + "code": "sr-Latn" + }, + { + "name": "Swedish", + "nativeName": "Svenska", + "dir": "ltr", + "code": "sv" + }, + { + "name": "Swahili", + "nativeName": "Kiswahili", + "dir": "ltr", + "code": "sw" + }, + { + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "dir": "ltr", + "code": "ta" + }, + { + "name": "Thai", + "nativeName": "\u0E44\u0E17\u0E22", + "dir": "ltr", + "code": "th" + }, + { + "name": "Klingon (Latin)", + "nativeName": "Klingon (Latin)", + "dir": "ltr", + "code": "tlh-Latn" + }, + { + "name": "Turkish", + "nativeName": "T\u00FCrk\u00E7e", + "dir": "ltr", + "code": "tr" + }, + { + "name": "Ukrainian", + "nativeName": "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430", + "dir": "ltr", + "code": "uk" + }, + { + "name": "Urdu", + "nativeName": "\u0627\u0631\u062F\u0648", + "dir": "rtl", + "code": "ur" + }, + { + "name": "Vietnamese", + "nativeName": "Ti\u1EBFng Vi\u1EC7t", + "dir": "ltr", + "code": "vi" + } + ] + }, + "es": { + "name": "Spanish", + "nativeName": "Espa\u00F1ol", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "et": { + "name": "Estonian", + "nativeName": "Eesti", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "fa": { + "name": "Persian", + "nativeName": "\u0641\u0627\u0631\u0633\u06CC", + "dir": "rtl", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "fi": { + "name": "Finnish", + "nativeName": "Suomi", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "fr": { + "name": "French", + "nativeName": "Fran\u00E7ais", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "he": { + "name": "Hebrew", + "nativeName": "\u05E2\u05D1\u05E8\u05D9\u05EA", + "dir": "rtl", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "hi": { + "name": "Hindi", + "nativeName": "\u0939\u093F\u0928\u094D\u0926\u0940", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "hr": { + "name": "Croatian", + "nativeName": "Hrvatski", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "hu": { + "name": "Hungarian", + "nativeName": "Magyar", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "id": { + "name": "Indonesian", + "nativeName": "Indonesia", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "is": { + "name": "Icelandic", + "nativeName": "\u00CDslenska", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "it": { + "name": "Italian", + "nativeName": "Italiano", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ja": { + "name": "Japanese", + "nativeName": "\u65E5\u672C\u8A9E", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ko": { + "name": "Korean", + "nativeName": "\uD55C\uAD6D\uC5B4", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "lt": { + "name": "Lithuanian", + "nativeName": "Lietuvi\u0173", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "lv": { + "name": "Latvian", + "nativeName": "Latvie\u0161u", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ms": { + "name": "Malay", + "nativeName": "Melayu", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "mt": { + "name": "Maltese", + "nativeName": "Malti", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "mww": { + "name": "Hmong Daw", + "nativeName": "Hmong Daw", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "nb": { + "name": "Norwegian", + "nativeName": "Norsk Bokm\u00E5l", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "nl": { + "name": "Dutch", + "nativeName": "Nederlands", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "pl": { + "name": "Polish", + "nativeName": "Polski", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "pt": { + "name": "Portuguese (Brazil)", + "nativeName": "Portugu\u00EAs (Brasil)", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ro": { + "name": "Romanian", + "nativeName": "Rom\u00E2n\u0103", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ru": { + "name": "Russian", + "nativeName": "\u0420\u0443\u0441\u0441\u043A\u0438\u0439", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sk": { + "name": "Slovak", + "nativeName": "Sloven\u010Dina", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sl": { + "name": "Slovenian", + "nativeName": "Sloven\u0161\u010Dina", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sr-Latn": { + "name": "Serbian (Latin)", + "nativeName": "Srpski (latinica)", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sv": { + "name": "Swedish", + "nativeName": "Svenska", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sw": { + "name": "Swahili", + "nativeName": "Kiswahili", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ta": { + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "th": { + "name": "Thai", + "nativeName": "\u0E44\u0E17\u0E22", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "tlh-Latn": { + "name": "Klingon (Latin)", + "nativeName": "Klingon (Latin)", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "tr": { + "name": "Turkish", + "nativeName": "T\u00FCrk\u00E7e", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "uk": { + "name": "Ukrainian", + "nativeName": "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ur": { + "name": "Urdu", + "nativeName": "\u0627\u0631\u062F\u0648", + "dir": "rtl", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "vi": { + "name": "Vietnamese", + "nativeName": "Ti\u1EBFng Vi\u1EC7t", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "zh-Hans": { + "name": "Chinese Simplified", + "nativeName": "\u4E2D\u6587 (\u7B80\u4F53)", + "dir": "ltr", + "translations": [ + { + "name": "English", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + } + } + } + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_translation_scope.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_translation_scope.json new file mode 100644 index 000000000000..3be69244ca6e --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_translation_scope.json @@ -0,0 +1,652 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/languages?scope=translation\u0026api-version=3.0", + "RequestMethod": "GET", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": "X-RequestId", + "Content-Encoding": "gzip", + "Content-Length": "8269", + "Content-Type": "application/json", + "Date": "Mon, 03 Apr 2023 21:49:52 GMT", + "ETag": "\u0022rHr417XhodLwlnxjSk17cfznUiEAcOL0kBA61IEDWHU=\u0022", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-RequestId": "LANG.MW1P.99BE.0403T2149.2FCA540" + }, + "ResponseBody": { + "translation": { + "af": { + "name": "Afrikaans", + "nativeName": "Afrikaans", + "dir": "ltr" + }, + "am": { + "name": "Amharic", + "nativeName": "\u12A0\u121B\u122D\u129B", + "dir": "ltr" + }, + "ar": { + "name": "Arabic", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "dir": "rtl" + }, + "as": { + "name": "Assamese", + "nativeName": "\u0985\u09B8\u09AE\u09C0\u09AF\u09BC\u09BE", + "dir": "ltr" + }, + "az": { + "name": "Azerbaijani", + "nativeName": "Az\u0259rbaycan", + "dir": "ltr" + }, + "ba": { + "name": "Bashkir", + "nativeName": "Bashkir", + "dir": "ltr" + }, + "bg": { + "name": "Bulgarian", + "nativeName": "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438", + "dir": "ltr" + }, + "bn": { + "name": "Bangla", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr" + }, + "bo": { + "name": "Tibetan", + "nativeName": "\u0F56\u0F7C\u0F51\u0F0B\u0F66\u0F90\u0F51\u0F0B", + "dir": "ltr" + }, + "bs": { + "name": "Bosnian", + "nativeName": "Bosnian", + "dir": "ltr" + }, + "ca": { + "name": "Catalan", + "nativeName": "Catal\u00E0", + "dir": "ltr" + }, + "cs": { + "name": "Czech", + "nativeName": "\u010Ce\u0161tina", + "dir": "ltr" + }, + "cy": { + "name": "Welsh", + "nativeName": "Cymraeg", + "dir": "ltr" + }, + "da": { + "name": "Danish", + "nativeName": "Dansk", + "dir": "ltr" + }, + "de": { + "name": "German", + "nativeName": "Deutsch", + "dir": "ltr" + }, + "dv": { + "name": "Divehi", + "nativeName": "\u078B\u07A8\u0788\u07AC\u0780\u07A8\u0784\u07A6\u0790\u07B0", + "dir": "rtl" + }, + "el": { + "name": "Greek", + "nativeName": "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC", + "dir": "ltr" + }, + "en": { + "name": "English", + "nativeName": "English", + "dir": "ltr" + }, + "es": { + "name": "Spanish", + "nativeName": "Espa\u00F1ol", + "dir": "ltr" + }, + "et": { + "name": "Estonian", + "nativeName": "Eesti", + "dir": "ltr" + }, + "eu": { + "name": "Basque", + "nativeName": "Euskara", + "dir": "ltr" + }, + "fa": { + "name": "Persian", + "nativeName": "\u0641\u0627\u0631\u0633\u06CC", + "dir": "rtl" + }, + "fi": { + "name": "Finnish", + "nativeName": "Suomi", + "dir": "ltr" + }, + "fil": { + "name": "Filipino", + "nativeName": "Filipino", + "dir": "ltr" + }, + "fj": { + "name": "Fijian", + "nativeName": "Na Vosa Vakaviti", + "dir": "ltr" + }, + "fo": { + "name": "Faroese", + "nativeName": "F\u00F8royskt", + "dir": "ltr" + }, + "fr": { + "name": "French", + "nativeName": "Fran\u00E7ais", + "dir": "ltr" + }, + "fr-CA": { + "name": "French (Canada)", + "nativeName": "Fran\u00E7ais (Canada)", + "dir": "ltr" + }, + "ga": { + "name": "Irish", + "nativeName": "Gaeilge", + "dir": "ltr" + }, + "gl": { + "name": "Galician", + "nativeName": "Galego", + "dir": "ltr" + }, + "gu": { + "name": "Gujarati", + "nativeName": "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0", + "dir": "ltr" + }, + "ha": { + "name": "Hausa", + "nativeName": "Hausa", + "dir": "ltr" + }, + "he": { + "name": "Hebrew", + "nativeName": "\u05E2\u05D1\u05E8\u05D9\u05EA", + "dir": "rtl" + }, + "hi": { + "name": "Hindi", + "nativeName": "\u0939\u093F\u0928\u094D\u0926\u0940", + "dir": "ltr" + }, + "hr": { + "name": "Croatian", + "nativeName": "Hrvatski", + "dir": "ltr" + }, + "hsb": { + "name": "Upper Sorbian", + "nativeName": "Hornjoserb\u0161\u0107ina", + "dir": "ltr" + }, + "ht": { + "name": "Haitian Creole", + "nativeName": "Haitian Creole", + "dir": "ltr" + }, + "hu": { + "name": "Hungarian", + "nativeName": "Magyar", + "dir": "ltr" + }, + "hy": { + "name": "Armenian", + "nativeName": "\u0540\u0561\u0575\u0565\u0580\u0565\u0576", + "dir": "ltr" + }, + "id": { + "name": "Indonesian", + "nativeName": "Indonesia", + "dir": "ltr" + }, + "ig": { + "name": "Igbo", + "nativeName": "\u00C1s\u1EE5\u0300s\u1EE5\u0301 \u00CCgb\u00F2", + "dir": "ltr" + }, + "ikt": { + "name": "Inuinnaqtun", + "nativeName": "Inuinnaqtun", + "dir": "ltr" + }, + "is": { + "name": "Icelandic", + "nativeName": "\u00CDslenska", + "dir": "ltr" + }, + "it": { + "name": "Italian", + "nativeName": "Italiano", + "dir": "ltr" + }, + "iu": { + "name": "Inuktitut", + "nativeName": "\u1403\u14C4\u1483\u144E\u1450\u1466", + "dir": "ltr" + }, + "iu-Latn": { + "name": "Inuktitut (Latin)", + "nativeName": "Inuktitut (Latin)", + "dir": "ltr" + }, + "ja": { + "name": "Japanese", + "nativeName": "\u65E5\u672C\u8A9E", + "dir": "ltr" + }, + "ka": { + "name": "Georgian", + "nativeName": "\u10E5\u10D0\u10E0\u10D7\u10E3\u10DA\u10D8", + "dir": "ltr" + }, + "kk": { + "name": "Kazakh", + "nativeName": "\u049A\u0430\u0437\u0430\u049B \u0422\u0456\u043B\u0456", + "dir": "ltr" + }, + "km": { + "name": "Khmer", + "nativeName": "\u1781\u17D2\u1798\u17C2\u179A", + "dir": "ltr" + }, + "kmr": { + "name": "Kurdish (Northern)", + "nativeName": "Kurd\u00EE (Bakur)", + "dir": "ltr" + }, + "kn": { + "name": "Kannada", + "nativeName": "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1", + "dir": "ltr" + }, + "ko": { + "name": "Korean", + "nativeName": "\uD55C\uAD6D\uC5B4", + "dir": "ltr" + }, + "ku": { + "name": "Kurdish (Central)", + "nativeName": "Kurd\u00EE (Nav\u00EEn)", + "dir": "rtl" + }, + "ky": { + "name": "Kyrgyz", + "nativeName": "\u041A\u044B\u0440\u0433\u044B\u0437\u0447\u0430", + "dir": "ltr" + }, + "ln": { + "name": "Lingala", + "nativeName": "Ling\u00E1la", + "dir": "ltr" + }, + "lo": { + "name": "Lao", + "nativeName": "\u0EA5\u0EB2\u0EA7", + "dir": "ltr" + }, + "lt": { + "name": "Lithuanian", + "nativeName": "Lietuvi\u0173", + "dir": "ltr" + }, + "lug": { + "name": "Ganda", + "nativeName": "Ganda", + "dir": "ltr" + }, + "lv": { + "name": "Latvian", + "nativeName": "Latvie\u0161u", + "dir": "ltr" + }, + "lzh": { + "name": "Chinese (Literary)", + "nativeName": "\u4E2D\u6587 (\u6587\u8A00\u6587)", + "dir": "ltr" + }, + "mg": { + "name": "Malagasy", + "nativeName": "Malagasy", + "dir": "ltr" + }, + "mi": { + "name": "M\u0101ori", + "nativeName": "Te Reo M\u0101ori", + "dir": "ltr" + }, + "mk": { + "name": "Macedonian", + "nativeName": "\u041C\u0430\u043A\u0435\u0434\u043E\u043D\u0441\u043A\u0438", + "dir": "ltr" + }, + "ml": { + "name": "Malayalam", + "nativeName": "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02", + "dir": "ltr" + }, + "mn-Cyrl": { + "name": "Mongolian (Cyrillic)", + "nativeName": "Mongolian (Cyrillic)", + "dir": "ltr" + }, + "mn-Mong": { + "name": "Mongolian (Traditional)", + "nativeName": "\u182E\u1823\u1829\u182D\u1823\u182F \u182C\u1821\u182F\u1821", + "dir": "ltr" + }, + "mr": { + "name": "Marathi", + "nativeName": "\u092E\u0930\u093E\u0920\u0940", + "dir": "ltr" + }, + "ms": { + "name": "Malay", + "nativeName": "Melayu", + "dir": "ltr" + }, + "mt": { + "name": "Maltese", + "nativeName": "Malti", + "dir": "ltr" + }, + "mww": { + "name": "Hmong Daw", + "nativeName": "Hmong Daw", + "dir": "ltr" + }, + "my": { + "name": "Myanmar (Burmese)", + "nativeName": "\u1019\u103C\u1014\u103A\u1019\u102C", + "dir": "ltr" + }, + "nb": { + "name": "Norwegian", + "nativeName": "Norsk Bokm\u00E5l", + "dir": "ltr" + }, + "ne": { + "name": "Nepali", + "nativeName": "\u0928\u0947\u092A\u093E\u0932\u0940", + "dir": "ltr" + }, + "nl": { + "name": "Dutch", + "nativeName": "Nederlands", + "dir": "ltr" + }, + "nso": { + "name": "Sesotho sa Leboa", + "nativeName": "Sesotho sa Leboa", + "dir": "ltr" + }, + "nya": { + "name": "Nyanja", + "nativeName": "Nyanja", + "dir": "ltr" + }, + "or": { + "name": "Odia", + "nativeName": "\u0B13\u0B21\u0B3C\u0B3F\u0B06", + "dir": "ltr" + }, + "otq": { + "name": "Quer\u00E9taro Otomi", + "nativeName": "H\u00F1\u00E4h\u00F1u", + "dir": "ltr" + }, + "pa": { + "name": "Punjabi", + "nativeName": "\u0A2A\u0A70\u0A1C\u0A3E\u0A2C\u0A40", + "dir": "ltr" + }, + "pl": { + "name": "Polish", + "nativeName": "Polski", + "dir": "ltr" + }, + "prs": { + "name": "Dari", + "nativeName": "\u062F\u0631\u06CC", + "dir": "rtl" + }, + "ps": { + "name": "Pashto", + "nativeName": "\u067E\u069A\u062A\u0648", + "dir": "rtl" + }, + "pt": { + "name": "Portuguese (Brazil)", + "nativeName": "Portugu\u00EAs (Brasil)", + "dir": "ltr" + }, + "pt-PT": { + "name": "Portuguese (Portugal)", + "nativeName": "Portugu\u00EAs (Portugal)", + "dir": "ltr" + }, + "ro": { + "name": "Romanian", + "nativeName": "Rom\u00E2n\u0103", + "dir": "ltr" + }, + "ru": { + "name": "Russian", + "nativeName": "\u0420\u0443\u0441\u0441\u043A\u0438\u0439", + "dir": "ltr" + }, + "run": { + "name": "Rundi", + "nativeName": "Rundi", + "dir": "ltr" + }, + "rw": { + "name": "Kinyarwanda", + "nativeName": "Kinyarwanda", + "dir": "ltr" + }, + "sk": { + "name": "Slovak", + "nativeName": "Sloven\u010Dina", + "dir": "ltr" + }, + "sl": { + "name": "Slovenian", + "nativeName": "Sloven\u0161\u010Dina", + "dir": "ltr" + }, + "sm": { + "name": "Samoan", + "nativeName": "Gagana S\u0101moa", + "dir": "ltr" + }, + "sn": { + "name": "Shona", + "nativeName": "chiShona", + "dir": "ltr" + }, + "so": { + "name": "Somali", + "nativeName": "Soomaali", + "dir": "ltr" + }, + "sq": { + "name": "Albanian", + "nativeName": "Shqip", + "dir": "ltr" + }, + "sr-Cyrl": { + "name": "Serbian (Cyrillic)", + "nativeName": "\u0421\u0440\u043F\u0441\u043A\u0438 (\u045B\u0438\u0440\u0438\u043B\u0438\u0446\u0430)", + "dir": "ltr" + }, + "sr-Latn": { + "name": "Serbian (Latin)", + "nativeName": "Srpski (latinica)", + "dir": "ltr" + }, + "st": { + "name": "Sesotho", + "nativeName": "Sesotho", + "dir": "ltr" + }, + "sv": { + "name": "Swedish", + "nativeName": "Svenska", + "dir": "ltr" + }, + "sw": { + "name": "Swahili", + "nativeName": "Kiswahili", + "dir": "ltr" + }, + "ta": { + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "dir": "ltr" + }, + "te": { + "name": "Telugu", + "nativeName": "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41", + "dir": "ltr" + }, + "th": { + "name": "Thai", + "nativeName": "\u0E44\u0E17\u0E22", + "dir": "ltr" + }, + "ti": { + "name": "Tigrinya", + "nativeName": "\u1275\u130D\u122D", + "dir": "ltr" + }, + "tk": { + "name": "Turkmen", + "nativeName": "T\u00FCrkmen Dili", + "dir": "ltr" + }, + "tlh-Latn": { + "name": "Klingon (Latin)", + "nativeName": "Klingon (Latin)", + "dir": "ltr" + }, + "tlh-Piqd": { + "name": "Klingon (pIqaD)", + "nativeName": "Klingon (pIqaD)", + "dir": "ltr" + }, + "tn": { + "name": "Setswana", + "nativeName": "Setswana", + "dir": "ltr" + }, + "to": { + "name": "Tongan", + "nativeName": "Lea Fakatonga", + "dir": "ltr" + }, + "tr": { + "name": "Turkish", + "nativeName": "T\u00FCrk\u00E7e", + "dir": "ltr" + }, + "tt": { + "name": "Tatar", + "nativeName": "\u0422\u0430\u0442\u0430\u0440", + "dir": "ltr" + }, + "ty": { + "name": "Tahitian", + "nativeName": "Reo Tahiti", + "dir": "ltr" + }, + "ug": { + "name": "Uyghur", + "nativeName": "\u0626\u06C7\u064A\u063A\u06C7\u0631\u0686\u06D5", + "dir": "rtl" + }, + "uk": { + "name": "Ukrainian", + "nativeName": "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430", + "dir": "ltr" + }, + "ur": { + "name": "Urdu", + "nativeName": "\u0627\u0631\u062F\u0648", + "dir": "rtl" + }, + "uz": { + "name": "Uzbek (Latin)", + "nativeName": "Uzbek (Latin)", + "dir": "ltr" + }, + "vi": { + "name": "Vietnamese", + "nativeName": "Ti\u1EBFng Vi\u1EC7t", + "dir": "ltr" + }, + "xh": { + "name": "Xhosa", + "nativeName": "isiXhosa", + "dir": "ltr" + }, + "yo": { + "name": "Yoruba", + "nativeName": "\u00C8d\u00E8 Yor\u00F9b\u00E1", + "dir": "ltr" + }, + "yua": { + "name": "Yucatec Maya", + "nativeName": "Yucatec Maya", + "dir": "ltr" + }, + "yue": { + "name": "Cantonese (Traditional)", + "nativeName": "\u7CB5\u8A9E (\u7E41\u9AD4)", + "dir": "ltr" + }, + "zh-Hans": { + "name": "Chinese Simplified", + "nativeName": "\u4E2D\u6587 (\u7B80\u4F53)", + "dir": "ltr" + }, + "zh-Hant": { + "name": "Chinese Traditional", + "nativeName": "\u7E41\u9AD4\u4E2D\u6587 (\u7E41\u9AD4)", + "dir": "ltr" + }, + "zu": { + "name": "Zulu", + "nativeName": "Isi-Zulu", + "dir": "ltr" + } + } + } + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_transliteration_multiple_scripts.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_transliteration_multiple_scripts.json new file mode 100644 index 000000000000..51daf7ed5f05 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_transliteration_multiple_scripts.json @@ -0,0 +1,1238 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/languages?scope=transliteration\u0026api-version=3.0", + "RequestMethod": "GET", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": "X-RequestId", + "Content-Encoding": "gzip", + "Content-Length": "14061", + "Content-Type": "application/json", + "Date": "Mon, 03 Apr 2023 21:49:52 GMT", + "ETag": "\u00221Mj5PAUPEo6wh00ohbKWzAXBky66X3UMAdd8VirMp/c=\u0022", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-RequestId": "LANG.MW1P.99BE.0403T2149.2FCA582" + }, + "ResponseBody": { + "transliteration": { + "ar": { + "name": "Arabic", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "scripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "dir": "rtl", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0627\u0644\u0644\u0627\u062A\u064A\u0646\u064A\u0629", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0627\u0644\u0644\u0627\u062A\u064A\u0646\u064A\u0629", + "dir": "ltr", + "toScripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "dir": "rtl" + } + ] + } + ] + }, + "as": { + "name": "Assamese", + "nativeName": "\u0985\u09B8\u09AE\u09C0\u09AF\u09BC\u09BE", + "scripts": [ + { + "code": "Beng", + "name": "Bengali", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u09B2\u09C7\u099F\u09BF\u09A8", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u09B2\u09C7\u099F\u09BF\u09A8", + "dir": "ltr", + "toScripts": [ + { + "code": "Beng", + "name": "Bangla", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr" + } + ] + } + ] + }, + "be": { + "name": "Belarusian", + "nativeName": "Belarusian", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "Cyrillic", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "Cyrillic", + "dir": "ltr" + } + ] + } + ] + }, + "bg": { + "name": "Bulgarian", + "nativeName": "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u0430", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0438\u0446\u0430", + "dir": "ltr" + } + ] + } + ] + }, + "bn": { + "name": "Bangla", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "scripts": [ + { + "code": "Beng", + "name": "Bengali", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u09B2\u09CD\u09AF\u09BE\u099F\u09BF\u09A8", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u09B2\u09CD\u09AF\u09BE\u099F\u09BF\u09A8", + "dir": "ltr", + "toScripts": [ + { + "code": "Beng", + "name": "Bangla", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr" + } + ] + } + ] + }, + "el": { + "name": "Greek", + "nativeName": "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC", + "scripts": [ + { + "code": "Grek", + "name": "Greek", + "nativeName": "\u03B5\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03CC", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u03BB\u03B1\u03C4\u03B9\u03BD\u03B9\u03BA\u03CC", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u03BB\u03B1\u03C4\u03B9\u03BD\u03B9\u03BA\u03CC", + "dir": "ltr", + "toScripts": [ + { + "code": "Grek", + "name": "Greek", + "nativeName": "\u03B5\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03CC", + "dir": "ltr" + } + ] + } + ] + }, + "fa": { + "name": "Persian", + "nativeName": "\u0641\u0627\u0631\u0633\u06CC", + "scripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0639\u0631\u0628\u06CC", + "dir": "rtl", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0644\u0627\u062A\u06CC\u0646", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0644\u0627\u062A\u06CC\u0646", + "dir": "ltr", + "toScripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0639\u0631\u0628\u06CC", + "dir": "rtl" + } + ] + } + ] + }, + "gu": { + "name": "Gujarati", + "nativeName": "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0", + "scripts": [ + { + "code": "Gujr", + "name": "Gujarati", + "nativeName": "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0AB2\u0AC7\u0A9F\u0ABF\u0AA8", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0AB2\u0AC7\u0A9F\u0ABF\u0AA8", + "dir": "ltr", + "toScripts": [ + { + "code": "Gujr", + "name": "Gujarati", + "nativeName": "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0", + "dir": "ltr" + } + ] + } + ] + }, + "he": { + "name": "Hebrew", + "nativeName": "\u05E2\u05D1\u05E8\u05D9\u05EA", + "scripts": [ + { + "code": "Hebr", + "name": "Hebrew", + "nativeName": "\u05E2\u05D1\u05E8\u05D9", + "dir": "rtl", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u05DC\u05D8\u05D9\u05E0\u05D9", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u05DC\u05D8\u05D9\u05E0\u05D9", + "dir": "ltr", + "toScripts": [ + { + "code": "Hebr", + "name": "Hebrew", + "nativeName": "\u05E2\u05D1\u05E8\u05D9", + "dir": "rtl" + } + ] + } + ] + }, + "hi": { + "name": "Hindi", + "nativeName": "\u0939\u093F\u0928\u094D\u0926\u0940", + "scripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u0948\u091F\u093F\u0928", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u0948\u091F\u093F\u0928", + "dir": "ltr", + "toScripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr" + } + ] + } + ] + }, + "ja": { + "name": "Japanese", + "nativeName": "\u65E5\u672C\u8A9E", + "scripts": [ + { + "code": "Jpan", + "name": "Japanese", + "nativeName": "\u65E5\u672C\u8A9E\u306E\u6587\u5B57", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u30E9\u30C6\u30F3\u6587\u5B57", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u30E9\u30C6\u30F3\u6587\u5B57", + "dir": "ltr", + "toScripts": [ + { + "code": "Jpan", + "name": "Japanese", + "nativeName": "\u65E5\u672C\u8A9E\u306E\u6587\u5B57", + "dir": "ltr" + } + ] + } + ] + }, + "kk": { + "name": "Kazakh", + "nativeName": "\u049A\u0430\u0437\u0430\u049B \u0422\u0456\u043B\u0456", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B \u0436\u0430\u0437\u0443\u044B", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u044B\u043D \u0436\u0430\u0437\u0443\u044B", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u044B\u043D \u0436\u0430\u0437\u0443\u044B", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B \u0436\u0430\u0437\u0443\u044B", + "dir": "ltr" + } + ] + } + ] + }, + "kn": { + "name": "Kannada", + "nativeName": "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1", + "scripts": [ + { + "code": "Knda", + "name": "Kannada", + "nativeName": "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0CB2\u0CCD\u0CAF\u0CBE\u0C9F\u0CBF\u0CA8\u0CCD", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0CB2\u0CCD\u0CAF\u0CBE\u0C9F\u0CBF\u0CA8\u0CCD", + "dir": "ltr", + "toScripts": [ + { + "code": "Knda", + "name": "Kannada", + "nativeName": "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1", + "dir": "ltr" + } + ] + } + ] + }, + "ko": { + "name": "Korean", + "nativeName": "\uD55C\uAD6D\uC5B4", + "scripts": [ + { + "code": "Kore", + "name": "Korean", + "nativeName": "\uD55C\uAD6D \uBB38\uC790", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\uB85C\uB9C8\uC790", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\uB85C\uB9C8\uC790", + "dir": "ltr", + "toScripts": [ + { + "code": "Kore", + "name": "Korean", + "nativeName": "\uD55C\uAD6D \uBB38\uC790", + "dir": "ltr" + } + ] + } + ] + }, + "ky": { + "name": "Kyrgyz", + "nativeName": "\u041A\u044B\u0440\u0433\u044B\u0437\u0447\u0430", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u044B\u043D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u044B\u043D", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr" + } + ] + } + ] + }, + "mk": { + "name": "Macedonian", + "nativeName": "\u041C\u0430\u043A\u0435\u0434\u043E\u043D\u0441\u043A\u0438", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0441\u043A\u043E \u043F\u0438\u0441\u043C\u043E", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0447\u043D\u043E \u043F\u0438\u0441\u043C\u043E", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0447\u043D\u043E \u043F\u0438\u0441\u043C\u043E", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0441\u043A\u043E \u043F\u0438\u0441\u043C\u043E", + "dir": "ltr" + } + ] + } + ] + }, + "ml": { + "name": "Malayalam", + "nativeName": "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02", + "scripts": [ + { + "code": "Mlym", + "name": "Malayalam", + "nativeName": "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0D32\u0D3E\u0D31\u0D4D\u0D31\u0D3F\u0D7B", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0D32\u0D3E\u0D31\u0D4D\u0D31\u0D3F\u0D7B", + "dir": "ltr", + "toScripts": [ + { + "code": "Mlym", + "name": "Malayalam", + "nativeName": "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02", + "dir": "ltr" + } + ] + } + ] + }, + "mn-Cyrl": { + "name": "Mongolian (Cyrillic)", + "nativeName": "Mongolian (Cyrillic)", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr" + } + ] + } + ] + }, + "mr": { + "name": "Marathi", + "nativeName": "\u092E\u0930\u093E\u0920\u0940", + "scripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u0945\u091F\u093F\u0928", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u0945\u091F\u093F\u0928", + "dir": "ltr", + "toScripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr" + } + ] + } + ] + }, + "ne": { + "name": "Nepali", + "nativeName": "\u0928\u0947\u092A\u093E\u0932\u0940", + "scripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u093E\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u094D\u092F\u093E\u091F\u093F\u0928", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u094D\u092F\u093E\u091F\u093F\u0928", + "dir": "ltr", + "toScripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u093E\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr" + } + ] + } + ] + }, + "or": { + "name": "Odia", + "nativeName": "\u0B13\u0B21\u0B3C\u0B3F\u0B06", + "scripts": [ + { + "code": "Orya", + "name": "Odia", + "nativeName": "\u0B13\u0B21\u0B3C\u0B3F\u0B06", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0B32\u0B3E\u0B1F\u0B3F\u0B28\u0B4D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0B32\u0B3E\u0B1F\u0B3F\u0B28\u0B4D", + "dir": "ltr", + "toScripts": [ + { + "code": "Orya", + "name": "Odia", + "nativeName": "\u0B13\u0B21\u0B3C\u0B3F\u0B06", + "dir": "ltr" + } + ] + } + ] + }, + "pa": { + "name": "Punjabi", + "nativeName": "\u0A2A\u0A70\u0A1C\u0A3E\u0A2C\u0A40", + "scripts": [ + { + "code": "Guru", + "name": "Gurmukhi", + "nativeName": "\u0A17\u0A41\u0A30\u0A2E\u0A41\u0A16\u0A40", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0A32\u0A3E\u0A24\u0A40\u0A28\u0A40", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0A32\u0A3E\u0A24\u0A40\u0A28\u0A40", + "dir": "ltr", + "toScripts": [ + { + "code": "Guru", + "name": "Gurmukhi", + "nativeName": "\u0A17\u0A41\u0A30\u0A2E\u0A41\u0A16\u0A40", + "dir": "ltr" + } + ] + } + ] + }, + "ru": { + "name": "Russian", + "nativeName": "\u0420\u0443\u0441\u0441\u043A\u0438\u0439", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u0430", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B\u0438\u0446\u0430", + "dir": "ltr" + } + ] + } + ] + }, + "sd": { + "name": "Sindhi", + "nativeName": "\u0633\u0646\u068C\u064A", + "scripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "Arabic", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr", + "toScripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "Arabic", + "dir": "ltr" + } + ] + } + ] + }, + "si": { + "name": "Sinhala", + "nativeName": "\u0DC3\u0DD2\u0D82\u0DC4\u0DBD", + "scripts": [ + { + "code": "Sinh", + "name": "Sinhala", + "nativeName": "Sinhala", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr", + "toScripts": [ + { + "code": "Sinh", + "name": "Sinhala", + "nativeName": "Sinhala", + "dir": "ltr" + } + ] + } + ] + }, + "sr-Cyrl": { + "name": "Serbian (Cyrillic)", + "nativeName": "\u0421\u0440\u043F\u0441\u043A\u0438 (\u045B\u0438\u0440\u0438\u043B\u0438\u0446\u0430)", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u045B\u0438\u0440\u0438\u043B\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "latinica", + "dir": "ltr" + } + ] + } + ] + }, + "sr-Latn": { + "name": "Serbian (Latin)", + "nativeName": "Srpski (latinica)", + "scripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "latinica", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u0107irilica", + "dir": "ltr" + } + ] + } + ] + }, + "ta": { + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "scripts": [ + { + "code": "Taml", + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0BB2\u0BA4\u0BCD\u0BA4\u0BBF\u0BA9\u0BCD", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0BB2\u0BA4\u0BCD\u0BA4\u0BBF\u0BA9\u0BCD", + "dir": "ltr", + "toScripts": [ + { + "code": "Taml", + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "dir": "ltr" + } + ] + } + ] + }, + "te": { + "name": "Telugu", + "nativeName": "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41", + "scripts": [ + { + "code": "Telu", + "name": "Telugu", + "nativeName": "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0C32\u0C3E\u0C1F\u0C3F\u0C28\u0C4D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0C32\u0C3E\u0C1F\u0C3F\u0C28\u0C4D", + "dir": "ltr", + "toScripts": [ + { + "code": "Telu", + "name": "Telugu", + "nativeName": "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41", + "dir": "ltr" + } + ] + } + ] + }, + "tg": { + "name": "Tajik", + "nativeName": "Tajik (Cyrillic)", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "Cyrillic", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "Cyrillic", + "dir": "ltr" + } + ] + } + ] + }, + "th": { + "name": "Thai", + "nativeName": "\u0E44\u0E17\u0E22", + "scripts": [ + { + "code": "Thai", + "name": "Thai", + "nativeName": "\u0E44\u0E17\u0E22", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0E25\u0E30\u0E15\u0E34\u0E19", + "dir": "ltr" + } + ] + } + ] + }, + "tt": { + "name": "Tatar", + "nativeName": "\u0422\u0430\u0442\u0430\u0440", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr" + } + ] + } + ] + }, + "uk": { + "name": "Ukrainian", + "nativeName": "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0438\u0446\u044F", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u044F", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u044F", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0438\u0446\u044F", + "dir": "ltr" + } + ] + } + ] + }, + "ur": { + "name": "Urdu", + "nativeName": "\u0627\u0631\u062F\u0648", + "scripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0639\u0631\u0628\u06CC", + "dir": "rtl", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0644\u0627\u0637\u06CC\u0646\u06CC", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0644\u0627\u0637\u06CC\u0646\u06CC", + "dir": "ltr", + "toScripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0639\u0631\u0628\u06CC", + "dir": "rtl" + } + ] + } + ] + }, + "zh-Hans": { + "name": "Chinese Simplified", + "nativeName": "\u4E2D\u6587 (\u7B80\u4F53)", + "scripts": [ + { + "code": "Hans", + "name": "Simplified", + "nativeName": "\u7B80\u4F53\u6C49\u8BED", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u62C9\u4E01\u8BED", + "dir": "ltr" + }, + { + "code": "Hant", + "name": "Hat", + "nativeName": "\u4F20\u7EDF", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u62C9\u4E01\u8BED", + "dir": "ltr", + "toScripts": [ + { + "code": "Hans", + "name": "Han", + "nativeName": "\u7B80\u4F53\u6C49\u8BED", + "dir": "ltr" + }, + { + "code": "Hant", + "name": "Hat", + "nativeName": "\u4F20\u7EDF", + "dir": "ltr" + } + ] + } + ] + }, + "zh-Hant": { + "name": "Chinese Traditional", + "nativeName": "\u7E41\u9AD4\u4E2D\u6587 (\u7E41\u9AD4)", + "scripts": [ + { + "code": "Hant", + "name": "Traditional", + "nativeName": "\u50B3\u7D71", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u62C9\u4E01\u8BED", + "dir": "ltr" + }, + { + "code": "Hans", + "name": "Han", + "nativeName": "\u7B80\u4F53\u6C49\u8BED", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u62C9\u4E01\u6587", + "dir": "ltr", + "toScripts": [ + { + "code": "Hans", + "name": "Han", + "nativeName": "\u7B80\u4F53\u6C49\u8BED", + "dir": "ltr" + }, + { + "code": "Hant", + "name": "Hat", + "nativeName": "\u4F20\u7EDF", + "dir": "ltr" + } + ] + } + ] + } + } + } + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_transliteration_scope.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_transliteration_scope.json new file mode 100644 index 000000000000..7dd6939f792d --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_transliteration_scope.json @@ -0,0 +1,1238 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/languages?scope=transliteration\u0026api-version=3.0", + "RequestMethod": "GET", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": "X-RequestId", + "Content-Encoding": "gzip", + "Content-Length": "14061", + "Content-Type": "application/json", + "Date": "Mon, 03 Apr 2023 21:49:52 GMT", + "ETag": "\u00221Mj5PAUPEo6wh00ohbKWzAXBky66X3UMAdd8VirMp/c=\u0022", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-RequestId": "LANG.MW1P.99BE.0403T2149.2FCA55D" + }, + "ResponseBody": { + "transliteration": { + "ar": { + "name": "Arabic", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "scripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "dir": "rtl", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0627\u0644\u0644\u0627\u062A\u064A\u0646\u064A\u0629", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0627\u0644\u0644\u0627\u062A\u064A\u0646\u064A\u0629", + "dir": "ltr", + "toScripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "dir": "rtl" + } + ] + } + ] + }, + "as": { + "name": "Assamese", + "nativeName": "\u0985\u09B8\u09AE\u09C0\u09AF\u09BC\u09BE", + "scripts": [ + { + "code": "Beng", + "name": "Bengali", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u09B2\u09C7\u099F\u09BF\u09A8", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u09B2\u09C7\u099F\u09BF\u09A8", + "dir": "ltr", + "toScripts": [ + { + "code": "Beng", + "name": "Bangla", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr" + } + ] + } + ] + }, + "be": { + "name": "Belarusian", + "nativeName": "Belarusian", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "Cyrillic", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "Cyrillic", + "dir": "ltr" + } + ] + } + ] + }, + "bg": { + "name": "Bulgarian", + "nativeName": "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u0430", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0438\u0446\u0430", + "dir": "ltr" + } + ] + } + ] + }, + "bn": { + "name": "Bangla", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "scripts": [ + { + "code": "Beng", + "name": "Bengali", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u09B2\u09CD\u09AF\u09BE\u099F\u09BF\u09A8", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u09B2\u09CD\u09AF\u09BE\u099F\u09BF\u09A8", + "dir": "ltr", + "toScripts": [ + { + "code": "Beng", + "name": "Bangla", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr" + } + ] + } + ] + }, + "el": { + "name": "Greek", + "nativeName": "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC", + "scripts": [ + { + "code": "Grek", + "name": "Greek", + "nativeName": "\u03B5\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03CC", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u03BB\u03B1\u03C4\u03B9\u03BD\u03B9\u03BA\u03CC", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u03BB\u03B1\u03C4\u03B9\u03BD\u03B9\u03BA\u03CC", + "dir": "ltr", + "toScripts": [ + { + "code": "Grek", + "name": "Greek", + "nativeName": "\u03B5\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03CC", + "dir": "ltr" + } + ] + } + ] + }, + "fa": { + "name": "Persian", + "nativeName": "\u0641\u0627\u0631\u0633\u06CC", + "scripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0639\u0631\u0628\u06CC", + "dir": "rtl", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0644\u0627\u062A\u06CC\u0646", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0644\u0627\u062A\u06CC\u0646", + "dir": "ltr", + "toScripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0639\u0631\u0628\u06CC", + "dir": "rtl" + } + ] + } + ] + }, + "gu": { + "name": "Gujarati", + "nativeName": "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0", + "scripts": [ + { + "code": "Gujr", + "name": "Gujarati", + "nativeName": "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0AB2\u0AC7\u0A9F\u0ABF\u0AA8", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0AB2\u0AC7\u0A9F\u0ABF\u0AA8", + "dir": "ltr", + "toScripts": [ + { + "code": "Gujr", + "name": "Gujarati", + "nativeName": "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0", + "dir": "ltr" + } + ] + } + ] + }, + "he": { + "name": "Hebrew", + "nativeName": "\u05E2\u05D1\u05E8\u05D9\u05EA", + "scripts": [ + { + "code": "Hebr", + "name": "Hebrew", + "nativeName": "\u05E2\u05D1\u05E8\u05D9", + "dir": "rtl", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u05DC\u05D8\u05D9\u05E0\u05D9", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u05DC\u05D8\u05D9\u05E0\u05D9", + "dir": "ltr", + "toScripts": [ + { + "code": "Hebr", + "name": "Hebrew", + "nativeName": "\u05E2\u05D1\u05E8\u05D9", + "dir": "rtl" + } + ] + } + ] + }, + "hi": { + "name": "Hindi", + "nativeName": "\u0939\u093F\u0928\u094D\u0926\u0940", + "scripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u0948\u091F\u093F\u0928", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u0948\u091F\u093F\u0928", + "dir": "ltr", + "toScripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr" + } + ] + } + ] + }, + "ja": { + "name": "Japanese", + "nativeName": "\u65E5\u672C\u8A9E", + "scripts": [ + { + "code": "Jpan", + "name": "Japanese", + "nativeName": "\u65E5\u672C\u8A9E\u306E\u6587\u5B57", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u30E9\u30C6\u30F3\u6587\u5B57", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u30E9\u30C6\u30F3\u6587\u5B57", + "dir": "ltr", + "toScripts": [ + { + "code": "Jpan", + "name": "Japanese", + "nativeName": "\u65E5\u672C\u8A9E\u306E\u6587\u5B57", + "dir": "ltr" + } + ] + } + ] + }, + "kk": { + "name": "Kazakh", + "nativeName": "\u049A\u0430\u0437\u0430\u049B \u0422\u0456\u043B\u0456", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B \u0436\u0430\u0437\u0443\u044B", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u044B\u043D \u0436\u0430\u0437\u0443\u044B", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u044B\u043D \u0436\u0430\u0437\u0443\u044B", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B \u0436\u0430\u0437\u0443\u044B", + "dir": "ltr" + } + ] + } + ] + }, + "kn": { + "name": "Kannada", + "nativeName": "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1", + "scripts": [ + { + "code": "Knda", + "name": "Kannada", + "nativeName": "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0CB2\u0CCD\u0CAF\u0CBE\u0C9F\u0CBF\u0CA8\u0CCD", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0CB2\u0CCD\u0CAF\u0CBE\u0C9F\u0CBF\u0CA8\u0CCD", + "dir": "ltr", + "toScripts": [ + { + "code": "Knda", + "name": "Kannada", + "nativeName": "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1", + "dir": "ltr" + } + ] + } + ] + }, + "ko": { + "name": "Korean", + "nativeName": "\uD55C\uAD6D\uC5B4", + "scripts": [ + { + "code": "Kore", + "name": "Korean", + "nativeName": "\uD55C\uAD6D \uBB38\uC790", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\uB85C\uB9C8\uC790", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\uB85C\uB9C8\uC790", + "dir": "ltr", + "toScripts": [ + { + "code": "Kore", + "name": "Korean", + "nativeName": "\uD55C\uAD6D \uBB38\uC790", + "dir": "ltr" + } + ] + } + ] + }, + "ky": { + "name": "Kyrgyz", + "nativeName": "\u041A\u044B\u0440\u0433\u044B\u0437\u0447\u0430", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u044B\u043D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u044B\u043D", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr" + } + ] + } + ] + }, + "mk": { + "name": "Macedonian", + "nativeName": "\u041C\u0430\u043A\u0435\u0434\u043E\u043D\u0441\u043A\u0438", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0441\u043A\u043E \u043F\u0438\u0441\u043C\u043E", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0447\u043D\u043E \u043F\u0438\u0441\u043C\u043E", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0447\u043D\u043E \u043F\u0438\u0441\u043C\u043E", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0441\u043A\u043E \u043F\u0438\u0441\u043C\u043E", + "dir": "ltr" + } + ] + } + ] + }, + "ml": { + "name": "Malayalam", + "nativeName": "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02", + "scripts": [ + { + "code": "Mlym", + "name": "Malayalam", + "nativeName": "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0D32\u0D3E\u0D31\u0D4D\u0D31\u0D3F\u0D7B", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0D32\u0D3E\u0D31\u0D4D\u0D31\u0D3F\u0D7B", + "dir": "ltr", + "toScripts": [ + { + "code": "Mlym", + "name": "Malayalam", + "nativeName": "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02", + "dir": "ltr" + } + ] + } + ] + }, + "mn-Cyrl": { + "name": "Mongolian (Cyrillic)", + "nativeName": "Mongolian (Cyrillic)", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr" + } + ] + } + ] + }, + "mr": { + "name": "Marathi", + "nativeName": "\u092E\u0930\u093E\u0920\u0940", + "scripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u0945\u091F\u093F\u0928", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u0945\u091F\u093F\u0928", + "dir": "ltr", + "toScripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr" + } + ] + } + ] + }, + "ne": { + "name": "Nepali", + "nativeName": "\u0928\u0947\u092A\u093E\u0932\u0940", + "scripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u093E\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u094D\u092F\u093E\u091F\u093F\u0928", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u094D\u092F\u093E\u091F\u093F\u0928", + "dir": "ltr", + "toScripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u093E\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr" + } + ] + } + ] + }, + "or": { + "name": "Odia", + "nativeName": "\u0B13\u0B21\u0B3C\u0B3F\u0B06", + "scripts": [ + { + "code": "Orya", + "name": "Odia", + "nativeName": "\u0B13\u0B21\u0B3C\u0B3F\u0B06", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0B32\u0B3E\u0B1F\u0B3F\u0B28\u0B4D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0B32\u0B3E\u0B1F\u0B3F\u0B28\u0B4D", + "dir": "ltr", + "toScripts": [ + { + "code": "Orya", + "name": "Odia", + "nativeName": "\u0B13\u0B21\u0B3C\u0B3F\u0B06", + "dir": "ltr" + } + ] + } + ] + }, + "pa": { + "name": "Punjabi", + "nativeName": "\u0A2A\u0A70\u0A1C\u0A3E\u0A2C\u0A40", + "scripts": [ + { + "code": "Guru", + "name": "Gurmukhi", + "nativeName": "\u0A17\u0A41\u0A30\u0A2E\u0A41\u0A16\u0A40", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0A32\u0A3E\u0A24\u0A40\u0A28\u0A40", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0A32\u0A3E\u0A24\u0A40\u0A28\u0A40", + "dir": "ltr", + "toScripts": [ + { + "code": "Guru", + "name": "Gurmukhi", + "nativeName": "\u0A17\u0A41\u0A30\u0A2E\u0A41\u0A16\u0A40", + "dir": "ltr" + } + ] + } + ] + }, + "ru": { + "name": "Russian", + "nativeName": "\u0420\u0443\u0441\u0441\u043A\u0438\u0439", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u0430", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B\u0438\u0446\u0430", + "dir": "ltr" + } + ] + } + ] + }, + "sd": { + "name": "Sindhi", + "nativeName": "\u0633\u0646\u068C\u064A", + "scripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "Arabic", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr", + "toScripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "Arabic", + "dir": "ltr" + } + ] + } + ] + }, + "si": { + "name": "Sinhala", + "nativeName": "\u0DC3\u0DD2\u0D82\u0DC4\u0DBD", + "scripts": [ + { + "code": "Sinh", + "name": "Sinhala", + "nativeName": "Sinhala", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr", + "toScripts": [ + { + "code": "Sinh", + "name": "Sinhala", + "nativeName": "Sinhala", + "dir": "ltr" + } + ] + } + ] + }, + "sr-Cyrl": { + "name": "Serbian (Cyrillic)", + "nativeName": "\u0421\u0440\u043F\u0441\u043A\u0438 (\u045B\u0438\u0440\u0438\u043B\u0438\u0446\u0430)", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u045B\u0438\u0440\u0438\u043B\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "latinica", + "dir": "ltr" + } + ] + } + ] + }, + "sr-Latn": { + "name": "Serbian (Latin)", + "nativeName": "Srpski (latinica)", + "scripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "latinica", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u0107irilica", + "dir": "ltr" + } + ] + } + ] + }, + "ta": { + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "scripts": [ + { + "code": "Taml", + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0BB2\u0BA4\u0BCD\u0BA4\u0BBF\u0BA9\u0BCD", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0BB2\u0BA4\u0BCD\u0BA4\u0BBF\u0BA9\u0BCD", + "dir": "ltr", + "toScripts": [ + { + "code": "Taml", + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "dir": "ltr" + } + ] + } + ] + }, + "te": { + "name": "Telugu", + "nativeName": "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41", + "scripts": [ + { + "code": "Telu", + "name": "Telugu", + "nativeName": "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0C32\u0C3E\u0C1F\u0C3F\u0C28\u0C4D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0C32\u0C3E\u0C1F\u0C3F\u0C28\u0C4D", + "dir": "ltr", + "toScripts": [ + { + "code": "Telu", + "name": "Telugu", + "nativeName": "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41", + "dir": "ltr" + } + ] + } + ] + }, + "tg": { + "name": "Tajik", + "nativeName": "Tajik (Cyrillic)", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "Cyrillic", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "Cyrillic", + "dir": "ltr" + } + ] + } + ] + }, + "th": { + "name": "Thai", + "nativeName": "\u0E44\u0E17\u0E22", + "scripts": [ + { + "code": "Thai", + "name": "Thai", + "nativeName": "\u0E44\u0E17\u0E22", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0E25\u0E30\u0E15\u0E34\u0E19", + "dir": "ltr" + } + ] + } + ] + }, + "tt": { + "name": "Tatar", + "nativeName": "\u0422\u0430\u0442\u0430\u0440", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr" + } + ] + } + ] + }, + "uk": { + "name": "Ukrainian", + "nativeName": "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430", + "scripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0438\u0446\u044F", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u044F", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u044F", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0438\u0446\u044F", + "dir": "ltr" + } + ] + } + ] + }, + "ur": { + "name": "Urdu", + "nativeName": "\u0627\u0631\u062F\u0648", + "scripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0639\u0631\u0628\u06CC", + "dir": "rtl", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0644\u0627\u0637\u06CC\u0646\u06CC", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0644\u0627\u0637\u06CC\u0646\u06CC", + "dir": "ltr", + "toScripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0639\u0631\u0628\u06CC", + "dir": "rtl" + } + ] + } + ] + }, + "zh-Hans": { + "name": "Chinese Simplified", + "nativeName": "\u4E2D\u6587 (\u7B80\u4F53)", + "scripts": [ + { + "code": "Hans", + "name": "Simplified", + "nativeName": "\u7B80\u4F53\u6C49\u8BED", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u62C9\u4E01\u8BED", + "dir": "ltr" + }, + { + "code": "Hant", + "name": "Hat", + "nativeName": "\u4F20\u7EDF", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u62C9\u4E01\u8BED", + "dir": "ltr", + "toScripts": [ + { + "code": "Hans", + "name": "Han", + "nativeName": "\u7B80\u4F53\u6C49\u8BED", + "dir": "ltr" + }, + { + "code": "Hant", + "name": "Hat", + "nativeName": "\u4F20\u7EDF", + "dir": "ltr" + } + ] + } + ] + }, + "zh-Hant": { + "name": "Chinese Traditional", + "nativeName": "\u7E41\u9AD4\u4E2D\u6587 (\u7E41\u9AD4)", + "scripts": [ + { + "code": "Hant", + "name": "Traditional", + "nativeName": "\u50B3\u7D71", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u62C9\u4E01\u8BED", + "dir": "ltr" + }, + { + "code": "Hans", + "name": "Han", + "nativeName": "\u7B80\u4F53\u6C49\u8BED", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u62C9\u4E01\u6587", + "dir": "ltr", + "toScripts": [ + { + "code": "Hans", + "name": "Han", + "nativeName": "\u7B80\u4F53\u6C49\u8BED", + "dir": "ltr" + }, + { + "code": "Hant", + "name": "Hat", + "nativeName": "\u4F20\u7EDF", + "dir": "ltr" + } + ] + } + ] + } + } + } + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_with_culture.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_with_culture.json new file mode 100644 index 000000000000..24484e1e99e5 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_get_languages.pyTestGetLanguagestest_with_culture.json @@ -0,0 +1,2801 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/languages?api-version=3.0", + "RequestMethod": "GET", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Accept-Language": "es", + "Connection": "keep-alive", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": null, + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": "X-RequestId", + "Content-Encoding": "gzip", + "Content-Length": "33158", + "Content-Type": "application/json", + "Date": "Mon, 03 Apr 2023 21:49:53 GMT", + "ETag": "\u0022LQTsldUvlOCoaB8izOlOafv5YPLihFhZR1W7ksXaerc=\u0022", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-RequestId": "LANG.MW1P.99BE.0403T2149.2FCA5E3" + }, + "ResponseBody": { + "translation": { + "af": { + "name": "Afrik\u00E1ans", + "nativeName": "Afrikaans", + "dir": "ltr" + }, + "am": { + "name": "Am\u00E1rico", + "nativeName": "\u12A0\u121B\u122D\u129B", + "dir": "ltr" + }, + "ar": { + "name": "\u00C1rabe", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "dir": "rtl" + }, + "as": { + "name": "Asam\u00E9s", + "nativeName": "\u0985\u09B8\u09AE\u09C0\u09AF\u09BC\u09BE", + "dir": "ltr" + }, + "az": { + "name": "Azerbaiyano", + "nativeName": "Az\u0259rbaycan", + "dir": "ltr" + }, + "ba": { + "name": "Baskir", + "nativeName": "Bashkir", + "dir": "ltr" + }, + "bg": { + "name": "B\u00FAlgaro", + "nativeName": "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438", + "dir": "ltr" + }, + "bn": { + "name": "Bengal\u00ED", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr" + }, + "bo": { + "name": "Tibetano", + "nativeName": "\u0F56\u0F7C\u0F51\u0F0B\u0F66\u0F90\u0F51\u0F0B", + "dir": "ltr" + }, + "bs": { + "name": "Bosnio", + "nativeName": "Bosnian", + "dir": "ltr" + }, + "ca": { + "name": "Catal\u00E1n", + "nativeName": "Catal\u00E0", + "dir": "ltr" + }, + "cs": { + "name": "Checo", + "nativeName": "\u010Ce\u0161tina", + "dir": "ltr" + }, + "cy": { + "name": "Gal\u00E9s", + "nativeName": "Cymraeg", + "dir": "ltr" + }, + "da": { + "name": "Dan\u00E9s", + "nativeName": "Dansk", + "dir": "ltr" + }, + "de": { + "name": "Alem\u00E1n", + "nativeName": "Deutsch", + "dir": "ltr" + }, + "dv": { + "name": "Divehi", + "nativeName": "\u078B\u07A8\u0788\u07AC\u0780\u07A8\u0784\u07A6\u0790\u07B0", + "dir": "rtl" + }, + "el": { + "name": "Griego", + "nativeName": "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC", + "dir": "ltr" + }, + "en": { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr" + }, + "es": { + "name": "Espa\u00F1ol", + "nativeName": "Espa\u00F1ol", + "dir": "ltr" + }, + "et": { + "name": "Estonio", + "nativeName": "Eesti", + "dir": "ltr" + }, + "eu": { + "name": "Euskera", + "nativeName": "Euskara", + "dir": "ltr" + }, + "fa": { + "name": "Persa", + "nativeName": "\u0641\u0627\u0631\u0633\u06CC", + "dir": "rtl" + }, + "fi": { + "name": "Fin\u00E9s", + "nativeName": "Suomi", + "dir": "ltr" + }, + "fil": { + "name": "Filipino", + "nativeName": "Filipino", + "dir": "ltr" + }, + "fj": { + "name": "Fiyiano", + "nativeName": "Na Vosa Vakaviti", + "dir": "ltr" + }, + "fo": { + "name": "Fero\u00E9s", + "nativeName": "F\u00F8royskt", + "dir": "ltr" + }, + "fr": { + "name": "Franc\u00E9s", + "nativeName": "Fran\u00E7ais", + "dir": "ltr" + }, + "fr-CA": { + "name": "Franc\u00E9s (Canad\u00E1)", + "nativeName": "Fran\u00E7ais (Canada)", + "dir": "ltr" + }, + "ga": { + "name": "Irland\u00E9s", + "nativeName": "Gaeilge", + "dir": "ltr" + }, + "gl": { + "name": "Gallego", + "nativeName": "Galego", + "dir": "ltr" + }, + "gu": { + "name": "Guyarat\u00ED", + "nativeName": "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0", + "dir": "ltr" + }, + "ha": { + "name": "Hausa", + "nativeName": "Hausa", + "dir": "ltr" + }, + "he": { + "name": "Hebreo", + "nativeName": "\u05E2\u05D1\u05E8\u05D9\u05EA", + "dir": "rtl" + }, + "hi": { + "name": "Hindi", + "nativeName": "\u0939\u093F\u0928\u094D\u0926\u0940", + "dir": "ltr" + }, + "hr": { + "name": "Croata", + "nativeName": "Hrvatski", + "dir": "ltr" + }, + "hsb": { + "name": "Alto Sorbio", + "nativeName": "Hornjoserb\u0161\u0107ina", + "dir": "ltr" + }, + "ht": { + "name": "Criollo Haitiano", + "nativeName": "Haitian Creole", + "dir": "ltr" + }, + "hu": { + "name": "H\u00FAngaro", + "nativeName": "Magyar", + "dir": "ltr" + }, + "hy": { + "name": "Armenio", + "nativeName": "\u0540\u0561\u0575\u0565\u0580\u0565\u0576", + "dir": "ltr" + }, + "id": { + "name": "Indonesio", + "nativeName": "Indonesia", + "dir": "ltr" + }, + "ig": { + "name": "Igbo", + "nativeName": "\u00C1s\u1EE5\u0300s\u1EE5\u0301 \u00CCgb\u00F2", + "dir": "ltr" + }, + "ikt": { + "name": "Inuinnaqtun", + "nativeName": "Inuinnaqtun", + "dir": "ltr" + }, + "is": { + "name": "Island\u00E9s", + "nativeName": "\u00CDslenska", + "dir": "ltr" + }, + "it": { + "name": "Italiano", + "nativeName": "Italiano", + "dir": "ltr" + }, + "iu": { + "name": "Inuktitut", + "nativeName": "\u1403\u14C4\u1483\u144E\u1450\u1466", + "dir": "ltr" + }, + "iu-Latn": { + "name": "Inuktitut (Latin)", + "nativeName": "Inuktitut (Latin)", + "dir": "ltr" + }, + "ja": { + "name": "Japon\u00E9s", + "nativeName": "\u65E5\u672C\u8A9E", + "dir": "ltr" + }, + "ka": { + "name": "Georgiano", + "nativeName": "\u10E5\u10D0\u10E0\u10D7\u10E3\u10DA\u10D8", + "dir": "ltr" + }, + "kk": { + "name": "Kazajo", + "nativeName": "\u049A\u0430\u0437\u0430\u049B \u0422\u0456\u043B\u0456", + "dir": "ltr" + }, + "km": { + "name": "Jemer", + "nativeName": "\u1781\u17D2\u1798\u17C2\u179A", + "dir": "ltr" + }, + "kmr": { + "name": "Kurdo (septentrional)", + "nativeName": "Kurd\u00EE (Bakur)", + "dir": "ltr" + }, + "kn": { + "name": "Canar\u00E9s", + "nativeName": "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1", + "dir": "ltr" + }, + "ko": { + "name": "Coreano", + "nativeName": "\uD55C\uAD6D\uC5B4", + "dir": "ltr" + }, + "ku": { + "name": "Kurdo (Centro)", + "nativeName": "Kurd\u00EE (Nav\u00EEn)", + "dir": "rtl" + }, + "ky": { + "name": "Kirgu\u00EDs", + "nativeName": "\u041A\u044B\u0440\u0433\u044B\u0437\u0447\u0430", + "dir": "ltr" + }, + "ln": { + "name": "Lingala", + "nativeName": "Ling\u00E1la", + "dir": "ltr" + }, + "lo": { + "name": "Lao", + "nativeName": "\u0EA5\u0EB2\u0EA7", + "dir": "ltr" + }, + "lt": { + "name": "Lituano", + "nativeName": "Lietuvi\u0173", + "dir": "ltr" + }, + "lug": { + "name": "Ganda", + "nativeName": "Ganda", + "dir": "ltr" + }, + "lv": { + "name": "Let\u00F3n", + "nativeName": "Latvie\u0161u", + "dir": "ltr" + }, + "lzh": { + "name": "Chinese (Literary)", + "nativeName": "\u4E2D\u6587 (\u6587\u8A00\u6587)", + "dir": "ltr" + }, + "mg": { + "name": "Malgache", + "nativeName": "Malagasy", + "dir": "ltr" + }, + "mi": { + "name": "Maor\u00ED", + "nativeName": "Te Reo M\u0101ori", + "dir": "ltr" + }, + "mk": { + "name": "Macedonio", + "nativeName": "\u041C\u0430\u043A\u0435\u0434\u043E\u043D\u0441\u043A\u0438", + "dir": "ltr" + }, + "ml": { + "name": "Malayalam", + "nativeName": "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02", + "dir": "ltr" + }, + "mn-Cyrl": { + "name": "Mongolian (Cyrillic)", + "nativeName": "Mongolian (Cyrillic)", + "dir": "ltr" + }, + "mn-Mong": { + "name": "Mongolian (Traditional)", + "nativeName": "\u182E\u1823\u1829\u182D\u1823\u182F \u182C\u1821\u182F\u1821", + "dir": "ltr" + }, + "mr": { + "name": "Marat\u00ED", + "nativeName": "\u092E\u0930\u093E\u0920\u0940", + "dir": "ltr" + }, + "ms": { + "name": "Malayo", + "nativeName": "Melayu", + "dir": "ltr" + }, + "mt": { + "name": "Malt\u00E9s", + "nativeName": "Malti", + "dir": "ltr" + }, + "mww": { + "name": "Hmong", + "nativeName": "Hmong Daw", + "dir": "ltr" + }, + "my": { + "name": "Birmano", + "nativeName": "\u1019\u103C\u1014\u103A\u1019\u102C", + "dir": "ltr" + }, + "nb": { + "name": "Noruego Bokmal", + "nativeName": "Norsk Bokm\u00E5l", + "dir": "ltr" + }, + "ne": { + "name": "Nepal\u00ED", + "nativeName": "\u0928\u0947\u092A\u093E\u0932\u0940", + "dir": "ltr" + }, + "nl": { + "name": "Neerland\u00E9s", + "nativeName": "Nederlands", + "dir": "ltr" + }, + "nso": { + "name": "Sesotho sa Leboa", + "nativeName": "Sesotho sa Leboa", + "dir": "ltr" + }, + "nya": { + "name": "Nyanja", + "nativeName": "Nyanja", + "dir": "ltr" + }, + "or": { + "name": "Oriya", + "nativeName": "\u0B13\u0B21\u0B3C\u0B3F\u0B06", + "dir": "ltr" + }, + "otq": { + "name": "Otom\u00ED Quer\u00E9taro", + "nativeName": "H\u00F1\u00E4h\u00F1u", + "dir": "ltr" + }, + "pa": { + "name": "Punyab\u00ED", + "nativeName": "\u0A2A\u0A70\u0A1C\u0A3E\u0A2C\u0A40", + "dir": "ltr" + }, + "pl": { + "name": "Polaco", + "nativeName": "Polski", + "dir": "ltr" + }, + "prs": { + "name": "Dar\u00ED", + "nativeName": "\u062F\u0631\u06CC", + "dir": "rtl" + }, + "ps": { + "name": "Past\u00FAn", + "nativeName": "\u067E\u069A\u062A\u0648", + "dir": "rtl" + }, + "pt": { + "name": "Portugu\u00E9s (Brasil)", + "nativeName": "Portugu\u00EAs (Brasil)", + "dir": "ltr" + }, + "pt-PT": { + "name": "Portugu\u00E9s (Portugal)", + "nativeName": "Portugu\u00EAs (Portugal)", + "dir": "ltr" + }, + "ro": { + "name": "Rumano", + "nativeName": "Rom\u00E2n\u0103", + "dir": "ltr" + }, + "ru": { + "name": "Ruso", + "nativeName": "\u0420\u0443\u0441\u0441\u043A\u0438\u0439", + "dir": "ltr" + }, + "run": { + "name": "Rundi", + "nativeName": "Rundi", + "dir": "ltr" + }, + "rw": { + "name": "Kinyarwanda", + "nativeName": "Kinyarwanda", + "dir": "ltr" + }, + "sk": { + "name": "Eslovaco", + "nativeName": "Sloven\u010Dina", + "dir": "ltr" + }, + "sl": { + "name": "Esloveno", + "nativeName": "Sloven\u0161\u010Dina", + "dir": "ltr" + }, + "sm": { + "name": "Samoano", + "nativeName": "Gagana S\u0101moa", + "dir": "ltr" + }, + "sn": { + "name": "Shona", + "nativeName": "chiShona", + "dir": "ltr" + }, + "so": { + "name": "Somal\u00ED", + "nativeName": "Soomaali", + "dir": "ltr" + }, + "sq": { + "name": "Alban\u00E9s", + "nativeName": "Shqip", + "dir": "ltr" + }, + "sr-Cyrl": { + "name": "Serbio (Cir\u00EDlico)", + "nativeName": "\u0421\u0440\u043F\u0441\u043A\u0438 (\u045B\u0438\u0440\u0438\u043B\u0438\u0446\u0430)", + "dir": "ltr" + }, + "sr-Latn": { + "name": "Serbio (Latino)", + "nativeName": "Srpski (latinica)", + "dir": "ltr" + }, + "st": { + "name": "Sesotho", + "nativeName": "Sesotho", + "dir": "ltr" + }, + "sv": { + "name": "Sueco", + "nativeName": "Svenska", + "dir": "ltr" + }, + "sw": { + "name": "Suajili", + "nativeName": "Kiswahili", + "dir": "ltr" + }, + "ta": { + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "dir": "ltr" + }, + "te": { + "name": "Telugu", + "nativeName": "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41", + "dir": "ltr" + }, + "th": { + "name": "Tailand\u00E9s", + "nativeName": "\u0E44\u0E17\u0E22", + "dir": "ltr" + }, + "ti": { + "name": "Tigri\u00F1a", + "nativeName": "\u1275\u130D\u122D", + "dir": "ltr" + }, + "tk": { + "name": "Turcomano", + "nativeName": "T\u00FCrkmen Dili", + "dir": "ltr" + }, + "tlh-Latn": { + "name": "Klingon (Latino)", + "nativeName": "Klingon (Latin)", + "dir": "ltr" + }, + "tlh-Piqd": { + "name": "Klingon (pIqaD)", + "nativeName": "Klingon (pIqaD)", + "dir": "ltr" + }, + "tn": { + "name": "Setswana", + "nativeName": "Setswana", + "dir": "ltr" + }, + "to": { + "name": "Tongano", + "nativeName": "Lea Fakatonga", + "dir": "ltr" + }, + "tr": { + "name": "Turco", + "nativeName": "T\u00FCrk\u00E7e", + "dir": "ltr" + }, + "tt": { + "name": "T\u00E1rtaro", + "nativeName": "\u0422\u0430\u0442\u0430\u0440", + "dir": "ltr" + }, + "ty": { + "name": "Tahitiano", + "nativeName": "Reo Tahiti", + "dir": "ltr" + }, + "ug": { + "name": "Uigur", + "nativeName": "\u0626\u06C7\u064A\u063A\u06C7\u0631\u0686\u06D5", + "dir": "rtl" + }, + "uk": { + "name": "Ucraniano", + "nativeName": "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430", + "dir": "ltr" + }, + "ur": { + "name": "Urdu", + "nativeName": "\u0627\u0631\u062F\u0648", + "dir": "rtl" + }, + "uz": { + "name": "Uzbeko", + "nativeName": "Uzbek (Latin)", + "dir": "ltr" + }, + "vi": { + "name": "Vietnamita", + "nativeName": "Ti\u1EBFng Vi\u1EC7t", + "dir": "ltr" + }, + "xh": { + "name": "Xhosa", + "nativeName": "isiXhosa", + "dir": "ltr" + }, + "yo": { + "name": "Yoruba", + "nativeName": "\u00C8d\u00E8 Yor\u00F9b\u00E1", + "dir": "ltr" + }, + "yua": { + "name": "Maya Yucateco", + "nativeName": "Yucatec Maya", + "dir": "ltr" + }, + "yue": { + "name": "Canton\u00E9s (Tradicional)", + "nativeName": "\u7CB5\u8A9E (\u7E41\u9AD4)", + "dir": "ltr" + }, + "zh-Hans": { + "name": "Chino (Simplificado)", + "nativeName": "\u4E2D\u6587 (\u7B80\u4F53)", + "dir": "ltr" + }, + "zh-Hant": { + "name": "Chino (Tradicional)", + "nativeName": "\u7E41\u9AD4\u4E2D\u6587 (\u7E41\u9AD4)", + "dir": "ltr" + }, + "zu": { + "name": "Zul\u00FA", + "nativeName": "Isi-Zulu", + "dir": "ltr" + } + }, + "transliteration": { + "ar": { + "name": "\u00C1rabe", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "scripts": [ + { + "code": "Arab", + "name": "\u00E1rabe", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "dir": "rtl", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0627\u0644\u0644\u0627\u062A\u064A\u0646\u064A\u0629", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u0627\u0644\u0644\u0627\u062A\u064A\u0646\u064A\u0629", + "dir": "ltr", + "toScripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "dir": "rtl" + } + ] + } + ] + }, + "as": { + "name": "Asam\u00E9s", + "nativeName": "\u0985\u09B8\u09AE\u09C0\u09AF\u09BC\u09BE", + "scripts": [ + { + "code": "Beng", + "name": "bengal\u00ED", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u09B2\u09C7\u099F\u09BF\u09A8", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u09B2\u09C7\u099F\u09BF\u09A8", + "dir": "ltr", + "toScripts": [ + { + "code": "Beng", + "name": "Bangla", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr" + } + ] + } + ] + }, + "be": { + "name": "Belarusian", + "nativeName": "Belarusian", + "scripts": [ + { + "code": "Cyrl", + "name": "cir\u00EDlico", + "nativeName": "Cyrillic", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "Latin", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "Cyrillic", + "dir": "ltr" + } + ] + } + ] + }, + "bg": { + "name": "B\u00FAlgaro", + "nativeName": "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438", + "scripts": [ + { + "code": "Cyrl", + "name": "cir\u00EDlico", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u0430", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0438\u0446\u0430", + "dir": "ltr" + } + ] + } + ] + }, + "bn": { + "name": "Bengal\u00ED", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "scripts": [ + { + "code": "Beng", + "name": "bengal\u00ED", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u09B2\u09CD\u09AF\u09BE\u099F\u09BF\u09A8", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u09B2\u09CD\u09AF\u09BE\u099F\u09BF\u09A8", + "dir": "ltr", + "toScripts": [ + { + "code": "Beng", + "name": "Bangla", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr" + } + ] + } + ] + }, + "el": { + "name": "Griego", + "nativeName": "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC", + "scripts": [ + { + "code": "Grek", + "name": "griego", + "nativeName": "\u03B5\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03CC", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u03BB\u03B1\u03C4\u03B9\u03BD\u03B9\u03BA\u03CC", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u03BB\u03B1\u03C4\u03B9\u03BD\u03B9\u03BA\u03CC", + "dir": "ltr", + "toScripts": [ + { + "code": "Grek", + "name": "Greek", + "nativeName": "\u03B5\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03CC", + "dir": "ltr" + } + ] + } + ] + }, + "fa": { + "name": "Persa", + "nativeName": "\u0641\u0627\u0631\u0633\u06CC", + "scripts": [ + { + "code": "Arab", + "name": "\u00E1rabe", + "nativeName": "\u0639\u0631\u0628\u06CC", + "dir": "rtl", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0644\u0627\u062A\u06CC\u0646", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u0644\u0627\u062A\u06CC\u0646", + "dir": "ltr", + "toScripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0639\u0631\u0628\u06CC", + "dir": "rtl" + } + ] + } + ] + }, + "gu": { + "name": "Guyarat\u00ED", + "nativeName": "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0", + "scripts": [ + { + "code": "Gujr", + "name": "gujarati", + "nativeName": "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0AB2\u0AC7\u0A9F\u0ABF\u0AA8", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u0AB2\u0AC7\u0A9F\u0ABF\u0AA8", + "dir": "ltr", + "toScripts": [ + { + "code": "Gujr", + "name": "Gujarati", + "nativeName": "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0", + "dir": "ltr" + } + ] + } + ] + }, + "he": { + "name": "Hebreo", + "nativeName": "\u05E2\u05D1\u05E8\u05D9\u05EA", + "scripts": [ + { + "code": "Hebr", + "name": "hebreo", + "nativeName": "\u05E2\u05D1\u05E8\u05D9", + "dir": "rtl", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u05DC\u05D8\u05D9\u05E0\u05D9", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u05DC\u05D8\u05D9\u05E0\u05D9", + "dir": "ltr", + "toScripts": [ + { + "code": "Hebr", + "name": "Hebrew", + "nativeName": "\u05E2\u05D1\u05E8\u05D9", + "dir": "rtl" + } + ] + } + ] + }, + "hi": { + "name": "Hindi", + "nativeName": "\u0939\u093F\u0928\u094D\u0926\u0940", + "scripts": [ + { + "code": "Deva", + "name": "devanagari", + "nativeName": "\u0926\u0947\u0935\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u0948\u091F\u093F\u0928", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u0932\u0948\u091F\u093F\u0928", + "dir": "ltr", + "toScripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr" + } + ] + } + ] + }, + "ja": { + "name": "Japon\u00E9s", + "nativeName": "\u65E5\u672C\u8A9E", + "scripts": [ + { + "code": "Jpan", + "name": "japon\u00E9s", + "nativeName": "\u65E5\u672C\u8A9E\u306E\u6587\u5B57", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u30E9\u30C6\u30F3\u6587\u5B57", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u30E9\u30C6\u30F3\u6587\u5B57", + "dir": "ltr", + "toScripts": [ + { + "code": "Jpan", + "name": "Japanese", + "nativeName": "\u65E5\u672C\u8A9E\u306E\u6587\u5B57", + "dir": "ltr" + } + ] + } + ] + }, + "kk": { + "name": "Kazajo", + "nativeName": "\u049A\u0430\u0437\u0430\u049B \u0422\u0456\u043B\u0456", + "scripts": [ + { + "code": "Cyrl", + "name": "cir\u00EDlico", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B \u0436\u0430\u0437\u0443\u044B", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u044B\u043D \u0436\u0430\u0437\u0443\u044B", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u043B\u0430\u0442\u044B\u043D \u0436\u0430\u0437\u0443\u044B", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B \u0436\u0430\u0437\u0443\u044B", + "dir": "ltr" + } + ] + } + ] + }, + "kn": { + "name": "Canar\u00E9s", + "nativeName": "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1", + "scripts": [ + { + "code": "Knda", + "name": "canar\u00E9s", + "nativeName": "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0CB2\u0CCD\u0CAF\u0CBE\u0C9F\u0CBF\u0CA8\u0CCD", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u0CB2\u0CCD\u0CAF\u0CBE\u0C9F\u0CBF\u0CA8\u0CCD", + "dir": "ltr", + "toScripts": [ + { + "code": "Knda", + "name": "Kannada", + "nativeName": "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1", + "dir": "ltr" + } + ] + } + ] + }, + "ko": { + "name": "Coreano", + "nativeName": "\uD55C\uAD6D\uC5B4", + "scripts": [ + { + "code": "Kore", + "name": "coreano", + "nativeName": "\uD55C\uAD6D \uBB38\uC790", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\uB85C\uB9C8\uC790", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\uB85C\uB9C8\uC790", + "dir": "ltr", + "toScripts": [ + { + "code": "Kore", + "name": "Korean", + "nativeName": "\uD55C\uAD6D \uBB38\uC790", + "dir": "ltr" + } + ] + } + ] + }, + "ky": { + "name": "Kirgu\u00EDs", + "nativeName": "\u041A\u044B\u0440\u0433\u044B\u0437\u0447\u0430", + "scripts": [ + { + "code": "Cyrl", + "name": "cir\u00EDlico", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u044B\u043D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u043B\u0430\u0442\u044B\u043D", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr" + } + ] + } + ] + }, + "mk": { + "name": "Macedonio", + "nativeName": "\u041C\u0430\u043A\u0435\u0434\u043E\u043D\u0441\u043A\u0438", + "scripts": [ + { + "code": "Cyrl", + "name": "cir\u00EDlico", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0441\u043A\u043E \u043F\u0438\u0441\u043C\u043E", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0447\u043D\u043E \u043F\u0438\u0441\u043C\u043E", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0447\u043D\u043E \u043F\u0438\u0441\u043C\u043E", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0441\u043A\u043E \u043F\u0438\u0441\u043C\u043E", + "dir": "ltr" + } + ] + } + ] + }, + "ml": { + "name": "Malayalam", + "nativeName": "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02", + "scripts": [ + { + "code": "Mlym", + "name": "malay\u00E1lam", + "nativeName": "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0D32\u0D3E\u0D31\u0D4D\u0D31\u0D3F\u0D7B", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u0D32\u0D3E\u0D31\u0D4D\u0D31\u0D3F\u0D7B", + "dir": "ltr", + "toScripts": [ + { + "code": "Mlym", + "name": "Malayalam", + "nativeName": "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02", + "dir": "ltr" + } + ] + } + ] + }, + "mn-Cyrl": { + "name": "Mongolian (Cyrillic)", + "nativeName": "Mongolian (Cyrillic)", + "scripts": [ + { + "code": "Cyrl", + "name": "cir\u00EDlico", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u043B\u0430\u0442\u0438\u043D", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr" + } + ] + } + ] + }, + "mr": { + "name": "Marat\u00ED", + "nativeName": "\u092E\u0930\u093E\u0920\u0940", + "scripts": [ + { + "code": "Deva", + "name": "devanagari", + "nativeName": "\u0926\u0947\u0935\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u0945\u091F\u093F\u0928", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u0932\u0945\u091F\u093F\u0928", + "dir": "ltr", + "toScripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr" + } + ] + } + ] + }, + "ne": { + "name": "Nepal\u00ED", + "nativeName": "\u0928\u0947\u092A\u093E\u0932\u0940", + "scripts": [ + { + "code": "Deva", + "name": "devanagari", + "nativeName": "\u0926\u0947\u0935\u093E\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0932\u094D\u092F\u093E\u091F\u093F\u0928", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u0932\u094D\u092F\u093E\u091F\u093F\u0928", + "dir": "ltr", + "toScripts": [ + { + "code": "Deva", + "name": "Devanagari", + "nativeName": "\u0926\u0947\u0935\u093E\u0928\u093E\u0917\u0930\u0940", + "dir": "ltr" + } + ] + } + ] + }, + "or": { + "name": "Oriya", + "nativeName": "\u0B13\u0B21\u0B3C\u0B3F\u0B06", + "scripts": [ + { + "code": "Orya", + "name": "oriya", + "nativeName": "\u0B13\u0B21\u0B3C\u0B3F\u0B06", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0B32\u0B3E\u0B1F\u0B3F\u0B28\u0B4D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u0B32\u0B3E\u0B1F\u0B3F\u0B28\u0B4D", + "dir": "ltr", + "toScripts": [ + { + "code": "Orya", + "name": "Odia", + "nativeName": "\u0B13\u0B21\u0B3C\u0B3F\u0B06", + "dir": "ltr" + } + ] + } + ] + }, + "pa": { + "name": "Punyab\u00ED", + "nativeName": "\u0A2A\u0A70\u0A1C\u0A3E\u0A2C\u0A40", + "scripts": [ + { + "code": "Guru", + "name": "gurmuji", + "nativeName": "\u0A17\u0A41\u0A30\u0A2E\u0A41\u0A16\u0A40", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0A32\u0A3E\u0A24\u0A40\u0A28\u0A40", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u0A32\u0A3E\u0A24\u0A40\u0A28\u0A40", + "dir": "ltr", + "toScripts": [ + { + "code": "Guru", + "name": "Gurmukhi", + "nativeName": "\u0A17\u0A41\u0A30\u0A2E\u0A41\u0A16\u0A40", + "dir": "ltr" + } + ] + } + ] + }, + "ru": { + "name": "Ruso", + "nativeName": "\u0420\u0443\u0441\u0441\u043A\u0438\u0439", + "scripts": [ + { + "code": "Cyrl", + "name": "cir\u00EDlico", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u0430", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B\u0438\u0446\u0430", + "dir": "ltr" + } + ] + } + ] + }, + "sd": { + "name": "Sindhi", + "nativeName": "\u0633\u0646\u068C\u064A", + "scripts": [ + { + "code": "Arab", + "name": "\u00E1rabe", + "nativeName": "Arabic", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "Latin", + "dir": "ltr", + "toScripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "Arabic", + "dir": "ltr" + } + ] + } + ] + }, + "si": { + "name": "Sinhala", + "nativeName": "\u0DC3\u0DD2\u0D82\u0DC4\u0DBD", + "scripts": [ + { + "code": "Sinh", + "name": "cingal\u00E9s", + "nativeName": "Sinhala", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "Latin", + "dir": "ltr", + "toScripts": [ + { + "code": "Sinh", + "name": "Sinhala", + "nativeName": "Sinhala", + "dir": "ltr" + } + ] + } + ] + }, + "sr-Cyrl": { + "name": "Serbio (Cir\u00EDlico)", + "nativeName": "\u0421\u0440\u043F\u0441\u043A\u0438 (\u045B\u0438\u0440\u0438\u043B\u0438\u0446\u0430)", + "scripts": [ + { + "code": "Cyrl", + "name": "cir\u00EDlico", + "nativeName": "\u045B\u0438\u0440\u0438\u043B\u0438\u0446\u0430", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "latinica", + "dir": "ltr" + } + ] + } + ] + }, + "sr-Latn": { + "name": "Serbio (Latino)", + "nativeName": "Srpski (latinica)", + "scripts": [ + { + "code": "Latn", + "name": "latino", + "nativeName": "latinica", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u0107irilica", + "dir": "ltr" + } + ] + } + ] + }, + "ta": { + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "scripts": [ + { + "code": "Taml", + "name": "tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0BB2\u0BA4\u0BCD\u0BA4\u0BBF\u0BA9\u0BCD", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u0BB2\u0BA4\u0BCD\u0BA4\u0BBF\u0BA9\u0BCD", + "dir": "ltr", + "toScripts": [ + { + "code": "Taml", + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "dir": "ltr" + } + ] + } + ] + }, + "te": { + "name": "Telugu", + "nativeName": "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41", + "scripts": [ + { + "code": "Telu", + "name": "telugu", + "nativeName": "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0C32\u0C3E\u0C1F\u0C3F\u0C28\u0C4D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u0C32\u0C3E\u0C1F\u0C3F\u0C28\u0C4D", + "dir": "ltr", + "toScripts": [ + { + "code": "Telu", + "name": "Telugu", + "nativeName": "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41", + "dir": "ltr" + } + ] + } + ] + }, + "tg": { + "name": "Tajik", + "nativeName": "Tajik (Cyrillic)", + "scripts": [ + { + "code": "Cyrl", + "name": "cir\u00EDlico", + "nativeName": "Cyrillic", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "Latin", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "Latin", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "Cyrillic", + "dir": "ltr" + } + ] + } + ] + }, + "th": { + "name": "Tailand\u00E9s", + "nativeName": "\u0E44\u0E17\u0E22", + "scripts": [ + { + "code": "Thai", + "name": "tailand\u00E9s", + "nativeName": "\u0E44\u0E17\u0E22", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0E25\u0E30\u0E15\u0E34\u0E19", + "dir": "ltr" + } + ] + } + ] + }, + "tt": { + "name": "T\u00E1rtaro", + "nativeName": "\u0422\u0430\u0442\u0430\u0440", + "scripts": [ + { + "code": "Cyrl", + "name": "cir\u00EDlico", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u043B\u0430\u0442\u0438\u043D", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u043B", + "dir": "ltr" + } + ] + } + ] + }, + "uk": { + "name": "Ucraniano", + "nativeName": "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430", + "scripts": [ + { + "code": "Cyrl", + "name": "cir\u00EDlico", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0438\u0446\u044F", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u044F", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u043B\u0430\u0442\u0438\u043D\u0438\u0446\u044F", + "dir": "ltr", + "toScripts": [ + { + "code": "Cyrl", + "name": "Cyrillic", + "nativeName": "\u043A\u0438\u0440\u0438\u043B\u0438\u0446\u044F", + "dir": "ltr" + } + ] + } + ] + }, + "ur": { + "name": "Urdu", + "nativeName": "\u0627\u0631\u062F\u0648", + "scripts": [ + { + "code": "Arab", + "name": "\u00E1rabe", + "nativeName": "\u0639\u0631\u0628\u06CC", + "dir": "rtl", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u0644\u0627\u0637\u06CC\u0646\u06CC", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u0644\u0627\u0637\u06CC\u0646\u06CC", + "dir": "ltr", + "toScripts": [ + { + "code": "Arab", + "name": "Arabic", + "nativeName": "\u0639\u0631\u0628\u06CC", + "dir": "rtl" + } + ] + } + ] + }, + "zh-Hans": { + "name": "Chino (Simplificado)", + "nativeName": "\u4E2D\u6587 (\u7B80\u4F53)", + "scripts": [ + { + "code": "Hans", + "name": "simplificado", + "nativeName": "\u7B80\u4F53\u6C49\u8BED", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u62C9\u4E01\u8BED", + "dir": "ltr" + }, + { + "code": "Hant", + "name": "Hat", + "nativeName": "\u4F20\u7EDF", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u62C9\u4E01\u8BED", + "dir": "ltr", + "toScripts": [ + { + "code": "Hans", + "name": "Han", + "nativeName": "\u7B80\u4F53\u6C49\u8BED", + "dir": "ltr" + }, + { + "code": "Hant", + "name": "Hat", + "nativeName": "\u4F20\u7EDF", + "dir": "ltr" + } + ] + } + ] + }, + "zh-Hant": { + "name": "Chino (Tradicional)", + "nativeName": "\u7E41\u9AD4\u4E2D\u6587 (\u7E41\u9AD4)", + "scripts": [ + { + "code": "Hant", + "name": "tradicional", + "nativeName": "\u50B3\u7D71", + "dir": "ltr", + "toScripts": [ + { + "code": "Latn", + "name": "Latin", + "nativeName": "\u62C9\u4E01\u8BED", + "dir": "ltr" + }, + { + "code": "Hans", + "name": "Han", + "nativeName": "\u7B80\u4F53\u6C49\u8BED", + "dir": "ltr" + } + ] + }, + { + "code": "Latn", + "name": "latino", + "nativeName": "\u62C9\u4E01\u6587", + "dir": "ltr", + "toScripts": [ + { + "code": "Hans", + "name": "Han", + "nativeName": "\u7B80\u4F53\u6C49\u8BED", + "dir": "ltr" + }, + { + "code": "Hant", + "name": "Hat", + "nativeName": "\u4F20\u7EDF", + "dir": "ltr" + } + ] + } + ] + } + }, + "dictionary": { + "af": { + "name": "Afrik\u00E1ans", + "nativeName": "Afrikaans", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ar": { + "name": "\u00C1rabe", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "dir": "rtl", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "bg": { + "name": "B\u00FAlgaro", + "nativeName": "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "bn": { + "name": "Bengal\u00ED", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "bs": { + "name": "Bosnian", + "nativeName": "Bosnian", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ca": { + "name": "Catal\u00E1n", + "nativeName": "Catal\u00E0", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "cs": { + "name": "Checo", + "nativeName": "\u010Ce\u0161tina", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "cy": { + "name": "Gal\u00E9s", + "nativeName": "Cymraeg", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "da": { + "name": "Dan\u00E9s", + "nativeName": "Dansk", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "de": { + "name": "Alem\u00E1n", + "nativeName": "Deutsch", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "el": { + "name": "Griego", + "nativeName": "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "en": { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "translations": [ + { + "name": "Afrik\u00E1ans", + "nativeName": "Afrikaans", + "dir": "ltr", + "code": "af" + }, + { + "name": "\u00C1rabe", + "nativeName": "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", + "dir": "rtl", + "code": "ar" + }, + { + "name": "B\u00FAlgaro", + "nativeName": "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438", + "dir": "ltr", + "code": "bg" + }, + { + "name": "Bengal\u00ED", + "nativeName": "\u09AC\u09BE\u0982\u09B2\u09BE", + "dir": "ltr", + "code": "bn" + }, + { + "name": "Bosnian", + "nativeName": "Bosnian", + "dir": "ltr", + "code": "bs" + }, + { + "name": "Catal\u00E1n", + "nativeName": "Catal\u00E0", + "dir": "ltr", + "code": "ca" + }, + { + "name": "Chino (Simplificado)", + "nativeName": "\u4E2D\u6587 (\u7B80\u4F53)", + "dir": "ltr", + "code": "zh-Hans" + }, + { + "name": "Checo", + "nativeName": "\u010Ce\u0161tina", + "dir": "ltr", + "code": "cs" + }, + { + "name": "Gal\u00E9s", + "nativeName": "Cymraeg", + "dir": "ltr", + "code": "cy" + }, + { + "name": "Dan\u00E9s", + "nativeName": "Dansk", + "dir": "ltr", + "code": "da" + }, + { + "name": "Alem\u00E1n", + "nativeName": "Deutsch", + "dir": "ltr", + "code": "de" + }, + { + "name": "Griego", + "nativeName": "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC", + "dir": "ltr", + "code": "el" + }, + { + "name": "Espa\u00F1ol", + "nativeName": "Espa\u00F1ol", + "dir": "ltr", + "code": "es" + }, + { + "name": "Estonio", + "nativeName": "Eesti", + "dir": "ltr", + "code": "et" + }, + { + "name": "Persa", + "nativeName": "\u0641\u0627\u0631\u0633\u06CC", + "dir": "rtl", + "code": "fa" + }, + { + "name": "Fin\u00E9s", + "nativeName": "Suomi", + "dir": "ltr", + "code": "fi" + }, + { + "name": "Franc\u00E9s", + "nativeName": "Fran\u00E7ais", + "dir": "ltr", + "code": "fr" + }, + { + "name": "Hebreo", + "nativeName": "\u05E2\u05D1\u05E8\u05D9\u05EA", + "dir": "rtl", + "code": "he" + }, + { + "name": "Hindi", + "nativeName": "\u0939\u093F\u0928\u094D\u0926\u0940", + "dir": "ltr", + "code": "hi" + }, + { + "name": "Croata", + "nativeName": "Hrvatski", + "dir": "ltr", + "code": "hr" + }, + { + "name": "H\u00FAngaro", + "nativeName": "Magyar", + "dir": "ltr", + "code": "hu" + }, + { + "name": "Indonesio", + "nativeName": "Indonesia", + "dir": "ltr", + "code": "id" + }, + { + "name": "Island\u00E9s", + "nativeName": "\u00CDslenska", + "dir": "ltr", + "code": "is" + }, + { + "name": "Italiano", + "nativeName": "Italiano", + "dir": "ltr", + "code": "it" + }, + { + "name": "Japon\u00E9s", + "nativeName": "\u65E5\u672C\u8A9E", + "dir": "ltr", + "code": "ja" + }, + { + "name": "Coreano", + "nativeName": "\uD55C\uAD6D\uC5B4", + "dir": "ltr", + "code": "ko" + }, + { + "name": "Lituano", + "nativeName": "Lietuvi\u0173", + "dir": "ltr", + "code": "lt" + }, + { + "name": "Let\u00F3n", + "nativeName": "Latvie\u0161u", + "dir": "ltr", + "code": "lv" + }, + { + "name": "Malt\u00E9s", + "nativeName": "Malti", + "dir": "ltr", + "code": "mt" + }, + { + "name": "Malayo", + "nativeName": "Melayu", + "dir": "ltr", + "code": "ms" + }, + { + "name": "Hmong", + "nativeName": "Hmong Daw", + "dir": "ltr", + "code": "mww" + }, + { + "name": "Neerland\u00E9s", + "nativeName": "Nederlands", + "dir": "ltr", + "code": "nl" + }, + { + "name": "Noruego Bokmal", + "nativeName": "Norsk Bokm\u00E5l", + "dir": "ltr", + "code": "nb" + }, + { + "name": "Polaco", + "nativeName": "Polski", + "dir": "ltr", + "code": "pl" + }, + { + "name": "Portugu\u00E9s (Brasil)", + "nativeName": "Portugu\u00EAs (Brasil)", + "dir": "ltr", + "code": "pt" + }, + { + "name": "Rumano", + "nativeName": "Rom\u00E2n\u0103", + "dir": "ltr", + "code": "ro" + }, + { + "name": "Ruso", + "nativeName": "\u0420\u0443\u0441\u0441\u043A\u0438\u0439", + "dir": "ltr", + "code": "ru" + }, + { + "name": "Eslovaco", + "nativeName": "Sloven\u010Dina", + "dir": "ltr", + "code": "sk" + }, + { + "name": "Esloveno", + "nativeName": "Sloven\u0161\u010Dina", + "dir": "ltr", + "code": "sl" + }, + { + "name": "Serbio (Latino)", + "nativeName": "Srpski (latinica)", + "dir": "ltr", + "code": "sr-Latn" + }, + { + "name": "Sueco", + "nativeName": "Svenska", + "dir": "ltr", + "code": "sv" + }, + { + "name": "Suajili", + "nativeName": "Kiswahili", + "dir": "ltr", + "code": "sw" + }, + { + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "dir": "ltr", + "code": "ta" + }, + { + "name": "Tailand\u00E9s", + "nativeName": "\u0E44\u0E17\u0E22", + "dir": "ltr", + "code": "th" + }, + { + "name": "Klingon (Latino)", + "nativeName": "Klingon (Latin)", + "dir": "ltr", + "code": "tlh-Latn" + }, + { + "name": "Turco", + "nativeName": "T\u00FCrk\u00E7e", + "dir": "ltr", + "code": "tr" + }, + { + "name": "Ucraniano", + "nativeName": "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430", + "dir": "ltr", + "code": "uk" + }, + { + "name": "Urdu", + "nativeName": "\u0627\u0631\u062F\u0648", + "dir": "rtl", + "code": "ur" + }, + { + "name": "Vietnamita", + "nativeName": "Ti\u1EBFng Vi\u1EC7t", + "dir": "ltr", + "code": "vi" + } + ] + }, + "es": { + "name": "Espa\u00F1ol", + "nativeName": "Espa\u00F1ol", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "et": { + "name": "Estonio", + "nativeName": "Eesti", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "fa": { + "name": "Persa", + "nativeName": "\u0641\u0627\u0631\u0633\u06CC", + "dir": "rtl", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "fi": { + "name": "Fin\u00E9s", + "nativeName": "Suomi", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "fr": { + "name": "Franc\u00E9s", + "nativeName": "Fran\u00E7ais", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "he": { + "name": "Hebreo", + "nativeName": "\u05E2\u05D1\u05E8\u05D9\u05EA", + "dir": "rtl", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "hi": { + "name": "Hindi", + "nativeName": "\u0939\u093F\u0928\u094D\u0926\u0940", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "hr": { + "name": "Croata", + "nativeName": "Hrvatski", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "hu": { + "name": "H\u00FAngaro", + "nativeName": "Magyar", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "id": { + "name": "Indonesio", + "nativeName": "Indonesia", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "is": { + "name": "Island\u00E9s", + "nativeName": "\u00CDslenska", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "it": { + "name": "Italiano", + "nativeName": "Italiano", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ja": { + "name": "Japon\u00E9s", + "nativeName": "\u65E5\u672C\u8A9E", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ko": { + "name": "Coreano", + "nativeName": "\uD55C\uAD6D\uC5B4", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "lt": { + "name": "Lituano", + "nativeName": "Lietuvi\u0173", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "lv": { + "name": "Let\u00F3n", + "nativeName": "Latvie\u0161u", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ms": { + "name": "Malayo", + "nativeName": "Melayu", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "mt": { + "name": "Malt\u00E9s", + "nativeName": "Malti", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "mww": { + "name": "Hmong", + "nativeName": "Hmong Daw", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "nb": { + "name": "Noruego Bokmal", + "nativeName": "Norsk Bokm\u00E5l", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "nl": { + "name": "Neerland\u00E9s", + "nativeName": "Nederlands", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "pl": { + "name": "Polaco", + "nativeName": "Polski", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "pt": { + "name": "Portugu\u00E9s (Brasil)", + "nativeName": "Portugu\u00EAs (Brasil)", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ro": { + "name": "Rumano", + "nativeName": "Rom\u00E2n\u0103", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ru": { + "name": "Ruso", + "nativeName": "\u0420\u0443\u0441\u0441\u043A\u0438\u0439", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sk": { + "name": "Eslovaco", + "nativeName": "Sloven\u010Dina", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sl": { + "name": "Esloveno", + "nativeName": "Sloven\u0161\u010Dina", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sr-Latn": { + "name": "Serbio (Latino)", + "nativeName": "Srpski (latinica)", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sv": { + "name": "Sueco", + "nativeName": "Svenska", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "sw": { + "name": "Suajili", + "nativeName": "Kiswahili", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ta": { + "name": "Tamil", + "nativeName": "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "th": { + "name": "Tailand\u00E9s", + "nativeName": "\u0E44\u0E17\u0E22", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "tlh-Latn": { + "name": "Klingon (Latino)", + "nativeName": "Klingon (Latin)", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "tr": { + "name": "Turco", + "nativeName": "T\u00FCrk\u00E7e", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "uk": { + "name": "Ucraniano", + "nativeName": "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "ur": { + "name": "Urdu", + "nativeName": "\u0627\u0631\u062F\u0648", + "dir": "rtl", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "vi": { + "name": "Vietnamita", + "nativeName": "Ti\u1EBFng Vi\u1EC7t", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + }, + "zh-Hans": { + "name": "Chino (Simplificado)", + "nativeName": "\u4E2D\u6587 (\u7B80\u4F53)", + "dir": "ltr", + "translations": [ + { + "name": "Ingl\u00E9s", + "nativeName": "English", + "dir": "ltr", + "code": "en" + } + ] + } + } + } + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_alignment.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_alignment.json new file mode 100644 index 000000000000..83930fa17c08 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_alignment.json @@ -0,0 +1,35 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/translate?to=cs\u0026includeAlignment=true\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "39", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022It is a beautiful morning\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Length": "159", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:54 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "25", + "X-MT-System": "Microsoft", + "X-RequestId": "TRAN.MW1P.99BE.0403T2149.2FCA6C6" + }, + "ResponseBody": "[{\u0022detectedLanguage\u0022:{\u0022language\u0022:\u0022en\u0022,\u0022score\u0022:1.0},\u0022translations\u0022:[{\u0022text\u0022:\u0022Je kr\u00E1sn\u00E9 r\u00E1no\u0022,\u0022to\u0022:\u0022cs\u0022,\u0022alignment\u0022:{\u0022proj\u0022:\u00220:1-0:1 0:1-3:8 18:24-10:13\u0022}}]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_autodetect.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_autodetect.json new file mode 100644 index 000000000000..51b2e8d36cf8 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_autodetect.json @@ -0,0 +1,35 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/translate?to=cs\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "29", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022This is a test.\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Length": "105", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:53 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "15", + "X-MT-System": "Microsoft", + "X-RequestId": "TRAN.MW1P.99BE.0403T2149.2FCA61B" + }, + "ResponseBody": "[{\u0022detectedLanguage\u0022:{\u0022language\u0022:\u0022en\u0022,\u0022score\u0022:1.0},\u0022translations\u0022:[{\u0022text\u0022:\u0022Tohle je test.\u0022,\u0022to\u0022:\u0022cs\u0022}]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_custom_endpoint.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_custom_endpoint.json new file mode 100644 index 000000000000..0d61d9835e3b --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_custom_endpoint.json @@ -0,0 +1,34 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeCustomEndpoint.cognitiveservices.azure.com/translator/text/v3.0/translate?to=fr\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "39", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022It is a beautiful morning\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": "X-RequestId,X-Metered-Usage", + "apim-request-id": "c49a5453-bb37-4484-8c01-81d5b31ce7b1", + "Content-Length": "117", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:54 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "25", + "x-ms-region": "West US 2", + "X-MT-System": "Microsoft", + "X-RequestId": "TRAN.MW1P.9A67.0403T2149.2EB3559" + }, + "ResponseBody": "[{\u0022detectedLanguage\u0022:{\u0022language\u0022:\u0022en\u0022,\u0022score\u0022:1.0},\u0022translations\u0022:[{\u0022text\u0022:\u0022C\u2019est une belle matin\u00E9e\u0022,\u0022to\u0022:\u0022fr\u0022}]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_dictionary_tag.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_dictionary_tag.json new file mode 100644 index 000000000000..790acf385a67 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_dictionary_tag.json @@ -0,0 +1,35 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/translate?to=es\u0026from=en\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "126", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022The word \u003C mstrans:dictionary translation =\\\u0022wordomatic\\\u0022\u003Ewordomatic\u003C/mstrans:dictionary\u003E is a dictionary entry.\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Length": "164", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:53 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "110", + "X-MT-System": "Microsoft", + "X-RequestId": "TRAN.MW1P.99BE.0403T2149.2FCA643" + }, + "ResponseBody": "[{\u0022translations\u0022:[{\u0022text\u0022:\u0022La palabra \u003C mstrans:dictionary translation =\\\u0022wordomatic\\\u0022\u003Ewordomatic\u003C/mstrans:dictionary\u003E es una entrada de diccionario.\u0022,\u0022to\u0022:\u0022es\u0022}]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_different_texttypes.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_different_texttypes.json new file mode 100644 index 000000000000..39010ec27f63 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_different_texttypes.json @@ -0,0 +1,35 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/translate?to=cs\u0026textType=html\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "62", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022\u003Chtml\u003E\u003Cbody\u003EThis \u003Cb\u003Eis\u003C/b\u003E a test.\u003C/body\u003E\u003C/html\u003E\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Length": "137", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:53 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "48", + "X-MT-System": "Microsoft", + "X-RequestId": "TRAN.MW1P.99BE.0403T2149.2FCA695" + }, + "ResponseBody": "[{\u0022detectedLanguage\u0022:{\u0022language\u0022:\u0022en\u0022,\u0022score\u0022:1.0},\u0022translations\u0022:[{\u0022text\u0022:\u0022\u003Chtml\u003E\u003Cbody\u003EToto \u003Cb\u003Eje\u003C/b\u003E test.\u003C/body\u003E\u003C/html\u003E\u0022,\u0022to\u0022:\u0022cs\u0022}]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_from_to_latin.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_from_to_latin.json new file mode 100644 index 000000000000..c01f8b9baca8 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_from_to_latin.json @@ -0,0 +1,35 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/translate?to=ta\u0026from=hi\u0026fromScript=Latn\u0026toScript=Latn\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "25", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022ap kaise ho\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Length": "213", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:53 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "11", + "X-MT-System": "Microsoft", + "X-RequestId": "TRAN.MW1P.99BE.0403T2149.2FCA663" + }, + "ResponseBody": "[{\u0022sourceText\u0022:{\u0022text\u0022:\u0022\u090F\u092A\u0940 \u0915\u0948\u0938\u0947 \u0939\u094B\u0022},\u0022translations\u0022:[{\u0022text\u0022:\u0022\u0B8E\u0BAA\u0BCD\u0BAA\u0B9F\u0BBF \u0B87\u0BB0\u0BC1\u0B95\u0BCD\u0B95\u0BBF\u0BB1\u0BBE\u0BAF\u0BCD?\u0022,\u0022transliteration\u0022:{\u0022text\u0022:\u0022eppadi irukkiraai?\u0022,\u0022script\u0022:\u0022Latn\u0022},\u0022to\u0022:\u0022ta\u0022}]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_multiple_input.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_multiple_input.json new file mode 100644 index 000000000000..14bc2a083868 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_multiple_input.json @@ -0,0 +1,35 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/translate?to=cs\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "94", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022This is a test.\u0022}, {\u0022text\u0022: \u0022Esto es una prueba.\u0022}, {\u0022text\u0022: \u0022Dies ist ein Test.\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Length": "313", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:53 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "52", + "X-MT-System": "Microsoft,Microsoft,Microsoft", + "X-RequestId": "TRAN.MW1P.99BE.0403T2149.2FCA672" + }, + "ResponseBody": "[{\u0022detectedLanguage\u0022:{\u0022language\u0022:\u0022en\u0022,\u0022score\u0022:1.0},\u0022translations\u0022:[{\u0022text\u0022:\u0022Tohle je test.\u0022,\u0022to\u0022:\u0022cs\u0022}]},{\u0022detectedLanguage\u0022:{\u0022language\u0022:\u0022es\u0022,\u0022score\u0022:1.0},\u0022translations\u0022:[{\u0022text\u0022:\u0022Tohle je test.\u0022,\u0022to\u0022:\u0022cs\u0022}]},{\u0022detectedLanguage\u0022:{\u0022language\u0022:\u0022de\u0022,\u0022score\u0022:1.0},\u0022translations\u0022:[{\u0022text\u0022:\u0022Tohle je test.\u0022,\u0022to\u0022:\u0022cs\u0022}]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_multiple_target_languages.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_multiple_target_languages.json new file mode 100644 index 000000000000..657ad7a29290 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_multiple_target_languages.json @@ -0,0 +1,35 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/translate?to=cs\u0026to=es\u0026to=de\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "29", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022This is a test.\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Length": "186", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:53 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "45", + "X-MT-System": "Microsoft,Microsoft,Microsoft", + "X-RequestId": "TRAN.MW1P.99BE.0403T2149.2FCA687" + }, + "ResponseBody": "[{\u0022detectedLanguage\u0022:{\u0022language\u0022:\u0022en\u0022,\u0022score\u0022:1.0},\u0022translations\u0022:[{\u0022text\u0022:\u0022Tohle je test.\u0022,\u0022to\u0022:\u0022cs\u0022},{\u0022text\u0022:\u0022Esto es una prueba.\u0022,\u0022to\u0022:\u0022es\u0022},{\u0022text\u0022:\u0022Dies ist ein Test.\u0022,\u0022to\u0022:\u0022de\u0022}]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_no_translate_tag.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_no_translate_tag.json new file mode 100644 index 000000000000..ebd7fd4246c4 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_no_translate_tag.json @@ -0,0 +1,35 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/translate?to=en\u0026from=zh-chs\u0026textType=html\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "123", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022\u003Cspan class=notranslate\u003E\\u4eca\\u5929\\u662f\\u600e\\u4e48\\u56de\\u4e8b\\u662f\u003C/span\u003E\\u975e\\u5e38\\u53ef\\u6015\\u7684\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Length": "107", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:53 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "44", + "X-MT-System": "Microsoft", + "X-RequestId": "TRAN.MW1P.99BE.0403T2149.2FCA62D" + }, + "ResponseBody": "[{\u0022translations\u0022:[{\u0022text\u0022:\u0022\u003Cspan class=notranslate\u003E\u4ECA\u5929\u662F\u600E\u4E48\u56DE\u4E8B\u662F\u003C/span\u003Every scary\u0022,\u0022to\u0022:\u0022en\u0022}]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_profanity.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_profanity.json new file mode 100644 index 000000000000..6ac63f7b83c5 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_profanity.json @@ -0,0 +1,35 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/translate?to=zh-cn\u0026profanityAction=Marked\u0026profanityMarker=Asterisk\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "40", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022shit this is fucking crazy\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Length": "123", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:54 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "26", + "X-MT-System": "Microsoft", + "X-RequestId": "TRAN.MW1P.99BE.0403T2149.2FCA6B2" + }, + "ResponseBody": "[{\u0022detectedLanguage\u0022:{\u0022language\u0022:\u0022en\u0022,\u0022score\u0022:1.0},\u0022translations\u0022:[{\u0022text\u0022:\u0022\u5988\u7684\uFF0C\u8FD9***\u592A\u75AF\u72C2\u4E86\u0022,\u0022to\u0022:\u0022zh-Hans\u0022}]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_sentence_length.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_sentence_length.json new file mode 100644 index 000000000000..bc31e8643107 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_sentence_length.json @@ -0,0 +1,35 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/translate?to=fr\u0026includeSentenceLength=true\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "311", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022La r\\u00e9ponse se trouve dans la traduction automatique. La meilleure technologie de traduction automatique ne peut pas toujours fournir des traductions adapt\\u00e9es \\u00e0 un site ou des utilisateurs comme un \\u00eatre humain. Il suffit de copier et coller un extrait de code n\u0027importe o\\u00f9.\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Length": "432", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:54 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "272", + "X-MT-System": "Microsoft", + "X-RequestId": "TRAN.MW1P.99BE.0403T2149.2FCA6E3" + }, + "ResponseBody": "[{\u0022detectedLanguage\u0022:{\u0022language\u0022:\u0022fr\u0022,\u0022score\u0022:1.0},\u0022translations\u0022:[{\u0022text\u0022:\u0022La r\u00E9ponse se trouve dans la traduction automatique. La meilleure technologie de traduction automatique ne peut pas toujours fournir des traductions adapt\u00E9es \u00E0 un site ou des utilisateurs comme un \u00EAtre humain. Il suffit de copier et coller un extrait de code n\u0027importe o\u00F9.\u0022,\u0022to\u0022:\u0022fr\u0022,\u0022sentLen\u0022:{\u0022srcSentLen\u0022:[53,157,62],\u0022transSentLen\u0022:[53,157,62]}}]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_token.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_token.json new file mode 100644 index 000000000000..8abacfe180c0 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_token.json @@ -0,0 +1,34 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/translate?to=cs\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "29", + "Content-Type": "application/json", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022This is a test.\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Length": "105", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:54 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "15", + "X-MT-System": "Microsoft", + "X-RequestId": "TRAN.MW1P.99BE.0403T2149.2FCA790" + }, + "ResponseBody": "[{\u0022detectedLanguage\u0022:{\u0022language\u0022:\u0022en\u0022,\u0022score\u0022:1.0},\u0022translations\u0022:[{\u0022text\u0022:\u0022Tohle je test.\u0022,\u0022to\u0022:\u0022cs\u0022}]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_translate.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_translate.json new file mode 100644 index 000000000000..57a86c6e991e --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_translate.json @@ -0,0 +1,35 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/translate?to=cs\u0026from=es\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "24", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022Hola mundo\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Length": "53", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:53 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "10", + "X-MT-System": "Microsoft", + "X-RequestId": "TRAN.MW1P.99BE.0403T2149.2FCA60E" + }, + "ResponseBody": "[{\u0022translations\u0022:[{\u0022text\u0022:\u0022Ahoj sv\u011Bte\u0022,\u0022to\u0022:\u0022cs\u0022}]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_transliteration.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_transliteration.json new file mode 100644 index 000000000000..8bc486ea4a63 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_translation.pyTestTranslationtest_transliteration.json @@ -0,0 +1,35 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/translate?to=zh-Hans\u0026from=ar\u0026fromScript=Latn\u0026toScript=Latn\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "29", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022hudha akhtabar.\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Length": "179", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:53 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "15", + "X-MT-System": "Microsoft", + "X-RequestId": "TRAN.MW1P.99BE.0403T2149.2FCA64C" + }, + "ResponseBody": "[{\u0022sourceText\u0022:{\u0022text\u0022:\u0022\u0647\u0630\u0627 \u0627\u062E\u062A\u0628\u0627\u0631.\u0022},\u0022translations\u0022:[{\u0022text\u0022:\u0022\u8FD9\u662F\u4E2A\u6D4B\u8BD5\u3002\u0022,\u0022transliteration\u0022:{\u0022text\u0022:\u0022zh\u00E8 sh\u00ECg\u00E8 c\u00E8sh\u00EC\u3002\u0022,\u0022script\u0022:\u0022Latn\u0022},\u0022to\u0022:\u0022zh-Hans\u0022}]}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_transliteration.pyTestTransliterationtest_edit_distance.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_transliteration.pyTestTransliterationtest_edit_distance.json new file mode 100644 index 000000000000..c064cf8f879b --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_transliteration.pyTestTransliterationtest_edit_distance.json @@ -0,0 +1,34 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/transliterate?language=gu\u0026fromScript=Latn\u0026toScript=Gujr\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "63", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022gujarat\u0022}, {\u0022text\u0022: \u0022hadman\u0022}, {\u0022text\u0022: \u0022hukkabar\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Length": "148", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:55 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "21", + "X-RequestId": "TLIT.MW1P.99BE.0403T2149.2FCA7B9" + }, + "ResponseBody": "[{\u0022text\u0022:\u0022\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0022,\u0022script\u0022:\u0022Gujr\u0022},{\u0022text\u0022:\u0022\u0AB9\u0AC7\u0AA1\u0AAE\u0AC7\u0AA8\u0022,\u0022script\u0022:\u0022Gujr\u0022},{\u0022text\u0022:\u0022\u0AB9\u0AC1\u0A95\u0ACD\u0A95\u0ABE\u0AAC\u0ABE\u0AB0\u0022,\u0022script\u0022:\u0022Gujr\u0022}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_transliteration.pyTestTransliterationtest_multiple_inputs.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_transliteration.pyTestTransliterationtest_multiple_inputs.json new file mode 100644 index 000000000000..d20ccf5fb667 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_transliteration.pyTestTransliterationtest_multiple_inputs.json @@ -0,0 +1,34 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/transliterate?language=hi\u0026fromScript=Deva\u0026toScript=Latn\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "226", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022\\u092f\\u0939\\u090f\\u0915\\u0915\\u0938\\u094c\\u091f\\u0940\\u0939\\u0948\\u092f\\u0939\\u090f\\u0915\\u0915\\u0938\\u094c\\u091f\\u0940\\u0939\\u0948\u0022}, {\u0022text\u0022: \u0022\\u092f\\u0939\\u090f\\u0915\\u0915\\u0938\\u094c\\u091f\\u0940\\u0939\\u0948\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Length": "96", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:55 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "33", + "X-RequestId": "TLIT.MW1P.99BE.0403T2149.2FCA7AA" + }, + "ResponseBody": "[{\u0022text\u0022:\u0022yhekakasautihekasautihai\u0022,\u0022script\u0022:\u0022Latn\u0022},{\u0022text\u0022:\u0022yhekakasoutihai\u0022,\u0022script\u0022:\u0022Latn\u0022}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/recordings/test_transliteration.pyTestTransliterationtest_transliteration.json b/sdk/translation/azure-ai-translation-text/tests/recordings/test_transliteration.pyTestTransliterationtest_transliteration.json new file mode 100644 index 000000000000..cba186fc992a --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/recordings/test_transliteration.pyTestTransliterationtest_transliteration.json @@ -0,0 +1,34 @@ +{ + "Entries": [ + { + "RequestUri": "https://fakeEndpoint.cognitive.microsofttranslator.com/transliterate?language=zh-Hans\u0026fromScript=Hans\u0026toScript=Latn\u0026api-version=3.0", + "RequestMethod": "POST", + "RequestHeaders": { + "Accept": "application/json", + "Accept-Encoding": "gzip, deflate", + "Connection": "keep-alive", + "Content-Length": "57", + "Content-Type": "application/json", + "Ocp-Apim-Subscription-Region": "fakeregion", + "User-Agent": "azsdk-python-ai-translation-text/1.0.0b1 Python/3.10.10 (Windows-10-10.0.19042-SP0)" + }, + "RequestBody": "[{\u0022text\u0022: \u0022\\u8fd9\\u91cc\\u600e\\u4e48\\u4e00\\u56de\\u4e8b?\u0022}]", + "StatusCode": 200, + "ResponseHeaders": { + "Access-Control-Expose-Headers": [ + "X-RequestId", + "X-Metered-Usage" + ], + "Content-Length": "56", + "Content-Type": "application/json; charset=utf-8", + "Date": "Mon, 03 Apr 2023 21:49:54 GMT", + "Strict-Transport-Security": "max-age=31536000; includeSubDomains", + "X-Content-Type-Options": "nosniff", + "X-Metered-Usage": "8", + "X-RequestId": "TLIT.MW1P.99BE.0403T2149.2FCA79C" + }, + "ResponseBody": "[{\u0022text\u0022:\u0022zh\u00E8l\u01D0 z\u011Bnme y\u00EChu\u00EDsh\u00EC?\u0022,\u0022script\u0022:\u0022Latn\u0022}]" + } + ], + "Variables": {} +} diff --git a/sdk/translation/azure-ai-translation-text/tests/static_access_token_credential.py b/sdk/translation/azure-ai-translation-text/tests/static_access_token_credential.py new file mode 100644 index 000000000000..d3c9d8612b86 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/static_access_token_credential.py @@ -0,0 +1,21 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +import datetime +import requests +from azure.core.credentials import AccessToken + +class StaticAccessTokenCredential(object): + request_url: str + + def __init__(self, apikey, region): + self.request_url = "https://{0}.api.cognitive.microsoft.com/sts/v1.0/issueToken?Subscription-Key={1}".format( + region, apikey) + + def get_token(self, *scopes, **kwargs): + response = requests.post(self.request_url) + access_token = response.content.decode('UTF-8') + expires_on = datetime.datetime.now() + datetime.timedelta(days=1) + return AccessToken(access_token, expires_on) diff --git a/sdk/translation/azure-ai-translation-text/tests/test_break_sentence.py b/sdk/translation/azure-ai-translation-text/tests/test_break_sentence.py new file mode 100644 index 000000000000..e434667fea7f --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/test_break_sentence.py @@ -0,0 +1,77 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +from devtools_testutils import recorded_by_proxy +from azure.ai.translation.text.models import InputTextItem +from preparer import TextTranslationPreparer +from testcase import TextTranslationTest + +class TestBreakSentence(TextTranslationTest): + + @TextTranslationPreparer() + @recorded_by_proxy + def test_autodetect(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + input_text_elements = [InputTextItem(text="Hello world")] + + response = client.find_sentence_boundaries(content=input_text_elements) + assert response is not None + assert response[0].detected_language.language == "en" + assert response[0].detected_language.score == 1 + assert response[0].sent_len[0] == 11 + + @TextTranslationPreparer() + @recorded_by_proxy + def test_with_language(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + input_text_elements = [InputTextItem( + text="รวบรวมแผ่นคำตอบ ระยะเวลาของโครงการ วิธีเลือกชายในฝัน หมายเลขซีเรียลของระเบียน วันที่สิ้นสุดของโครงการเมื่อเสร็จสมบูรณ์ ปีที่มีการรวบรวม ทุกคนมีวัฒนธรรมและวิธีคิดเหมือนกัน ได้รับโทษจำคุกตลอดชีวิตใน ฉันลดได้ถึง 55 ปอนด์ได้อย่างไร ฉันคิดว่าใครๆ ก็ต้องการกำหนดเมนูอาหารส่วนบุคคล")] + + response = client.find_sentence_boundaries( + content = input_text_elements, language="th") + assert response is not None + expected_lengths = [78, 41, 110, 46] + for i, expected_length in enumerate(expected_lengths): + assert expected_length == response[0].sent_len[i] + + @TextTranslationPreparer() + @recorded_by_proxy + def test_with_language_script(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + input_text_elements = [InputTextItem(text="zhè shì gè cè shì。")] + + response = client.find_sentence_boundaries( + content=input_text_elements, language="zh-Hans", script="Latn") + assert response is not None + assert response[0].sent_len[0] == 18 + + @TextTranslationPreparer() + @recorded_by_proxy + def test_with_multiple_languages(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + input_text_elements = [InputTextItem(text="hello world"), InputTextItem( + text="العالم هو مكان مثير جدا للاهتمام")] + + response = client.find_sentence_boundaries(content=input_text_elements) + assert response is not None + assert response[0].detected_language.language == "en" + assert response[1].detected_language.language == "ar" + assert response[0].sent_len[0] == 11 + assert response[1].sent_len[0] == 32 diff --git a/sdk/translation/azure-ai-translation-text/tests/test_dictionary_examples.py b/sdk/translation/azure-ai-translation-text/tests/test_dictionary_examples.py new file mode 100644 index 000000000000..9b232f07b67b --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/test_dictionary_examples.py @@ -0,0 +1,58 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +from devtools_testutils import recorded_by_proxy +from azure.ai.translation.text.models import DictionaryExampleTextItem +from preparer import TextTranslationPreparer +from testcase import TextTranslationTest + + +class TestDictionaryExamples(TextTranslationTest): + + @TextTranslationPreparer() + @recorded_by_proxy + def test_single_input_element(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + source_language = "en" + target_language = "es" + input_text_elements = [DictionaryExampleTextItem( + text="fly", translation="volar")] + + response = client.lookup_dictionary_examples( + content=input_text_elements, + from_parameter=source_language, + to=target_language) + assert response is not None + assert response[0].normalized_source == "fly" + assert response[0].normalized_target == "volar" + + @TextTranslationPreparer() + @recorded_by_proxy + def test_multiple_input_elements(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + source_language = "en" + target_language = "es" + input_text_elements = [DictionaryExampleTextItem( + text="fly", translation="volar"), + DictionaryExampleTextItem(text="beef", translation="came")] + + response = client.lookup_dictionary_examples( + content=input_text_elements, + from_parameter=source_language, + to=target_language) + assert response is not None + assert len(response) == 2 + assert response[0].normalized_source == "fly" + assert response[0].normalized_target == "volar" + assert response[1].normalized_source == "beef" + assert response[1].normalized_target == "came" diff --git a/sdk/translation/azure-ai-translation-text/tests/test_dictionary_lookup.py b/sdk/translation/azure-ai-translation-text/tests/test_dictionary_lookup.py new file mode 100644 index 000000000000..86aed86e4782 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/test_dictionary_lookup.py @@ -0,0 +1,51 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +from devtools_testutils import recorded_by_proxy +from azure.ai.translation.text.models import InputTextItem +from preparer import TextTranslationPreparer +from testcase import TextTranslationTest + +class TestDictionaryLookup(TextTranslationTest): + + @TextTranslationPreparer() + @recorded_by_proxy + def test_single_input_element(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + source_language = "en" + target_language = "es" + input_text_elements = [InputTextItem(text="fly")] + + response = client.lookup_dictionary_entries( + content=input_text_elements, from_parameter=source_language, to=target_language) + assert response is not None + assert response[0].normalized_source == "fly" + assert response[0].display_source == "fly" + + @TextTranslationPreparer() + @recorded_by_proxy + def test_multiple_input_elements(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + source_language = "en" + target_language = "es" + input_text_elements = [InputTextItem( + text="fly"), InputTextItem(text="fox")] + + response = client.lookup_dictionary_entries( + content=input_text_elements, from_parameter=source_language, to=target_language) + assert response is not None + assert len(response) == 2 + assert response[0].normalized_source == "fly" + assert response[0].display_source == "fly" + assert response[1].normalized_source == "fox" + assert response[1].display_source == "fox" \ No newline at end of file diff --git a/sdk/translation/azure-ai-translation-text/tests/test_get_languages.py b/sdk/translation/azure-ai-translation-text/tests/test_get_languages.py new file mode 100644 index 000000000000..37fa83e03308 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/test_get_languages.py @@ -0,0 +1,129 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +from devtools_testutils import recorded_by_proxy +from preparer import TextTranslationPreparer +from testcase import TextTranslationTest + + +class TestGetLanguages(TextTranslationTest): + + @TextTranslationPreparer() + @recorded_by_proxy + def test_all_scopes(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + client = self.create_getlanguage_client(endpoint) + response = client.get_languages() + + assert len(response.translation) > 0 + assert len(response.transliteration) > 0 + assert len(response.dictionary) > 0 + + @TextTranslationPreparer() + @recorded_by_proxy + def test_translation_scope(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + client = self.create_getlanguage_client(endpoint) + response = client.get_languages(scope="translation") + + assert len(response.translation) > 0 + translations = response.translation["af"] + assert translations.dir is not None + assert translations.name is not None + assert translations.native_name is not None + + @TextTranslationPreparer() + @recorded_by_proxy + def test_transliteration_scope(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + client = self.create_getlanguage_client(endpoint) + response = client.get_languages(scope="transliteration") + + assert len(response.transliteration) > 0 + transliterations = response.transliteration["be"] + assert transliterations.name is not None + assert transliterations.native_name is not None + assert transliterations.scripts is not None + + assert len(transliterations.scripts) > 0 + assert transliterations.scripts[0].name is not None + assert transliterations.scripts[0].native_name is not None + assert transliterations.scripts[0].code is not None + assert transliterations.scripts[0].dir is not None + assert transliterations.scripts[0].to_scripts is not None + + assert len(transliterations.scripts[0].to_scripts) > 0 + assert transliterations.scripts[0].to_scripts[0].name is not None + assert transliterations.scripts[0].to_scripts[0].native_name is not None + assert transliterations.scripts[0].to_scripts[0].code is not None + assert transliterations.scripts[0].to_scripts[0].dir is not None + + @TextTranslationPreparer() + @recorded_by_proxy + def test_transliteration_multiple_scripts(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + client = self.create_getlanguage_client(endpoint) + response = client.get_languages(scope="transliteration") + + assert len(response.transliteration) > 0 + transliterations = response.transliteration["zh-Hant"] + assert transliterations.name is not None + assert transliterations.native_name is not None + assert transliterations.scripts is not None + + assert len(transliterations.scripts) > 1 + assert len(transliterations.scripts[0].to_scripts) > 1 + assert len(transliterations.scripts[1].to_scripts) > 1 + + @TextTranslationPreparer() + @recorded_by_proxy + def test_dictionary_scope(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + client = self.create_getlanguage_client(endpoint) + response = client.get_languages(scope="dictionary") + + assert len(response.dictionary) > 0 + dictionaries = response.dictionary["de"] + assert dictionaries.name is not None + assert dictionaries.native_name is not None + + assert len(dictionaries.translations) > 0 + assert dictionaries.translations[0].code is not None + assert dictionaries.translations[0].dir is not None + assert dictionaries.translations[0].name is not None + assert dictionaries.translations[0].native_name is not None + + @TextTranslationPreparer() + @recorded_by_proxy + def test_dictionary_multiple_translations(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + client = self.create_getlanguage_client(endpoint) + response = client.get_languages(scope="dictionary") + + assert len(response.dictionary) > 0 + dictionaries = response.dictionary["en"] + assert dictionaries.name is not None + assert dictionaries.native_name is not None + + assert len(dictionaries.translations) > 1 + assert dictionaries.translations[0].code is not None + assert dictionaries.translations[0].dir is not None + assert dictionaries.translations[0].name is not None + assert dictionaries.translations[0].native_name is not None + + @TextTranslationPreparer() + @recorded_by_proxy + def test_with_culture(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + client = self.create_getlanguage_client(endpoint) + response = client.get_languages(accept_language="es") + + assert len(response.translation.items()) > 0 + assert len(response.transliteration.items()) > 0 + assert len(response.dictionary.items()) > 0 + translations = response.translation["en"] + assert translations.dir is not None + assert translations.name is not None + assert translations.native_name is not None diff --git a/sdk/translation/azure-ai-translation-text/tests/test_helper.py b/sdk/translation/azure-ai-translation-text/tests/test_helper.py new file mode 100644 index 000000000000..b70bf9f41e95 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/test_helper.py @@ -0,0 +1,25 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +class TestHelper(): + def distance(self, s1, s2, n1, n2): + if n1 == 0: + return n2 + + if n2 == 0: + return n1 + + if s1[n1 - 1] == s2[n2 - 1]: + return self.distance(s1, s2, n1 - 1, n2 - 1) + + nums = [self.distance(s1, s2, n1, n2 - 1), + self.distance(s1, s2, n1 - 1, n2), + self.distance(s1, s2, n1 - 1, n2 - 1)] + return 1 + min(nums) + + def edit_distance(self, s1, s2): + n1 = len(s1) + n2 = len(s2) + return self.distance(s1, s2, n1, n2) diff --git a/sdk/translation/azure-ai-translation-text/tests/test_translation.py b/sdk/translation/azure-ai-translation-text/tests/test_translation.py new file mode 100644 index 000000000000..10acbbfc4f2b --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/test_translation.py @@ -0,0 +1,308 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +import pytest +from devtools_testutils import recorded_by_proxy +from azure.ai.translation.text.models import InputTextItem, TextType, ProfanityAction, ProfanityMarker +from preparer import TextTranslationPreparer +from testcase import TextTranslationTest + + +class TestTranslation(TextTranslationTest): + + @TextTranslationPreparer() + @recorded_by_proxy + def test_translate(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + source_language = "es" + target_languages = ["cs"] + input_text_elements = [InputTextItem(text="Hola mundo")] + response = client.translate( + content=input_text_elements, to=target_languages, from_parameter=source_language) + + assert len(response) == 1 + assert len(response[0].translations) == 1 + assert response[0].translations[0].to == "cs" + assert response[0].translations[0].text is not None + + @TextTranslationPreparer() + @recorded_by_proxy + def test_autodetect(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + target_languages = ["cs"] + input_text_elements = [InputTextItem(text="This is a test.")] + response = client.translate( + content=input_text_elements, to=target_languages) + + assert len(response) == 1 + assert len(response[0].translations) == 1 + assert response[0].detected_language.language == "en" + assert response[0].detected_language.score == 1 + assert response[0].translations[0].to == "cs" + assert response[0].translations[0].text is not None + + @TextTranslationPreparer() + @recorded_by_proxy + def test_no_translate_tag(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + source_language = "zh-chs" + target_languages = ["en"] + input_text_elements = [InputTextItem( + text="今天是怎么回事是非常可怕的")] + response = client.translate(content=input_text_elements, + to=target_languages, + from_parameter=source_language, + text_type=TextType.HTML) + + assert len(response) == 1 + assert len(response[0].translations) == 1 + assert "今天是怎么回事是" in response[0].translations[0].text + + @TextTranslationPreparer() + @recorded_by_proxy + def test_dictionary_tag(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + source_language = "en" + target_languages = ["es"] + input_text_elements = [InputTextItem( + text="The word < mstrans:dictionary translation =\"wordomatic\">wordomatic is a dictionary entry.")] + response = client.translate( + content=input_text_elements, + to=target_languages, + from_parameter=source_language) + + assert len(response) == 1 + assert len(response[0].translations) == 1 + assert response[0].translations[0].to == "es" + assert "wordomatic" in response[0].translations[0].text + + @TextTranslationPreparer() + @recorded_by_proxy + def test_transliteration(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + source_language = "ar" + target_languages = ["zh-Hans"] + input_text_elements = [InputTextItem(text="hudha akhtabar.")] + response = client.translate(content=input_text_elements, + to=target_languages, + from_parameter=source_language, + from_script="Latn", + to_script="Latn") + + assert len(response) == 1 + assert response[0].source_text is not None + assert len(response[0].translations) == 1 + assert response[0].translations[0].to == "zh-Hans" + assert response[0].translations[0].text is not None + + @TextTranslationPreparer() + @recorded_by_proxy + def test_from_to_latin(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + source_language = "hi" + target_languages = ["ta"] + input_text_elements = [InputTextItem(text="ap kaise ho")] + response = client.translate(content=input_text_elements, + to=target_languages, + from_parameter=source_language, + from_script="Latn", + to_script="Latn") + + assert len(response) == 1 + assert len(response[0].translations) == 1 + assert response[0].translations[0].text is not None + assert "eppadi irukkiraai?" in response[0].translations[0].transliteration.text + + @TextTranslationPreparer() + @recorded_by_proxy + def test_multiple_input(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + target_languages = ["cs"] + input_text_elements = [InputTextItem(text="This is a test."), InputTextItem( + text="Esto es una prueba."), InputTextItem(text="Dies ist ein Test.")] + response = client.translate( + content=input_text_elements, to=target_languages) + + assert len(response) == 3 + assert response[0].detected_language.language == "en" + assert response[1].detected_language.language == "es" + assert response[2].detected_language.language == "de" + assert response[0].detected_language.score == 1 + assert response[1].detected_language.score == 1 + assert response[2].detected_language.score == 1 + + assert response[0].translations[0].text is not None + assert response[1].translations[0].text is not None + assert response[2].translations[0].text is not None + + @TextTranslationPreparer() + @recorded_by_proxy + def test_multiple_target_languages(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + target_languages = ["cs", "es", "de"] + input_text_elements = [InputTextItem(text="This is a test.")] + response = client.translate( + content=input_text_elements, to=target_languages) + + assert len(response) == 1 + assert len(response[0].translations) == 3 + assert response[0].detected_language.language == "en" + assert response[0].detected_language.score == 1 + assert response[0].translations[0].text is not None + assert response[0].translations[1].text is not None + assert response[0].translations[2].text is not None + + @TextTranslationPreparer() + @recorded_by_proxy + def test_different_texttypes(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + target_languages = ["cs"] + input_text_elements = [InputTextItem( + text="This is a test.")] + response = client.translate( + content=input_text_elements, to=target_languages, text_type=TextType.HTML) + + assert len(response) == 1 + assert len(response[0].translations) == 1 + assert response[0].detected_language.language == "en" + assert response[0].detected_language.score == 1 + + @TextTranslationPreparer() + @recorded_by_proxy + def test_profanity(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + target_languages = ["zh-cn"] + input_text_elements = [InputTextItem( + text="shit this is fucking crazy")] + response = client.translate(content=input_text_elements, + to=target_languages, + profanity_action=ProfanityAction.MARKED, + profanity_marker=ProfanityMarker.ASTERISK) + + assert len(response) == 1 + assert len(response[0].translations) == 1 + assert response[0].detected_language.language == "en" + assert response[0].detected_language.score == 1 + assert "***" in response[0].translations[0].text + + @TextTranslationPreparer() + @recorded_by_proxy + def test_alignment(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + target_languages = ["cs"] + input_text_elements = [InputTextItem(text="It is a beautiful morning")] + response = client.translate( + content=input_text_elements, to=target_languages, include_alignment=True) + + assert len(response) == 1 + assert len(response[0].translations) == 1 + assert response[0].detected_language.language == "en" + assert response[0].detected_language.score == 1 + assert response[0].translations[0].alignment.proj is not None + + @TextTranslationPreparer() + @recorded_by_proxy + def test_sentence_length(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + target_languages = ["fr"] + input_text_elements = [InputTextItem( + text="La réponse se trouve dans la traduction automatique. La meilleure technologie de traduction automatique ne peut pas toujours fournir des traductions adaptées à un site ou des utilisateurs comme un être humain. Il suffit de copier et coller un extrait de code n'importe où.")] + response = client.translate( + content=input_text_elements, + to=target_languages, + include_sentence_length=True) + + assert len(response) == 1 + assert len(response[0].translations) == 1 + assert response[0].detected_language.language == "fr" + assert response[0].detected_language.score == 1 + assert len(response[0].translations[0].sent_len.src_sent_len) == 3 + assert len(response[0].translations[0].sent_len.trans_sent_len) == 3 + + @TextTranslationPreparer() + @recorded_by_proxy + def test_custom_endpoint(self, **kwargs): + endpoint = kwargs.get("text_translation_custom_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + target_languages = ["fr"] + input_text_elements = [InputTextItem(text="It is a beautiful morning")] + response = client.translate( + content=input_text_elements, + to=target_languages) + + assert len(response) == 1 + assert len(response[0].translations) == 1 + assert response[0].detected_language.language == "en" + assert response[0].detected_language.score == 1 + + @pytest.mark.live_test_only + @TextTranslationPreparer() + @recorded_by_proxy + def test_token(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client_token(endpoint, apikey, region) + + target_languages = ["cs"] + input_text_elements = [InputTextItem(text="This is a test.")] + response = client.translate( + content=input_text_elements, to=target_languages) + + assert len(response) == 1 + assert len(response[0].translations) == 1 + assert response[0].detected_language.language == "en" + assert response[0].detected_language.score == 1 diff --git a/sdk/translation/azure-ai-translation-text/tests/test_transliteration.py b/sdk/translation/azure-ai-translation-text/tests/test_transliteration.py new file mode 100644 index 000000000000..af2756041abb --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/test_transliteration.py @@ -0,0 +1,70 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +from devtools_testutils import recorded_by_proxy +from azure.ai.translation.text.models import InputTextItem +from preparer import TextTranslationPreparer +from test_helper import TestHelper +from testcase import TextTranslationTest + + +class TestTransliteration(TextTranslationTest, TestHelper): + + @TextTranslationPreparer() + @recorded_by_proxy + def test_transliteration(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + input_text_elements = [InputTextItem(text="这里怎么一回事?")] + response = client.transliterate( + content=input_text_elements, language="zh-Hans", from_script="Hans", to_script="Latn") + + assert response is not None + assert response[0].text is not None + + @TextTranslationPreparer() + @recorded_by_proxy + def test_multiple_inputs(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + input_text_elements = [InputTextItem( + text="यहएककसौटीहैयहएककसौटीहै"), InputTextItem(text="यहएककसौटीहै")] + response = client.transliterate( + content=input_text_elements, language="hi", from_script="Deva", to_script="Latn") + + assert response is not None + assert response[0].text is not None + assert response[1].text is not None + + @TextTranslationPreparer() + @recorded_by_proxy + def test_edit_distance(self, **kwargs): + endpoint = kwargs.get("text_translation_endpoint") + apikey = kwargs.get("text_translation_apikey") + region = kwargs.get("text_translation_region") + client = self.create_client(endpoint, apikey, region) + + input_text_elements = [InputTextItem(text="gujarat"), InputTextItem( + text="hadman"), InputTextItem(text="hukkabar")] + response = client.transliterate( + content=input_text_elements, language="gu", from_script="Latn", to_script="Gujr") + + assert response is not None + assert response[0].text is not None + assert response[1].text is not None + assert response[2].text is not None + + expected_texts = ["ગુજરાત", "હદમાં", "હુક્કાબાર"] + edit_distance_value = 0 + for i, expected_text in enumerate(expected_texts): + edit_distance_value = edit_distance_value + \ + self.edit_distance(expected_text, response[i].text) + assert edit_distance_value < 6 diff --git a/sdk/translation/azure-ai-translation-text/tests/testcase.py b/sdk/translation/azure-ai-translation-text/tests/testcase.py new file mode 100644 index 000000000000..a7a448e74855 --- /dev/null +++ b/sdk/translation/azure-ai-translation-text/tests/testcase.py @@ -0,0 +1,27 @@ +# ------------------------------------ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +# ------------------------------------ + +from devtools_testutils import AzureRecordedTestCase +from azure.ai.translation.text import TextTranslationClient, TranslatorCredential + +from static_access_token_credential import StaticAccessTokenCredential + + +class TextTranslationTest(AzureRecordedTestCase): + def create_getlanguage_client(self, endpoint): + client = TextTranslationClient(endpoint=endpoint, credential=None) + return client + + def create_client(self, endpoint, apikey, region): + credential = TranslatorCredential(apikey, region) + client = TextTranslationClient( + endpoint=endpoint, credential=credential) + return client + + def create_client_token(self, endpoint, apikey, region): + credential = StaticAccessTokenCredential(apikey, region) + client = TextTranslationClient( + endpoint=endpoint, credential=credential) + return client diff --git a/sdk/translation/ci.yml b/sdk/translation/ci.yml index eb2a98917eb3..bb8ef7a875af 100644 --- a/sdk/translation/ci.yml +++ b/sdk/translation/ci.yml @@ -33,3 +33,5 @@ extends: Artifacts: - name: azure-ai-translation-document safeName: azureaitranslationdocument + - name: azure-ai-translation-text + safeName: azureaitranslationtext diff --git a/sdk/translation/test-resources.json b/sdk/translation/test-resources.json index 880fe345f7ea..4b7dc23f96e3 100644 --- a/sdk/translation/test-resources.json +++ b/sdk/translation/test-resources.json @@ -136,6 +136,10 @@ } }, "variables": { + "txtUniqueSubDomainName": "[format('{0}', parameters('baseName'))]", + "txtEndpointValue": "[format('https://api.cognitive.microsofttranslator.com')]", + "txtCustomEndpointValue": "[format('https://{0}.cognitiveservices.azure.com', parameters('baseName'))]", + "txtRegionValue": "[format('{0}', parameters('location'))]", "authorizationApiVersion": "2018-09-01-preview", "docTranslationBaseName": "[parameters('baseName')]", "docTranslationApiVersion": "2017-04-18", @@ -161,6 +165,19 @@ } }, "resources": [ + { + "type": "Microsoft.CognitiveServices/accounts", + "apiVersion": "2017-04-18", + "name": "[variables('txtUniqueSubDomainName')]", + "location": "[parameters('location')]", + "sku": { + "name": "S1" + }, + "kind": "TextTranslation", + "properties": { + "customSubDomainName": "[variables('txtUniqueSubDomainName')]" + } + }, { "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "[variables('authorizationApiVersion')]", @@ -346,6 +363,22 @@ "condition": "[not(parameters('useStaticStorageResource'))]", "type": "string", "value": "[concat(reference(parameters('storageAccResourceId'), '2019-06-01').primaryEndpoints.blob, parameters('targetContainerName_4'), '?', listServiceSas(parameters('storageAccResourceId'), '2019-06-01', parameters('targetContainerSasProperties_4')).serviceSasToken)]" + }, + "TEXT_TRANSLATION_APIKEY": { + "type": "string", + "value": "[listKeys(resourceId('Microsoft.CognitiveServices/accounts', variables('txtUniqueSubDomainName')), '2017-04-18').key1]" + }, + "TEXT_TRANSLATION_ENDPOINT": { + "type": "string", + "value": "[variables('txtEndpointValue')]" + }, + "TEXT_TRANSLATION_CUSTOM_ENDPOINT": { + "type": "string", + "value": "[variables('txtCustomEndpointValue')]" + }, + "TEXT_TRANSLATION_REGION": { + "type": "string", + "value": "[variables('txtRegionValue')]" } } } \ No newline at end of file