8000 Merge branch 'master' into axsuarez/integration-and-skills-tests · TheCompuGuru/botbuilder-python@a275712 · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a275712

Browse files
authored
Merge branch 'master' into axsuarez/integration-and-skills-tests
2 parents 406f4c9 + a1a4ed6 commit a275712

File tree

56 files changed

+1094
-113
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1094
-113
lines changed

libraries/botbuilder-ai/botbuilder/ai/qna/models/generate_answer_request_body.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from .metadata import Metadata
99
from .qna_request_context import QnARequestContext
10+
from .ranker_types import RankerTypes
1011

1112

1213
class GenerateAnswerRequestBody(Model):
@@ -19,6 +20,8 @@ class GenerateAnswerRequestBody(Model):
1920
"strict_filters": {"key": "strictFilters", "type": "[Metadata]"},
2021
"context": {"key": "context", "type": "QnARequestContext"},
2122
"qna_id": {"key": "qnaId", "type": "int"},
23+
"is_test": {"key": "isTest", "type": "bool"},
24+
"ranker_type": {"key": "rankerType", "type": "RankerTypes"},
2225
}
2326

2427
def __init__(
@@ -29,6 +32,8 @@ def __init__(
2932
strict_filters: List[Metadata],
3033
context: QnARequestContext = None,
3134
qna_id: int = None,
35+
is_test: bool = False,
36+
ranker_type: str = RankerTypes.DEFAULT,
3237
**kwargs
3338
):
3439
"""
@@ -47,6 +52,10 @@ def __init__(
4752
4853
qna_id: Id of the current question asked.
4954
55+
is_test: (Optional) A value indicating whether to call test or prod environment of knowledgebase.
56+
57+
ranker_types: (Optional) Ranker types.
58+
5059
"""
5160

5261
super().__init__(**kwargs)
@@ -57,3 +66,5 @@ def __init__(
5766
self.strict_filters = strict_filters
5867
self.context = context
5968
self.qna_id = qna_id
69+
self.is_test = is_test
70+
self.ranker_type = ranker_type

libraries/botbuilder-ai/botbuilder/ai/qna/models/qnamaker_trace_info.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from .metadata import Metadata
88
from .query_result import QueryResult
99
from .qna_request_context import QnARequestContext
10+
from .ranker_types import RankerTypes
1011

1112

1213
class QnAMakerTraceInfo:
@@ -22,6 +23,8 @@ def __init__(
2223
strict_filters: List[Metadata],
2324
context: QnARequestContext = None,
2425
qna_id: int = None,
26+
is_test: bool = False,
27+
ranker_type: str = RankerTypes.DEFAULT,
2528
):
2629
"""
2730
Parameters:
@@ -42,6 +45,10 @@ def __init__(
4245
context: (Optional) The context from which the QnA was extracted.
4346
4447
qna_id: (Optional) Id of the current question asked.
48+
49+
is_test: (Optional) A value indicating whether to call test or prod environment of knowledgebase.
50+
51+
ranker_types: (Optional) Ranker types.
4552
"""
4653
self.message = message
4754
self.query_results = query_results
@@ -51,3 +58,5 @@ def __init__(
5158
self.strict_filters = strict_filters
5259
self.context = context
5360
self.qna_id = qna_id
61+
self.is_test = is_test
62+
self.ranker_type = ranker_type
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
5+
class RankerTypes:
6+
7+
""" Default Ranker Behaviour. i.e. Ranking based on Questions and Answer. """
8+
9+
DEFAULT = "Default"
10+
11+
""" Ranker based on question Only. """
12+
QUESTION_ONLY = "QuestionOnly"
13+
14+
""" Ranker based on Autosuggest for question field only. """
15+
AUTO_SUGGEST_QUESTION = "AutoSuggestQuestion"

libraries/botbuilder-ai/botbuilder/ai/qna/qnamaker_options.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# Licensed under the MIT License.
33

44
from .models import Metadata, QnARequestContext
5+
from .models.ranker_types import RankerTypes
56

67
# figure out if 300 milliseconds is ok for python requests library...or 100000
78
class QnAMakerOptions:
@@ -13,10 +14,14 @@ def __init__(
1314
strict_filters: [Metadata] = None,
1415
context: [QnARequestContext] = None,
1516
qna_id: int = None,
17+
is_test: bool = False,
18+
ranker_type: bool = RankerTypes.DEFAULT,
1619
):
1720
self.score_threshold = score_threshold
1821
self.timeout = timeout
1922
self.top = top
2023
self.strict_filters = strict_filters or []
2124
self.context = context
2225
self.qna_id = qna_id
26+
self.is_test = is_test
27+
self.ranker_type = ranker_type

libraries/botbuilder-ai/botbuilder/ai/qna/utils/generate_answer_utils.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ def _hydrate_options(self, query_options: QnAMakerOptions) -> QnAMakerOptions:
139139

140140
hydrated_options.context = query_options.context
141141
hydrated_options.qna_id = query_options.qna_id
142+
hydrated_options.is_test = query_options.is_test
143+
hydrated_options.ranker_type = query_options.ranker_type
142144

143145
return hydrated_options
144146

@@ -154,6 +156,8 @@ async def _query_qna_service(
154156
strict_filters=options.strict_filters,
155157
context=options.context,
156158
qna_id=options.qna_id,
159+
is_test=options.is_test,
160+
ranker_type=options.ranker_type,
157161
)
158162

159163
http_request_helper = HttpRequestUtils(self._http_client)
@@ -178,6 +182,8 @@ async def _emit_trace_info(
178182
strict_filters=options.strict_filters,
179183
context=options.context,
180184
qna_id=options.qna_id,
185+
is_test=options.is_test,
186+
ranker_type=options.ranker_type,
181187
)
182188

183189
trace_activity = Activity(
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"activeLearningEnabled": true,
3+
"answers": [
4+
{
5+
"questions": [],
6+
"answer": "No good match found in KB.",
7+
"score": 0,
8+
"id": -1,
9+
"source": null,
10+
"metadata": []
11+
}
12+
]
13+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"activeLearningEnabled": false,
3+
"answers": [
4+
{
5+
"questions": [
6+
"Q1"
7+
],
8+
"answer": "A1",
9+
"score": 80,
10+
"id": 15,
11+
"source": "Editorial",
12+
"metadata": [
13+
{
14+
"name": "topic",
15+
"value": "value"
16+
}
17+
]
18+
},
19+
{
20+
"questions": [
21+
"Q2"
22+
],
23+
"answer": "A2",
24+
"score": 78,
25+
"id": 16,
26+
"source": "Editorial",
27+
"metadata": [
28+
{
29+
"name": "topic",
30+
"value": "value"
31+
}
32+
]
33+
}
34+
]
35+
}

libraries/botbuilder-ai/tests/qna/test_qna.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,38 @@ async def test_should_filter_low_score_variation(self):
702702
"Should have 3 filtered answers after low score variation.",
703703
)
704704

705+
async def test_should_answer_with_is_test_true(self):
706+
options = QnAMakerOptions(top=1, is_test=True)
707+
qna = QnAMaker(QnaApplicationTest.tests_endpoint)
708+
question: str = "Q11"
709+
context = QnaApplicationTest._get_context(question, TestAdapter())
710+
response_json = QnaApplicationTest._get_json_for_file(
711+
"QnaMaker_IsTest_true.json"
712+
)
713+
714+
with patch(
715+
"aiohttp.ClientSession.post",
716+
return_value=aiounittest.futurized(response_json),
717+
):
718+
results = await qna.get_answers(context, options=options)
719+
self.assertEqual(0, len(results), "Should have received zero answer.")
720+
721+
async def test_should_answer_with_ranker_type_question_only(self):
722+
options = QnAMakerOptions(top=1, ranker_type="QuestionOnly")
723+
qna = QnAMaker(QnaApplicationTest.tests_endpoint)
724+
question: str = "Q11"
725+
context = QnaApplicationTest._get_context(question, TestAdapter())
726+
response_json = QnaApplicationTest._get_json_for_file(
727+
"QnaMaker_RankerType_QuestionOnly.json"
728+
)
729+
730+
with patch(
731+
"aiohttp.ClientSession.post",
732+
return_value=aiounittest.futurized(response_json),
733+
):
734+
results = await qna.get_answers(context, options=options)
735+
self.assertEqual(2, len(results), "Should have received two answers.")
736+
705737
async def test_should_answer_with_prompts(self):
706738
options = QnAMakerOptions(top=2)
707739
qna = QnAMaker(QnaApplicationTest.tests_endpoint, options)

libraries/botbuilder-core/botbuilder/core/activity_handler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ async def on_turn(self, turn_context: TurnContext):
3333
elif turn_context.activity.type == ActivityTypes.event:
3434
await self.on_event_activity(turn_context)
3535
elif turn_context.activity.type == ActivityTypes.end_of_conversation:
36-
await self.on_end_of_conversation(turn_context)
36+
await self.on_end_of_conversation_activity(turn_context)
3737
else:
3838
await self.on_unrecognized_activity_type(turn_context)
3939

@@ -106,7 +106,7 @@ async def on_event( # pylint: disable=unused-argument
106106
):
107107
return
108108

109-
async def on_end_of_conversation( # pylint: disable=unused-argument
109+
async def on_end_of_conversation_activity( # pylint: disable=unused-argument
110110
self, turn_context: TurnContext
111111
):
112112
return

libraries/botbuilder-core/botbuilder/core/auto_save_state_middleware.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
14
from typing import Awaitable, Callable, List, Union
25

36
from .bot_state import BotState

libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
from .bot_adapter import BotAdapter
3939
from .turn_context import TurnContext
4040
from .user_token_provider import UserTokenProvider
41+
from .invoke_response import InvokeResponse
4142
from .conversation_reference_extension import get_continuation_activity
4243

4344
USER_AGENT = f"Microsoft-BotFramework/3.1 (BotBuilder Python/{__version__})"
@@ -263,7 +264,17 @@ async def process_activity(self, req, auth_header: str, logic: Callable):
263264
teams_channel_data["tenant"]["id"]
264265
)
265266

266-
return await self.run_pipeline(context, logic)
267+
await self.run_pipeline(context, logic)
268+
269+
if activity.type == ActivityTypes.invoke:
270+
invoke_response = context.turn_state.get(
271+
BotFrameworkAdapter._INVOKE_RESPONSE_KEY # pylint: disable=protected-access
272+
)
273+
if invoke_response is None:
274+
return InvokeResponse(status=501)
275+
return invoke_response.value
276+
277+
return None
267278

268279
async def authenticate_request(
269280
self, request: Activity, auth_header: str
@@ -283,7 +294,7 @@ async def authenticate_request(
283294
)
284295

285296
if not claims.is_authenticated:
286-
raise Exception("Unauthorized Access. Request is not authorized")
297+
raise PermissionError("Unauthorized Access. Request is not authorized")
287298

288299
return claims
289300

libraries/botbuilder-core/botbuilder/core/bot_state_set.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
14
from asyncio import wait
25
from typing import List
36
from .bot_state import BotState

libraries/botbuilder-core/botbuilder/core/integration/aiohttp_channel_service_exception_middleware.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
14
from aiohttp.web import (
25
middleware,
36
HTTPNotImplemented,

libraries/botbuilder-core/botbuilder/core/private_conversation_state.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
14
from .bot_state import BotState
25
from .turn_context import TurnContext
36
from .storage import Storage

libraries/botbuilder-core/botbuilder/core/show_typing_middleware.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
14
import time
25
from functools import wraps
36
from typing import Awaitable, Callable

libraries/botbuilder-core/botbuilder/core/teams/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from .teams_activity_handler import TeamsActivityHandler
99
from .teams_info import TeamsInfo
10-
from .teams_helper import deserializer_helper
10+
from .teams_helper import deserializer_helper, serializer_helper
1111
from .teams_activity_extensions import (
1212
teams_get_channel_id,
1313
teams_get_team_info,
@@ -21,4 +21,5 @@
2121
"teams_get_channel_id",
2222
"teams_get_team_info",
2323
"teams_notify_user",
24+
"serializer_helper",
2425
]

libraries/botbuilder-core/botbuilder/core/teams/teams_activity_extensions.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
14
from botbuilder.schema import Activity
25
from botbuilder.schema.teams import NotificationInfo, TeamsChannelData, TeamInfo
36

47

5-
def dummy():
6-
return 1
7-
8-
98
def teams_get_channel_id(activity: Activity) -> str:
109
if not activity:
1110
return None

0 commit comments

Comments
 (0)
0