diff --git a/sdk/textanalytics/azure-ai-textanalytics/CHANGELOG.md b/sdk/textanalytics/azure-ai-textanalytics/CHANGELOG.md index 0a988192e7a0..c4eadbce4345 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/CHANGELOG.md +++ b/sdk/textanalytics/azure-ai-textanalytics/CHANGELOG.md @@ -12,8 +12,15 @@ of action results, in the same order they've been inputted. The actual document each action result. **New Features** -- No longer need to specify `api_version=TextAnalyticsApiVersion.V3_1_PREVIEW_3` when calling `begin_analyze` and `begin_analyze_healthcare`. `begin_analyze_healthcare` is still in gated preview though. -- Added a new parameter `string_index_type` to the service client methods `begin_analyze_healthcare`, `analyze_sentiment`, `recognize_entities`, `recognize_pii_entities`, and `recognize_linked_entities`. +- Renamed `begin_analyze_healthcare` to `begin_analyze_healthcare_entities`. +- Renamed `AnalyzeHealthcareResult` to `AnalyzeHealthcareEntitiesResult` and `AnalyzeHealthcareResultItem` to `AnalyzeHealthcareEntitiesResultItem`. +- Renamed `HealthcareEntityLink` to `HealthcareEntityDataSource` and renamed its properties `id` to `entity_id` and `data_source` to `name`. +- Removed `relations` from `AnalyzeHealthcareEntitiesResultItem` and added `related_entities` to `HealthcareEntity`. +- Moved the cancellation logic for the Analyze Healthcare Entities service from +the service client to the poller object returned from `begin_analyze_healthcare_entities`. +- Exposed Analyze Healthcare Entities operation metadata on the poller object returned from `begin_analyze_healthcare_entities`. +- No longer need to specify `api_version=TextAnalyticsApiVersion.V3_1_PREVIEW_3` when calling `begin_analyze` and `begin_analyze_healthcare_entities`. `begin_analyze_healthcare_entities` is still in gated preview though. +- Added a new parameter `string_index_type` to the service client methods `begin_analyze_healthcare_entities`, `analyze_sentiment`, `recognize_entities`, `recognize_pii_entities`, and `recognize_linked_entities` which tells the service how to interpret string offsets. - Added property `length` to `CategorizedEntity`, `SentenceSentiment`, `LinkedEntityMatch`, `AspectSentiment`, `OpinionSentiment`, `PiiEntity` and `HealthcareEntity`. diff --git a/sdk/textanalytics/azure-ai-textanalytics/README.md b/sdk/textanalytics/azure-ai-textanalytics/README.md index 01352ec67c45..4811e267f198 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/README.md +++ b/sdk/textanalytics/azure-ai-textanalytics/README.md @@ -9,7 +9,7 @@ Text Analytics is a cloud-based service that provides advanced natural language - Language Detection - Key Phrase Extraction - Batch Analysis -- Healthcare Analysis (Gated Preview) +- Healthcare Entities Analysis (Gated Preview) [Source code][source_code] | [Package (PyPI)][ta_pypi] | [API reference documentation][ta_ref_docs]| [Product documentation][ta_product_documentation] | [Samples][ta_samples] @@ -224,7 +224,7 @@ The following section provides several code snippets covering some of the most c - [Recognize PII Entities](#recognize-pii-entities "Recognize pii entities") - [Extract Key Phrases](#extract-key-phrases "Extract key phrases") - [Detect Language](#detect-language "Detect language") -- [Healthcare Analysis](#healthcare-analysis "Healthcare analysis") +- [Healthcare Entities Analysis](#healthcare-entities-analysis "Healthcare Entities Analysis") - [Batch Analysis](#batch-analysis "Batch analysis") ### Analyze sentiment @@ -443,9 +443,9 @@ The returned response is a heterogeneous list of result and error objects: list[ Please refer to the service documentation for a conceptual discussion of [language detection][language_detection] and [language and regional support][language_and_regional_support]. -### Healthcare Analysis +### Healthcare Entities Analysis -The example below extracts entities recognized within the healthcare domain, and identifies relationships between entities within the input document and links to known sources of information in various well known databases, such as UMLS, CHV, MSH, etc. This sample demonstrates the usage for [long-running operations](#long-running-operations). +The example below extracts entities recognized within the healthcare domain, and identifies relationships between entities within the input document and links to known sources of information in various well known databases, such as UMLS, CHV, MSH, etc. This sample demonstrates the usage for [long-running operations](#long-running-operations). ```python from azure.core.credentials import AzureKeyCredential @@ -458,12 +458,12 @@ text_analytics_client = TextAnalyticsClient(endpoint, credential) documents = ["Subject is taking 100mg of ibuprofen twice daily"] -poller = text_analytics_client.begin_analyze_healthcare(documents, show_stats=True) +poller = text_analytics_client.begin_analyze_healthcare_entities(documents, show_stats=True) result = poller.result() docs = [doc for doc in result if not doc.is_error] -print("Results of Healthcare Analysis:") +print("Results of Healthcare Entities Analysis:") for idx, doc in enumerate(docs): for entity in doc.entities: print("Entity: {}".format(entity.text)) @@ -471,11 +471,11 @@ for idx, doc in enumerate(docs): print("...Subcategory: {}".format(entity.subcategory)) print("...Offset: {}".format(entity.offset)) print("...Confidence score: {}".format(entity.confidence_score)) - if entity.links is not None: - print("...Links:") - for link in entity.links: - print("......ID: {}".format(link.id)) - print("......Data source: {}".format(link.data_source)) + if entity.data_sources is not None: + print("...Data Sources:") + for data_source in entity.data_sources: + print("......Entity ID: {}".format(data_source.entity_id)) + print("......Name: {}".format(data_source.name)) for relation in doc.relations: print("Relation:") print("...Source: {}".format(relation.source.text)) @@ -485,7 +485,7 @@ for idx, doc in enumerate(docs): print("------------------------------------------") ``` -Note: The Healthcare Analysis service is currently available only in API version v3.1-preview.3 in gated preview. Since this is a gated preview, AAD is not supported. More information [here](https://docs.microsoft.com/azure/cognitive-services/text-analytics/how-tos/text-analytics-for-health?tabs=ner#request-access-to-the-public-preview). +Note: The Healthcare Entities Analysis service is currently available only in API version v3.1-preview.3 in gated preview. Since this is a gated preview, AAD is not supported. More information [here](https://docs.microsoft.com/azure/cognitive-services/text-analytics/how-tos/text-analytics-for-health?tabs=ner#request-access-to-the-public-preview). ### Batch Analysis @@ -633,7 +633,7 @@ Common scenarios - Recognize linked entities: [sample_recognize_linked_entities.py][recognize_linked_entities_sample] ([async version][recognize_linked_entities_sample_async]) - Extract key phrases: [sample_extract_key_phrases.py][extract_key_phrases_sample] ([async version][extract_key_phrases_sample_async]) - Detect language: [sample_detect_language.py][detect_language_sample] ([async version][detect_language_sample_async]) -- Healthcare Analysis: [sample_analyze_healthcare.py][analyze_healthcare_sample] ([async version][analyze_healthcare_sample_async]) +- Healthcare Entities Analysis: [sample_analyze_healthcare_entities.py][analyze_healthcare_entities_sample] ([async version][analyze_healthcare_entities_sample_async]) - Batch Analysis: [sample_analyze_batch_actions.py][analyze_sample] ([async version][analyze_sample_async]) Advanced scenarios @@ -722,8 +722,8 @@ This project has adopted the [Microsoft Open Source Code of Conduct][code_of_con [recognize_linked_entities_sample_async]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_recognize_linked_entities_async.py [recognize_pii_entities_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/textanalytics/azure-ai-textanalytics/samples/sample_recognize_pii_entities.py [recognize_pii_entities_sample_async]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_recognize_pii_entities_async.py -[analyze_healthcare_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/textanalytics/azure-ai-textanalytics/samples/sample_analyze_healthcare.py -[analyze_healthcare_sample_async]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_analyze_healthcare_async.py +[analyze_healthcare_entities_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/textanalytics/azure-ai-textanalytics/samples/sample_analyze_healthcare_entities.py +[analyze_healthcare_entities_sample_async]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_analyze_healthcare_entities_async.py [analyze_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/textanalytics/azure-ai-textanalytics/samples/sample_analyze_batch_actions.py [analyze_sample_async]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_analyze_batch_actions_async.py [opinion_mining_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/textanalytics/azure-ai-textanalytics/samples/sample_analyze_sentiment_with_opinion_mining.py diff --git a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/__init__.py b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/__init__.py index 9b0d0bc5ddfb..8008b27db8b8 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/__init__.py +++ b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/__init__.py @@ -32,10 +32,9 @@ RecognizePiiEntitiesResult, PiiEntity, PiiEntityDomainType, - AnalyzeHealthcareResultItem, + AnalyzeHealthcareEntitiesResultItem, HealthcareEntity, - HealthcareRelation, - HealthcareEntityLink, + HealthcareEntityDataSource, RecognizeEntitiesAction, RecognizePiiEntitiesAction, ExtractKeyPhrasesAction, @@ -44,7 +43,7 @@ AnalyzeBatchActionsType, AnalyzeBatchActionsError, ) -from._paging import AnalyzeHealthcareResult +from ._paging import AnalyzeHealthcareEntitiesResult __all__ = [ 'TextAnalyticsApiVersion', @@ -73,11 +72,10 @@ 'RecognizePiiEntitiesResult', 'PiiEntity', 'PiiEntityDomainType', - 'AnalyzeHealthcareResultItem', - 'AnalyzeHealthcareResult', + 'AnalyzeHealthcareEntitiesResultItem', + 'AnalyzeHealthcareEntitiesResult', 'HealthcareEntity', - 'HealthcareRelation', - 'HealthcareEntityLink', + 'HealthcareEntityDataSource', 'RecognizeEntitiesAction', 'RecognizePiiEntitiesAction', 'ExtractKeyPhrasesAction', diff --git a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_async_lro.py b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_async_lro.py index 2f6fd71f93f8..a5fbcc5957f6 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_async_lro.py +++ b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_async_lro.py @@ -4,9 +4,10 @@ # Licensed under the MIT License. # ------------------------------------ +from azure.core.exceptions import HttpResponseError +from azure.core.polling import AsyncLROPoller from azure.core.polling.base_polling import OperationFailed, BadStatus from azure.core.polling.async_base_polling import AsyncLROBasePolling -from azure.core.polling import AsyncLROPoller from azure.core.polling._async_poller import PollingReturnType @@ -76,6 +77,95 @@ async def _poll(self): # pylint:disable=invalid-overridden-method self._pipeline_response.http_response ) +class AnalyzeHealthcareEntitiesAsyncLROPollingMethod(TextAnalyticsAsyncLROPollingMethod): + + def __init__(self, *args, **kwargs): + self._text_analytics_client = kwargs.pop("text_analytics_client") + super(AnalyzeHealthcareEntitiesAsyncLROPollingMethod, self).__init__(*args, **kwargs) + + @property + def _current_body(self): + from ._generated.v3_1_preview_3.models import JobMetadata + return JobMetadata.deserialize(self._pipeline_response) + + @property + def created_on(self): + if not self._current_body: + return None + return self._current_body.created_date_time + + @property + def expires_on(self): + if not self._current_body: + return None + return self._current_body.expiration_date_time + + @property + def last_modified_on(self): + if not self._current_body: + return None + return self._current_body.last_update_date_time + + @property + def id(self): + if not self._current_body: + return None + return self._current_body.job_id + + +class AnalyzeHealthcareEntitiesAsyncLROPoller(AsyncLROPoller[PollingReturnType]): + + @property + def created_on(self): + return self._polling_method.created_on + + @property + def expires_on(self): + return self._polling_method.expires_on + + @property + def last_modified_on(self): + return self._polling_method.last_modified_on + + @property + def id(self): + return self._polling_method.id + + async def cancel( # type: ignore + self, + **kwargs + ): + """Cancel the operation currently being polled. + + :keyword int polling_interval: The polling interval to use to poll the cancellation status. + The default value is 5 seconds. + :return: Returns an instance of an LROPoller that returns None. + :rtype: ~azure.core.polling.LROPoller[None] + :raises: Warning when the operation has already reached a terminal state. + + .. admonition:: Example: + + .. literalinclude:: ../samples/async_samples/sample_analyze_healthcare_entities_with_cancellation_async.py + :start-after: [START analyze_healthcare_entities_with_cancellation_async] + :end-before: [END analyze_healthcare_entities_with_cancellation_async] + :language: python + :dedent: 8 + :caption: Cancel an existing health operation. + """ + polling_interval = kwargs.pop("polling_interval", 5) + await self._polling_method.update_status() + + try: + return await getattr(self._polling_method, "_text_analytics_client").begin_cancel_health_job( + self.id, + polling=TextAnalyticsAsyncLROPollingMethod(timeout=polling_interval) + ) + + except HttpResponseError as error: + from ._response_handlers import process_http_response_error + process_http_response_error(error) + + class AsyncAnalyzeBatchActionsLROPollingMethod(TextAnalyticsAsyncLROPollingMethod): @property @@ -137,6 +227,7 @@ def id(self): return None return self._current_body.job_id + class AsyncAnalyzeBatchActionsLROPoller(AsyncLROPoller[PollingReturnType]): @property @@ -166,6 +257,7 @@ def actions_succeeded_count(self): @property def last_modified_on(self): return self._polling_method.last_modified_on + @property def total_actions_count(self): return self._polling_method.total_actions_count @@ -173,3 +265,4 @@ def total_actions_count(self): @property def id(self): return self._polling_method.id + \ No newline at end of file diff --git a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_async_paging.py b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_async_paging.py index 1ce1ed2f524a..a6d775ed78df 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_async_paging.py +++ b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_async_paging.py @@ -7,11 +7,11 @@ from azure.core.async_paging import AsyncItemPaged -class AnalyzeHealthcareResultAsync(AsyncItemPaged): +class AnalyzeHealthcareEntitiesResultAsync(AsyncItemPaged): def __init__(self, *args, **kwargs): self.model_version = kwargs.pop('model_version') self.statistics = kwargs.pop('statistics') - super(AnalyzeHealthcareResultAsync, self).__init__(*args, **kwargs) + super(AnalyzeHealthcareEntitiesResultAsync, self).__init__(*args, **kwargs) class AnalyzeResultAsync(AsyncItemPaged): diff --git a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_generated/_operations_mixin.py b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_generated/_operations_mixin.py index dd1be3b9a11e..28efc6437820 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_generated/_operations_mixin.py +++ b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_generated/_operations_mixin.py @@ -13,6 +13,7 @@ import warnings # FIXME: have to manually reconfigure import path for multiapi operation mixin +from .._lro import AnalyzeHealthcareEntitiesLROPoller, AnalyzeHealthcareEntitiesLROPollingMethod from .._lro import AnalyzeBatchActionsLROPoller, AnalyzeBatchActionsLROPollingMethod from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error from azure.core.pipeline import PipelineResponse @@ -162,12 +163,12 @@ def begin_health( :type string_index_type: str or ~azure.ai.textanalytics.v3_1_preview_3.models.StringIndexType :keyword callable cls: A custom type or function that will be passed the direct response :keyword str continuation_token: A continuation token to restart a poller from a saved state. - :keyword polling: Pass in True if you'd like the AnalyzeBatchActionsLROPollingMethod polling method, + :keyword polling: Pass in True if you'd like the AnalyzeHealthcareEntitiesLROPollingMethod polling method, False for no polling, or your own initialized polling object for a personal polling strategy. :paramtype polling: bool or ~azure.core.polling.PollingMethod :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. - :return: An instance of AnalyzeBatchActionsLROPoller that returns either HealthcareJobState or the result of cls(response) - :rtype: ~...._lro.AnalyzeBatchActionsLROPoller[~azure.ai.textanalytics.v3_1_preview_3.models.HealthcareJobState] + :return: An instance of AnalyzeHealthcareEntitiesLROPoller that returns either HealthcareJobState or the result of cls(response) + :rtype: ~...._lro.AnalyzeHealthcareEntitiesLROPoller[~azure.ai.textanalytics.v3_1_preview_3.models.HealthcareJobState] :raises ~azure.core.exceptions.HttpResponseError: """ api_version = self._get_api_version('begin_health') diff --git a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_generated/aio/_operations_mixin.py b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_generated/aio/_operations_mixin.py index 101c1b1cf923..cb2794948437 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_generated/aio/_operations_mixin.py +++ b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_generated/aio/_operations_mixin.py @@ -13,6 +13,7 @@ import warnings # FIXME: have to manually reconfigure import path for multiapi operation mixin +from ..._async_lro import AnalyzeHealthcareEntitiesAsyncLROPoller, AnalyzeHealthcareEntitiesAsyncLROPollingMethod from ..._async_lro import AsyncAnalyzeBatchActionsLROPoller, AsyncAnalyzeBatchActionsLROPollingMethod from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error from azure.core.pipeline import PipelineResponse @@ -141,7 +142,7 @@ async def begin_health( model_version: Optional[str] = None, string_index_type: Optional[Union[str, "_models.StringIndexType"]] = "TextElements_v8", **kwargs - ) -> AsyncAnalyzeBatchActionsLROPoller["_models.HealthcareJobState"]: + ) -> AnalyzeHealthcareEntitiesAsyncLROPoller["_models.HealthcareJobState"]: """Submit healthcare analysis job. Start a healthcare analysis job to recognize healthcare related entities (drugs, conditions, @@ -158,12 +159,12 @@ async def begin_health( :type string_index_type: str or ~azure.ai.textanalytics.v3_1_preview_3.models.StringIndexType :keyword callable cls: A custom type or function that will be passed the direct response :keyword str continuation_token: A continuation token to restart a poller from a saved state. - :keyword polling: Pass in True if you'd like the AsyncAnalyzeBatchActionsLROPollingMethod polling method, + :keyword polling: Pass in True if you'd like the AnalyzeHealthcareEntitiesAsyncLROPollingMethod polling method, False for no polling, or your own initialized polling object for a personal polling strategy. :paramtype polling: bool or ~azure.core.polling.AsyncPollingMethod :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. - :return: An instance of AsyncAnalyzeBatchActionsLROPoller that returns either HealthcareJobState or the result of cls(response) - :rtype: ~...._async_lro.AsyncAnalyzeBatchActionsLROPoller[~azure.ai.textanalytics.v3_1_preview_3.models.HealthcareJobState] + :return: An instance of AnalyzeHealthcareEntitiesAsyncLROPoller that returns either HealthcareJobState or the result of cls(response) + :rtype: ~....._async_lro.AnalyzeHealthcareEntitiesAsyncLROPoller[~azure.ai.textanalytics.v3_1_preview_3.models.HealthcareJobState] :raises ~azure.core.exceptions.HttpResponseError: """ api_version = self._get_api_version('begin_health') diff --git a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_generated/v3_1_preview_3/_metadata.json b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_generated/v3_1_preview_3/_metadata.json deleted file mode 100644 index 1758cf5ae7e5..000000000000 --- a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_generated/v3_1_preview_3/_metadata.json +++ /dev/null @@ -1,264 +0,0 @@ -{ - "chosen_version": "v3.1-preview.3", - "total_api_version_list": ["v3.1-preview.3"], - "client": { - "name": "TextAnalyticsClient", - "filename": "_text_analytics_client", - "description": "The Text Analytics API is a suite of natural language processing (NLP) services built with best-in-class Microsoft machine learning algorithms. The API can be used to analyze unstructured text for tasks such as sentiment analysis, key phrase extraction and language detection. Further documentation can be found in :code:`\u003ca href=\"https://docs.microsoft.com/en-us/azure/cognitive-services/text-analytics/overview\"\u003ehttps://docs.microsoft.com/en-us/azure/cognitive-services/text-analytics/overview\u003c/a\u003e`.", - "base_url": null, - "custom_base_url": "\u0027{Endpoint}/text/analytics/v3.1-preview.3\u0027", - "azure_arm": false, - "has_lro_operations": true, - "client_side_validation": false, - "sync_imports": "{\"typing\": {\"azurecore\": {\"azure.core.credentials\": [\"TokenCredential\"]}}, \"regular\": {\"azurecore\": {\"azure.profiles\": [\"KnownProfiles\", \"ProfileDefinition\"], \"azure.profiles.multiapiclient\": [\"MultiApiClientMixin\"], \"msrest\": [\"Deserializer\", \"Serializer\"], \"azure.core\": [\"PipelineClient\"]}, \"local\": {\"._configuration\": [\"TextAnalyticsClientConfiguration\"], \"._operations_mixin\": [\"TextAnalyticsClientOperationsMixin\"]}}, \"conditional\": {\"stdlib\": {\"typing\": [\"Any\", \"Optional\"]}}}", - "async_imports": "{\"typing\": {\"azurecore\": {\"azure.core.credentials_async\": [\"AsyncTokenCredential\"]}}, \"regular\": {\"azurecore\": {\"azure.profiles\": [\"KnownProfiles\", \"ProfileDefinition\"], \"azure.profiles.multiapiclient\": [\"MultiApiClientMixin\"], \"msrest\": [\"Deserializer\", \"Serializer\"], \"azure.core\": [\"AsyncPipelineClient\"]}, \"local\": {\"._configuration\": [\"TextAnalyticsClientConfiguration\"], \"._operations_mixin\": [\"TextAnalyticsClientOperationsMixin\"]}}, \"conditional\": {\"stdlib\": {\"typing\": [\"Any\", \"Optional\"]}}}" - }, - "global_parameters": { - "sync": { - "credential": { - "signature": "credential, # type: \"TokenCredential\"", - "description": "Credential needed for the client to connect to Azure.", - "docstring_type": "~azure.core.credentials.TokenCredential", - "required": true - }, - "endpoint": { - "signature": "endpoint, # type: str", - "description": "Supported Cognitive Services endpoints (protocol and hostname, for example: https://westus.api.cognitive.microsoft.com).", - "docstring_type": "str", - "required": true - } - }, - "async": { - "credential": { - "signature": "credential: \"AsyncTokenCredential\",", - "description": "Credential needed for the client to connect to Azure.", - "docstring_type": "~azure.core.credentials_async.AsyncTokenCredential", - "required": true - }, - "endpoint": { - "signature": "endpoint: str,", - "description": "Supported Cognitive Services endpoints (protocol and hostname, for example: https://westus.api.cognitive.microsoft.com).", - "docstring_type": "str", - "required": true - } - }, - "constant": { - }, - "call": "credential, endpoint", - "service_client_specific": { - "sync": { - "api_version": { - "signature": "api_version=None, # type: Optional[str]", - "description": "API version to use if no profile is provided, or if missing in profile.", - "docstring_type": "str", - "required": false - }, - "profile": { - "signature": "profile=KnownProfiles.default, # type: KnownProfiles", - "description": "A profile definition, from KnownProfiles to dict.", - "docstring_type": "azure.profiles.KnownProfiles", - "required": false - } - }, - "async": { - "api_version": { - "signature": "api_version: Optional[str] = None,", - "description": "API version to use if no profile is provided, or if missing in profile.", - "docstring_type": "str", - "required": false - }, - "profile": { - "signature": "profile: KnownProfiles = KnownProfiles.default,", - "description": "A profile definition, from KnownProfiles to dict.", - "docstring_type": "azure.profiles.KnownProfiles", - "required": false - } - } - } - }, - "config": { - "credential": true, - "credential_scopes": ["https://cognitiveservices.azure.com/.default"], - "credential_default_policy_type": "BearerTokenCredentialPolicy", - "credential_default_policy_type_has_async_version": true, - "credential_key_header_name": null, - "sync_imports": "{\"regular\": {\"azurecore\": {\"azure.core.configuration\": [\"Configuration\"], \"azure.core.pipeline\": [\"policies\"]}, \"local\": {\"._version\": [\"VERSION\"]}}, \"conditional\": {\"stdlib\": {\"typing\": [\"Any\"]}}, \"typing\": {\"azurecore\": {\"azure.core.credentials\": [\"TokenCredential\"]}}}", - "async_imports": "{\"regular\": {\"azurecore\": {\"azure.core.configuration\": [\"Configuration\"], \"azure.core.pipeline\": [\"policies\"]}, \"local\": {\".._version\": [\"VERSION\"]}}, \"conditional\": {\"stdlib\": {\"typing\": [\"Any\"]}}, \"typing\": {\"azurecore\": {\"azure.core.credentials_async\": [\"AsyncTokenCredential\"]}}}" - }, - "operation_groups": { - }, - "operation_mixins": { - "sync_imports": "{\"regular\": {\"azurecore\": {\"azure.core.exceptions\": [\"ClientAuthenticationError\", \"HttpResponseError\", \"ResourceExistsError\", \"ResourceNotFoundError\", \"map_error\"], \"azure.core.pipeline\": [\"PipelineResponse\"], \"azure.core.pipeline.transport\": [\"HttpRequest\", \"HttpResponse\"], \"...._lro\": [\"AnalyzeBatchActionsLROPoller\", \"AnalyzeBatchActionsLROPollingMethod\"], \"azure.core.polling\": [\"LROPoller\", \"NoPolling\", \"PollingMethod\"], \"azure.core.polling.base_polling\": [\"LROBasePolling\"]}, \"stdlib\": {\"warnings\": [null]}}, \"conditional\": {\"stdlib\": {\"typing\": [\"Any\", \"Callable\", \"Dict\", \"Generic\", \"List\", \"Optional\", \"TypeVar\", \"Union\"]}}}", - "async_imports": "{\"regular\": {\"azurecore\": {\"azure.core.exceptions\": [\"ClientAuthenticationError\", \"HttpResponseError\", \"ResourceExistsError\", \"ResourceNotFoundError\", \"map_error\"], \"azure.core.pipeline\": [\"PipelineResponse\"], \"azure.core.pipeline.transport\": [\"AsyncHttpResponse\", \"HttpRequest\"], \"...._async_lro\": [\"AsyncAnalyzeBatchActionsLROPoller\", \"AsyncAnalyzeBatchActionsLROPollingMethod\"], \"azure.core.polling\": [\"AsyncLROPoller\", \"AsyncNoPolling\", \"AsyncPollingMethod\"], \"azure.core.polling.async_base_polling\": [\"AsyncLROBasePolling\"]}, \"stdlib\": {\"warnings\": [null]}}, \"conditional\": {\"stdlib\": {\"typing\": [\"Any\", \"Callable\", \"Dict\", \"Generic\", \"List\", \"Optional\", \"TypeVar\", \"Union\"]}}}", - "operations": { - "_analyze_initial" : { - "sync": { - "signature": "def _analyze_initial(\n self,\n body=None, # type: Optional[\"_models.AnalyzeBatchInput\"]\n **kwargs # type: Any\n):\n", - "doc": "\"\"\"\n\n:param body: Collection of documents to analyze and tasks to execute.\n:type body: ~azure.ai.textanalytics.v3_1_preview_3.models.AnalyzeBatchInput\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: AnalyzeJobState, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.AnalyzeJobState or None\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "async": { - "coroutine": true, - "signature": "async def _analyze_initial(\n self,\n body: Optional[\"_models.AnalyzeBatchInput\"] = None,\n **kwargs\n) -\u003e Optional[\"_models.AnalyzeJobState\"]:\n", - "doc": "\"\"\"\n\n:param body: Collection of documents to analyze and tasks to execute.\n:type body: ~azure.ai.textanalytics.v3_1_preview_3.models.AnalyzeBatchInput\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: AnalyzeJobState, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.AnalyzeJobState or None\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "call": "body" - }, - "begin_analyze" : { - "sync": { - "signature": "def begin_analyze(\n self,\n body=None, # type: Optional[\"_models.AnalyzeBatchInput\"]\n **kwargs # type: Any\n):\n", - "doc": "\"\"\"Submit analysis job.\n\nSubmit a collection of text documents for analysis. Specify one or more unique tasks to be\nexecuted.\n\n:param body: Collection of documents to analyze and tasks to execute.\n:type body: ~azure.ai.textanalytics.v3_1_preview_3.models.AnalyzeBatchInput\n:keyword callable cls: A custom type or function that will be passed the direct response\n:keyword str continuation_token: A continuation token to restart a poller from a saved state.\n:keyword polling: Pass in True if you\u0027d like the AnalyzeBatchActionsLROPollingMethod polling method,\n False for no polling, or your own initialized polling object for a personal polling strategy.\n:paramtype polling: bool or ~azure.core.polling.PollingMethod\n:keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present.\n:return: An instance of AnalyzeBatchActionsLROPoller that returns either AnalyzeJobState or the result of cls(response)\n:rtype: ~...._lro.AnalyzeBatchActionsLROPoller[~azure.ai.textanalytics.v3_1_preview_3.models.AnalyzeJobState]\n:raises ~azure.core.exceptions.HttpResponseError:\n\"\"\"" - }, - "async": { - "coroutine": true, - "signature": "async def begin_analyze(\n self,\n body: Optional[\"_models.AnalyzeBatchInput\"] = None,\n **kwargs\n) -\u003e AsyncAnalyzeBatchActionsLROPoller[\"_models.AnalyzeJobState\"]:\n", - "doc": "\"\"\"Submit analysis job.\n\nSubmit a collection of text documents for analysis. Specify one or more unique tasks to be\nexecuted.\n\n:param body: Collection of documents to analyze and tasks to execute.\n:type body: ~azure.ai.textanalytics.v3_1_preview_3.models.AnalyzeBatchInput\n:keyword callable cls: A custom type or function that will be passed the direct response\n:keyword str continuation_token: A continuation token to restart a poller from a saved state.\n:keyword polling: Pass in True if you\u0027d like the AsyncAnalyzeBatchActionsLROPollingMethod polling method,\n False for no polling, or your own initialized polling object for a personal polling strategy.\n:paramtype polling: bool or ~azure.core.polling.AsyncPollingMethod\n:keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present.\n:return: An instance of AsyncAnalyzeBatchActionsLROPoller that returns either AnalyzeJobState or the result of cls(response)\n:rtype: ~...._async_lro.AsyncAnalyzeBatchActionsLROPoller[~azure.ai.textanalytics.v3_1_preview_3.models.AnalyzeJobState]\n:raises ~azure.core.exceptions.HttpResponseError:\n\"\"\"" - }, - "call": "body" - }, - "analyze_status" : { - "sync": { - "signature": "def analyze_status(\n self,\n job_id, # type: str\n show_stats=None, # type: Optional[bool]\n top=20, # type: Optional[int]\n skip=0, # type: Optional[int]\n **kwargs # type: Any\n):\n", - "doc": "\"\"\"Get analysis status and results.\n\nGet the status of an analysis job. A job may consist of one or more tasks. Once all tasks are\ncompleted, the job will transition to the completed state and results will be available for\neach task.\n\n:param job_id: Job ID for Analyze.\n:type job_id: str\n:param show_stats: (Optional) if set to true, response will contain request and document level\n statistics.\n:type show_stats: bool\n:param top: (Optional) Set the maximum number of results per task. When both $top and $skip are\n specified, $skip is applied first.\n:type top: int\n:param skip: (Optional) Set the number of elements to offset in the response. When both $top\n and $skip are specified, $skip is applied first.\n:type skip: int\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: AnalyzeJobState, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.AnalyzeJobState\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "async": { - "coroutine": true, - "signature": "async def analyze_status(\n self,\n job_id: str,\n show_stats: Optional[bool] = None,\n top: Optional[int] = 20,\n skip: Optional[int] = 0,\n **kwargs\n) -\u003e \"_models.AnalyzeJobState\":\n", - "doc": "\"\"\"Get analysis status and results.\n\nGet the status of an analysis job. A job may consist of one or more tasks. Once all tasks are\ncompleted, the job will transition to the completed state and results will be available for\neach task.\n\n:param job_id: Job ID for Analyze.\n:type job_id: str\n:param show_stats: (Optional) if set to true, response will contain request and document level\n statistics.\n:type show_stats: bool\n:param top: (Optional) Set the maximum number of results per task. When both $top and $skip are\n specified, $skip is applied first.\n:type top: int\n:param skip: (Optional) Set the number of elements to offset in the response. When both $top\n and $skip are specified, $skip is applied first.\n:type skip: int\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: AnalyzeJobState, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.AnalyzeJobState\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "call": "job_id, show_stats, top, skip" - }, - "health_status" : { - "sync": { - "signature": "def health_status(\n self,\n job_id, # type: str\n top=20, # type: Optional[int]\n skip=0, # type: Optional[int]\n show_stats=None, # type: Optional[bool]\n **kwargs # type: Any\n):\n", - "doc": "\"\"\"Get healthcare analysis job status and results.\n\nGet details of the healthcare prediction job specified by the jobId.\n\n:param job_id: Job ID.\n:type job_id: str\n:param top: (Optional) Set the maximum number of results per task. When both $top and $skip are\n specified, $skip is applied first.\n:type top: int\n:param skip: (Optional) Set the number of elements to offset in the response. When both $top\n and $skip are specified, $skip is applied first.\n:type skip: int\n:param show_stats: (Optional) if set to true, response will contain request and document level\n statistics.\n:type show_stats: bool\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: HealthcareJobState, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.HealthcareJobState\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "async": { - "coroutine": true, - "signature": "async def health_status(\n self,\n job_id: str,\n top: Optional[int] = 20,\n skip: Optional[int] = 0,\n show_stats: Optional[bool] = None,\n **kwargs\n) -\u003e \"_models.HealthcareJobState\":\n", - "doc": "\"\"\"Get healthcare analysis job status and results.\n\nGet details of the healthcare prediction job specified by the jobId.\n\n:param job_id: Job ID.\n:type job_id: str\n:param top: (Optional) Set the maximum number of results per task. When both $top and $skip are\n specified, $skip is applied first.\n:type top: int\n:param skip: (Optional) Set the number of elements to offset in the response. When both $top\n and $skip are specified, $skip is applied first.\n:type skip: int\n:param show_stats: (Optional) if set to true, response will contain request and document level\n statistics.\n:type show_stats: bool\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: HealthcareJobState, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.HealthcareJobState\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "call": "job_id, top, skip, show_stats" - }, - "_cancel_health_job_initial" : { - "sync": { - "signature": "def _cancel_health_job_initial(\n self,\n job_id, # type: str\n **kwargs # type: Any\n):\n", - "doc": "\"\"\"\n\n:param job_id: Job ID.\n:type job_id: str\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: None, or the result of cls(response)\n:rtype: None\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "async": { - "coroutine": true, - "signature": "async def _cancel_health_job_initial(\n self,\n job_id: str,\n **kwargs\n) -\u003e None:\n", - "doc": "\"\"\"\n\n:param job_id: Job ID.\n:type job_id: str\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: None, or the result of cls(response)\n:rtype: None\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "call": "job_id" - }, - "begin_cancel_health_job" : { - "sync": { - "signature": "def begin_cancel_health_job(\n self,\n job_id, # type: str\n **kwargs # type: Any\n):\n", - "doc": "\"\"\"Cancel healthcare prediction job.\n\nCancel healthcare prediction job.\n\n:param job_id: Job ID.\n:type job_id: str\n:keyword callable cls: A custom type or function that will be passed the direct response\n:keyword str continuation_token: A continuation token to restart a poller from a saved state.\n:keyword polling: Pass in True if you\u0027d like the LROBasePolling polling method,\n False for no polling, or your own initialized polling object for a personal polling strategy.\n:paramtype polling: bool or ~azure.core.polling.PollingMethod\n:keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present.\n:return: An instance of LROPoller that returns either None or the result of cls(response)\n:rtype: ~azure.core.polling.LROPoller[None]\n:raises ~azure.core.exceptions.HttpResponseError:\n\"\"\"" - }, - "async": { - "coroutine": true, - "signature": "async def begin_cancel_health_job(\n self,\n job_id: str,\n **kwargs\n) -\u003e AsyncLROPoller[None]:\n", - "doc": "\"\"\"Cancel healthcare prediction job.\n\nCancel healthcare prediction job.\n\n:param job_id: Job ID.\n:type job_id: str\n:keyword callable cls: A custom type or function that will be passed the direct response\n:keyword str continuation_token: A continuation token to restart a poller from a saved state.\n:keyword polling: Pass in True if you\u0027d like the AsyncLROBasePolling polling method,\n False for no polling, or your own initialized polling object for a personal polling strategy.\n:paramtype polling: bool or ~azure.core.polling.AsyncPollingMethod\n:keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present.\n:return: An instance of AsyncLROPoller that returns either None or the result of cls(response)\n:rtype: ~azure.core.polling.AsyncLROPoller[None]\n:raises ~azure.core.exceptions.HttpResponseError:\n\"\"\"" - }, - "call": "job_id" - }, - "_health_initial" : { - "sync": { - "signature": "def _health_initial(\n self,\n documents, # type: List[\"_models.MultiLanguageInput\"]\n model_version=None, # type: Optional[str]\n string_index_type=\"TextElements_v8\", # type: Optional[Union[str, \"_models.StringIndexType\"]]\n **kwargs # type: Any\n):\n", - "doc": "\"\"\"\n\n:param documents: The set of documents to process as part of this batch.\n:type documents: list[~azure.ai.textanalytics.v3_1_preview_3.models.MultiLanguageInput]\n:param model_version: (Optional) This value indicates which model will be used for scoring. If\n a model-version is not specified, the API should default to the latest, non-preview version.\n:type model_version: str\n:param string_index_type: (Optional) Specifies the method used to interpret string offsets.\n Defaults to Text Elements (Graphemes) according to Unicode v8.0.0. For additional information\n see https://aka.ms/text-analytics-offsets.\n:type string_index_type: str or ~azure.ai.textanalytics.v3_1_preview_3.models.StringIndexType\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: HealthcareJobState, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.HealthcareJobState or None\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "async": { - "coroutine": true, - "signature": "async def _health_initial(\n self,\n documents: List[\"_models.MultiLanguageInput\"],\n model_version: Optional[str] = None,\n string_index_type: Optional[Union[str, \"_models.StringIndexType\"]] = \"TextElements_v8\",\n **kwargs\n) -\u003e Optional[\"_models.HealthcareJobState\"]:\n", - "doc": "\"\"\"\n\n:param documents: The set of documents to process as part of this batch.\n:type documents: list[~azure.ai.textanalytics.v3_1_preview_3.models.MultiLanguageInput]\n:param model_version: (Optional) This value indicates which model will be used for scoring. If\n a model-version is not specified, the API should default to the latest, non-preview version.\n:type model_version: str\n:param string_index_type: (Optional) Specifies the method used to interpret string offsets.\n Defaults to Text Elements (Graphemes) according to Unicode v8.0.0. For additional information\n see https://aka.ms/text-analytics-offsets.\n:type string_index_type: str or ~azure.ai.textanalytics.v3_1_preview_3.models.StringIndexType\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: HealthcareJobState, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.HealthcareJobState or None\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "call": "documents, model_version, string_index_type" - }, - "begin_health" : { - "sync": { - "signature": "def begin_health(\n self,\n documents, # type: List[\"_models.MultiLanguageInput\"]\n model_version=None, # type: Optional[str]\n string_index_type=\"TextElements_v8\", # type: Optional[Union[str, \"_models.StringIndexType\"]]\n **kwargs # type: Any\n):\n", - "doc": "\"\"\"Submit healthcare analysis job.\n\nStart a healthcare analysis job to recognize healthcare related entities (drugs, conditions,\nsymptoms, etc) and their relations.\n\n:param documents: The set of documents to process as part of this batch.\n:type documents: list[~azure.ai.textanalytics.v3_1_preview_3.models.MultiLanguageInput]\n:param model_version: (Optional) This value indicates which model will be used for scoring. If\n a model-version is not specified, the API should default to the latest, non-preview version.\n:type model_version: str\n:param string_index_type: (Optional) Specifies the method used to interpret string offsets.\n Defaults to Text Elements (Graphemes) according to Unicode v8.0.0. For additional information\n see https://aka.ms/text-analytics-offsets.\n:type string_index_type: str or ~azure.ai.textanalytics.v3_1_preview_3.models.StringIndexType\n:keyword callable cls: A custom type or function that will be passed the direct response\n:keyword str continuation_token: A continuation token to restart a poller from a saved state.\n:keyword polling: Pass in True if you\u0027d like the AnalyzeBatchActionsLROPollingMethod polling method,\n False for no polling, or your own initialized polling object for a personal polling strategy.\n:paramtype polling: bool or ~azure.core.polling.PollingMethod\n:keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present.\n:return: An instance of AnalyzeBatchActionsLROPoller that returns either HealthcareJobState or the result of cls(response)\n:rtype: ~...._lro.AnalyzeBatchActionsLROPoller[~azure.ai.textanalytics.v3_1_preview_3.models.HealthcareJobState]\n:raises ~azure.core.exceptions.HttpResponseError:\n\"\"\"" - }, - "async": { - "coroutine": true, - "signature": "async def begin_health(\n self,\n documents: List[\"_models.MultiLanguageInput\"],\n model_version: Optional[str] = None,\n string_index_type: Optional[Union[str, \"_models.StringIndexType\"]] = \"TextElements_v8\",\n **kwargs\n) -\u003e AsyncAnalyzeBatchActionsLROPoller[\"_models.HealthcareJobState\"]:\n", - "doc": "\"\"\"Submit healthcare analysis job.\n\nStart a healthcare analysis job to recognize healthcare related entities (drugs, conditions,\nsymptoms, etc) and their relations.\n\n:param documents: The set of documents to process as part of this batch.\n:type documents: list[~azure.ai.textanalytics.v3_1_preview_3.models.MultiLanguageInput]\n:param model_version: (Optional) This value indicates which model will be used for scoring. If\n a model-version is not specified, the API should default to the latest, non-preview version.\n:type model_version: str\n:param string_index_type: (Optional) Specifies the method used to interpret string offsets.\n Defaults to Text Elements (Graphemes) according to Unicode v8.0.0. For additional information\n see https://aka.ms/text-analytics-offsets.\n:type string_index_type: str or ~azure.ai.textanalytics.v3_1_preview_3.models.StringIndexType\n:keyword callable cls: A custom type or function that will be passed the direct response\n:keyword str continuation_token: A continuation token to restart a poller from a saved state.\n:keyword polling: Pass in True if you\u0027d like the AsyncAnalyzeBatchActionsLROPollingMethod polling method,\n False for no polling, or your own initialized polling object for a personal polling strategy.\n:paramtype polling: bool or ~azure.core.polling.AsyncPollingMethod\n:keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present.\n:return: An instance of AsyncAnalyzeBatchActionsLROPoller that returns either HealthcareJobState or the result of cls(response)\n:rtype: ~...._async_lro.AsyncAnalyzeBatchActionsLROPoller[~azure.ai.textanalytics.v3_1_preview_3.models.HealthcareJobState]\n:raises ~azure.core.exceptions.HttpResponseError:\n\"\"\"" - }, - "call": "documents, model_version, string_index_type" - }, - "entities_recognition_general" : { - "sync": { - "signature": "def entities_recognition_general(\n self,\n documents, # type: List[\"_models.MultiLanguageInput\"]\n model_version=None, # type: Optional[str]\n show_stats=None, # type: Optional[bool]\n string_index_type=\"TextElements_v8\", # type: Optional[Union[str, \"_models.StringIndexType\"]]\n **kwargs # type: Any\n):\n", - "doc": "\"\"\"Named Entity Recognition.\n\nThe API returns a list of general named entities in a given document. For the list of supported\nentity types, check :code:`\u003ca href=\"https://aka.ms/taner\"\u003eSupported Entity Types in Text\nAnalytics API\u003c/a\u003e`. See the :code:`\u003ca href=\"https://aka.ms/talangs\"\u003eSupported languages in Text\nAnalytics API\u003c/a\u003e` for the list of enabled languages.\n\n:param documents: The set of documents to process as part of this batch.\n:type documents: list[~azure.ai.textanalytics.v3_1_preview_3.models.MultiLanguageInput]\n:param model_version: (Optional) This value indicates which model will be used for scoring. If\n a model-version is not specified, the API should default to the latest, non-preview version.\n:type model_version: str\n:param show_stats: (Optional) if set to true, response will contain request and document level\n statistics.\n:type show_stats: bool\n:param string_index_type: (Optional) Specifies the method used to interpret string offsets.\n Defaults to Text Elements (Graphemes) according to Unicode v8.0.0. For additional information\n see https://aka.ms/text-analytics-offsets.\n:type string_index_type: str or ~azure.ai.textanalytics.v3_1_preview_3.models.StringIndexType\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: EntitiesResult, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.EntitiesResult\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "async": { - "coroutine": true, - "signature": "async def entities_recognition_general(\n self,\n documents: List[\"_models.MultiLanguageInput\"],\n model_version: Optional[str] = None,\n show_stats: Optional[bool] = None,\n string_index_type: Optional[Union[str, \"_models.StringIndexType\"]] = \"TextElements_v8\",\n **kwargs\n) -\u003e \"_models.EntitiesResult\":\n", - "doc": "\"\"\"Named Entity Recognition.\n\nThe API returns a list of general named entities in a given document. For the list of supported\nentity types, check :code:`\u003ca href=\"https://aka.ms/taner\"\u003eSupported Entity Types in Text\nAnalytics API\u003c/a\u003e`. See the :code:`\u003ca href=\"https://aka.ms/talangs\"\u003eSupported languages in Text\nAnalytics API\u003c/a\u003e` for the list of enabled languages.\n\n:param documents: The set of documents to process as part of this batch.\n:type documents: list[~azure.ai.textanalytics.v3_1_preview_3.models.MultiLanguageInput]\n:param model_version: (Optional) This value indicates which model will be used for scoring. If\n a model-version is not specified, the API should default to the latest, non-preview version.\n:type model_version: str\n:param show_stats: (Optional) if set to true, response will contain request and document level\n statistics.\n:type show_stats: bool\n:param string_index_type: (Optional) Specifies the method used to interpret string offsets.\n Defaults to Text Elements (Graphemes) according to Unicode v8.0.0. For additional information\n see https://aka.ms/text-analytics-offsets.\n:type string_index_type: str or ~azure.ai.textanalytics.v3_1_preview_3.models.StringIndexType\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: EntitiesResult, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.EntitiesResult\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "call": "documents, model_version, show_stats, string_index_type" - }, - "entities_recognition_pii" : { - "sync": { - "signature": "def entities_recognition_pii(\n self,\n documents, # type: List[\"_models.MultiLanguageInput\"]\n model_version=None, # type: Optional[str]\n show_stats=None, # type: Optional[bool]\n domain=None, # type: Optional[str]\n string_index_type=\"TextElements_v8\", # type: Optional[Union[str, \"_models.StringIndexType\"]]\n **kwargs # type: Any\n):\n", - "doc": "\"\"\"Entities containing personal information.\n\nThe API returns a list of entities with personal information (\\\"SSN\\\", \\\"Bank Account\\\" etc) in\nthe document. For the list of supported entity types, check :code:`\u003ca\nhref=\"https://aka.ms/tanerpii\"\u003eSupported Entity Types in Text Analytics API\u003c/a\u003e`. See the\n:code:`\u003ca href=\"https://aka.ms/talangs\"\u003eSupported languages in Text Analytics API\u003c/a\u003e` for the\nlist of enabled languages.\n\n:param documents: The set of documents to process as part of this batch.\n:type documents: list[~azure.ai.textanalytics.v3_1_preview_3.models.MultiLanguageInput]\n:param model_version: (Optional) This value indicates which model will be used for scoring. If\n a model-version is not specified, the API should default to the latest, non-preview version.\n:type model_version: str\n:param show_stats: (Optional) if set to true, response will contain request and document level\n statistics.\n:type show_stats: bool\n:param domain: (Optional) if specified, will set the PII domain to include only a subset of the\n entity categories. Possible values include: \u0027PHI\u0027, \u0027none\u0027.\n:type domain: str\n:param string_index_type: (Optional) Specifies the method used to interpret string offsets.\n Defaults to Text Elements (Graphemes) according to Unicode v8.0.0. For additional information\n see https://aka.ms/text-analytics-offsets.\n:type string_index_type: str or ~azure.ai.textanalytics.v3_1_preview_3.models.StringIndexType\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: PiiResult, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.PiiResult\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "async": { - "coroutine": true, - "signature": "async def entities_recognition_pii(\n self,\n documents: List[\"_models.MultiLanguageInput\"],\n model_version: Optional[str] = None,\n show_stats: Optional[bool] = None,\n domain: Optional[str] = None,\n string_index_type: Optional[Union[str, \"_models.StringIndexType\"]] = \"TextElements_v8\",\n **kwargs\n) -\u003e \"_models.PiiResult\":\n", - "doc": "\"\"\"Entities containing personal information.\n\nThe API returns a list of entities with personal information (\\\"SSN\\\", \\\"Bank Account\\\" etc) in\nthe document. For the list of supported entity types, check :code:`\u003ca\nhref=\"https://aka.ms/tanerpii\"\u003eSupported Entity Types in Text Analytics API\u003c/a\u003e`. See the\n:code:`\u003ca href=\"https://aka.ms/talangs\"\u003eSupported languages in Text Analytics API\u003c/a\u003e` for the\nlist of enabled languages.\n\n:param documents: The set of documents to process as part of this batch.\n:type documents: list[~azure.ai.textanalytics.v3_1_preview_3.models.MultiLanguageInput]\n:param model_version: (Optional) This value indicates which model will be used for scoring. If\n a model-version is not specified, the API should default to the latest, non-preview version.\n:type model_version: str\n:param show_stats: (Optional) if set to true, response will contain request and document level\n statistics.\n:type show_stats: bool\n:param domain: (Optional) if specified, will set the PII domain to include only a subset of the\n entity categories. Possible values include: \u0027PHI\u0027, \u0027none\u0027.\n:type domain: str\n:param string_index_type: (Optional) Specifies the method used to interpret string offsets.\n Defaults to Text Elements (Graphemes) according to Unicode v8.0.0. For additional information\n see https://aka.ms/text-analytics-offsets.\n:type string_index_type: str or ~azure.ai.textanalytics.v3_1_preview_3.models.StringIndexType\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: PiiResult, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.PiiResult\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "call": "documents, model_version, show_stats, domain, string_index_type" - }, - "entities_linking" : { - "sync": { - "signature": "def entities_linking(\n self,\n documents, # type: List[\"_models.MultiLanguageInput\"]\n model_version=None, # type: Optional[str]\n show_stats=None, # type: Optional[bool]\n string_index_type=\"TextElements_v8\", # type: Optional[Union[str, \"_models.StringIndexType\"]]\n **kwargs # type: Any\n):\n", - "doc": "\"\"\"Linked entities from a well-known knowledge base.\n\nThe API returns a list of recognized entities with links to a well-known knowledge base. See\nthe :code:`\u003ca href=\"https://aka.ms/talangs\"\u003eSupported languages in Text Analytics API\u003c/a\u003e` for\nthe list of enabled languages.\n\n:param documents: The set of documents to process as part of this batch.\n:type documents: list[~azure.ai.textanalytics.v3_1_preview_3.models.MultiLanguageInput]\n:param model_version: (Optional) This value indicates which model will be used for scoring. If\n a model-version is not specified, the API should default to the latest, non-preview version.\n:type model_version: str\n:param show_stats: (Optional) if set to true, response will contain request and document level\n statistics.\n:type show_stats: bool\n:param string_index_type: (Optional) Specifies the method used to interpret string offsets.\n Defaults to Text Elements (Graphemes) according to Unicode v8.0.0. For additional information\n see https://aka.ms/text-analytics-offsets.\n:type string_index_type: str or ~azure.ai.textanalytics.v3_1_preview_3.models.StringIndexType\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: EntityLinkingResult, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.EntityLinkingResult\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "async": { - "coroutine": true, - "signature": "async def entities_linking(\n self,\n documents: List[\"_models.MultiLanguageInput\"],\n model_version: Optional[str] = None,\n show_stats: Optional[bool] = None,\n string_index_type: Optional[Union[str, \"_models.StringIndexType\"]] = \"TextElements_v8\",\n **kwargs\n) -\u003e \"_models.EntityLinkingResult\":\n", - "doc": "\"\"\"Linked entities from a well-known knowledge base.\n\nThe API returns a list of recognized entities with links to a well-known knowledge base. See\nthe :code:`\u003ca href=\"https://aka.ms/talangs\"\u003eSupported languages in Text Analytics API\u003c/a\u003e` for\nthe list of enabled languages.\n\n:param documents: The set of documents to process as part of this batch.\n:type documents: list[~azure.ai.textanalytics.v3_1_preview_3.models.MultiLanguageInput]\n:param model_version: (Optional) This value indicates which model will be used for scoring. If\n a model-version is not specified, the API should default to the latest, non-preview version.\n:type model_version: str\n:param show_stats: (Optional) if set to true, response will contain request and document level\n statistics.\n:type show_stats: bool\n:param string_index_type: (Optional) Specifies the method used to interpret string offsets.\n Defaults to Text Elements (Graphemes) according to Unicode v8.0.0. For additional information\n see https://aka.ms/text-analytics-offsets.\n:type string_index_type: str or ~azure.ai.textanalytics.v3_1_preview_3.models.StringIndexType\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: EntityLinkingResult, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.EntityLinkingResult\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "call": "documents, model_version, show_stats, string_index_type" - }, - "key_phrases" : { - "sync": { - "signature": "def key_phrases(\n self,\n documents, # type: List[\"_models.MultiLanguageInput\"]\n model_version=None, # type: Optional[str]\n show_stats=None, # type: Optional[bool]\n **kwargs # type: Any\n):\n", - "doc": "\"\"\"Key Phrases.\n\nThe API returns a list of strings denoting the key phrases in the input text. See the :code:`\u003ca\nhref=\"https://aka.ms/talangs\"\u003eSupported languages in Text Analytics API\u003c/a\u003e` for the list of\nenabled languages.\n\n:param documents: The set of documents to process as part of this batch.\n:type documents: list[~azure.ai.textanalytics.v3_1_preview_3.models.MultiLanguageInput]\n:param model_version: (Optional) This value indicates which model will be used for scoring. If\n a model-version is not specified, the API should default to the latest, non-preview version.\n:type model_version: str\n:param show_stats: (Optional) if set to true, response will contain request and document level\n statistics.\n:type show_stats: bool\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: KeyPhraseResult, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.KeyPhraseResult\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "async": { - "coroutine": true, - "signature": "async def key_phrases(\n self,\n documents: List[\"_models.MultiLanguageInput\"],\n model_version: Optional[str] = None,\n show_stats: Optional[bool] = None,\n **kwargs\n) -\u003e \"_models.KeyPhraseResult\":\n", - "doc": "\"\"\"Key Phrases.\n\nThe API returns a list of strings denoting the key phrases in the input text. See the :code:`\u003ca\nhref=\"https://aka.ms/talangs\"\u003eSupported languages in Text Analytics API\u003c/a\u003e` for the list of\nenabled languages.\n\n:param documents: The set of documents to process as part of this batch.\n:type documents: list[~azure.ai.textanalytics.v3_1_preview_3.models.MultiLanguageInput]\n:param model_version: (Optional) This value indicates which model will be used for scoring. If\n a model-version is not specified, the API should default to the latest, non-preview version.\n:type model_version: str\n:param show_stats: (Optional) if set to true, response will contain request and document level\n statistics.\n:type show_stats: bool\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: KeyPhraseResult, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.KeyPhraseResult\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "call": "documents, model_version, show_stats" - }, - "languages" : { - "sync": { - "signature": "def languages(\n self,\n documents, # type: List[\"_models.LanguageInput\"]\n model_version=None, # type: Optional[str]\n show_stats=None, # type: Optional[bool]\n **kwargs # type: Any\n):\n", - "doc": "\"\"\"Detect Language.\n\nThe API returns the detected language and a numeric score between 0 and 1. Scores close to 1\nindicate 100% certainty that the identified language is true. See the :code:`\u003ca\nhref=\"https://aka.ms/talangs\"\u003eSupported languages in Text Analytics API\u003c/a\u003e` for the list of\nenabled languages.\n\n:param documents:\n:type documents: list[~azure.ai.textanalytics.v3_1_preview_3.models.LanguageInput]\n:param model_version: (Optional) This value indicates which model will be used for scoring. If\n a model-version is not specified, the API should default to the latest, non-preview version.\n:type model_version: str\n:param show_stats: (Optional) if set to true, response will contain request and document level\n statistics.\n:type show_stats: bool\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: LanguageResult, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.LanguageResult\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "async": { - "coroutine": true, - "signature": "async def languages(\n self,\n documents: List[\"_models.LanguageInput\"],\n model_version: Optional[str] = None,\n show_stats: Optional[bool] = None,\n **kwargs\n) -\u003e \"_models.LanguageResult\":\n", - "doc": "\"\"\"Detect Language.\n\nThe API returns the detected language and a numeric score between 0 and 1. Scores close to 1\nindicate 100% certainty that the identified language is true. See the :code:`\u003ca\nhref=\"https://aka.ms/talangs\"\u003eSupported languages in Text Analytics API\u003c/a\u003e` for the list of\nenabled languages.\n\n:param documents:\n:type documents: list[~azure.ai.textanalytics.v3_1_preview_3.models.LanguageInput]\n:param model_version: (Optional) This value indicates which model will be used for scoring. If\n a model-version is not specified, the API should default to the latest, non-preview version.\n:type model_version: str\n:param show_stats: (Optional) if set to true, response will contain request and document level\n statistics.\n:type show_stats: bool\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: LanguageResult, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.LanguageResult\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "call": "documents, model_version, show_stats" - }, - "sentiment" : { - "sync": { - "signature": "def sentiment(\n self,\n documents, # type: List[\"_models.MultiLanguageInput\"]\n model_version=None, # type: Optional[str]\n show_stats=None, # type: Optional[bool]\n opinion_mining=None, # type: Optional[bool]\n string_index_type=\"TextElements_v8\", # type: Optional[Union[str, \"_models.StringIndexType\"]]\n **kwargs # type: Any\n):\n", - "doc": "\"\"\"Sentiment.\n\nThe API returns a detailed sentiment analysis for the input text. The analysis is done in\nmultiple levels of granularity, start from the a document level, down to sentence and key terms\n(aspects) and opinions.\n\n:param documents: The set of documents to process as part of this batch.\n:type documents: list[~azure.ai.textanalytics.v3_1_preview_3.models.MultiLanguageInput]\n:param model_version: (Optional) This value indicates which model will be used for scoring. If\n a model-version is not specified, the API should default to the latest, non-preview version.\n:type model_version: str\n:param show_stats: (Optional) if set to true, response will contain request and document level\n statistics.\n:type show_stats: bool\n:param opinion_mining: (Optional) if set to true, response will contain input and document\n level statistics including aspect-based sentiment analysis results.\n:type opinion_mining: bool\n:param string_index_type: (Optional) Specifies the method used to interpret string offsets.\n Defaults to Text Elements (Graphemes) according to Unicode v8.0.0. For additional information\n see https://aka.ms/text-analytics-offsets.\n:type string_index_type: str or ~azure.ai.textanalytics.v3_1_preview_3.models.StringIndexType\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: SentimentResponse, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.SentimentResponse\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "async": { - "coroutine": true, - "signature": "async def sentiment(\n self,\n documents: List[\"_models.MultiLanguageInput\"],\n model_version: Optional[str] = None,\n show_stats: Optional[bool] = None,\n opinion_mining: Optional[bool] = None,\n string_index_type: Optional[Union[str, \"_models.StringIndexType\"]] = \"TextElements_v8\",\n **kwargs\n) -\u003e \"_models.SentimentResponse\":\n", - "doc": "\"\"\"Sentiment.\n\nThe API returns a detailed sentiment analysis for the input text. The analysis is done in\nmultiple levels of granularity, start from the a document level, down to sentence and key terms\n(aspects) and opinions.\n\n:param documents: The set of documents to process as part of this batch.\n:type documents: list[~azure.ai.textanalytics.v3_1_preview_3.models.MultiLanguageInput]\n:param model_version: (Optional) This value indicates which model will be used for scoring. If\n a model-version is not specified, the API should default to the latest, non-preview version.\n:type model_version: str\n:param show_stats: (Optional) if set to true, response will contain request and document level\n statistics.\n:type show_stats: bool\n:param opinion_mining: (Optional) if set to true, response will contain input and document\n level statistics including aspect-based sentiment analysis results.\n:type opinion_mining: bool\n:param string_index_type: (Optional) Specifies the method used to interpret string offsets.\n Defaults to Text Elements (Graphemes) according to Unicode v8.0.0. For additional information\n see https://aka.ms/text-analytics-offsets.\n:type string_index_type: str or ~azure.ai.textanalytics.v3_1_preview_3.models.StringIndexType\n:keyword callable cls: A custom type or function that will be passed the direct response\n:return: SentimentResponse, or the result of cls(response)\n:rtype: ~azure.ai.textanalytics.v3_1_preview_3.models.SentimentResponse\n:raises: ~azure.core.exceptions.HttpResponseError\n\"\"\"" - }, - "call": "documents, model_version, show_stats, opinion_mining, string_index_type" - } - } - } -} \ No newline at end of file diff --git a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_generated/v3_1_preview_3/aio/operations/_text_analytics_client_operations.py b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_generated/v3_1_preview_3/aio/operations/_text_analytics_client_operations.py index ed3357ce8ad7..4271cfa5ad8f 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_generated/v3_1_preview_3/aio/operations/_text_analytics_client_operations.py +++ b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_generated/v3_1_preview_3/aio/operations/_text_analytics_client_operations.py @@ -8,7 +8,12 @@ from typing import Any, Callable, Dict, Generic, List, Optional, TypeVar, Union import warnings -from ....._async_lro import AsyncAnalyzeBatchActionsLROPoller, AsyncAnalyzeBatchActionsLROPollingMethod +from ....._async_lro import ( + AnalyzeHealthcareEntitiesAsyncLROPoller, + AnalyzeHealthcareEntitiesAsyncLROPollingMethod, + AsyncAnalyzeBatchActionsLROPoller, + AsyncAnalyzeBatchActionsLROPollingMethod +) from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error from azure.core.pipeline import PipelineResponse from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest @@ -476,7 +481,7 @@ async def begin_health( model_version: Optional[str] = None, string_index_type: Optional[Union[str, "_models.StringIndexType"]] = "TextElements_v8", **kwargs - ) -> AsyncAnalyzeBatchActionsLROPoller["_models.HealthcareJobState"]: + ) -> AnalyzeHealthcareEntitiesAsyncLROPoller["_models.HealthcareJobState"]: """Submit healthcare analysis job. Start a healthcare analysis job to recognize healthcare related entities (drugs, conditions, @@ -493,12 +498,12 @@ async def begin_health( :type string_index_type: str or ~azure.ai.textanalytics.v3_1_preview_3.models.StringIndexType :keyword callable cls: A custom type or function that will be passed the direct response :keyword str continuation_token: A continuation token to restart a poller from a saved state. - :keyword polling: Pass in True if you'd like the AsyncAnalyzeBatchActionsLROPollingMethod polling method, + :keyword polling: Pass in True if you'd like the AnalyzeHealthcareEntitiesAsyncLROPollingMethod polling method, False for no polling, or your own initialized polling object for a personal polling strategy. :paramtype polling: bool or ~azure.core.polling.AsyncPollingMethod :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. - :return: An instance of AsyncAnalyzeBatchActionsLROPoller that returns either HealthcareJobState or the result of cls(response) - :rtype: ~...._async_lro.AsyncAnalyzeBatchActionsLROPoller[~azure.ai.textanalytics.v3_1_preview_3.models.HealthcareJobState] + :return: An instance of AnalyzeHealthcareEntitiesAsyncLROPoller that returns either HealthcareJobState or the result of cls(response) + :rtype: ~....._async_lro.AnalyzeHealthcareEntitiesAsyncLROPoller[~azure.ai.textanalytics.v3_1_preview_3.models.HealthcareJobState] :raises ~azure.core.exceptions.HttpResponseError: """ polling = kwargs.pop('polling', False) # type: Union[bool, AsyncPollingMethod] @@ -531,18 +536,18 @@ def get_long_running_output(pipeline_response): 'Endpoint': self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), } - if polling is True: polling_method = AsyncAnalyzeBatchActionsLROPollingMethod(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + if polling is True: polling_method = AnalyzeHealthcareEntitiesAsyncLROPollingMethod(lro_delay, path_format_arguments=path_format_arguments, **kwargs) elif polling is False: polling_method = AsyncNoPolling() else: polling_method = polling if cont_token: - return AsyncAnalyzeBatchActionsLROPoller.from_continuation_token( + return AnalyzeHealthcareEntitiesAsyncLROPoller.from_continuation_token( polling_method=polling_method, continuation_token=cont_token, client=self._client, deserialization_callback=get_long_running_output ) else: - return AsyncAnalyzeBatchActionsLROPoller(self._client, raw_result, get_long_running_output, polling_method) + return AnalyzeHealthcareEntitiesAsyncLROPoller(self._client, raw_result, get_long_running_output, polling_method) begin_health.metadata = {'url': '/entities/health/jobs'} # type: ignore async def entities_recognition_general( diff --git a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_generated/v3_1_preview_3/operations/_text_analytics_client_operations.py b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_generated/v3_1_preview_3/operations/_text_analytics_client_operations.py index 1f8461df94fb..e35bc5c9bc38 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_generated/v3_1_preview_3/operations/_text_analytics_client_operations.py +++ b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_generated/v3_1_preview_3/operations/_text_analytics_client_operations.py @@ -8,6 +8,8 @@ from typing import TYPE_CHECKING import warnings +# FIXME: have to manually reconfigure import path for multiapi operation mixin +from ...._lro import AnalyzeHealthcareEntitiesLROPoller, AnalyzeHealthcareEntitiesLROPollingMethod from ...._lro import AnalyzeBatchActionsLROPoller, AnalyzeBatchActionsLROPollingMethod from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error from azure.core.pipeline import PipelineResponse @@ -488,7 +490,7 @@ def begin_health( string_index_type="TextElements_v8", # type: Optional[Union[str, "_models.StringIndexType"]] **kwargs # type: Any ): - # type: (...) -> AnalyzeBatchActionsLROPoller["_models.HealthcareJobState"] + # type: (...) -> AnalyzeHealthcareEntitiesLROPoller["_models.HealthcareJobState"] """Submit healthcare analysis job. Start a healthcare analysis job to recognize healthcare related entities (drugs, conditions, @@ -505,12 +507,12 @@ def begin_health( :type string_index_type: str or ~azure.ai.textanalytics.v3_1_preview_3.models.StringIndexType :keyword callable cls: A custom type or function that will be passed the direct response :keyword str continuation_token: A continuation token to restart a poller from a saved state. - :keyword polling: Pass in True if you'd like the AnalyzeBatchActionsLROPollingMethod polling method, + :keyword polling: Pass in True if you'd like the AnalyzeHealthcareEntitiesLROPollingMethod polling method, False for no polling, or your own initialized polling object for a personal polling strategy. :paramtype polling: bool or ~azure.core.polling.PollingMethod :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. - :return: An instance of AnalyzeBatchActionsLROPoller that returns either HealthcareJobState or the result of cls(response) - :rtype: ~...._lro.AnalyzeBatchActionsLROPoller[~azure.ai.textanalytics.v3_1_preview_3.models.HealthcareJobState] + :return: An instance of AnalyzeHealthcareEntitiesLROPoller that returns either HealthcareJobState or the result of cls(response) + :rtype: ~...._lro.AnalyzeHealthcareEntitiesLROPoller[~azure.ai.textanalytics.v3_1_preview_3.models.HealthcareJobState] :raises ~azure.core.exceptions.HttpResponseError: """ polling = kwargs.pop('polling', False) # type: Union[bool, PollingMethod] @@ -543,18 +545,18 @@ def get_long_running_output(pipeline_response): 'Endpoint': self._serialize.url("self._config.endpoint", self._config.endpoint, 'str', skip_quote=True), } - if polling is True: polling_method = AnalyzeBatchActionsLROPollingMethod(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + if polling is True: polling_method = AnalyzeHealthcareEntitiesLROPollingMethod(lro_delay, path_format_arguments=path_format_arguments, **kwargs) elif polling is False: polling_method = NoPolling() else: polling_method = polling if cont_token: - return AnalyzeBatchActionsLROPoller.from_continuation_token( + return AnalyzeHealthcareEntitiesLROPoller.from_continuation_token( polling_method=polling_method, continuation_token=cont_token, client=self._client, deserialization_callback=get_long_running_output ) else: - return AnalyzeBatchActionsLROPoller(self._client, raw_result, get_long_running_output, polling_method) + return AnalyzeHealthcareEntitiesLROPoller(self._client, raw_result, get_long_running_output, polling_method) begin_health.metadata = {'url': '/entities/health/jobs'} # type: ignore def entities_recognition_general( diff --git a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_lro.py b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_lro.py index 6c1da1bae8f1..bd7f33b54ec6 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_lro.py +++ b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_lro.py @@ -4,10 +4,10 @@ # Licensed under the MIT License. # ------------------------------------ from six.moves.urllib.parse import urlencode +from azure.core.exceptions import HttpResponseError from azure.core.polling import LROPoller from azure.core.polling.base_polling import LROBasePolling, OperationResourcePolling, OperationFailed, BadStatus - _FINISHED = frozenset(["succeeded", "cancelled", "failed", "partiallysucceeded"]) _FAILED = frozenset(["failed"]) _SUCCEEDED = frozenset(["succeeded", "partiallysucceeded"]) @@ -30,7 +30,6 @@ def get_polling_url(self): class TextAnalyticsLROPollingMethod(LROBasePolling): - def finished(self): """Is this polling finished? :rtype: bool @@ -89,7 +88,12 @@ def _poll(self): self._pipeline_response = self.request_status(final_get_url) TextAnalyticsLROPollingMethod._raise_if_bad_http_status_and_method(self._pipeline_response.http_response) -class AnalyzeBatchActionsLROPollingMethod(TextAnalyticsLROPollingMethod): + +class AnalyzeHealthcareEntitiesLROPollingMethod(TextAnalyticsLROPollingMethod): + + def __init__(self, *args, **kwargs): + self._text_analytics_client = kwargs.pop("text_analytics_client") + super(AnalyzeHealthcareEntitiesLROPollingMethod, self).__init__(*args, **kwargs) @property def _current_body(self): @@ -103,10 +107,93 @@ def created_on(self): return self._current_body.created_date_time @property - def display_name(self): + def expires_on(self): if not self._current_body: return None - return self._current_body.display_name + return self._current_body.expiration_date_time + + @property + def last_modified_on(self): + if not self._current_body: + return None + return self._current_body.last_update_date_time + + @property + def id(self): + if not self._current_body: + return None + return self._current_body.job_id + + +class AnalyzeHealthcareEntitiesLROPoller(LROPoller): + + @property + def created_on(self): + return self._polling_method.created_on + + @property + def expires_on(self): + return self._polling_method.expires_on + + @property + def last_modified_on(self): + return self._polling_method.last_modified_on + + @property + def id(self): + return self._polling_method.id + + def cancel( # type: ignore + self, + **kwargs + ): # type: (...) -> LROPoller[None] + """Cancel the operation currently being polled. + + :keyword int polling_interval: The polling interval to use to poll the cancellation status. + The default value is 5 seconds. + :return: Returns an instance of an LROPoller that returns None. + :rtype: ~azure.core.polling.LROPoller[None] + :raises: Warning when the operation has already reached a terminal state. + + .. admonition:: Example: + + .. literalinclude:: ../samples/sample_analyze_healthcare_entities_with_cancellation.py + :start-after: [START analyze_healthcare_entities_with_cancellation] + :end-before: [END analyze_healthcare_entities_with_cancellation] + :language: python + :dedent: 8 + :caption: Cancel an existing health operation. + """ + polling_interval = kwargs.pop("polling_interval", 5) + + try: + # Join the thread so we no longer have to wait for a result from it. + getattr(self, "_thread").join() + + # Get a final status update. + getattr(self._polling_method, "update_status")() + + return getattr(self._polling_method, "_text_analytics_client").begin_cancel_health_job( + self.id, + polling=TextAnalyticsLROPollingMethod(timeout=polling_interval) + ) + + except HttpResponseError as error: + from ._response_handlers import process_http_response_error + process_http_response_error(error) + +class AnalyzeBatchActionsLROPollingMethod(TextAnalyticsLROPollingMethod): + + @property + def _current_body(self): + from ._generated.v3_1_preview_3.models import JobMetadata + return JobMetadata.deserialize(self._pipeline_response) + + @property + def created_on(self): + if not self._current_body: + return None + return self._current_body.created_date_time @property def expires_on(self): @@ -114,6 +201,12 @@ def expires_on(self): return None return self._current_body.expiration_date_time + @property + def display_name(self): + if not self._current_body: + return None + return self._current_body.display_name + @property def actions_failed_count(self): if not self._current_body: @@ -150,20 +243,21 @@ def id(self): return None return self._current_body.job_id + class AnalyzeBatchActionsLROPoller(LROPoller): @property def created_on(self): return self._polling_method.created_on - @property - def display_name(self): - return self._polling_method.display_name - @property def expires_on(self): return self._polling_method.expires_on + @property + def display_name(self): + return self._polling_method.display_name + @property def actions_failed_count(self): return self._polling_method.actions_failed_count @@ -179,6 +273,7 @@ def actions_succeeded_count(self): @property def last_modified_on(self): return self._polling_method.last_modified_on + @property def total_actions_count(self): return self._polling_method.total_actions_count diff --git a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_models.py b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_models.py index 8a7bcb1ed5af..c95585f76ed6 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_models.py +++ b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_models.py @@ -182,9 +182,9 @@ def __repr__(self): )[:1024] -class AnalyzeHealthcareResultItem(DictMixin): +class AnalyzeHealthcareEntitiesResultItem(DictMixin): """ - AnalyzeHealthcareResultItem contains the Healthcare entities and relations from a + AnalyzeHealthcareEntitiesResultItem contains the Healthcare entities and relations from a particular document. :ivar str id: Unique, non-empty document identifier that matches the @@ -204,41 +204,56 @@ class AnalyzeHealthcareResultItem(DictMixin): :vartype statistics: ~azure.ai.textanalytics.TextDocumentStatistics :ivar bool is_error: Boolean check for error item when iterating over list of - results. Always False for an instance of a AnalyzeHealthcareResult. + results. Always False for an instance of a AnalyzeHealthcareEntitiesResultItem. """ def __init__(self, **kwargs): self.id = kwargs.get("id", None) self.entities = kwargs.get("entities", None) - self.relations = kwargs.get("relations", None) self.warnings = kwargs.get("warnings", []) self.statistics = kwargs.get("statistics", None) self.is_error = False + @staticmethod + def _update_related_entities(entities, relations_result): + relation_dict = {} + for r in relations_result: + _, source_idx = _get_indices(r.source) + _, target_idx = _get_indices(r.target) + + if entities[source_idx] not in relation_dict.keys(): + relation_dict[entities[source_idx]] = {} + + if entities[target_idx] not in relation_dict.keys(): + relation_dict[entities[target_idx]] = {} + + if r.bidirectional: + relation_dict[entities[target_idx]][entities[source_idx]] = r.relation_type + + relation_dict[entities[source_idx]][entities[target_idx]] = r.relation_type + + for entity in entities: + if entity in relation_dict.keys(): + entity.related_entities.update(relation_dict[entity]) + @classmethod def _from_generated(cls, healthcare_result): entities = [HealthcareEntity._from_generated(e) for e in healthcare_result.entities] # pylint: disable=protected-access - relations = [] if healthcare_result.relations: - for r in healthcare_result.relations: - _, source_idx = _get_indices(r.source) - _, target_idx = _get_indices(r.target) - relations.append(HealthcareRelation._from_generated(r, entities[source_idx], entities[target_idx])) # pylint: disable=protected-access + cls._update_related_entities(entities, healthcare_result.relations) return cls( id=healthcare_result.id, entities=entities, - relations=relations, warnings=healthcare_result.warnings, statistics=healthcare_result.statistics ) def __repr__(self): - return "AnalyzeHealthcareResultItem(id={}, entities={}, relations={}, warnings={}, statistics={}, \ + return "AnalyzeHealthcareEntitiesResultItem(id={}, entities={}, warnings={}, statistics={}, \ is_error={})".format( self.id, self.entities, - self.relations, self.warnings, self.statistics, self.is_error @@ -406,9 +421,9 @@ class HealthcareEntity(DictMixin): This value depends on the value of the `string_index_type` parameter specified in the original request, which is UnicodeCodePoints by default. :ivar float confidence_score: Confidence score between 0 and 1 of the extracted - entity. - :ivar links: A collection of entity references in known data sources. - :vartype links: list[~azure.ai.textanalytics.HealthcareEntityLink] + entity. + :ivar data_sources: A collection of entity references in known data sources. + :vartype data_sources: list[~azure.ai.textanalytics.HealthcareEntityDataSource] """ def __init__(self, **kwargs): @@ -418,7 +433,8 @@ def __init__(self, **kwargs): self.length = kwargs.get("length", None) self.offset = kwargs.get("offset", None) self.confidence_score = kwargs.get("confidence_score", None) - self.links = kwargs.get("links", []) + self.data_sources = kwargs.get("data_sources", []) + self.related_entities = {} @classmethod def _from_generated(cls, healthcare_entity): @@ -429,76 +445,42 @@ def _from_generated(cls, healthcare_entity): length=healthcare_entity.length, offset=healthcare_entity.offset, confidence_score=healthcare_entity.confidence_score, - links=[ - HealthcareEntityLink(id=l.id, data_source=l.data_source) for l in healthcare_entity.links + data_sources=[ + HealthcareEntityDataSource(entity_id=l.id, name=l.data_source) for l in healthcare_entity.links ] if healthcare_entity.links else None ) + def __hash__(self): + return hash(repr(self)) + def __repr__(self): - return "HealthcareEntity(text={}, category={}, subcategory={}, length={}, offset={}, "\ - "confidence_score={}, links={})".format( + return "HealthcareEntity(text={}, category={}, subcategory={}, length={}, offset={}, confidence_score={}, "\ + "data_sources={}, related_entities={})".format( self.text, self.category, self.subcategory, self.length, self.offset, self.confidence_score, - repr(self.links) + repr(self.data_sources), + repr(self.related_entities) )[:1024] -class HealthcareRelation(DictMixin): - """ - HealthcareRelation contains information describing a relationship between two entities found in text. - - :ivar str type: The type of relation, such as DosageOfMedication or FrequencyOfMedication, etc. - :ivar bool is_bidirectional: Boolean value indicating that the relationship between the two entities is - bidirectional. If true the relation between the entities is bidirectional, otherwise directionality - is source to target. - :ivar source: A reference to an extracted Healthcare entity representing the source of the relation. - :vartype source: ~azure.ai.textanalytics.HealthcareEntity - :ivar target: A reference to an extracted Healthcare entity representing the target of the relation. - :vartype target: ~azure.ai.textanalytics.HealthcareEntity +class HealthcareEntityDataSource(DictMixin): """ + HealthcareEntityDataSource contains information representing an entity reference in a known data source. - def __init__(self, **kwargs): - self.relation_type = kwargs.get("relation_type", None) - self.is_bidirectional = kwargs.get("is_bidirectional", None) - self.source = kwargs.get("source", None) - self.target = kwargs.get("target", None) - - @classmethod - def _from_generated(cls, healthcare_relation, source_entity, target_entity): - return cls( - relation_type=healthcare_relation.relation_type, - is_bidirectional=healthcare_relation.bidirectional, - source=source_entity, - target=target_entity - ) - - def __repr__(self): - return "HealthcareRelation(relation_type={}, is_bidirectional={}, source={}, target={})".format( - self.relation_type, - self.is_bidirectional, - repr(self.source), - repr(self.target) - )[:1024] - - -class HealthcareEntityLink(DictMixin): - """ - HealthcareEntityLink contains information representing an entity reference in a known data source. - - :ivar str id: ID of the entity in the given source catalog. - :ivar str data_source: The entity catalog from where the entity was identified, such as UMLS, CHV, MSH, etc. + :ivar str entity_id: ID of the entity in the given source catalog. + :ivar str name: The name of the entity catalog from where the entity was identified, such as UMLS, CHV, MSH, etc. """ def __init__(self, **kwargs): - self.id = kwargs.get("id", None) - self.data_source = kwargs.get("data_source", None) + self.entity_id = kwargs.get("entity_id", None) + self.name = kwargs.get("name", None) def __repr__(self): - return "HealthcareEntityLink(id={}, data_source={})".format(self.id, self.data_source)[:1024] + return "HealthcareEntityDataSource(entity_id={}, name={})".format(self.entity_id, self.name)[:1024] class TextAnalyticsError(DictMixin): diff --git a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_paging.py b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_paging.py index 6072d2d657d9..e9aa479ac44a 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_paging.py +++ b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_paging.py @@ -7,11 +7,11 @@ from azure.core.paging import ItemPaged -class AnalyzeHealthcareResult(ItemPaged): +class AnalyzeHealthcareEntitiesResult(ItemPaged): def __init__(self, *args, **kwargs): self.model_version = kwargs.pop('model_version') self.statistics = kwargs.pop('statistics') - super(AnalyzeHealthcareResult, self).__init__(*args, **kwargs) + super(AnalyzeHealthcareEntitiesResult, self).__init__(*args, **kwargs) class AnalyzeResult(ItemPaged): diff --git a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_response_handlers.py b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_response_handlers.py index 9f3bad15b20c..5ee09d08fff6 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_response_handlers.py +++ b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_response_handlers.py @@ -30,7 +30,7 @@ TextAnalyticsWarning, RecognizePiiEntitiesResult, PiiEntity, - AnalyzeHealthcareResultItem, + AnalyzeHealthcareEntitiesResultItem, AnalyzeBatchActionsResult, RequestStatistics, AnalyzeBatchActionsType, @@ -38,7 +38,7 @@ TextDocumentBatchStatistics, _get_indices, ) -from ._paging import AnalyzeHealthcareResult, AnalyzeResult +from ._paging import AnalyzeHealthcareEntitiesResult, AnalyzeResult class CSODataV4Format(ODataV4Format): @@ -192,7 +192,7 @@ def pii_entities_result(entity, results, *args, **kwargs): # pylint: disable=un @prepare_result def healthcare_result(health_result, results, *args, **kwargs): # pylint: disable=unused-argument - return AnalyzeHealthcareResultItem._from_generated(health_result) # pylint: disable=protected-access + return AnalyzeHealthcareEntitiesResultItem._from_generated(health_result) # pylint: disable=protected-access def healthcare_extract_page_data(doc_id_order, obj, response_headers, health_job_state): # pylint: disable=unused-argument @@ -302,7 +302,7 @@ def lro_get_next_page(lro_status_callback, first_page, continuation_token, show_ def healthcare_paged_result(doc_id_order, health_status_callback, _, obj, response_headers, show_stats=False): # pylint: disable=unused-argument - return AnalyzeHealthcareResult( + return AnalyzeHealthcareEntitiesResult( functools.partial(lro_get_next_page, health_status_callback, obj, show_stats=show_stats), functools.partial(healthcare_extract_page_data, doc_id_order, obj, response_headers), model_version=obj.results.model_version, diff --git a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_response_handlers_async.py b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_response_handlers_async.py index cb9d23fe7de2..7874a54d45ef 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_response_handlers_async.py +++ b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_response_handlers_async.py @@ -10,7 +10,10 @@ from azure.core.async_paging import AsyncList from ._models import RequestStatistics, TextDocumentBatchStatistics -from ._async_paging import AnalyzeHealthcareResultAsync, AnalyzeResultAsync +from ._async_paging import ( + AnalyzeHealthcareEntitiesResultAsync, + AnalyzeResultAsync +) from ._response_handlers import healthcare_result, get_iter_items @@ -38,7 +41,7 @@ async def lro_get_next_page_async(lro_status_callback, first_page, continuation_ def healthcare_paged_result(doc_id_order, health_status_callback, response, obj, response_headers, show_stats=False): # pylint: disable=unused-argument - return AnalyzeHealthcareResultAsync( + return AnalyzeHealthcareEntitiesResultAsync( functools.partial(lro_get_next_page_async, health_status_callback, obj, show_stats=show_stats), functools.partial(healthcare_extract_page_data_async, doc_id_order, obj, response_headers), model_version=obj.results.model_version, diff --git a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_text_analytics_client.py b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_text_analytics_client.py index 4eeb34cc9564..cd19383489e9 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_text_analytics_client.py +++ b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/_text_analytics_client.py @@ -13,7 +13,6 @@ TYPE_CHECKING, ) from functools import partial -from six.moves.urllib.parse import urlparse from azure.core.paging import ItemPaged from azure.core.polling import LROPoller from azure.core.tracing.decorator import distributed_trace @@ -37,8 +36,9 @@ from ._lro import ( TextAnalyticsOperationResourcePolling, - TextAnalyticsLROPollingMethod, AnalyzeBatchActionsLROPollingMethod, + AnalyzeHealthcareEntitiesLROPollingMethod, + AnalyzeHealthcareEntitiesLROPoller ) if TYPE_CHECKING: @@ -56,7 +56,7 @@ RecognizeEntitiesAction, RecognizePiiEntitiesAction, ExtractKeyPhrasesAction, - AnalyzeHealthcareResultItem, + AnalyzeHealthcareEntitiesResultItem, AnalyzeBatchActionsResult, ) @@ -447,11 +447,11 @@ def _healthcare_result_callback(self, doc_id_order, raw_response, _, headers, sh ) @distributed_trace - def begin_analyze_healthcare( # type: ignore + def begin_analyze_healthcare_entities( # type: ignore self, documents, # type: Union[List[str], List[TextDocumentInput], List[Dict[str, str]]] **kwargs # type: Any - ): # type: (...) -> LROPoller[ItemPaged[AnalyzeHealthcareResultItem]] + ): # type: (...) -> AnalyzeHealthcareEntitiesLROPoller """Analyze healthcare entities and identify relationships between these entities in a batch of documents. Entities are associated with references that can be found in existing knowledge bases, @@ -478,8 +478,8 @@ def begin_analyze_healthcare( # type: ignore :keyword int polling_interval: Waiting time between two polls for LRO operations if no Retry-After header is present. Defaults to 5 seconds. :keyword str continuation_token: A continuation token to restart a poller from a saved state. - :return: An instance of an LROPoller. Call `result()` on the poller - object to return a list[:class:`~azure.ai.textanalytics.AnalyzeHealthcareResultItem`]. + :return: An instance of an AnalyzeHealthcareEntitiesLROPoller. Call `result()` on the this + object to return a list[:class:`~azure.ai.textanalytics.AnalyzeHealthcareEntitiesResultItem`]. :raises ~azure.core.exceptions.HttpResponseError or TypeError or ValueError or NotImplementedError: .. admonition:: Example: @@ -508,7 +508,8 @@ def begin_analyze_healthcare( # type: ignore model_version=model_version, string_index_type=string_index_type, cls=kwargs.pop("cls", partial(self._healthcare_result_callback, doc_id_order, show_stats=show_stats)), - polling=TextAnalyticsLROPollingMethod( + polling=AnalyzeHealthcareEntitiesLROPollingMethod( + text_analytics_client=self._client, timeout=polling_interval, lro_algorithms=[ TextAnalyticsOperationResourcePolling(show_stats=show_stats) @@ -521,49 +522,14 @@ def begin_analyze_healthcare( # type: ignore except ValueError as error: if "API version v3.0 does not have operation 'begin_health'" in str(error): raise ValueError( - "'begin_analyze_healthcare' endpoint is only available for API version v3.1-preview.3" + "'begin_analyze_healthcare_entities' method is only available for API version \ + v3.1-preview.3 and up." ) raise error except HttpResponseError as error: process_http_response_error(error) - def begin_cancel_analyze_healthcare( # type: ignore - self, - poller, # type: LROPoller[ItemPaged[AnalyzeHealthcareResultItem]] - **kwargs - ): - # type: (...) -> LROPoller[None] - """Cancel an existing health operation. - - :param poller: The LRO poller object associated with the health operation. - :return: An instance of an LROPoller that returns None. - :rtype: ~azure.core.polling.LROPoller[None] - :raises ~azure.core.exceptions.HttpResponseError or TypeError or ValueError or NotImplementedError: - - .. admonition:: Example: - - .. literalinclude:: ../samples/sample_health_with_cancellation.py - :start-after: [START health_with_cancellation] - :end-before: [END health_with_cancellation] - :language: python - :dedent: 8 - :caption: Cancel an existing health operation. - """ - polling_interval = kwargs.pop("polling_interval", 5) - initial_response = getattr(poller._polling_method, "_initial_response") # pylint: disable=protected-access - operation_location = initial_response.http_response.headers["Operation-Location"] - - job_id = urlparse(operation_location).path.split("/")[-1] - - try: - return self._client.begin_cancel_health_job( - job_id, - polling=TextAnalyticsLROPollingMethod(timeout=polling_interval) - ) - - except HttpResponseError as error: - process_http_response_error(error) @distributed_trace def extract_key_phrases( # type: ignore @@ -662,6 +628,9 @@ def analyze_sentiment( # type: ignore :class:`~azure.ai.textanalytics.SentenceSentiment` objects will have property `mined_opinions` containing the result of this analysis. Only available for API version v3.1-preview and up. + :keyword str string_index_type: Specifies the method used to interpret string offsets. Possible values are + 'UnicodeCodePoint', 'TextElements_v8', or 'Utf16CodeUnit'. The default value is 'UnicodeCodePoint'. + Only available for API version v3.1-preview and up. :keyword str language: The 2 letter ISO 639-1 representation of language for the entire batch. For example, use "en" for English; "es" for Spanish etc. If not set, uses "en" for English as default. Per-document language will diff --git a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/aio/_text_analytics_client_async.py b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/aio/_text_analytics_client_async.py index fd93203a9956..44d4ee020c65 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/aio/_text_analytics_client_async.py +++ b/sdk/textanalytics/azure-ai-textanalytics/azure/ai/textanalytics/aio/_text_analytics_client_async.py @@ -13,8 +13,8 @@ TYPE_CHECKING ) from functools import partial -from azure.core.async_paging import AsyncItemPaged from azure.core.polling import AsyncLROPoller +from azure.core.async_paging import AsyncItemPaged from azure.core.tracing.decorator_async import distributed_trace_async from azure.core.exceptions import HttpResponseError from ._base_client_async import AsyncTextAnalyticsClientBase @@ -40,7 +40,6 @@ AnalyzeSentimentResult, DocumentError, RecognizePiiEntitiesResult, - AnalyzeHealthcareResultItem, RecognizeEntitiesAction, RecognizePiiEntitiesAction, ExtractKeyPhrasesAction, @@ -48,7 +47,11 @@ AnalyzeBatchActionsType, ) from .._lro import TextAnalyticsOperationResourcePolling -from .._async_lro import AsyncAnalyzeBatchActionsLROPollingMethod, TextAnalyticsAsyncLROPollingMethod +from .._async_lro import ( + AnalyzeHealthcareEntitiesAsyncLROPollingMethod, + AnalyzeHealthcareEntitiesAsyncLROPoller, + AsyncAnalyzeBatchActionsLROPollingMethod +) if TYPE_CHECKING: from azure.core.credentials_async import AsyncTokenCredential @@ -599,11 +602,11 @@ def _healthcare_result_callback(self, doc_id_order, raw_response, _, headers, sh ) @distributed_trace_async - async def begin_analyze_healthcare( # type: ignore + async def begin_analyze_healthcare_entities( # type: ignore self, documents, # type: Union[List[str], List[TextDocumentInput], List[Dict[str, str]]] **kwargs # type: Any - ): # type: (...) -> AsyncLROPoller[AsyncItemPaged[AnalyzeHealthcareResultItem]] + ): # type: (...) -> AnalyzeHealthcareEntitiesAsyncLROPoller """Analyze healthcare entities and identify relationships between these entities in a batch of documents. Entities are associated with references that can be found in existing knowledge bases, @@ -629,7 +632,7 @@ async def begin_analyze_healthcare( # type: ignore :keyword int polling_interval: Waiting time between two polls for LRO operations if no Retry-After header is present. Defaults to 5 seconds. :keyword str continuation_token: A continuation token to restart a poller from a saved state. - :return: An instance of an AsyncLROPoller. Call `result()` on the poller + :return: An instance of an AnalyzeHealthcareEntitiesAsyncLROPoller. Call `result()` on the poller object to return a list[:class:`~azure.ai.textanalytics.AnalyzeHealthcareResultItem`]. :raises ~azure.core.exceptions.HttpResponseError or TypeError or ValueError or NotImplementedError: @@ -659,7 +662,8 @@ async def begin_analyze_healthcare( # type: ignore model_version=model_version, string_index_type=string_index_type, cls=kwargs.pop("cls", partial(self._healthcare_result_callback, doc_id_order, show_stats=show_stats)), - polling=TextAnalyticsAsyncLROPollingMethod( + polling=AnalyzeHealthcareEntitiesAsyncLROPollingMethod( + text_analytics_client=self._client, timeout=polling_interval, lro_algorithms=[ TextAnalyticsOperationResourcePolling(show_stats=show_stats) @@ -672,52 +676,13 @@ async def begin_analyze_healthcare( # type: ignore except ValueError as error: if "API version v3.0 does not have operation 'begin_health'" in str(error): raise ValueError( - "'begin_analyze_healthcare' endpoint is only available for API version v3.1-preview and up" + "'begin_analyze_healthcare_entities' endpoint is only available for API version v3.1-preview and up" ) raise error except HttpResponseError as error: process_http_response_error(error) - async def begin_cancel_analyze_healthcare( # type: ignore - self, - poller, # type: AsyncLROPoller[AsyncItemPaged[AnalyzeHealthcareResultItem]] - **kwargs - ): - # type: (...) -> AsyncLROPoller[None] - """Cancel an existing health operation. - - :param poller: The LRO poller object associated with the health operation. - :return: An instance of an LROPoller that returns None. - :rtype: ~azure.core.polling.LROPoller[None] - :raises ~azure.core.exceptions.HttpResponseError or TypeError or ValueError or NotImplementedError: - - .. admonition:: Example: - - .. literalinclude:: ../samples/async_samples/sample_health_with_cancellation_async.py - :start-after: [START health_with_cancellation_async] - :end-before: [END health_with_cancellation_async] - :language: python - :dedent: 8 - :caption: Cancel an existing health operation. - """ - polling_interval = kwargs.pop("polling_interval", 5) # pylint: disable=protected-access - - initial_response = getattr(poller._polling_method, "_initial_response") # pylint: disable=protected-access - operation_location = initial_response.http_response.headers["Operation-Location"] - - from urllib.parse import urlparse - job_id = urlparse(operation_location).path.split("/")[-1] - - try: - return await self._client.begin_cancel_health_job( - job_id, - polling=TextAnalyticsAsyncLROPollingMethod(timeout=polling_interval) - ) - - except HttpResponseError as error: - process_http_response_error(error) - def _analyze_result_callback(self, doc_id_order, task_order, raw_response, _, headers, show_stats=False): analyze_result = self._deserialize( self._client.models(api_version="v3.1-preview.3").AnalyzeJobState, diff --git a/sdk/textanalytics/azure-ai-textanalytics/samples/README.md b/sdk/textanalytics/azure-ai-textanalytics/samples/README.md index 1f976af86ab7..5746a4ff7e55 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/samples/README.md +++ b/sdk/textanalytics/azure-ai-textanalytics/samples/README.md @@ -28,7 +28,7 @@ These sample programs show common scenarios for the Text Analytics client's offe |[sample_extract_key_phrases.py][extract_key_phrases] and [sample_extract_key_phrases_async.py][extract_key_phrases_async]|Extract key phrases from documents| |[sample_analyze_sentiment.py][analyze_sentiment] and [sample_analyze_sentiment_async.py][analyze_sentiment_async]|Analyze the sentiment of documents| |[sample_alternative_document_input.py][sample_alternative_document_input] and [sample_alternative_document_input_async.py][sample_alternative_document_input_async]|Pass documents to an endpoint using dicts| -|[sample_analyze_healthcare.py][analyze_healthcare_sample] and [sample_analyze_healthcare_async.py][analyze_healthcare_sample_async]|Analyze healthcare entities| +|[sample_analyze_healthcare_entities.py][analyze_healthcare_entities_sample] and [sample_analyze_healthcare_entities_async.py][analyze_healthcare_entities_sample_async]|Analyze healthcare entities| |[sample_analyze_batch_actions.py][analyze_sample] and [sample_analyze_batch_actions_async.py][analyze_sample_async]|Batch multiple analyses together in a single request| ## Prerequisites @@ -91,8 +91,8 @@ what you can do with the Azure Text Analytics client library. [sample_alternative_document_input_async]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_alternative_document_input_async.py [sample_analyze_sentiment_with_opinion_mining]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/textanalytics/azure-ai-textanalytics/samples/sample_analyze_sentiment_with_opinion_mining.py [sample_analyze_sentiment_with_opinion_mining_async]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_analyze_sentiment_with_opinion_mining_async.py -[analyze_healthcare_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/textanalytics/azure-ai-textanalytics/samples/sample_analyze_healthcare.py -[analyze_healthcare_sample_async]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_analyze_healthcare_async.py +[analyze_healthcare_entities_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/textanalytics/azure-ai-textanalytics/samples/sample_analyze_healthcare_entities.py +[analyze_healthcare_entities_sample_async]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_analyze_healthcare_entities_async.py [analyze_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/textanalytics/azure-ai-textanalytics/samples/sample_analyze_batch_actions.py [analyze_sample_async]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_analyze_batch_actions_async.py [pip]: https://pypi.org/project/pip/ diff --git a/sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_analyze_healthcare_async.py b/sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_analyze_healthcare_entities_async.py similarity index 65% rename from sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_analyze_healthcare_async.py rename to sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_analyze_healthcare_entities_async.py index 90647109c171..550547608591 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_analyze_healthcare_async.py +++ b/sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_analyze_healthcare_entities_async.py @@ -7,7 +7,7 @@ # -------------------------------------------------------------------------- """ -FILE: sample_analyze_healthcare_async.py +FILE: sample_analyze_healthcare_entities_async.py DESCRIPTION: This sample demonstrates how to detect healthcare entities in a batch of documents. @@ -15,7 +15,7 @@ data source. Relations between entities will also be included in the response. USAGE: - python sample_analyze_healthcare_async.py + python sample_analyze_healthcare_entities_async.py Set the environment variables with your own values before running the sample: 1) AZURE_TEXT_ANALYTICS_ENDPOINT - the endpoint to your Cognitive Services resource. @@ -27,10 +27,10 @@ import asyncio -class AnalyzeHealthcareSampleAsync(object): +class AnalyzeHealthcareEntitiesSampleAsync(object): - async def analyze_healthcare_async(self): - # [START analyze_healthcare_async] + async def analyze_healthcare_entities_async(self): + # [START analyze_healthcare_entities_async] from azure.core.credentials import AzureKeyCredential from azure.ai.textanalytics.aio import TextAnalyticsClient @@ -47,11 +47,11 @@ async def analyze_healthcare_async(self): ] async with text_analytics_client: - poller = await text_analytics_client.begin_analyze_healthcare(documents) + poller = await text_analytics_client.begin_analyze_healthcare_entities(documents) result = await poller.result() docs = [doc async for doc in result if not doc.is_error] - print("Results of Healthcare Analysis:") + print("Results of Healthcare Entities Analysis:") for idx, doc in enumerate(docs): print("Document text: {}\n".format(documents[idx])) for entity in doc.entities: @@ -60,25 +60,24 @@ async def analyze_healthcare_async(self): print("...Subcategory: {}".format(entity.subcategory)) print("...Offset: {}".format(entity.offset)) print("...Confidence score: {}".format(entity.confidence_score)) - if entity.links is not None: - print("...Links:") - for link in entity.links: - print("......ID: {}".format(link.id)) - print("......Data source: {}".format(link.data_source)) - for relation in doc.relations: - print("Relation:") - print("...Source: {}".format(relation.source.text)) - print("...Target: {}".format(relation.target.text)) - print("...Type: {}".format(relation.relation_type)) - print("...Bidirectional: {}".format(relation.is_bidirectional)) + if entity.data_sources is not None: + print("...Data Sources:") + for data_source in entity.data_sources: + print("......Entity ID: {}".format(data_source.entity_id)) + print("......Name: {}".format(data_source.name)) + if len(entity.related_entities) > 0: + print("...Related Entities:") + for related_entity, relation_type in entity.related_entities.items(): + print("......Entity Text: {}".format(related_entity.text)) + print("......Relation Type: {}".format(relation_type)) print("------------------------------------------") - # [END analyze_healthcare_async] + # [END analyze_healthcare_entities_async] async def main(): - sample = AnalyzeHealthcareSampleAsync() - await sample.analyze_healthcare_async() + sample = AnalyzeHealthcareEntitiesSampleAsync() + await sample.analyze_healthcare_entities_async() if __name__ == '__main__': diff --git a/sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_health_with_cancellation_async.py b/sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_analyze_healthcare_entities_with_cancellation_async.py similarity index 74% rename from sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_health_with_cancellation_async.py rename to sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_analyze_healthcare_entities_with_cancellation_async.py index 9fb1dc9e7aef..43cef0ae5553 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_health_with_cancellation_async.py +++ b/sdk/textanalytics/azure-ai-textanalytics/samples/async_samples/sample_analyze_healthcare_entities_with_cancellation_async.py @@ -7,7 +7,7 @@ # -------------------------------------------------------------------------- """ -FILE: sample_health_with_cancellation.py +FILE: sample_analyze_healthcare_entities_with_cancellation.py DESCRIPTION: This sample demonstrates how to cancel a Health job after it's been started. @@ -17,7 +17,7 @@ USAGE: - python sample_health_with_cancellation.py + python sample_analyze_healthcare_entities_with_cancellation.py Set the environment variables with your own values before running the sample: 1) AZURE_TEXT_ANALYTICS_ENDPOINT - the endpoint to your Cognitive Services resource. @@ -27,11 +27,13 @@ import os import asyncio +from azure.core.exceptions import HttpResponseError -class HealthWithCancellationSampleAsync(object): - async def health_with_cancellation_async(self): - # [START health_with_cancellation_async] +class AnalyzeHealthcareEntitiesWithCancellationSampleAsync(object): + + async def analyze_healthcare_entities_with_cancellation_async(self): + # [START analyze_healthcare_entities_with_cancellation_async] from azure.core.credentials import AzureKeyCredential from azure.ai.textanalytics.aio import TextAnalyticsClient @@ -60,17 +62,25 @@ async def health_with_cancellation_async(self): ] async with text_analytics_client: - poller = await text_analytics_client.begin_analyze_healthcare(documents) - poller = await text_analytics_client.begin_cancel_analyze_healthcare(poller) + poller = await text_analytics_client.begin_analyze_healthcare_entities(documents) + + try: + cancellation_poller = await poller.cancel() + await cancellation_poller.wait() + + except HttpResponseError as e: + # If the operation has already reached a terminal state it cannot be cancelled. + print(e) - await poller.wait() + else: + print("Healthcare entities analysis was successfully cancelled.") - # [END health_with_cancellation_async] + # [END analyze_healthcare_entities_with_cancellation_async] async def main(): - sample = HealthWithCancellationSampleAsync() - await sample.health_with_cancellation_async() + sample = AnalyzeHealthcareEntitiesWithCancellationSampleAsync() + await sample.analyze_healthcare_entities_with_cancellation_async() if __name__ == '__main__': diff --git a/sdk/textanalytics/azure-ai-textanalytics/samples/sample_analyze_healthcare.py b/sdk/textanalytics/azure-ai-textanalytics/samples/sample_analyze_healthcare_entities.py similarity index 63% rename from sdk/textanalytics/azure-ai-textanalytics/samples/sample_analyze_healthcare.py rename to sdk/textanalytics/azure-ai-textanalytics/samples/sample_analyze_healthcare_entities.py index 6b73431d86e5..7755438c1180 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/samples/sample_analyze_healthcare.py +++ b/sdk/textanalytics/azure-ai-textanalytics/samples/sample_analyze_healthcare_entities.py @@ -7,7 +7,7 @@ # -------------------------------------------------------------------------- """ -FILE: sample_analyze_healthcare.py +FILE: sample_analyze_healthcare_entities.py DESCRIPTION: This sample demonstrates how to detect healthcare entities in a batch of documents. @@ -15,7 +15,7 @@ data source. Relations between entities will also be included in the response. USAGE: - python sample_analyze_healthcare.py + python sample_analyze_healthcare_entities.py Set the environment variables with your own values before running the sample: 1) AZURE_TEXT_ANALYTICS_ENDPOINT - the endpoint to your Cognitive Services resource. @@ -26,10 +26,10 @@ import os -class AnalyzeHealthcareSample(object): +class AnalyzeHealthcareEntitiesSample(object): - def analyze_healthcare(self): - # [START analyze_healthcare] + def analyze_healthcare_entities(self): + # [START analyze_healthcare_entities] from azure.core.credentials import AzureKeyCredential from azure.ai.textanalytics import TextAnalyticsClient @@ -45,12 +45,12 @@ def analyze_healthcare(self): "Subject is taking 100mg of ibuprofen twice daily" ] - poller = text_analytics_client.begin_analyze_healthcare(documents, show_stats=True) + poller = text_analytics_client.begin_analyze_healthcare_entities(documents, show_stats=True) result = poller.result() docs = [doc for doc in result if not doc.is_error] - print("Results of Healthcare Analysis:") + print("Results of Healthcare Entities Analysis:") for idx, doc in enumerate(docs): for entity in doc.entities: print("Entity: {}".format(entity.text)) @@ -58,21 +58,20 @@ def analyze_healthcare(self): print("...Subcategory: {}".format(entity.subcategory)) print("...Offset: {}".format(entity.offset)) print("...Confidence score: {}".format(entity.confidence_score)) - if entity.links is not None: - print("...Links:") - for link in entity.links: - print("......ID: {}".format(link.id)) - print("......Data source: {}".format(link.data_source)) - for relation in doc.relations: - print("Relation:") - print("...Source: {}".format(relation.source.text)) - print("...Target: {}".format(relation.target.text)) - print("...Type: {}".format(relation.relation_type)) - print("...Bidirectional: {}".format(relation.is_bidirectional)) + if entity.data_sources is not None: + print("...Data Sources:") + for data_source in entity.data_sources: + print("......Entity ID: {}".format(data_source.entity_id)) + print("......Name: {}".format(data_source.name)) + if len(entity.related_entities) > 0: + print("...Related Entities:") + for related_entity, relation_type in entity.related_entities.items(): + print("......Entity Text: {}".format(related_entity.text)) + print("......Relation Type: {}".format(relation_type)) print("------------------------------------------") - # [END analyze_health] + # [END analyze_healthcare_entities] if __name__ == "__main__": - sample = AnalyzeHealthcareSample() - sample.analyze_healthcare() + sample = AnalyzeHealthcareEntitiesSample() + sample.analyze_healthcare_entities() diff --git a/sdk/textanalytics/azure-ai-textanalytics/samples/sample_health_with_cancellation.py b/sdk/textanalytics/azure-ai-textanalytics/samples/sample_analyze_healthcare_entities_with_cancellation.py similarity index 71% rename from sdk/textanalytics/azure-ai-textanalytics/samples/sample_health_with_cancellation.py rename to sdk/textanalytics/azure-ai-textanalytics/samples/sample_analyze_healthcare_entities_with_cancellation.py index 80e5ffda50ed..37d856a174f8 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/samples/sample_health_with_cancellation.py +++ b/sdk/textanalytics/azure-ai-textanalytics/samples/sample_analyze_healthcare_entities_with_cancellation.py @@ -7,16 +7,16 @@ # -------------------------------------------------------------------------- """ -FILE: sample_health_with_cancellation.py +FILE: sample_analyze_healthcare_entities_with_cancellation.py DESCRIPTION: - This sample demonstrates how to cancel a Health job after it's been started. + This sample demonstrates how to cancel a Healthcare Entities Analysis job after it's been started. Since the Health API is currently only available in a gated preview, you need to have your subscription on the service's allow list. More information here: https://docs.microsoft.com/azure/cognitive-services/text-analytics/how-tos/text-analytics-for-health?tabs=ner#request-access-to-the-public-preview. USAGE: - python sample_health_with_cancellation.py + python sample_analyze_healthcare_entities_with_cancellation.py Set the environment variables with your own values before running the sample: 1) AZURE_TEXT_ANALYTICS_ENDPOINT - the endpoint to your Cognitive Services resource. @@ -25,12 +25,13 @@ import os +from azure.core.exceptions import HttpResponseError -class HealthWithCancellationSample(object): +class AnalyzeHealthcareEntitiesWithCancellationSample(object): - def health_with_cancellation(self): - # [START health_with_cancellation] + def analyze_healthcare_entities_with_cancellation(self): + # [START analyze_healthcare_entities_with_cancellation] from azure.core.credentials import AzureKeyCredential from azure.ai.textanalytics import TextAnalyticsClient @@ -58,15 +59,24 @@ def health_with_cancellation(self): for revascularization with open heart surgery." ] - poller = text_analytics_client.begin_analyze_healthcare(documents) - text_analytics_client.begin_cancel_analyze_healthcare(poller) - poller.wait() + poller = text_analytics_client.begin_analyze_healthcare_entities(documents) + + try: + cancellation_poller = poller.cancel() + cancellation_poller.wait() + + except HttpResponseError as e: + # If the operation has already reached a terminal state it cannot be cancelled. + print(e) - # [END health_with_cancellation] + else: + print("Healthcare entities analysis was successfully cancelled.") + + # [END analyze_healthcare_entities_with_cancellation] if __name__ == "__main__": - sample = HealthWithCancellationSample() - sample.health_with_cancellation() + sample = AnalyzeHealthcareEntitiesWithCancellationSample() + sample.analyze_healthcare_entities_with_cancellation() diff --git a/sdk/textanalytics/azure-ai-textanalytics/tests/recordings/test_analyze_healthcare.test_bidirectional_relation_type.yaml b/sdk/textanalytics/azure-ai-textanalytics/tests/recordings/test_analyze_healthcare.test_bidirectional_relation_type.yaml new file mode 100644 index 000000000000..16740815fe3f --- /dev/null +++ b/sdk/textanalytics/azure-ai-textanalytics/tests/recordings/test_analyze_healthcare.test_bidirectional_relation_type.yaml @@ -0,0 +1,78 @@ +interactions: +- request: + body: '{"documents": [{"id": "0", "text": "The patient was diagnosed with Parkinsons + Disease (PD)", "language": "en"}]}' + headers: + Accept: + - application/json, text/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '112' + Content-Type: + - application/json + User-Agent: + - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.7.5 (Linux-4.4.0-19041-Microsoft-x86_64-with-debian-stretch-sid) + method: POST + uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs?stringIndexType=UnicodeCodePoint + response: + body: + string: '' + headers: + apim-request-id: + - 0deab4b3-99e9-44d8-a1f4-e702b76e99f1 + date: + - Fri, 05 Feb 2021 19:38:16 GMT + operation-location: + - https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/4263098e-aa75-4a36-af10-442824b46987 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + transfer-encoding: + - chunked + x-content-type-options: + - nosniff + x-envoy-upstream-service-time: + - '511' + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.7.5 (Linux-4.4.0-19041-Microsoft-x86_64-with-debian-stretch-sid) + method: GET + uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/4263098e-aa75-4a36-af10-442824b46987 + response: + body: + string: '{"jobId":"4263098e-aa75-4a36-af10-442824b46987","lastUpdateDateTime":"2021-02-05T19:38:19Z","createdDateTime":"2021-02-05T19:38:16Z","expirationDateTime":"2021-02-06T19:38:16Z","status":"succeeded","errors":[],"results":{"documents":[{"id":"0","entities":[{"offset":31,"length":18,"text":"Parkinsons + Disease","category":"Diagnosis","confidenceScore":1.0,"isNegated":false,"links":[{"dataSource":"UMLS","id":"C0030567"},{"dataSource":"AOD","id":"0000006203"},{"dataSource":"BI","id":"BI00554"},{"dataSource":"CCPSS","id":"1018057"},{"dataSource":"CCS","id":"6.2.1"},{"dataSource":"CCSR_10","id":"NVS004"},{"dataSource":"CHV","id":"0000009319"},{"dataSource":"COSTAR","id":"559"},{"dataSource":"CSP","id":"2057-3689"},{"dataSource":"CST","id":"EXTRAPYR + SYND"},{"dataSource":"ICD10","id":"G20"},{"dataSource":"ICD10AM","id":"G20"},{"dataSource":"ICD10CM","id":"G20"},{"dataSource":"ICD9CM","id":"332.0"},{"dataSource":"ICPC2ICD10ENG","id":"MTHU004748"},{"dataSource":"ICPC2P","id":"N87001"},{"dataSource":"LCH_NW","id":"sh85098115"},{"dataSource":"LNC","id":"MTHU020807"},{"dataSource":"MDR","id":"10061536"},{"dataSource":"MEDCIN","id":"32004"},{"dataSource":"MEDLINEPLUS","id":"85"},{"dataSource":"MSH","id":"D010300"},{"dataSource":"NANDA-I","id":"03003"},{"dataSource":"NCI","id":"C26845"},{"dataSource":"NCI_CPTAC","id":"C26845"},{"dataSource":"NCI_NCI-GLOSS","id":"CDR0000044140"},{"dataSource":"OMIM","id":"516000"},{"dataSource":"PSY","id":"36720"},{"dataSource":"QMR","id":"R0121461"},{"dataSource":"RAM","id":"DX353"},{"dataSource":"RCD","id":"F12.."},{"dataSource":"SNM","id":"D-8450"},{"dataSource":"SNMI","id":"DA-21012"},{"dataSource":"SNOMEDCT_US","id":"49049000"},{"dataSource":"WHO","id":"0106"}]},{"offset":51,"length":2,"text":"PD","category":"Diagnosis","confidenceScore":1.0,"isNegated":false,"links":[{"dataSource":"UMLS","id":"C0030567"},{"dataSource":"AOD","id":"0000006203"},{"dataSource":"BI","id":"BI00554"},{"dataSource":"CCPSS","id":"1018057"},{"dataSource":"CCS","id":"6.2.1"},{"dataSource":"CCSR_10","id":"NVS004"},{"dataSource":"CHV","id":"0000009319"},{"dataSource":"COSTAR","id":"559"},{"dataSource":"CSP","id":"2057-3689"},{"dataSource":"CST","id":"EXTRAPYR + SYND"},{"dataSource":"ICD10","id":"G20"},{"dataSource":"ICD10AM","id":"G20"},{"dataSource":"ICD10CM","id":"G20"},{"dataSource":"ICD9CM","id":"332.0"},{"dataSource":"ICPC2ICD10ENG","id":"MTHU004748"},{"dataSource":"ICPC2P","id":"N87001"},{"dataSource":"LCH_NW","id":"sh85098115"},{"dataSource":"LNC","id":"MTHU020807"},{"dataSource":"MDR","id":"10061536"},{"dataSource":"MEDCIN","id":"32004"},{"dataSource":"MEDLINEPLUS","id":"85"},{"dataSource":"MSH","id":"D010300"},{"dataSource":"NANDA-I","id":"03003"},{"dataSource":"NCI","id":"C26845"},{"dataSource":"NCI_CPTAC","id":"C26845"},{"dataSource":"NCI_NCI-GLOSS","id":"CDR0000044140"},{"dataSource":"OMIM","id":"516000"},{"dataSource":"PSY","id":"36720"},{"dataSource":"QMR","id":"R0121461"},{"dataSource":"RAM","id":"DX353"},{"dataSource":"RCD","id":"F12.."},{"dataSource":"SNM","id":"D-8450"},{"dataSource":"SNMI","id":"DA-21012"},{"dataSource":"SNOMEDCT_US","id":"49049000"},{"dataSource":"WHO","id":"0106"}]}],"relations":[{"relationType":"Abbreviation","bidirectional":true,"source":"#/results/documents/0/entities/0","target":"#/results/documents/0/entities/1"}],"warnings":[]}],"errors":[],"modelVersion":"2020-09-03"}}' + headers: + apim-request-id: + - f482ac80-8855-4083-89f3-a937d1a5ac6a + content-type: + - application/json; charset=utf-8 + date: + - Fri, 05 Feb 2021 19:38:22 GMT + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + transfer-encoding: + - chunked + x-content-type-options: + - nosniff + x-envoy-upstream-service-time: + - '385' + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/textanalytics/azure-ai-textanalytics/tests/recordings/test_analyze_healthcare.test_cancellation.yaml b/sdk/textanalytics/azure-ai-textanalytics/tests/recordings/test_analyze_healthcare.test_cancellation.yaml index 740e3b722c4c..c85460340528 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/tests/recordings/test_analyze_healthcare.test_cancellation.yaml +++ b/sdk/textanalytics/azure-ai-textanalytics/tests/recordings/test_analyze_healthcare.test_cancellation.yaml @@ -19,7 +19,7 @@ interactions: Content-Type: - application/json User-Agent: - - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.8.5 (macOS-10.13.6-x86_64-i386-64bit) + - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.7.5 (Linux-4.4.0-19041-Microsoft-x86_64-with-debian-stretch-sid) method: POST uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs?stringIndexType=UnicodeCodePoint response: @@ -27,11 +27,11 @@ interactions: string: '' headers: apim-request-id: - - 619e9fa8-b317-4ebd-988b-d21a73bf03d1 + - f8c5ff83-ddda-42f4-a215-46c95fd0037b date: - - Wed, 27 Jan 2021 02:20:12 GMT + - Fri, 05 Feb 2021 21:32:42 GMT operation-location: - - https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/45e15c14-6956-4856-be0e-a7f411c528a6 + - https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/77d6cdaa-59d5-4b00-9d5e-de56d69faae2 strict-transport-security: - max-age=31536000; includeSubDomains; preload transfer-encoding: @@ -39,7 +39,7 @@ interactions: x-content-type-options: - nosniff x-envoy-upstream-service-time: - - '160' + - '1171' status: code: 202 message: Accepted @@ -47,27 +47,25 @@ interactions: body: null headers: Accept: - - application/json, text/json + - '*/*' Accept-Encoding: - gzip, deflate Connection: - keep-alive - Content-Length: - - '0' User-Agent: - - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.8.5 (macOS-10.13.6-x86_64-i386-64bit) - method: DELETE - uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/45e15c14-6956-4856-be0e-a7f411c528a6 + - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.7.5 (Linux-4.4.0-19041-Microsoft-x86_64-with-debian-stretch-sid) + method: GET + uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/77d6cdaa-59d5-4b00-9d5e-de56d69faae2 response: body: - string: '' + string: '{"jobId":"77d6cdaa-59d5-4b00-9d5e-de56d69faae2","lastUpdateDateTime":"2021-02-05T21:32:42Z","createdDateTime":"2021-02-05T21:32:41Z","expirationDateTime":"2021-02-06T21:32:41Z","status":"notStarted","errors":[]}' headers: apim-request-id: - - 3d756bc6-c864-49e4-bff9-81852f29998c + - 5300efa5-c916-456c-b1fe-5189dd5b4b5d + content-type: + - application/json; charset=utf-8 date: - - Wed, 27 Jan 2021 02:20:12 GMT - operation-location: - - https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/45e15c14-6956-4856-be0e-a7f411c528a6 + - Fri, 05 Feb 2021 21:32:42 GMT strict-transport-security: - max-age=31536000; includeSubDomains; preload transfer-encoding: @@ -75,10 +73,146 @@ interactions: x-content-type-options: - nosniff x-envoy-upstream-service-time: - - '10' + - '547' status: - code: 202 - message: Accepted + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.7.5 (Linux-4.4.0-19041-Microsoft-x86_64-with-debian-stretch-sid) + method: GET + uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/77d6cdaa-59d5-4b00-9d5e-de56d69faae2 + response: + body: + string: '{"jobId":"77d6cdaa-59d5-4b00-9d5e-de56d69faae2","lastUpdateDateTime":"2021-02-05T21:32:43Z","createdDateTime":"2021-02-05T21:32:41Z","expirationDateTime":"2021-02-06T21:32:41Z","status":"running","errors":[]}' + headers: + apim-request-id: + - 4995d355-d5d6-4372-9a8d-a92042b9b176 + content-type: + - application/json; charset=utf-8 + date: + - Fri, 05 Feb 2021 21:32:44 GMT + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + transfer-encoding: + - chunked + x-content-type-options: + - nosniff + x-envoy-upstream-service-time: + - '1391' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.7.5 (Linux-4.4.0-19041-Microsoft-x86_64-with-debian-stretch-sid) + method: GET + uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/77d6cdaa-59d5-4b00-9d5e-de56d69faae2 + response: + body: + string: '{"jobId":"77d6cdaa-59d5-4b00-9d5e-de56d69faae2","lastUpdateDateTime":"2021-02-05T21:32:44Z","createdDateTime":"2021-02-05T21:32:41Z","expirationDateTime":"2021-02-06T21:32:41Z","status":"running","errors":[]}' + headers: + apim-request-id: + - 4e357f67-fdbe-40ae-85b8-f57a878f7604 + content-type: + - application/json; charset=utf-8 + date: + - Fri, 05 Feb 2021 21:32:44 GMT + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + transfer-encoding: + - chunked + x-content-type-options: + - nosniff + x-envoy-upstream-service-time: + - '342' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.7.5 (Linux-4.4.0-19041-Microsoft-x86_64-with-debian-stretch-sid) + method: GET + uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/77d6cdaa-59d5-4b00-9d5e-de56d69faae2 + response: + body: + string: '{"jobId":"77d6cdaa-59d5-4b00-9d5e-de56d69faae2","lastUpdateDateTime":"2021-02-05T21:32:44Z","createdDateTime":"2021-02-05T21:32:41Z","expirationDateTime":"2021-02-06T21:32:41Z","status":"running","errors":[]}' + headers: + apim-request-id: + - 84f00584-4148-4420-8a6a-45653f4fec2e + content-type: + - application/json; charset=utf-8 + date: + - Fri, 05 Feb 2021 21:32:44 GMT + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + transfer-encoding: + - chunked + x-content-type-options: + - nosniff + x-envoy-upstream-service-time: + - '6' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.7.5 (Linux-4.4.0-19041-Microsoft-x86_64-with-debian-stretch-sid) + method: GET + uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/77d6cdaa-59d5-4b00-9d5e-de56d69faae2 + response: + body: + string: '{"jobId":"77d6cdaa-59d5-4b00-9d5e-de56d69faae2","lastUpdateDateTime":"2021-02-05T21:32:44Z","createdDateTime":"2021-02-05T21:32:41Z","expirationDateTime":"2021-02-06T21:32:41Z","status":"running","errors":[]}' + headers: + apim-request-id: + - 385dbc74-49df-4ce3-83a9-5b293c839122 + content-type: + - application/json; charset=utf-8 + date: + - Fri, 05 Feb 2021 21:32:44 GMT + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + transfer-encoding: + - chunked + x-content-type-options: + - nosniff + x-envoy-upstream-service-time: + - '41' + status: + code: 200 + message: OK - request: body: null headers: @@ -89,19 +223,19 @@ interactions: Connection: - keep-alive User-Agent: - - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.8.5 (macOS-10.13.6-x86_64-i386-64bit) + - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.7.5 (Linux-4.4.0-19041-Microsoft-x86_64-with-debian-stretch-sid) method: GET - uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/45e15c14-6956-4856-be0e-a7f411c528a6 + uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/77d6cdaa-59d5-4b00-9d5e-de56d69faae2 response: body: - string: '{"jobId":"45e15c14-6956-4856-be0e-a7f411c528a6","lastUpdateDateTime":"2021-01-27T02:20:12Z","createdDateTime":"2021-01-27T02:20:12Z","expirationDateTime":"2021-01-28T02:20:12Z","status":"cancelled","errors":[]}' + string: '{"jobId":"77d6cdaa-59d5-4b00-9d5e-de56d69faae2","lastUpdateDateTime":"2021-02-05T21:32:44Z","createdDateTime":"2021-02-05T21:32:41Z","expirationDateTime":"2021-02-06T21:32:41Z","status":"running","errors":[]}' headers: apim-request-id: - - 2aee6cc4-0ce3-46e8-8bac-3bd5e3ddf928 + - c0bbb9b4-80ca-4ed9-a2d4-5d52f20fa5d5 content-type: - application/json; charset=utf-8 date: - - Wed, 27 Jan 2021 02:20:17 GMT + - Fri, 05 Feb 2021 21:32:44 GMT strict-transport-security: - max-age=31536000; includeSubDomains; preload transfer-encoding: @@ -109,7 +243,7 @@ interactions: x-content-type-options: - nosniff x-envoy-upstream-service-time: - - '7' + - '6' status: code: 200 message: OK @@ -123,19 +257,19 @@ interactions: Connection: - keep-alive User-Agent: - - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.8.5 (macOS-10.13.6-x86_64-i386-64bit) + - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.7.5 (Linux-4.4.0-19041-Microsoft-x86_64-with-debian-stretch-sid) method: GET - uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/45e15c14-6956-4856-be0e-a7f411c528a6 + uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/77d6cdaa-59d5-4b00-9d5e-de56d69faae2 response: body: - string: '{"jobId":"45e15c14-6956-4856-be0e-a7f411c528a6","lastUpdateDateTime":"2021-01-27T02:20:12Z","createdDateTime":"2021-01-27T02:20:12Z","expirationDateTime":"2021-01-28T02:20:12Z","status":"cancelled","errors":[]}' + string: '{"jobId":"77d6cdaa-59d5-4b00-9d5e-de56d69faae2","lastUpdateDateTime":"2021-02-05T21:32:44Z","createdDateTime":"2021-02-05T21:32:41Z","expirationDateTime":"2021-02-06T21:32:41Z","status":"running","errors":[]}' headers: apim-request-id: - - b5916944-99b5-4c15-b4a8-0d8527264103 + - 02207426-4357-417f-bbbb-527aad7e0ad3 content-type: - application/json; charset=utf-8 date: - - Wed, 27 Jan 2021 02:20:17 GMT + - Fri, 05 Feb 2021 21:32:44 GMT strict-transport-security: - max-age=31536000; includeSubDomains; preload transfer-encoding: @@ -147,4 +281,109 @@ interactions: status: code: 200 message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.7.5 (Linux-4.4.0-19041-Microsoft-x86_64-with-debian-stretch-sid) + method: GET + uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/77d6cdaa-59d5-4b00-9d5e-de56d69faae2 + response: + body: + string: '{"jobId":"77d6cdaa-59d5-4b00-9d5e-de56d69faae2","lastUpdateDateTime":"2021-02-05T21:32:44Z","createdDateTime":"2021-02-05T21:32:41Z","expirationDateTime":"2021-02-06T21:32:41Z","status":"succeeded","errors":[],"results":{"documents":[{"id":"0","entities":[],"relations":[],"warnings":[]},{"id":"1","entities":[],"relations":[],"warnings":[]},{"id":"2","entities":[],"relations":[],"warnings":[]},{"id":"3","entities":[],"relations":[],"warnings":[]},{"id":"4","entities":[],"relations":[],"warnings":[]},{"id":"5","entities":[],"relations":[],"warnings":[]},{"id":"6","entities":[],"relations":[],"warnings":[]},{"id":"7","entities":[],"relations":[],"warnings":[]},{"id":"8","entities":[],"relations":[],"warnings":[]},{"id":"9","entities":[],"relations":[],"warnings":[]}],"errors":[],"modelVersion":"2020-09-03"}}' + headers: + apim-request-id: + - baa887ef-2d48-42f8-8d64-edd63325df84 + content-type: + - application/json; charset=utf-8 + date: + - Fri, 05 Feb 2021 21:32:44 GMT + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + transfer-encoding: + - chunked + x-content-type-options: + - nosniff + x-envoy-upstream-service-time: + - '91' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.7.5 (Linux-4.4.0-19041-Microsoft-x86_64-with-debian-stretch-sid) + method: GET + uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/77d6cdaa-59d5-4b00-9d5e-de56d69faae2 + response: + body: + string: '{"jobId":"77d6cdaa-59d5-4b00-9d5e-de56d69faae2","lastUpdateDateTime":"2021-02-05T21:32:44Z","createdDateTime":"2021-02-05T21:32:41Z","expirationDateTime":"2021-02-06T21:32:41Z","status":"succeeded","errors":[],"results":{"documents":[{"id":"0","entities":[],"relations":[],"warnings":[]},{"id":"1","entities":[],"relations":[],"warnings":[]},{"id":"2","entities":[],"relations":[],"warnings":[]},{"id":"3","entities":[],"relations":[],"warnings":[]},{"id":"4","entities":[],"relations":[],"warnings":[]},{"id":"5","entities":[],"relations":[],"warnings":[]},{"id":"6","entities":[],"relations":[],"warnings":[]},{"id":"7","entities":[],"relations":[],"warnings":[]},{"id":"8","entities":[],"relations":[],"warnings":[]},{"id":"9","entities":[],"relations":[],"warnings":[]}],"errors":[],"modelVersion":"2020-09-03"}}' + headers: + apim-request-id: + - dc33a930-a736-4862-ab01-bd14ec384023 + content-type: + - application/json; charset=utf-8 + date: + - Fri, 05 Feb 2021 21:32:45 GMT + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + transfer-encoding: + - chunked + x-content-type-options: + - nosniff + x-envoy-upstream-service-time: + - '688' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json, text/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.7.5 (Linux-4.4.0-19041-Microsoft-x86_64-with-debian-stretch-sid) + method: DELETE + uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/77d6cdaa-59d5-4b00-9d5e-de56d69faae2 + response: + body: + string: '{"error":{"code":"InvalidRequest","message":"Failed to cancel job with + job id 77d6cdaa-59d5-4b00-9d5e-de56d69faae2 as its already completed."}}' + headers: + apim-request-id: + - e19f269e-d4db-4bce-82f8-f5f863dd722e + content-type: + - application/json; charset=utf-8 + date: + - Fri, 05 Feb 2021 21:32:45 GMT + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + transfer-encoding: + - chunked + x-content-type-options: + - nosniff + x-envoy-upstream-service-time: + - '16' + status: + code: 400 + message: Bad Request version: 1 diff --git a/sdk/textanalytics/azure-ai-textanalytics/tests/recordings/test_analyze_healthcare_async.test_bidirectional_relation_type.yaml b/sdk/textanalytics/azure-ai-textanalytics/tests/recordings/test_analyze_healthcare_async.test_bidirectional_relation_type.yaml new file mode 100644 index 000000000000..ef0da80605d2 --- /dev/null +++ b/sdk/textanalytics/azure-ai-textanalytics/tests/recordings/test_analyze_healthcare_async.test_bidirectional_relation_type.yaml @@ -0,0 +1,56 @@ +interactions: +- request: + body: '{"documents": [{"id": "0", "text": "The patient was diagnosed with Parkinsons + Disease (PD)", "language": "en"}]}' + headers: + Accept: + - application/json, text/json + Content-Length: + - '112' + Content-Type: + - application/json + User-Agent: + - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.7.5 (Linux-4.4.0-19041-Microsoft-x86_64-with-debian-stretch-sid) + method: POST + uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs?stringIndexType=UnicodeCodePoint + response: + body: + string: '' + headers: + apim-request-id: b2df36ca-e02f-4bac-a1b7-7f20cb77de13 + date: Fri, 05 Feb 2021 19:52:18 GMT + operation-location: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/1d60f955-5998-475a-8b65-9e6f123c5e35 + strict-transport-security: max-age=31536000; includeSubDomains; preload + transfer-encoding: chunked + x-content-type-options: nosniff + x-envoy-upstream-service-time: '79' + status: + code: 202 + message: Accepted + url: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs?stringIndexType=UnicodeCodePoint +- request: + body: null + headers: + User-Agent: + - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.7.5 (Linux-4.4.0-19041-Microsoft-x86_64-with-debian-stretch-sid) + method: GET + uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/1d60f955-5998-475a-8b65-9e6f123c5e35 + response: + body: + string: '{"jobId":"1d60f955-5998-475a-8b65-9e6f123c5e35","lastUpdateDateTime":"2021-02-05T19:52:20Z","createdDateTime":"2021-02-05T19:52:19Z","expirationDateTime":"2021-02-06T19:52:19Z","status":"succeeded","errors":[],"results":{"documents":[{"id":"0","entities":[{"offset":31,"length":18,"text":"Parkinsons + Disease","category":"Diagnosis","confidenceScore":1.0,"isNegated":false,"links":[{"dataSource":"UMLS","id":"C0030567"},{"dataSource":"AOD","id":"0000006203"},{"dataSource":"BI","id":"BI00554"},{"dataSource":"CCPSS","id":"1018057"},{"dataSource":"CCS","id":"6.2.1"},{"dataSource":"CCSR_10","id":"NVS004"},{"dataSource":"CHV","id":"0000009319"},{"dataSource":"COSTAR","id":"559"},{"dataSource":"CSP","id":"2057-3689"},{"dataSource":"CST","id":"EXTRAPYR + SYND"},{"dataSource":"ICD10","id":"G20"},{"dataSource":"ICD10AM","id":"G20"},{"dataSource":"ICD10CM","id":"G20"},{"dataSource":"ICD9CM","id":"332.0"},{"dataSource":"ICPC2ICD10ENG","id":"MTHU004748"},{"dataSource":"ICPC2P","id":"N87001"},{"dataSource":"LCH_NW","id":"sh85098115"},{"dataSource":"LNC","id":"MTHU020807"},{"dataSource":"MDR","id":"10061536"},{"dataSource":"MEDCIN","id":"32004"},{"dataSource":"MEDLINEPLUS","id":"85"},{"dataSource":"MSH","id":"D010300"},{"dataSource":"NANDA-I","id":"03003"},{"dataSource":"NCI","id":"C26845"},{"dataSource":"NCI_CPTAC","id":"C26845"},{"dataSource":"NCI_NCI-GLOSS","id":"CDR0000044140"},{"dataSource":"OMIM","id":"516000"},{"dataSource":"PSY","id":"36720"},{"dataSource":"QMR","id":"R0121461"},{"dataSource":"RAM","id":"DX353"},{"dataSource":"RCD","id":"F12.."},{"dataSource":"SNM","id":"D-8450"},{"dataSource":"SNMI","id":"DA-21012"},{"dataSource":"SNOMEDCT_US","id":"49049000"},{"dataSource":"WHO","id":"0106"}]},{"offset":51,"length":2,"text":"PD","category":"Diagnosis","confidenceScore":1.0,"isNegated":false,"links":[{"dataSource":"UMLS","id":"C0030567"},{"dataSource":"AOD","id":"0000006203"},{"dataSource":"BI","id":"BI00554"},{"dataSource":"CCPSS","id":"1018057"},{"dataSource":"CCS","id":"6.2.1"},{"dataSource":"CCSR_10","id":"NVS004"},{"dataSource":"CHV","id":"0000009319"},{"dataSource":"COSTAR","id":"559"},{"dataSource":"CSP","id":"2057-3689"},{"dataSource":"CST","id":"EXTRAPYR + SYND"},{"dataSource":"ICD10","id":"G20"},{"dataSource":"ICD10AM","id":"G20"},{"dataSource":"ICD10CM","id":"G20"},{"dataSource":"ICD9CM","id":"332.0"},{"dataSource":"ICPC2ICD10ENG","id":"MTHU004748"},{"dataSource":"ICPC2P","id":"N87001"},{"dataSource":"LCH_NW","id":"sh85098115"},{"dataSource":"LNC","id":"MTHU020807"},{"dataSource":"MDR","id":"10061536"},{"dataSource":"MEDCIN","id":"32004"},{"dataSource":"MEDLINEPLUS","id":"85"},{"dataSource":"MSH","id":"D010300"},{"dataSource":"NANDA-I","id":"03003"},{"dataSource":"NCI","id":"C26845"},{"dataSource":"NCI_CPTAC","id":"C26845"},{"dataSource":"NCI_NCI-GLOSS","id":"CDR0000044140"},{"dataSource":"OMIM","id":"516000"},{"dataSource":"PSY","id":"36720"},{"dataSource":"QMR","id":"R0121461"},{"dataSource":"RAM","id":"DX353"},{"dataSource":"RCD","id":"F12.."},{"dataSource":"SNM","id":"D-8450"},{"dataSource":"SNMI","id":"DA-21012"},{"dataSource":"SNOMEDCT_US","id":"49049000"},{"dataSource":"WHO","id":"0106"}]}],"relations":[{"relationType":"Abbreviation","bidirectional":true,"source":"#/results/documents/0/entities/0","target":"#/results/documents/0/entities/1"}],"warnings":[]}],"errors":[],"modelVersion":"2020-09-03"}}' + headers: + apim-request-id: 4ad92138-d987-4bd7-b257-d55fa4cddf64 + content-type: application/json; charset=utf-8 + date: Fri, 05 Feb 2021 19:52:23 GMT + strict-transport-security: max-age=31536000; includeSubDomains; preload + transfer-encoding: chunked + x-content-type-options: nosniff + x-envoy-upstream-service-time: '31' + status: + code: 200 + message: OK + url: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/1d60f955-5998-475a-8b65-9e6f123c5e35 +version: 1 diff --git a/sdk/textanalytics/azure-ai-textanalytics/tests/recordings/test_analyze_healthcare_async.test_cancellation.yaml b/sdk/textanalytics/azure-ai-textanalytics/tests/recordings/test_analyze_healthcare_async.test_cancellation.yaml index 2b860c2b07f4..9a79a721b78b 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/tests/recordings/test_analyze_healthcare_async.test_cancellation.yaml +++ b/sdk/textanalytics/azure-ai-textanalytics/tests/recordings/test_analyze_healthcare_async.test_cancellation.yaml @@ -15,68 +15,68 @@ interactions: Content-Type: - application/json User-Agent: - - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.8.5 (macOS-10.13.6-x86_64-i386-64bit) + - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.7.5 (Linux-4.4.0-19041-Microsoft-x86_64-with-debian-stretch-sid) method: POST uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs?stringIndexType=UnicodeCodePoint response: body: string: '' headers: - apim-request-id: 6e02b244-9673-4fc1-8818-8f8a1d163515 - date: Wed, 27 Jan 2021 02:28:19 GMT - operation-location: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/fb1f9ae7-73a0-44a8-bdee-647c4f15e174 + apim-request-id: 6cf323ed-57af-4ce8-a967-4d6e5a13af27 + date: Fri, 05 Feb 2021 21:33:30 GMT + operation-location: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/8188079b-33b4-4bbc-be7c-556c78f86bfd strict-transport-security: max-age=31536000; includeSubDomains; preload transfer-encoding: chunked x-content-type-options: nosniff - x-envoy-upstream-service-time: '168' + x-envoy-upstream-service-time: '264' status: code: 202 message: Accepted - url: https://westus2.api.cognitive.microsoft.com//text/analytics/v3.1-preview.3/entities/health/jobs?stringIndexType=UnicodeCodePoint + url: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs?stringIndexType=UnicodeCodePoint - request: body: null headers: - Accept: - - application/json, text/json User-Agent: - - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.8.5 (macOS-10.13.6-x86_64-i386-64bit) - method: DELETE - uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/fb1f9ae7-73a0-44a8-bdee-647c4f15e174 + - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.7.5 (Linux-4.4.0-19041-Microsoft-x86_64-with-debian-stretch-sid) + method: GET + uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/8188079b-33b4-4bbc-be7c-556c78f86bfd response: body: - string: '' + string: '{"jobId":"8188079b-33b4-4bbc-be7c-556c78f86bfd","lastUpdateDateTime":"2021-02-05T21:33:31Z","createdDateTime":"2021-02-05T21:33:31Z","expirationDateTime":"2021-02-06T21:33:31Z","status":"notStarted","errors":[]}' headers: - apim-request-id: 6f8c86a1-0f63-4683-b3a8-9ff346734158 - date: Wed, 27 Jan 2021 02:28:19 GMT - operation-location: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/fb1f9ae7-73a0-44a8-bdee-647c4f15e174 + apim-request-id: 5dac857a-c850-494b-b820-0e9be4a65eda + content-type: application/json; charset=utf-8 + date: Fri, 05 Feb 2021 21:33:30 GMT strict-transport-security: max-age=31536000; includeSubDomains; preload transfer-encoding: chunked x-content-type-options: nosniff - x-envoy-upstream-service-time: '11' + x-envoy-upstream-service-time: '16' status: - code: 202 - message: Accepted - url: https://westus2.api.cognitive.microsoft.com//text/analytics/v3.1-preview.3/entities/health/jobs/fb1f9ae7-73a0-44a8-bdee-647c4f15e174 + code: 200 + message: OK + url: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/8188079b-33b4-4bbc-be7c-556c78f86bfd - request: body: null headers: + Accept: + - application/json, text/json User-Agent: - - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.8.5 (macOS-10.13.6-x86_64-i386-64bit) - method: GET - uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/fb1f9ae7-73a0-44a8-bdee-647c4f15e174 + - azsdk-python-ai-textanalytics/5.1.0b5 Python/3.7.5 (Linux-4.4.0-19041-Microsoft-x86_64-with-debian-stretch-sid) + method: DELETE + uri: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/8188079b-33b4-4bbc-be7c-556c78f86bfd response: body: - string: '{"jobId":"fb1f9ae7-73a0-44a8-bdee-647c4f15e174","lastUpdateDateTime":"2021-01-27T02:28:19Z","createdDateTime":"2021-01-27T02:28:19Z","expirationDateTime":"2021-01-28T02:28:19Z","status":"cancelled","errors":[]}' + string: '' headers: - apim-request-id: c7b449f3-ff2c-456a-8c54-30b98db0dec7 - content-type: application/json; charset=utf-8 - date: Wed, 27 Jan 2021 02:28:24 GMT + apim-request-id: 175503ab-f31d-49a3-9a01-565ff893c7c6 + date: Fri, 05 Feb 2021 21:33:30 GMT + operation-location: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/8188079b-33b4-4bbc-be7c-556c78f86bfd strict-transport-security: max-age=31536000; includeSubDomains; preload transfer-encoding: chunked x-content-type-options: nosniff - x-envoy-upstream-service-time: '8' + x-envoy-upstream-service-time: '20' status: - code: 200 - message: OK - url: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/fb1f9ae7-73a0-44a8-bdee-647c4f15e174 + code: 202 + message: Accepted + url: https://westus2.api.cognitive.microsoft.com/text/analytics/v3.1-preview.3/entities/health/jobs/8188079b-33b4-4bbc-be7c-556c78f86bfd version: 1 diff --git a/sdk/textanalytics/azure-ai-textanalytics/tests/test_analyze_healthcare.py b/sdk/textanalytics/azure-ai-textanalytics/tests/test_analyze_healthcare.py index a17f4e4a2c2f..adc9bb560d7b 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/tests/test_analyze_healthcare.py +++ b/sdk/textanalytics/azure-ai-textanalytics/tests/test_analyze_healthcare.py @@ -33,7 +33,7 @@ def _interval(self): @TextAnalyticsClientPreparer() def test_no_single_input(self, client): with self.assertRaises(TypeError): - response = client.begin_analyze_healthcare("hello world").result() + response = client.begin_analyze_healthcare_entities("hello world").result() @pytest.mark.playback_test_only @GlobalTextAnalyticsAccountPreparer() @@ -42,15 +42,26 @@ def test_all_successful_passing_dict(self, client): docs = [{"id": "1", "language": "en", "text": "Patient does not suffer from high blood pressure."}, {"id": "2", "language": "en", "text": "Prescribed 100mg ibuprofen, taken twice daily."}] - response = client.begin_analyze_healthcare(docs, show_stats=True, polling_interval=self._interval()).result() - + poller = client.begin_analyze_healthcare_entities(docs, show_stats=True, polling_interval=self._interval()) + response = poller.result() self.assertIsNotNone(response.statistics) + response = list(response) for doc in response: self.assertIsNotNone(doc.id) self.assertIsNotNone(doc.statistics) self.assertIsNotNone(doc.entities) - self.assertIsNotNone(doc.relations) + + self.assertEqual(len(response[0].entities), 2) + entity1 = list(filter(lambda x: x.text == "high", response[0].entities))[0] + entity2 = list(filter(lambda x: x.text == "blood pressure", response[0].entities))[0] + + self.assertEqual(len(entity1.related_entities), 1) + related_entity, relation_type = entity1.related_entities.popitem() + self.assertEqual(related_entity, entity2) + self.assertEqual(relation_type, "ValueOfExamination") + + self.assertEqual(len(entity2.related_entities), 0) @pytest.mark.playback_test_only @GlobalTextAnalyticsAccountPreparer() @@ -61,14 +72,14 @@ def test_all_successful_passing_text_document_input(self, client): TextDocumentInput(id="2", text="Prescribed 100mg ibuprofen, taken twice daily."), ] - response = client.begin_analyze_healthcare(docs, polling_interval=self._interval()).result() + response = client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()).result() + self.assertIsNone(response.statistics) # show_stats=False by default for doc in response: self.assertIsNotNone(doc.id) self.assertIsNone(doc.statistics) self.assertIsNotNone(doc.entities) - self.assertIsNotNone(doc.relations) @pytest.mark.playback_test_only @GlobalTextAnalyticsAccountPreparer() @@ -80,13 +91,12 @@ def test_passing_only_string(self, client): u"" ] - response = list(client.begin_analyze_healthcare(docs, polling_interval=self._interval()).result()) + response = list(client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()).result()) for i in range(2): self.assertIsNotNone(response[i].id) self.assertIsNone(response[i].statistics) self.assertIsNotNone(response[i].entities) - self.assertIsNotNone(response[i].relations) self.assertTrue(response[2].is_error) @@ -98,7 +108,7 @@ def test_input_with_some_errors(self, client): {"id": "2", "language": "english", "text": "Patient does not suffer from high blood pressure."}, {"id": "3", "language": "en", "text": "Prescribed 100mg ibuprofen, taken twice daily."}] - response = list(client.begin_analyze_healthcare(docs, polling_interval=self._interval()).result()) + response = list(client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()).result()) self.assertTrue(response[0].is_error) self.assertTrue(response[1].is_error) self.assertFalse(response[2].is_error) @@ -111,7 +121,7 @@ def test_input_with_all_errors(self, client): {"id": "2", "language": "english", "text": "Patient does not suffer from high blood pressure."}, {"id": "3", "language": "en", "text": ""}] - response = list(client.begin_analyze_healthcare(docs).result()) + response = list(client.begin_analyze_healthcare_entities(docs).result()) self.assertTrue(response[0].is_error) self.assertTrue(response[1].is_error) self.assertTrue(response[2].is_error) @@ -123,7 +133,7 @@ def test_too_many_documents(self, client): docs = list(itertools.repeat("input document", 11)) # Maximum number of documents per request is 10 with pytest.raises(HttpResponseError) as excinfo: - client.begin_analyze_healthcare(docs, polling_interval=self._interval()) + client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()) assert excinfo.value.status_code == 400 @@ -146,7 +156,7 @@ def test_payload_too_large(self, client): docs = list(itertools.repeat(large_doc, 500)) with pytest.raises(HttpResponseError) as excinfo: - client.begin_analyze_healthcare(docs, polling_interval=self._interval()) + client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()) assert excinfo.value.status_code == 413 @GlobalTextAnalyticsAccountPreparer() @@ -157,7 +167,7 @@ def test_document_warnings(self, client): {"id": "1", "text": "This won't actually create a warning :'("}, ] - result = client.begin_analyze_healthcare(docs, polling_interval=self._interval()).result() + result = client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()).result() response = list(result) for doc in response: doc_warnings = doc.warnings @@ -174,7 +184,7 @@ def test_output_same_order_as_input(self, client): TextDocumentInput(id="5", text="five") ] - response = client.begin_analyze_healthcare(docs, polling_interval=self._interval()).result() + response = client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()).result() for idx, doc in enumerate(response): self.assertEqual(str(idx + 1), doc.id) @@ -186,7 +196,7 @@ def test_output_same_order_as_input(self, client): }) def test_empty_credential_class(self, client): with self.assertRaises(ClientAuthenticationError): - response = client.begin_analyze_healthcare( + response = client.begin_analyze_healthcare_entities( ["This is written in English."], polling_interval=self._interval() ).result() @@ -198,7 +208,7 @@ def test_empty_credential_class(self, client): }) def test_bad_credentials(self, client): with self.assertRaises(ClientAuthenticationError): - response = client.begin_analyze_healthcare( + response = client.begin_analyze_healthcare_entities( ["This is written in English."], polling_interval=self._interval() ) @@ -210,7 +220,7 @@ def test_bad_document_input(self, client): docs = "This is the wrong type" with self.assertRaises(TypeError): - response = client.begin_analyze_healthcare(docs, polling_interval=self._interval()) + response = client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()) @GlobalTextAnalyticsAccountPreparer() @TextAnalyticsClientPreparer() @@ -221,7 +231,7 @@ def test_mixing_inputs(self, client): u"You cannot mix string input with the above inputs" ] with self.assertRaises(TypeError): - response = client.begin_analyze_healthcare(docs, polling_interval=self._interval()) + response = client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()) @GlobalTextAnalyticsAccountPreparer() @TextAnalyticsClientPreparer() @@ -232,7 +242,7 @@ def test_out_of_order_ids(self, client): {"id": "19", "text": ":P"}, {"id": "1", "text": ":D"}] - response = list(client.begin_analyze_healthcare(docs, polling_interval=self._interval()).result()) + response = list(client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()).result()) expected_order = ["56", "0", "22", "19", "1"] actual_order = [x.id for x in response] @@ -248,7 +258,7 @@ def test_show_stats_and_model_version(self, client): {"id": "19", "text": ":P"}, {"id": "1", "text": ":D"}] - response = client.begin_analyze_healthcare( + response = client.begin_analyze_healthcare_entities( docs, show_stats=True, model_version="2020-09-03", @@ -277,7 +287,7 @@ def test_whole_batch_language_hint(self, client): u"The restaurant was not as good as I hoped." ] - response = list(client.begin_analyze_healthcare(docs, language="en", polling_interval=self._interval()).result()) + response = list(client.begin_analyze_healthcare_entities(docs, language="en", polling_interval=self._interval()).result()) self.assertFalse(response[0].is_error) self.assertFalse(response[1].is_error) self.assertFalse(response[2].is_error) @@ -291,7 +301,7 @@ def test_whole_batch_dont_use_language_hint(self, client): u"The restaurant was not as good as I hoped." ] - response = list(client.begin_analyze_healthcare(docs, language="", polling_interval=self._interval()).result()) + response = list(client.begin_analyze_healthcare_entities(docs, language="", polling_interval=self._interval()).result()) self.assertFalse(response[0].is_error) self.assertFalse(response[1].is_error) self.assertFalse(response[2].is_error) @@ -304,7 +314,7 @@ def test_per_item_dont_use_language_hint(self, client): {"id": "2", "language": "", "text": "I did not like the hotel we stayed at."}, {"id": "3", "text": "The restaurant had really good food."}] - response = list(client.begin_analyze_healthcare(docs, polling_interval=self._interval()).result()) + response = list(client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()).result()) self.assertFalse(response[0].is_error) self.assertFalse(response[1].is_error) self.assertFalse(response[2].is_error) @@ -319,7 +329,7 @@ def test_whole_batch_language_hint_and_obj_input(self, client): TextDocumentInput(id="3", text="猫は幸せ"), ] - response = list(client.begin_analyze_healthcare(docs, language="en", polling_interval=self._interval()).result()) + response = list(client.begin_analyze_healthcare_entities(docs, language="en", polling_interval=self._interval()).result()) self.assertFalse(response[0].is_error) self.assertFalse(response[1].is_error) self.assertFalse(response[2].is_error) @@ -331,7 +341,7 @@ def test_whole_batch_language_hint_and_dict_input(self, client): {"id": "2", "text": "I did not like the hotel we stayed at."}, {"id": "3", "text": "The restaurant had really good food."}] - response = list(client.begin_analyze_healthcare(docs, language="en", polling_interval=self._interval()).result()) + response = list(client.begin_analyze_healthcare_entities(docs, language="en", polling_interval=self._interval()).result()) self.assertFalse(response[0].is_error) self.assertFalse(response[1].is_error) self.assertFalse(response[2].is_error) @@ -344,7 +354,7 @@ def test_whole_batch_language_hint_and_obj_per_item_hints(self, client): TextDocumentInput(id="2", text="猫は幸せ"), ] - response = list(client.begin_analyze_healthcare(docs, language="en", polling_interval=self._interval()).result()) + response = list(client.begin_analyze_healthcare_entities(docs, language="en", polling_interval=self._interval()).result()) self.assertFalse(response[0].is_error) self.assertFalse(response[1].is_error) @@ -355,7 +365,7 @@ def test_whole_batch_language_hint_and_dict_per_item_hints(self, client): {"id": "2", "language": "", "text": "I did not like the hotel we stayed at."}, {"id": "3", "text": "The restaurant had really good food."}] - response = list(client.begin_analyze_healthcare(docs, language="en", polling_interval=self._interval()).result()) + response = list(client.begin_analyze_healthcare_entities(docs, language="en", polling_interval=self._interval()).result()) self.assertFalse(response[0].is_error) self.assertFalse(response[1].is_error) self.assertFalse(response[2].is_error) @@ -369,7 +379,7 @@ def test_client_passed_default_language_hint(self, client): {"id": "2", "text": "I did not like the hotel we stayed at."}, {"id": "3", "text": "The restaurant had really good food."}] - result = client.begin_analyze_healthcare(docs, polling_interval=self._interval()).result() + result = client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()).result() response = list(result) self.assertFalse(response[0].is_error) self.assertFalse(response[1].is_error) @@ -378,7 +388,7 @@ def test_client_passed_default_language_hint(self, client): @GlobalTextAnalyticsAccountPreparer() @TextAnalyticsClientPreparer() def test_invalid_language_hint_method(self, client): - response = list(client.begin_analyze_healthcare( + response = list(client.begin_analyze_healthcare_entities( ["This should fail because we're passing in an invalid language hint"], language="notalanguage", polling_interval=self._interval() ).result()) self.assertEqual(response[0].error.code, 'UnsupportedLanguageCode') @@ -387,7 +397,7 @@ def test_invalid_language_hint_method(self, client): @GlobalTextAnalyticsAccountPreparer() @TextAnalyticsClientPreparer() def test_invalid_language_hint_docs(self, client): - response = list(client.begin_analyze_healthcare( + response = list(client.begin_analyze_healthcare_entities( [{"id": "1", "language": "notalanguage", "text": "This should fail because we're passing in an invalid language hint"}], polling_interval=self._interval() ).result()) @@ -403,15 +413,15 @@ def test_rotate_subscription_key(self, resource_group, location, text_analytics_ {"id": "2", "text": "I did not like the hotel we stayed at."}, {"id": "3", "text": "The restaurant had really good food."}] - response = client.begin_analyze_healthcare(docs, polling_interval=self._interval()).result() + response = client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()).result() self.assertIsNotNone(response) credential.update("xxx") # Make authentication fail with self.assertRaises(ClientAuthenticationError): - response = client.begin_analyze_healthcare(docs, polling_interval=self._interval()).result() + response = client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()).result() credential.update(text_analytics_account_key) # Authenticate successfully again - response = client.begin_analyze_healthcare(docs, polling_interval=self._interval()).result() + response = client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()).result() self.assertIsNotNone(response) @GlobalTextAnalyticsAccountPreparer() @@ -421,7 +431,7 @@ def test_user_agent(self, client): # TODO: verify {"id": "2", "text": "I did not like the hotel we stayed at."}, {"id": "3", "text": "The restaurant had really good food."}] - poller = client.begin_analyze_healthcare(docs, polling_interval=self._interval()) + poller = client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()) self.assertIn("azsdk-python-ai-textanalytics/{} Python/{} ({})".format( VERSION, platform.python_version(), platform.platform()), poller._polling_method._initial_response.http_request.headers["User-Agent"] @@ -433,7 +443,7 @@ def test_user_agent(self, client): # TODO: verify @TextAnalyticsClientPreparer() def test_document_attribute_error_no_result_attribute(self, client): docs = [{"id": "1", "text": ""}] - result = client.begin_analyze_healthcare(docs, polling_interval=self._interval()).result() + result = client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()).result() response = list(result) # Attributes on DocumentError @@ -457,7 +467,7 @@ def test_document_attribute_error_no_result_attribute(self, client): @TextAnalyticsClientPreparer() def test_document_attribute_error_nonexistent_attribute(self, client): docs = [{"id": "1", "text": ""}] - result = client.begin_analyze_healthcare(docs, polling_interval=self._interval()).result() + result = client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()).result() response = list(result) # Attribute not found on DocumentError or result obj, default behavior/message @@ -475,7 +485,7 @@ def test_bad_model_version_error(self, client): docs = [{"id": "1", "language": "english", "text": "I did not like the hotel we stayed at."}] try: - result = client.begin_analyze_healthcare(docs, model_version="bad", polling_interval=self._interval()).result() + result = client.begin_analyze_healthcare_entities(docs, model_version="bad", polling_interval=self._interval()).result() except HttpResponseError as err: self.assertEqual(err.error.code, "ModelVersionIncorrect") self.assertIsNotNone(err.error.message) @@ -491,7 +501,7 @@ def test_document_errors(self, client): {"id": "2", "language": "english", "text": "I did not like the hotel we stayed at."}, {"id": "3", "text": text}] - result = client.begin_analyze_healthcare(docs, polling_interval=self._interval()).result() + result = client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()).result() doc_errors = list(result) self.assertEqual(doc_errors[0].error.code, "InvalidDocument") self.assertIsNotNone(doc_errors[0].error.message) @@ -506,7 +516,7 @@ def test_document_errors(self, client): def test_not_passing_list_for_docs(self, client): docs = {"id": "1", "text": "hello world"} with pytest.raises(TypeError) as excinfo: - client.begin_analyze_healthcare(docs, polling_interval=self._interval()) + client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()) assert "Input documents cannot be a dict" in str(excinfo.value) @GlobalTextAnalyticsAccountPreparer() @@ -514,14 +524,14 @@ def test_not_passing_list_for_docs(self, client): def test_missing_input_records_error(self, client): docs = [] with pytest.raises(ValueError) as excinfo: - client.begin_analyze_healthcare(docs, polling_interval=self._interval()) + client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()) assert "Input documents can not be empty or None" in str(excinfo.value) @GlobalTextAnalyticsAccountPreparer() @TextAnalyticsClientPreparer() def test_passing_none_docs(self, client): with pytest.raises(ValueError) as excinfo: - client.begin_analyze_healthcare(None, polling_interval=self._interval()) + client.begin_analyze_healthcare_entities(None, polling_interval=self._interval()) assert "Input documents can not be empty or None" in str(excinfo.value) @GlobalTextAnalyticsAccountPreparer() @@ -531,7 +541,7 @@ def test_duplicate_ids_error(self, client): docs = [{"id": "1", "text": "hello world"}, {"id": "1", "text": "I did not like the hotel we stayed at."}] try: - result = client.begin_analyze_healthcare(docs, polling_interval=self._interval()).result() + result = client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()).result() except HttpResponseError as err: self.assertEqual(err.error.code, "InvalidDocument") @@ -542,7 +552,7 @@ def test_duplicate_ids_error(self, client): def test_pass_cls(self, client): def callback(pipeline_response, deserialized, _): return "cls result" - res = client.begin_analyze_healthcare( + res = client.begin_analyze_healthcare_entities( documents=["Test passing cls to endpoint"], cls=callback, polling_interval=self._interval() @@ -559,7 +569,7 @@ def test_multiple_pages_of_results_returned_successfully(self, client): # for records per page is 20, pagination logic will never be activated. This is intended to change # in the future but for now this test actually won't hit the pagination logic now. - result = client.begin_analyze_healthcare(docs, show_stats=True, polling_interval=self._interval()).result() + result = client.begin_analyze_healthcare_entities(docs, show_stats=True, polling_interval=self._interval()).result() response = list(result) self.assertEqual(len(docs), len(response)) @@ -580,7 +590,7 @@ def test_multiple_pages_of_results_with_errors_returned_successfully(self, clien # in the future but for now this test actually won't hit the pagination logic now. - result = client.begin_analyze_healthcare(docs, show_stats=True, polling_interval=self._interval()).result() + result = client.begin_analyze_healthcare_entities(docs, show_stats=True, polling_interval=self._interval()).result() response = list(result) self.assertEqual(len(docs), len(response)) @@ -597,22 +607,24 @@ def test_multiple_pages_of_results_with_errors_returned_successfully(self, clien self.assertIsNotNone(doc.statistics) @GlobalTextAnalyticsAccountPreparer() - @TextAnalyticsClientPreparer() + @TextAnalyticsClientPreparer(client_kwargs={"text_analytics_account_key": os.environ.get("AZURE_TEXT_ANALYTICS_KEY"), "text_analytics_account": os.environ.get("AZURE_TEXT_ANALYTICS_ENDPOINT")}) def test_cancellation(self, client): single_doc = "hello world" docs = [{"id": str(idx), "text": val} for (idx, val) in enumerate(list(itertools.repeat(single_doc, 10)))] - poller = client.begin_analyze_healthcare(docs, polling_interval=self._interval()) - cancellation_result = client.begin_cancel_analyze_healthcare(poller, polling_interval=self._interval()).result() + poller = client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()) - self.assertIsNone(cancellation_result) + try: + cancellation_poller = poller.cancel() + cancellation_poller.wait() - poller.wait() + except HttpResponseError: + pass # expected if the operation was already in a terminal state. @GlobalTextAnalyticsAccountPreparer() @TextAnalyticsClientPreparer() def test_default_string_index_type_is_UnicodeCodePoint(self, client): - poller = client.begin_analyze_healthcare(documents=["Hello world"]) + poller = client.begin_analyze_healthcare_entities(documents=["Hello world"]) actual_string_index_type = poller._polling_method._initial_response.http_request.query["stringIndexType"] self.assertEqual(actual_string_index_type, "UnicodeCodePoint") poller.result() @@ -620,10 +632,29 @@ def test_default_string_index_type_is_UnicodeCodePoint(self, client): @GlobalTextAnalyticsAccountPreparer() @TextAnalyticsClientPreparer() def test_explicit_set_string_index_type(self, client): - poller = client.begin_analyze_healthcare( + poller = client.begin_analyze_healthcare_entities( documents=["Hello world"], string_index_type="TextElements_v8" ) actual_string_index_type = poller._polling_method._initial_response.http_request.query["stringIndexType"] self.assertEqual(actual_string_index_type, "TextElements_v8") poller.result() + + @GlobalTextAnalyticsAccountPreparer() + @TextAnalyticsClientPreparer(client_kwargs={"text_analytics_account_key": os.environ.get("AZURE_TEXT_ANALYTICS_KEY"), "text_analytics_account": os.environ.get("AZURE_TEXT_ANALYTICS_ENDPOINT")}) + def test_bidirectional_relation_type(self, client): + result = list(client.begin_analyze_healthcare_entities( + documents=["The patient was diagnosed with Parkinsons Disease (PD)"] + ).result()) + + self.assertEqual(len(result[0].entities), 2) + entity1 = list(filter(lambda x: x.text == "Parkinsons Disease", result[0].entities))[0] + entity2 = list(filter(lambda x: x.text == "PD", result[0].entities))[0] + + related_entity1, relation_type1 = entity1.related_entities.popitem() + self.assertEqual(related_entity1, entity2) + self.assertEqual(relation_type1, "Abbreviation") + related_entity2, relation_type2 = entity2.related_entities.popitem() + self.assertEqual(related_entity2, entity1) + self.assertEqual(relation_type2, "Abbreviation") + diff --git a/sdk/textanalytics/azure-ai-textanalytics/tests/test_analyze_healthcare_async.py b/sdk/textanalytics/azure-ai-textanalytics/tests/test_analyze_healthcare_async.py index 14e43082ea5a..4e0af5eb71a4 100644 --- a/sdk/textanalytics/azure-ai-textanalytics/tests/test_analyze_healthcare_async.py +++ b/sdk/textanalytics/azure-ai-textanalytics/tests/test_analyze_healthcare_async.py @@ -47,7 +47,7 @@ def _interval(self): async def test_no_single_input(self, client): with self.assertRaises(TypeError): async with client: - response = await (await client.begin_analyze_healthcare("hello world", polling_interval=self._interval())).result() + response = await (await client.begin_analyze_healthcare_entities("hello world", polling_interval=self._interval())).result() @GlobalTextAnalyticsAccountPreparer() @TextAnalyticsClientPreparer() @@ -56,7 +56,7 @@ async def test_all_successful_passing_dict(self, client): {"id": "2", "language": "en", "text": "Prescribed 100mg ibuprofen, taken twice daily."}] async with client: - poller = await client.begin_analyze_healthcare(docs, show_stats=True, polling_interval=self._interval()) + poller = await client.begin_analyze_healthcare_entities(docs, show_stats=True, polling_interval=self._interval()) response = await poller.result() self.assertIsNotNone(response.statistics) @@ -65,7 +65,6 @@ async def test_all_successful_passing_dict(self, client): self.assertIsNotNone(doc.id) self.assertIsNotNone(doc.statistics) self.assertIsNotNone(doc.entities) - self.assertIsNotNone(doc.relations) @GlobalTextAnalyticsAccountPreparer() @TextAnalyticsClientPreparer() @@ -76,15 +75,29 @@ async def test_all_successful_passing_text_document_input(self, client): ] async with client: - response = await (await client.begin_analyze_healthcare(docs, polling_interval=self._interval())).result() + result = await (await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval())).result() - self.assertIsNone(response.statistics) # show_stats=False by default + self.assertIsNone(result.statistics) # show_stats=False by default - async for doc in response: + response = [] + async for r in result: + response.append(r) + + for doc in response: self.assertIsNotNone(doc.id) self.assertIsNone(doc.statistics) self.assertIsNotNone(doc.entities) - self.assertIsNotNone(doc.relations) + + self.assertEqual(len(response[0].entities), 2) + entity1 = list(filter(lambda x: x.text == "high", response[0].entities))[0] + entity2 = list(filter(lambda x: x.text == "blood pressure", response[0].entities))[0] + + self.assertEqual(len(entity1.related_entities), 1) + related_entity, relation_type = entity1.related_entities.popitem() + self.assertEqual(related_entity, entity2) + self.assertEqual(relation_type, "ValueOfExamination") + + self.assertEqual(len(entity2.related_entities), 0) @GlobalTextAnalyticsAccountPreparer() @TextAnalyticsClientPreparer() @@ -96,7 +109,7 @@ async def test_passing_only_string(self, client): ] async with client: - result = await(await client.begin_analyze_healthcare(docs, polling_interval=self._interval())).result() + result = await(await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval())).result() response = [] async for r in result: response.append(r) @@ -105,7 +118,6 @@ async def test_passing_only_string(self, client): for i in range(2): self.assertIsNotNone(response[i].id) self.assertIsNotNone(response[i].entities) - self.assertIsNotNone(response[i].relations) self.assertTrue(response[2].is_error) @@ -117,7 +129,7 @@ async def test_input_with_some_errors(self, client): {"id": "3", "language": "en", "text": "Prescribed 100mg ibuprofen, taken twice daily."}] async with client: - result = await(await client.begin_analyze_healthcare(docs, polling_interval=self._interval())).result() + result = await(await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval())).result() response = [] async for r in result: response.append(r) @@ -134,7 +146,7 @@ async def test_input_with_all_errors(self, client): {"id": "3", "language": "en", "text": ""}] async with client: - result = await(await client.begin_analyze_healthcare(docs, polling_interval=self._interval())).result() + result = await(await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval())).result() response = [] async for r in result: response.append(r) @@ -150,7 +162,7 @@ async def test_too_many_documents(self, client): with pytest.raises(HttpResponseError) as excinfo: async with client: - await client.begin_analyze_healthcare(docs, polling_interval=self._interval()) + await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()) assert excinfo.value.status_code == 400 @@ -174,7 +186,7 @@ async def test_payload_too_large(self, client): with pytest.raises(HttpResponseError) as excinfo: async with client: - await client.begin_analyze_healthcare(docs, polling_interval=self._interval()) + await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()) assert excinfo.value.status_code == 413 @@ -187,7 +199,7 @@ async def test_document_warnings(self, client): ] async with client: - result = await (await client.begin_analyze_healthcare(docs, polling_interval=self._interval())).result() + result = await (await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval())).result() async for doc in result: doc_warnings = doc.warnings @@ -205,7 +217,7 @@ async def test_output_same_order_as_input(self, client): ] async with client: - result = await(await client.begin_analyze_healthcare(docs, polling_interval=self._interval())).result() + result = await(await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval())).result() response = [] async for r in result: response.append(r) @@ -221,7 +233,7 @@ async def test_output_same_order_as_input(self, client): async def test_empty_credential_class(self, client): with self.assertRaises(ClientAuthenticationError): async with client: - response = await client.begin_analyze_healthcare( + response = await client.begin_analyze_healthcare_entities( ["This is written in English."], polling_interval=self._interval() ) @@ -234,7 +246,7 @@ async def test_empty_credential_class(self, client): async def test_bad_credentials(self, client): with self.assertRaises(ClientAuthenticationError): async with client: - response = await client.begin_analyze_healthcare( + response = await client.begin_analyze_healthcare_entities( ["This is written in English."], polling_interval=self._interval() ) @@ -247,7 +259,7 @@ async def test_bad_document_input(self, client): with self.assertRaises(TypeError): async with client: - response = await client.begin_analyze_healthcare(docs, polling_interval=self._interval()) + response = await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()) @GlobalTextAnalyticsAccountPreparer() @TextAnalyticsClientPreparer() @@ -259,7 +271,7 @@ async def test_mixing_inputs(self, client): ] with self.assertRaises(TypeError): async with client: - response = await client.begin_analyze_healthcare(docs, polling_interval=self._interval()) + response = await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()) @GlobalTextAnalyticsAccountPreparer() @TextAnalyticsClientPreparer() @@ -271,7 +283,7 @@ async def test_out_of_order_ids(self, client): {"id": "1", "text": ":D"}] async with client: - result = await(await client.begin_analyze_healthcare(docs, polling_interval=self._interval())).result() + result = await(await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval())).result() response = [] async for r in result: response.append(r) @@ -291,7 +303,7 @@ async def test_show_stats_and_model_version(self, client): {"id": "1", "text": ":D"}] async with client: - response = await (await client.begin_analyze_healthcare( + response = await (await client.begin_analyze_healthcare_entities( docs, show_stats=True, model_version="2020-09-03", @@ -321,7 +333,7 @@ async def test_whole_batch_language_hint(self, client): ] async with client: - result = await(await client.begin_analyze_healthcare(docs, language="en", polling_interval=self._interval())).result() + result = await(await client.begin_analyze_healthcare_entities(docs, language="en", polling_interval=self._interval())).result() response = [] async for r in result: response.append(r) @@ -340,7 +352,7 @@ async def test_whole_batch_dont_use_language_hint(self, client): ] async with client: - result = await(await client.begin_analyze_healthcare(docs, language="", polling_interval=self._interval())).result() + result = await(await client.begin_analyze_healthcare_entities(docs, language="", polling_interval=self._interval())).result() response = [] async for r in result: response.append(r) @@ -357,7 +369,7 @@ async def test_per_item_dont_use_language_hint(self, client): {"id": "3", "text": "The restaurant had really good food."}] async with client: - result = await(await client.begin_analyze_healthcare(docs, polling_interval=self._interval())).result() + result = await(await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval())).result() response = [] async for r in result: response.append(r) @@ -376,7 +388,7 @@ async def test_whole_batch_language_hint_and_obj_input(self, client): ] async with client: - result = await(await client.begin_analyze_healthcare(docs, language="en", polling_interval=self._interval())).result() + result = await(await client.begin_analyze_healthcare_entities(docs, language="en", polling_interval=self._interval())).result() response = [] async for r in result: response.append(r) @@ -394,7 +406,7 @@ async def test_whole_batch_language_hint_and_dict_input(self, client): {"id": "3", "text": "The restaurant had really good food."}] async with client: - result = await(await client.begin_analyze_healthcare(docs, language="en", polling_interval=self._interval())).result() + result = await(await client.begin_analyze_healthcare_entities(docs, language="en", polling_interval=self._interval())).result() response = [] async for r in result: response.append(r) @@ -412,7 +424,7 @@ async def test_whole_batch_language_hint_and_obj_per_item_hints(self, client): ] async with client: - result = await(await client.begin_analyze_healthcare(docs, language="en", polling_interval=self._interval())).result() + result = await(await client.begin_analyze_healthcare_entities(docs, language="en", polling_interval=self._interval())).result() response = [] async for r in result: response.append(r) @@ -429,7 +441,7 @@ async def test_whole_batch_language_hint_and_dict_per_item_hints(self, client): {"id": "3", "text": "The restaurant had really good food."}] async with client: - result = await(await client.begin_analyze_healthcare(docs, language="en", polling_interval=self._interval())).result() + result = await(await client.begin_analyze_healthcare_entities(docs, language="en", polling_interval=self._interval())).result() response = [] async for r in result: response.append(r) @@ -448,7 +460,7 @@ async def test_client_passed_default_language_hint(self, client): {"id": "3", "text": "The restaurant had really good food."}] async with client: - result = await(await client.begin_analyze_healthcare(docs, polling_interval=self._interval())).result() + result = await(await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval())).result() response = [] async for r in result: response.append(r) @@ -463,7 +475,7 @@ async def test_invalid_language_hint_method(self, client): docs = ["This should fail because we're passing in an invalid language hint"] async with client: - result = await(await client.begin_analyze_healthcare(docs, language="notalanguage", polling_interval=self._interval())).result() + result = await(await client.begin_analyze_healthcare_entities(docs, language="notalanguage", polling_interval=self._interval())).result() response = [] async for r in result: response.append(r) @@ -476,7 +488,7 @@ async def test_invalid_language_hint_docs(self, client): docs = [{"id": "1", "language": "notalanguage", "text": "This should fail because we're passing in an invalid language hint"}] async with client: - result = await(await client.begin_analyze_healthcare(docs, polling_interval=self._interval())).result() + result = await(await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval())).result() response = [] async for r in result: response.append(r) @@ -494,15 +506,15 @@ async def test_rotate_subscription_key(self, resource_group, location, text_anal {"id": "3", "text": "The restaurant had really good food."}] async with client: - response = await (await client.begin_analyze_healthcare(docs, polling_interval=self._interval())).result() + response = await (await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval())).result() self.assertIsNotNone(response) credential.update("xxx") # Make authentication fail with self.assertRaises(ClientAuthenticationError): - response = await (await client.begin_analyze_healthcare(docs, polling_interval=self._interval())).result() + response = await (await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval())).result() credential.update(text_analytics_account_key) # Authenticate successfully again - response = await (await client.begin_analyze_healthcare(docs, polling_interval=self._interval())).result() + response = await (await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval())).result() self.assertIsNotNone(response) @GlobalTextAnalyticsAccountPreparer() @@ -519,7 +531,7 @@ def callback(resp): {"id": "3", "text": "The restaurant had really good food."}] async with client: - poller = await client.begin_analyze_healthcare(docs, polling_interval=self._interval()) + poller = await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()) self.assertIn("azsdk-python-ai-textanalytics/{} Python/{} ({})".format( VERSION, platform.python_version(), platform.platform()), poller._polling_method._initial_response.http_request.headers["User-Agent"] @@ -533,7 +545,7 @@ def callback(resp): async def test_document_attribute_error_no_result_attribute(self, client): docs = [{"id": "1", "text": ""}] async with client: - result = await(await client.begin_analyze_healthcare(docs, polling_interval=self._interval())).result() + result = await(await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval())).result() response = [] async for r in result: response.append(r) @@ -559,7 +571,7 @@ async def test_document_attribute_error_no_result_attribute(self, client): async def test_document_attribute_error_nonexistent_attribute(self, client): docs = [{"id": "1", "text": ""}] async with client: - result = await(await client.begin_analyze_healthcare(docs, polling_interval=self._interval())).result() + result = await(await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval())).result() response = [] async for r in result: response.append(r) @@ -581,7 +593,7 @@ async def test_bad_model_version_error(self, client): try: async with client: - result = await(await client.begin_analyze_healthcare(docs, model_version="bad", polling_interval=self._interval())).result() + result = await(await client.begin_analyze_healthcare_entities(docs, model_version="bad", polling_interval=self._interval())).result() response = [] async for r in result: response.append(r) @@ -601,7 +613,7 @@ async def test_document_errors(self, client): {"id": "3", "text": text}] async with client: - result = await(await client.begin_analyze_healthcare(docs, polling_interval=self._interval())).result() + result = await(await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval())).result() doc_errors = [] async for r in result: doc_errors.append(r) @@ -619,7 +631,7 @@ async def test_not_passing_list_for_docs(self, client): docs = {"id": "1", "text": "hello world"} with pytest.raises(TypeError) as excinfo: async with client: - await client.begin_analyze_healthcare(docs, polling_interval=self._interval()) + await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()) assert "Input documents cannot be a dict" in str(excinfo.value) @GlobalTextAnalyticsAccountPreparer() @@ -628,7 +640,7 @@ async def test_missing_input_records_error(self, client): docs = [] with pytest.raises(ValueError) as excinfo: async with client: - await client.begin_analyze_healthcare(docs, polling_interval=self._interval()) + await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()) assert "Input documents can not be empty or None" in str(excinfo.value) @GlobalTextAnalyticsAccountPreparer() @@ -636,7 +648,7 @@ async def test_missing_input_records_error(self, client): async def test_passing_none_docs(self, client): with pytest.raises(ValueError) as excinfo: async with client: - await client.begin_analyze_healthcare(None, polling_interval=self._interval()) + await client.begin_analyze_healthcare_entities(None, polling_interval=self._interval()) assert "Input documents can not be empty or None" in str(excinfo.value) @pytest.mark.playback_test_only @@ -648,7 +660,7 @@ async def test_duplicate_ids_error(self, client): {"id": "1", "text": "I did not like the hotel we stayed at."}] try: async with client: - result = await client.begin_analyze_healthcare(docs, polling_interval=self._interval()) + result = await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()) except HttpResponseError as err: self.assertEqual(err.error.code, "InvalidDocument") self.assertIsNotNone(err.error.message) @@ -660,7 +672,7 @@ def callback(pipeline_response, deserialized, _): return "cls result" async with client: - res = await (await client.begin_analyze_healthcare( + res = await (await client.begin_analyze_healthcare_entities( documents=["Test passing cls to endpoint"], cls=callback, polling_interval=self._interval() @@ -678,7 +690,7 @@ async def test_multiple_pages_of_results_returned_successfully(self, client): # in the future but for now this test actually won't hit the pagination logic now. async with client: - poller = await client.begin_analyze_healthcare(docs, show_stats=True, polling_interval=self._interval()) + poller = await client.begin_analyze_healthcare_entities(docs, show_stats=True, polling_interval=self._interval()) result = await poller.result() response = [] async for r in result: @@ -701,7 +713,7 @@ async def test_multiple_pages_of_results_with_errors_returned_successfully(self, # in the future but for now this test actually won't hit the pagination logic now. async with client: - result = await (await client.begin_analyze_healthcare(docs, show_stats=True, polling_interval=self._interval())).result() + result = await (await client.begin_analyze_healthcare_entities(docs, show_stats=True, polling_interval=self._interval())).result() response = [] async for r in result: response.append(r) @@ -720,21 +732,26 @@ async def test_multiple_pages_of_results_with_errors_returned_successfully(self, self.assertIsNotNone(doc.statistics) @GlobalTextAnalyticsAccountPreparer() - @TextAnalyticsClientPreparer() + @TextAnalyticsClientPreparer(client_kwargs={"text_analytics_account_key": os.environ.get("AZURE_TEXT_ANALYTICS_KEY"), "text_analytics_account": os.environ.get("AZURE_TEXT_ANALYTICS_ENDPOINT")}) async def test_cancellation(self, client): single_doc = "hello world" docs = [{"id": str(idx), "text": val} for (idx, val) in enumerate(list(itertools.repeat(single_doc, 10)))] async with client: - poller = await client.begin_analyze_healthcare(docs, polling_interval=self._interval()) - cancellation_result = await (await client.begin_cancel_analyze_healthcare(poller, polling_interval=self._interval())).result() + poller = await client.begin_analyze_healthcare_entities(docs, polling_interval=self._interval()) + + try: + cancellation_poller = await poller.cancel() + cancellation_poller.wait() + + except HttpResponseError: + pass # expected if the operation was already in a terminal state. - self.assertIsNone(cancellation_result) @GlobalTextAnalyticsAccountPreparer() @TextAnalyticsClientPreparer() async def test_default_string_index_type_is_UnicodeCodePoint(self, client): - poller = await client.begin_analyze_healthcare(documents=["Hello world"]) + poller = await client.begin_analyze_healthcare_entities(documents=["Hello world"]) actual_string_index_type = poller._polling_method._initial_response.http_request.query["stringIndexType"] self.assertEqual(actual_string_index_type, "UnicodeCodePoint") await poller.result() @@ -742,10 +759,34 @@ async def test_default_string_index_type_is_UnicodeCodePoint(self, client): @GlobalTextAnalyticsAccountPreparer() @TextAnalyticsClientPreparer() async def test_explicit_set_string_index_type(self, client): - poller = await client.begin_analyze_healthcare( + poller = await client.begin_analyze_healthcare_entities( documents=["Hello world"], string_index_type="TextElements_v8" ) actual_string_index_type = poller._polling_method._initial_response.http_request.query["stringIndexType"] self.assertEqual(actual_string_index_type, "TextElements_v8") await poller.result() + + @GlobalTextAnalyticsAccountPreparer() + @TextAnalyticsClientPreparer(client_kwargs={"text_analytics_account_key": os.environ.get("AZURE_TEXT_ANALYTICS_KEY"), "text_analytics_account": os.environ.get("AZURE_TEXT_ANALYTICS_ENDPOINT")}) + async def test_bidirectional_relation_type(self, client): + response = await (await client.begin_analyze_healthcare_entities( + documents=["The patient was diagnosed with Parkinsons Disease (PD)"] + )).result() + + result = [] + async for r in response: + result.append(r) + + self.assertEqual(len(result[0].entities), 2) + entity1 = list(filter(lambda x: x.text == "Parkinsons Disease", result[0].entities))[0] + entity2 = list(filter(lambda x: x.text == "PD", result[0].entities))[0] + + related_entity1, relation_type1 = entity1.related_entities.popitem() + self.assertEqual(related_entity1, entity2) + self.assertEqual(relation_type1, "Abbreviation") + related_entity2, relation_type2 = entity2.related_entities.popitem() + self.assertEqual(related_entity2, entity1) + self.assertEqual(relation_type2, "Abbreviation") + +