Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[qna] regen with latest and implement design changes #20975

Merged
merged 21 commits into from
Sep 30, 2021
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,23 @@
* We are now targeting service version `2021-07-15-preview`

### Breaking changes

* The method `QuestionAnsweringClient.query_knowledgebase` has been renamed to `query_knowledge_base`.
* Options bag model `KnowledgeBaseQueryOptions` for `query_knowledge_base` is renamed to `QueryKnowledgeBaseOptions`
* Options bag model `TextQueryOptions` for `query_text` is renamed to `QueryTextOptions`
* The filters model `StrictFilters` is renamed to `QueryFilters`
* Enum `CompoundOperationKind` is renamed to `LogicalOperationKind`
* We have removed the `string_index_type` input to all models and operations. We have also removed the `StringIndexType` enum.
* The type of input `metadata` to `MetadataFilter` has changed from a dictionary of strings to a list of key-value tuples.
For example, the input has changed from `{"key": "value"}` to `[("key", "value")]`.
iscai-msft marked this conversation as resolved.
Show resolved Hide resolved
* The input to the `query_knowledge_base` and `query_text` overloads that take in a positional model for the body should be
considered positional only.

### Features Added

* The method `QuestionAnsweringClient.query_text` now supports a list of records as strings, where the ID value will be automatically populated.
* Added kwarg `default_language` onto `QuestionAnsweringClient`, which has default value `'en'`. The default language for any operation call will
be this default language value.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. In general, I don't wrap bullets partly to avoid this problem. Some READMEs I just let wrap and don't have artificial returns anywhere. It all renders fine. :)



## 1.0.0b1 (2021-07-27)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ Question Answering is a cloud-based API service that lets you create a conversat

### Prerequisites

* Python 2.7, or 3.6 or later is required to use this package.
* An [Azure subscription][azure_subscription]
* An existing Question Answering resource
- Python 2.7, or 3.6 or later is required to use this package.
- An [Azure subscription][azure_subscription]
- An existing Question Answering resource

> Note: the new unified Cognitive Language Services are not currently available for deployment.

Expand Down Expand Up @@ -56,14 +56,15 @@ client = QuestionAnsweringClient(endpoint, credential)

### QuestionAnsweringClient

The [QuestionAnsweringClient][questionanswering_client_class] is the primary interface for asking questions using a knowledge base with your own information, or text input using pre-trained models.
The [QuestionAnsweringClient][questionanswering_client_class] is the primary interface for asking questions using a knowledge base with your own information, or text input using pre-trained models.
For asynchronous operations, an async `QuestionAnsweringClient` is in the `azure.ai.language.questionanswering.aio` namespace.

## Examples

The `azure-ai-language-questionanswering` client library provides both synchronous and asynchronous APIs.

The following examples show common scenarios using the `client` [created above](#create-questionansweringclient).

- [Ask a question](#ask-a-question)
- [Ask a follow-up question](#ask-a-follow-up-question)
- [Asynchronous operations](#asynchronous-operations)
Expand All @@ -75,7 +76,7 @@ The only input required to ask a question using a knowledge base is just the que
```python
from azure.ai.language.questionanswering import models as qna

params = qna.KnowledgeBaseQueryOptions(
params = qna.QueryKnowledgeBaseOptions(
question="How long should my Surface battery last?"
)

Expand All @@ -89,14 +90,14 @@ for candidate in output.answers:

```

You can set additional properties on `KnowledgeBaseQueryOptions` to limit the number of answers, specify a minimum confidence score, and more.
You can set additional properties on `QueryKnowledgeBaseOptions` to limit the number of answers, specify a minimum confidence score, and more.

### Ask a follow-up question

If your knowledge base is configured for [chit-chat][questionanswering_docs_chat], the answers from the knowledge base may include suggested [prompts for follow-up questions][questionanswering_refdocs_prompts] to initiate a conversation. You can ask a follow-up question by providing the ID of your chosen answer as the context for the continued conversation:

```python
params = qna.models.KnowledgeBaseQueryOptions(
params = qna.models.QueryKnowledgeBaseOptions(
question="How long should charging take?"
context=qna.models.KnowledgeBaseAnswerRequestContext(
previous_qna_id=previous_answer.id
Expand All @@ -112,17 +113,19 @@ for candidate in output.answers:
print("Source: {}".format(candidate.source))

```

### Asynchronous operations

The above examples can also be run asynchronously using the client in the `aio` namespace:

```python
from azure.core.credentials import AzureKeyCredential
from azure.ai.language.questionanswering.aio import QuestionAnsweringClient
from azure.ai.language.questionanswering import models as qna

client = QuestionAnsweringClient(endpoint, credential)

params = qna.KnowledgeBaseQueryOptions(
params = qna.QueryKnowledgeBaseOptions(
question="How long should my Surface battery last?"
)

Expand All @@ -133,11 +136,13 @@ output = await client.query_knowledgebase(
```

## Optional Configuration

Optional keyword arguments can be passed in at the client and per-operation level. The azure-core [reference documentation][azure_core_ref_docs] describes available configurations for retries, logging, transport protocols, and more.

## Troubleshooting

### General

Azure QuestionAnswering clients raise exceptions defined in [Azure Core][azure_core_readme].
When you interact with the Cognitive Language Services Question Answering client library using the Python SDK, errors returned by the service correspond to the same HTTP status codes returned for [REST API][questionanswering_rest_docs] requests.

Expand All @@ -156,6 +161,7 @@ except HttpResponseError as error:
```

### Logging

This library uses the standard
[logging][python_logging] library for logging.
Basic information about HTTP sessions (URLs, headers, etc.) is logged at INFO
Expand All @@ -168,9 +174,9 @@ See full SDK logging documentation with examples [here][sdk_logging_docs].

## Next steps

* View our [samples][questionanswering_samples].
* Read about the different [features][questionanswering_docs_features] of the Question Answering service.
* Try our service [demos][questionanswering_docs_demos].
- View our [samples][questionanswering_samples].
- Read about the different [features][questionanswering_docs_features] of the Question Answering service.
- Try our service [demos][questionanswering_docs_demos].

## Contributing

Expand All @@ -183,6 +189,7 @@ When you submit a pull request, a CLA-bot will automatically determine whether y
This project has adopted the [Microsoft Open Source Code of Conduct][code_of_conduct]. For more information see the [Code of Conduct FAQ][coc_faq] or contact [opencode@microsoft.com][coc_contact] with any additional questions or comments.

<!-- LINKS -->

[azure_cli]: https://docs.microsoft.com/cli/azure/
[azure_portal]: https://portal.azure.com/
[azure_subscription]: https://azure.microsoft.com/free/
Expand All @@ -196,7 +203,7 @@ This project has adopted the [Microsoft Open Source Code of Conduct][code_of_con
[sdk_logging_docs]: https://docs.microsoft.com/azure/developer/python/azure-sdk-logging
[azure_core_ref_docs]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-core/latest/azure.core.html
[azure_core_readme]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/core/azure-core/README.md
[pip_link]:https://pypi.org/project/pip/
[pip_link]: https://pypi.org/project/pip/
[questionanswering_client_class]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-ai-language-questionanswering/1.0.0b1/azure.ai.language.questionanswering.html#azure.ai.language.questionanswering.QuestionAnsweringClient
[questionanswering_refdocs_prompts]: https://azuresdkdocs.blob.core.windows.net/$web/python/azure-ai-language-questionanswering/1.0.0b1/azure.ai.language.questionanswering.models.html#azure.ai.language.questionanswering.models.KnowledgeBaseAnswerDialog
[questionanswering_client_src]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/cognitivelanguage/azure-ai-language-questionanswering/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,26 @@ def _validate_text_records(records):
else:
request_batch.append(doc)
return request_batch

def _get_positional_body(*args, **kwargs):
"""Verify args and kwargs are valid, and then return the positional body, if users passed it in."""
if len(args) > 1:
raise TypeError("There can only be one positional argument, which is the post body of this request.")
iscai-msft marked this conversation as resolved.
Show resolved Hide resolved
if args and "options" in kwargs:
raise TypeError(
"You have already supplied the request body as a positional parameter, you can not supply it as a kwarg as well."
iscai-msft marked this conversation as resolved.
Show resolved Hide resolved
)
return args[0] if args else None

def _verify_qna_id_and_question(query_knowledgebase_options):
"""For query_knowledge_base we require either `question` or `qna_id`."""
try:
qna_id = query_knowledgebase_options.qna_id
question = query_knowledgebase_options.question
except AttributeError:
qna_id = query_knowledgebase_options.get("qna_id") or query_knowledgebase_options.get("qnaId")
question = query_knowledgebase_options.get("question")
if not (qna_id or question):
iscai-msft marked this conversation as resolved.
Show resolved Hide resolved
raise TypeError(
"You need to pass in either `qna_id` or `question`."
)
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class QuestionAnsweringClient(QuestionAnsweringClientOperationsMixin):
:type endpoint: str
:param credential: Credential needed for the client to connect to Azure.
:type credential: ~azure.core.credentials.AzureKeyCredential
:keyword str default_language: Sets the default language to use for all operations.
Defaults to "en".
"""

def __init__(
Expand All @@ -49,6 +51,7 @@ def __init__(
self._serialize = Serializer(client_models)
self._deserialize = Deserializer(client_models)
self._serialize.client_side_validation = False
self._default_language = kwargs.pop("default_language", "en")
iscai-msft marked this conversation as resolved.
Show resolved Hide resolved

def send_request(
self,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class QuestionAnsweringClient(QuestionAnsweringClientOperationsMixin):
:type endpoint: str
:param credential: Credential needed for the client to connect to Azure.
:type credential: ~azure.core.credentials.AzureKeyCredential
:keyword str default_language: Sets the default language to use for all operations.
Defaults to "en".
iscai-msft marked this conversation as resolved.
Show resolved Hide resolved
"""

def __init__(self, endpoint: str, credential: AzureKeyCredential, **kwargs: Any) -> None:
Expand All @@ -38,6 +40,7 @@ def __init__(self, endpoint: str, credential: AzureKeyCredential, **kwargs: Any)
self._serialize = Serializer(client_models)
self._deserialize = Deserializer(client_models)
self._serialize.client_side_validation = False
self._default_language = kwargs.pop("default_language", "en")

def send_request(self, request: HttpRequest, **kwargs: Any) -> Awaitable[AsyncHttpResponse]:
"""Runs the network request through the client's chained policies.
Expand Down
Loading