1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
|
# Guide for migrating to azure-ai-language-questionanswering from azure-cognitiveservices-knowledge-qnamaker
This guide is intended to assist in the migration to [azure-ai-language-questionanswering](https://pypi.org/project/azure-ai-language-questionanswering/) from the old one [azure-cognitiveservices-knowledge-qnamaker](https://pypi.org/project/azure-cognitiveservices-knowledge-qnamaker/). It will focus on side-by-side comparisons for similar operations between the two packages.
Familiarity with the `azure-cognitiveservices-knowledge-qnamaker` package is assumed. For those new to the Question Answering client library for Python, please refer to the [README for azure-ai-language-questionanswering][qna_readme] rather than this guide.
## Table of contents
- [Migration benefits](#migration-benefits)
- [General changes](#general-changes)
- [Package and namespaces](#package-and-namespaces)
- [Runtime Client](#runtime-client)
- [Authenticating runtime client](#authenticating-runtime-client)
- [Querying a question](#querying-a-question)
- [Chatting](#chatting)
- [Authoring Client](#authoring-client)
- [Authenticating authoring client](#authenticating-authoring-client)
- [Creating knowledge base](#creating-knowledge-base)
- [Updating knowledge base](#updating-knowledge-base)
- [Exporting knowledge base](#exporting-knowledge-base)
- [Deleting knowledge base](#deleting-knowledge-base)
- [Async operations](#async-operations)
- [Additional Samples](#additional-samples)
## Migration benefits
A natural question to ask when considering whether or not to adopt a new version or library is what the benefits of doing so would be. As Azure has matured and been embraced by a more diverse group of developers, we have been focused on learning the patterns and practices to best support developer productivity and to understand the gaps that the Python client libraries have.
There were several areas of consistent feedback expressed across the Azure client library ecosystem. One of the most important is that the client libraries for different Azure services have not had a consistent approach to organization, naming, and API structure. Additionally, many developers have felt that the learning curve was difficult, and the APIs did not offer a good, approachable, and consistent onboarding story for those learning Azure or exploring a specific Azure service.
To try and improve the development experience across Azure services, a set of uniform [design guidelines][design_guidelines] was created for all languages to drive a consistent experience with established API patterns for all services. A set of [Python-specific guidelines][python_specific_guidelines] was also introduced to ensure that Python clients have a natural and idiomatic feel with respect to the Python ecosystem. Further details are available in the guidelines for those interested.
## General changes
The modern Question Answering client library provides the ability to share in some of the cross-service improvements made to the Azure development experience, such as
- using the new [azure-identity][identity_readme] library to share a single authentication approach between clients
- a unified logging and diagnostics pipeline offering a common view of the activities across each of the client libraries
### Package and namespaces
Package names and the namespace root for the modern Azure Cognitive Services client libraries for Python have changed. Each will follow the pattern `azure.ai.[services]` where the legacy clients followed the pattern `azure.cognitiveservices.[services]`. This provides a quick and accessible means to help understand, at a glance, whether you are using the modern or legacy clients.
In the case of Question Answering, the modern client libraries have packages and namespaces that begin with `azure.ai.language.questionanswering` and were released beginning with version 1. The legacy client libraries have packages and namespaces that begin with `azure.cognitiveservices.knowledge.qnamaker` and a version of 0.3.0 or below.
### Runtime Client
#### Authenticating runtime client
Previously in `azure-cognitiveservices-knowledge-qnamaker` you could create a `QnAMakerClient` by using `CognitiveServicesCredentials` from `msrest.authentication`:
```python
from msrest.authentication import CognitiveServicesCredentials
from azure.cognitiveservices.knowledge.qnamaker import QnAMakerClient
client = QnAMakerClient(
endpoint="https://<my-cognitiveservices-account>.cognitiveservices.azure.com",
credentials=CognitiveServicesCredentials("API key")
)
```
Now in `azure-ai-language-questionanswering` you can create a `QuestionAnsweringClient` using an [AzureKeyCredential][azure_key_credential] or a token credential from the [azure-identity](https://pypi.org/project/azure-identity/) library:
```python
from azure.core.credentials import AzureKeyCredential
from azure.ai.language.questionanswering import QuestionAnsweringClient
client = QuestionAnsweringClient(
endpoint="https://<my-cognitiveservices-account>.cognitiveservices.azure.com",
credential=AzureKeyCredential("API key")
)
```
```python
from azure.identity import DefaultAzureCredential
from azure.ai.language.questionanswering import QuestionAnsweringClient
client = QuestionAnsweringClient(
endpoint="https://<my-cognitiveservices-account>.cognitiveservices.azure.com",
credential=DefaultAzureCredential()
)
```
#### Querying a question
In `azure-cognitiveservices-knowledge-qnamaker`, you could query for a question using `QueryDTO`:
```python
from azure.cognitiveservices.knowledge.qnamaker.models import QueryDTO
from azure.cognitiveservices.knowledge.qnamaker import QnAMakerClient
client = QnAMakerClient(endpoint, credentials)
generate_answer_payload = QueryDTO(
question="How long should my Surface battery last?",
)
response = client.knowledgebase.generate_answer(
kb_id="<my-knowledge-base-id>",
generate_answer_payload=generate_answer_payload,
)
best_answers = [a for a in response.answers if a.score > 0.9]
```
In the modern `azure-ai-language-questionanswering`, you use `get_answers`:
```python
from azure.ai.language.questionanswering import QuestionAnsweringClient
client = QuestionAnsweringClient(endpoint=endpoint, credential=credential)
response = client.get_answers(
question="How long should my Surface battery last?",
project_name="<my-qna-project-name>",
deployment_name="<my-qna-deployment-name>"
)
best_answers = [a for a in response.answers if a.confidence_score > 0.9]
```
#### Chatting
Previously in `azure-cognitiveservices-knowledge-qnamaker`, you could chat using `QueryDTO` along with setting the context to have `previous_qna_id`:
```python
from azure.cognitiveservices.knowledge.qnamaker.models import QueryDTO, QueryDTOContext
from azure.cognitiveservices.knowledge.qnamaker import QnAMakerClient
client = QnAMakerClient(endpoint, credentials)
generate_answer_payload = QueryDTO(
question="How long should my Surface battery last?",
context=QueryDTOContext(previous_qna_id=1)
)
response = client.knowledgebase.generate_answer(
kb_id="<my-knowledge-base-id>",
generate_answer_payload=generate_answer_payload,
)
best_answers = [a for a in response.answers if a.score > 0.9]
```
Now in `azure-ai-language-questionanswering`, you use `KnowledgeBaseAnswerContext` to set `project_name`, `deployment_name`, and `question` along with setting the `answer_context` to have `previous_qna_id`:
```python
from azure.ai.language.questionanswering import QuestionAnsweringClient
from azure.ai.language.questionanswering.models import KnowledgeBaseAnswerContext
client = QuestionAnsweringClient(endpoint=endpoint, credential=credential)
response = client.get_answers(
question="How long should my Surface battery last?",
project_name="<my-qna-project-name>",
deployment_name="<my-qna-deployment-name>",
answer_context=KnowledgeBaseAnswerContext(
previous_qna_id=1
)
)
best_answers = [a for a in response.answers if a.confidence_score > 0.9]
```
### Authoring Client
#### Authenticating authoring client
Previously in `azure-cognitiveservices-knowledge-qnamaker` you could create a `QnAMakerClient` by using `CognitiveServicesCredentials` from `msrest.authentication`:
```python
from msrest.authentication import CognitiveServicesCredentials
from azure.cognitiveservices.knowledge.qnamaker import QnAMakerClient
client = QnAMakerClient(
endpoint="https://<my-cognitiveservices-account>.cognitiveservices.azure.com",
credentials=CognitiveServicesCredentials("API key")
)
```
Now in `azure-ai-language-questionanswering` you can create a `AuthoringClient` using an [AzureKeyCredential][azure_key_credential] or a token credential from the [azure-identity](https://pypi.org/project/azure-identity/) library:
```python
from azure.core.credentials import AzureKeyCredential
from azure.ai.language.questionanswering.authoring import AuthoringClient
client = AuthoringClient(
endpoint="https://<my-cognitiveservices-account>.cognitiveservices.azure.com",
credential=AzureKeyCredential("API key")
)
```
```python
from azure.identity import DefaultAzureCredential
from azure.ai.language.questionanswering.authoring import AuthoringClient
client = AuthoringClient(
endpoint="https://<my-cognitiveservices-account>.cognitiveservices.azure.com",
credential=DefaultAzureCredential()
)
```
#### Creating knowledge base
Previously in `azure-cognitiveservices-knowledge-qnamaker`, you could create a new knowledgebase using a `CreateKbDTO`:
```python
import time
from msrest.authentication import CognitiveServicesCredentials
from azure.cognitiveservices.knowledge.qnamaker.models import CreateKbDTO, QnADTO
from azure.cognitiveservices.knowledge.qnamaker import QnAMakerClient
client = QnAMakerClient(
endpoint="https://<my-cognitiveservices-account>.cognitiveservices.azure.com",
credentials=CognitiveServicesCredentials("API key")
)
operation = client.knowledgebase.create(
create_kb_payload=CreateKbDTO(
name="<knowledgebase-name>",
qna_list=[
QnADTO(
questions=["questions"],
answer="answer"
)
]
)
)
for i in range(20):
if operation.operation_state in ["NotStarted", "Running"]:
print("Waiting for operation: {} to complete.".format(operation.operation_id))
time.sleep(5)
operation = client.operations.get_details(operation_id=operation.operation_id)
else:
break
if operation.operation_state != "Succeeded":
raise Exception("Operation {} failed to complete.".format(operation.operation_id))
# Get knowledge base ID from resourceLocation HTTP header
knowledge_base_id = operation.resource_location.replace("/knowledgebases/", "")
print("Created KB with ID: {}".format(knowledge_base_id))
```
Now in `azure-ai-language-questionanswering`, you can create a new Question Answering project by passing a `dict` with the needed project creation properties:
```python
from azure.core.credentials import AzureKeyCredential
from azure.ai.language.questionanswering.authoring import AuthoringClient
client = AuthoringClient(
endpoint="https://<my-cognitiveservices-account>.cognitiveservices.azure.com",
credential=AzureKeyCredential("API key")
)
project = client.create_project(
project_name="<project_name>",
options={
"description": "This is the description for a test project",
"language": "en",
"multilingualResource": True,
"settings": {
"defaultAnswer": "no answer"
}
})
print(f"Project name: {project['projectName']}")
print(f"language: {project['language']}")
print(f"description: {project['description']}")
```
#### Updating knowledge base
Previously in `azure-cognitiveservices-knowledge-qnamaker`, you could update your knowledge base using a `UpdateKbOperationDTO`:
```python
import time
from msrest.authentication import CognitiveServicesCredentials
from azure.cognitiveservices.knowledge.qnamaker.models import UpdateKbOperationDTO, UpdateKbOperationDTOAdd, QnADTO
from azure.cognitiveservices.knowledge.qnamaker import QnAMakerClient
client = QnAMakerClient(
endpoint="https://<my-cognitiveservices-account>.cognitiveservices.azure.com",
credentials=CognitiveServicesCredentials("API key")
)
operation = client.knowledgebase.update(
kb_id="<knowledgebase-id>",
update_kb=UpdateKbOperationDTO(
add=UpdateKbOperationDTOAdd(
qna_list=[
QnADTO(
questions=["questions"],
answer="answer"
)
]
)
)
)
for i in range(20):
if operation.operation_state in ["NotStarted", "Running"]:
print("Waiting for operation: {} to complete.".format(operation.operation_id))
time.sleep(5)
operation = client.operations.get_details(operation_id=operation.operation_id)
else:
break
if operation.operation_state != "Succeeded":
raise Exception("Operation {} failed to complete.".format(operation.operation_id))
# Get knowledge base ID from resourceLocation HTTP header
knowledge_base_id = operation.resource_location.replace("/knowledgebases/", "")
print("Created KB with ID: {}".format(knowledge_base_id))
```
Now in `azure-ai-language-questionanswering`, you can update your knowledge source using the `begin_update_sources` method:
```python
from azure.core.credentials import AzureKeyCredential
from azure.ai.language.questionanswering.authoring import AuthoringClient
client = AuthoringClient(
endpoint="https://<my-cognitiveservices-account>.cognitiveservices.azure.com",
credential=AzureKeyCredential("API key")
)
sources_poller = client.begin_update_sources(
project_name="<project_name>",
sources=[{
"op": "add",
"value": {
"displayName": "MicrosoftFAQ",
"source": "https://www.microsoft.com/en-in/software-download/faq",
"sourceUri": "https://www.microsoft.com/en-in/software-download/faq",
"sourceKind": "url",
"contentStructureKind": "unstructured",
"refresh": False
}
}]
)
sources = sources_poller.result()
for item in sources:
print(f"source name: {item.get('displayName', 'N/A')}")
print(f"\tsource: {item['source']}")
print(f"\tsource uri: {item.get('sourceUri', 'N/A')}")
print(f"\tsource kind: {item['sourceKind']}")
```
You can also update a project's questions and answers directly as follows:
```python
from azure.core.credentials import AzureKeyCredential
from azure.ai.language.questionanswering.authoring import AuthoringClient
client = AuthoringClient(
endpoint="https://<my-cognitiveservices-account>.cognitiveservices.azure.com",
credential=AzureKeyCredential("API key")
)
qna_poller = client.begin_update_qnas(
project_name="<project_name>",
qnas=[{
"op": "add",
"value": {
"questions": [
"What is the easiest way to use Azure services in my Python project?"
],
"answer": "Using the Azure SDKs"
}
}]
)
qnas = qna_poller.result()
for item in qnas:
print(f"qna: {item['id']}")
print("\tquestions:")
for question in item["questions"]:
print(f"\t\t{question}")
print(f"\tanswer: {item['answer']}")
```
#### Exporting knowledge base
Previously in `azure-cognitiveservices-knowledge-qnamaker`, you could download your knowledge base using the `download` method:
```python
from msrest.authentication import CognitiveServicesCredentials
from azure.cognitiveservices.knowledge.qnamaker import QnAMakerClient
client = QnAMakerClient(
endpoint="https://<my-cognitiveservices-account>.cognitiveservices.azure.com",
credentials=CognitiveServicesCredentials("API key")
)
data = client.knowledgebase.download(
kb_id="<knowledgebase-id>",
environment="Test",
)
print(data.qna_documents)
```
Now you can export your Question Answering project:
```python
from azure.core.credentials import AzureKeyCredential
from azure.ai.language.questionanswering.authoring import AuthoringClient
client = AuthoringClient(
endpoint="https://<my-cognitiveservices-account>.cognitiveservices.azure.com",
credential=AzureKeyCredential("API key")
)
export_poller = client.begin_export(
project_name="<project_name>",
file_format="json"
)
export_result = export_poller.result()
export_url = export_result["resultUrl"]
```
#### Deleting knowledge base
Previously in `azure-cognitiveservices-knowledge-qnamaker`, you could delete your knowledge base using the `delete` method:
```python
from msrest.authentication import CognitiveServicesCredentials
from azure.cognitiveservices.knowledge.qnamaker import QnAMakerClient
client = QnAMakerClient(
endpoint="https://<my-cognitiveservices-account>.cognitiveservices.azure.com",
credentials=CognitiveServicesCredentials("API key")
)
client.knowledgebase.delete(
kb_id="<knowledgebase-id>"
)
```
Now in `azure-ai-language-questionanswering`, you can delete a project using the `begin_delete_project` method:
```python
from azure.core.credentials import AzureKeyCredential
from azure.ai.language.questionanswering.authoring import AuthoringClient
client = AuthoringClient(
endpoint="https://<my-cognitiveservices-account>.cognitiveservices.azure.com",
credential=AzureKeyCredential("API key")
)
delete_poller = client.begin_delete_project(
project_name="<project_name>",
)
delete_poller.result()
```
## Async operations
The modern `azure-ai-language-questionanswering` library includes a complete set of async APIs. To use it, you must first install an async transport, such as [aiohttp][aiohttp]. See [azure-core documentation][azure_core_transport] for more information.
Async operations are available on async clients, which should be closed when they're no longer needed. Each async client is an async context manager and defines an async `close` method. For example:
```python
from azure.core.credentials import AzureKeyCredential
from azure.ai.language.questionanswering.aio import QuestionAnsweringClient
endpoint = "https://<my-cognitiveservices-account>.cognitiveservices.azure.com"
credential = AzureKeyCredential("API key")
# call close when the client is no longer needed
client = QuestionAnsweringClient(endpoint=endpoint, credential=credential)
...
await client.close()
# alternatively, use the client as an async context manager
async with QuestionAnsweringClient(endpoint=endpoint, credential=credential) as client:
...
```
## Additional Samples
The new `azure-ai-language-questionanswering` has new capabilities not supported by the old client library, you can
see additional samples [here][qna_samples].
<!--LINKS-->
[qna_readme]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/cognitivelanguage/azure-ai-language-questionanswering/README.md
[design_guidelines]: https://azure.github.io/azure-sdk/python/guidelines/index.html
[python_specific_guidelines]: https://azure.github.io/azure-sdk/python_design.html
[identity_readme]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/identity/azure-identity/README.md
[azure_key_credential]: https://learn.microsoft.com/python/api/azure-core/azure.core.credentials.azurekeycredential?view=azure-python
[aiohttp]: https://pypi.org/project/aiohttp/
[azure_core_transport]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/core/azure-core/CLIENT_LIBRARY_DEVELOPER.md#transport
[qna_samples]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/cognitivelanguage/azure-ai-language-questionanswering/samples
|