8000 Merge branch 'master' into kyled/ActivityPrompt · snifhex/botbuilder-python@a428abb · GitHub
[go: up one dir, main page]

Skip to content

Commit a428abb

Browse files
authored
Merge branch 'master' into kyled/ActivityPrompt
2 parents 7cb4ff3 + dc9d4f0 commit a428abb

File tree

16 files changed

+534
-63
lines changed

16 files changed

+534
-63
lines changed

README.md

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
### [What's new with Bot Framework](https://docs.microsoft.com/en-us/azure/bot-service/what-is-new?view=azure-bot-service-4.0)
44

5-
This repository contains code for the Python version of the [Microsoft Bot Framework SDK](https://github.com/Microsoft/botframework-sdk), which is part of the Microsoft Bot Framework - a comprehensive framework for building enterprise-grade conversational AI experiences.
5+
This repository contains code for the Python version of the [Microsoft Bot Framework SDK](https://github.com/Microsoft/botframework-sdk), which is part of the Microsoft Bot Framework - a comprehensive framework for building enterprise-grade conversational AI experiences.
66

77
This SDK enables developers to model conversation and build sophisticated bot applications using Python. SDKs for [JavaScript](https://github.com/Microsoft/botbuilder-js), [.NET](https://github.com/Microsoft/botbuilder-dotnet) and [Java (preview)](https://github.com/Microsoft/botbuilder-java) are also available.
88

@@ -40,13 +40,13 @@ To get started building bots using the SDK, see the [Azure Bot Service Documenta
4040

4141
The [Bot Framework Samples](https://github.com/microsoft/botbuilder-samples) includes a rich set of samples repository.
4242

43-
If you want to debug an issue, would like to [contribute](#contributing), or understand how the Bot Builder SDK works, instructions for building and testing the SDK are below.
43+
If you want to debug an issue, would like to [contribute](#contributing-code), or understand how the Bot Builder SDK works, instructions for building and testing the SDK are below.
4444

4545
### Prerequisites
4646
- [Git](https://git-scm.com/downloads)
4747
- [Python 3.8.2](https://www.python.org/downloads/)
4848

49-
Python "Virtual Environments" allow Python packages to be installed in an isolated location for a particular application, rather than being installed globally, as such it is common practice to use them. Click [here](https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments) to learn more about creating _and activating_ Virtual Environments in Python.
49+
Python "Virtual Environments" allow Python packages to be installed in an isolated location for a particular application, rather than being installed globally, as such it is common practice to use them. Click [here](https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments) to learn more about creating _and activating_ Virtual Environments in Python.
5050

5151
### Clone
5252
Clone a copy of the repo:
@@ -60,12 +60,7 @@ cd botbuilder-python
6060

6161
### Using the SDK locally
6262

63-
You will need the following 3 packages installed in your environment:
64-
- [botframework-connector](https://pypi.org/project/botframework-connector/)
65-
- [botbuilder-core](https://pypi.org/project/botbuilder-core/)
66-
- [botbuilder-schema](https://pypi.org/project/botbuilder-schema/)
67-
68-
To use a local copy of the SDK you can link to these packages with the pip -e option.
63+
To use a local copy of the SDK you can link to these packages with the pip -e option.
6964

7065
```bash
7166
pip install -e ./libraries/botbuilder-schema
@@ -108,12 +103,12 @@ plugins: cov-2.5.1
108103
Below are the various channels that are available to you for obtaining support and providing feedback. Please pay carful attention to which channel should be used for which type of content. e.g. general "how do I..." questions should be asked on Stack Overflow, Twitter or Gitter, with GitHub issues being for feature requests and bug reports.
109104

110105
### Github issues
111-
[Github issues](https://github.com/Microsoft/botbuilder-python/issues) should be used for bugs and feature requests.
106+
[Github issues](https://github.com/Microsoft/botbuilder-python/issues) should be used for bugs and feature requests.
112107

113108
### Stack overflow
114109
[Stack Overflow](https://stackoverflow.com/questions/tagged/botframework) is a great place for getting high-quality answers. Our support team, as well as many of our community members are already on Stack Overflow providing answers to 'how-to' questions.
115110

116-
### Azure Support
111+
### Azure Support
117112
If you issues relates to [Azure Bot Service](https://azure.microsoft.com/en-gb/services/bot-service/), you can take advantage of the available [Azure support options](https://azure.microsoft.com/en-us/support/options/).
118113

119114
### Twitter
@@ -125,19 +120,29 @@ The [Gitter Channel](https://gitter.im/Microsoft/BotBuilder) provides a place wh
125120
## Contributing and our code of conduct
126121
We welcome contributions and suggestions. Please see our [contributing guidelines](./contributing.md) for more information.
127122

128-
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
123+
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
124+
129125
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact
130126
[opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
131127

128+
### Contributing Code
129+
130+
In order to create pull requests, submitted code must pass ```pylint``` and ```black``` checks. Run both tools on every file you've changed.
131+
132+
For more information and installation instructions, see:
133+
134+
* [black](https://pypi.org/project/black/)
135+
* [pylint](https://pylint.org/)
136+
132137
## Reporting Security Issues
133-
Security issues and bugs should be reported privately, via email, to the Microsoft Security Response Center (MSRC)
138+
Security issues and bugs should be reported privately, via email, to the Microsoft Security Response Center (MSRC)
134139
at [secure@microsoft.com](mailto:secure@microsoft.com). You should receive a response within 24 hours. If for some
135-
reason you do not, please follow up via email to ensure we received your original message. Further information,
136-
including the [MSRC PGP](https://technet.microsoft.com/en-us/security/dn606155) key, can be found in the
140+
reason you do not, please follow up via email to ensure we received your original message. Further information,
141+
including the [MSRC PGP](https://technet.microsoft.com/en-us/security/dn606155) key, can be found in the
137142
[Security TechCenter](https://technet.microsoft.com/en-us/security/default).
138143

139144
Copyright (c) Microsoft Corporation. All rights reserved.
140145

141-
Licensed under the [MIT](./LICENSE.md) License.
146+
Licensed under the [MIT](./LICENSE) License.
142147

143148

libraries/botbuilder-azure/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from setuptools import setup
66

77
REQUIRES = [
8-
"azure-cosmos==3.1.2",
8+
"azure-cosmos==3.2.0",
99
"azure-storage-blob==2.1.0",
1010
"botbuilder-schema==4.10.0",
1111
"botframework-connector==4.10.0",

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ async def on_turn(self, turn_context: TurnContext):
8686
await self.on_end_of_conversation_activity(turn_context)
8787
elif turn_context.activity.type == ActivityTypes.typing:
8888
await self.on_typing_activity(turn_context)
89+
elif turn_context.activity.type == ActivityTypes.installation_update:
90+
await self.on_installation_update(turn_context)
8991
else:
9092
await self.on_unrecognized_activity_type(turn_context)
9193

@@ -365,6 +367,19 @@ async def on_typing_activity( # pylint: disable=unused-argument
365367
"""
366368
return
367369

370+
async def on_installation_update( # pylint: disable=unused-argument
371+
self, turn_context: TurnContext
372+
):
373+
"""
374+
Override this in a derived class to provide logic specific to
375+
ActivityTypes.InstallationUpdate activities.
376+
377+
:param turn_context: The context object for this turn
378+
:type turn_context: :class:`botbuilder.core.TurnContext`
379+
:returns: A task that represents the work queued to execute
380+
"""
381+
return
382+
368383
async def on_unrecognized_activity_type( # pylint: disable=unused-argument
369384
self, turn_context: TurnContext
370385
):

libraries/botbuilder-core/botbuilder/core/adapters/test_adapter.py

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313
from typing import Awaitable, Coroutine, Dict, List, Callable, Union
1414
from copy import copy
1515
from threading import Lock
16+
from botframework.connector.auth import AppCredentials, ClaimsIdentity
17+
from botframework.connector.token_api.models import (
18+
SignInUrlResponse,
19+
TokenExchangeResource,
20+
TokenExchangeRequest,
21+
)
1622
from botbuilder.schema import (
1723
ActivityTypes,
1824
Activity,
@@ -22,12 +28,6 @@
2228
ResourceResponse,
2329
TokenResponse,
2430
)
25-
from botframework.connector.auth import AppCredentials, ClaimsIdentity
26-
from botframework.connector.token_api.models import (
27-
SignInUrlResponse,
28-
TokenExchangeResource,
29-
TokenExchangeRequest,
30-
)
3131
from ..bot_adapter import BotAdapter
3232
from ..turn_context import TurnContext
3333
from ..oauth.extended_user_token_provider import ExtendedUserTokenProvider
@@ -595,6 +595,7 @@ async def assert_reply(
595595
:param is_substring:
596596
:return:
597597
"""
598+
598599
# TODO: refactor method so expected can take a Callable[[Activity], None]
599600
def default_inspector(reply, description=None):
600601
if isinstance(expected, Activity):
@@ -651,6 +652,45 @@ async def wait_for_activity():
651652

652653
return TestFlow(await test_flow_previous(), self.adapter)
653654

655+
async def assert_no_reply(
656+
self, description=None, timeout=None, # pylint: disable=unused-argument
657+
) -> "TestFlow":
658+
"""
659+
Generates an assertion if the bot responds when no response is expected.
660+
:param description:
661+
:param timeout:
662+
"""
663+
if description is None:
664+
description = ""
665+
666+
async def test_flow_previous():
667+
nonlocal timeout
668+
if not timeout:
669+
timeout = 3000
670+
start = datetime.now()
671+
adapter = self.adapter
672+
673+
async def wait_for_activity():
674+
nonlocal timeout
675+
current = datetime.now()
676+
677+
if (current - start).total_seconds() * 1000 > timeout:
678+
# operation timed out and recieved no reply
679+
return
680+
681+
if adapter.activity_buffer:
682+
reply = adapter.activity_buffer.pop(0)
683+
raise RuntimeError(
684+
f"TestAdapter.assert_no_reply(): '{reply.text}' is responded when waiting for no reply."
685+
)
686+
687+
await asyncio.sleep(0.05)
688+
await wait_for_activity()
689+
690+
await wait_for_activity()
691+
692+
return TestFlow(await test_flow_previous(), self.adapter)
693+
654694

655695
def validate_activity(activity, expected) -> None:
656696
"""

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

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,39 +1174,43 @@ async def get_sign_in_resource_from_user_and_credentials(
11741174
) -> SignInUrlResponse:
11751175
if not connection_name:
11761176
raise TypeError(
1177-
"BotFrameworkAdapter.get_sign_in_resource_from_user(): missing connection_name"
1177+
"BotFrameworkAdapter.get_sign_in_resource_from_user_and_credentials(): missing connection_name"
11781178
)
1179-
if (
1180-
not turn_context.activity.from_property
1181-
or not turn_context.activity.from_property.id
1182-
):
1183-
raise TypeError(
1184-
"BotFrameworkAdapter.get_sign_in_resource_from_user(): missing activity id"
1185-
)
1186-
if user_id and turn_context.activity.from_property.id != user_id:
1179+
if not user_id:
11871180
raise TypeError(
1188-
"BotFrameworkAdapter.get_sign_in_resource_from_user(): cannot get signin resource"
1189-
" for a user that is different from the conversation"
1181+
"BotFrameworkAdapter.get_sign_in_resource_from_user_and_credentials(): missing user_id"
11901182
)
11911183

1192-
client = await self._create_token_api_client(
1193-
turn_context, oauth_app_credentials
1194-
)
1195-
conversation = TurnContext.get_conversation_reference(turn_context.activity)
1184+
activity = turn_context.activity
11961185

1197-
state = TokenExchangeState(
1186+
app_id = self.__get_app_id(turn_context)
1187+
token_exchange_state = TokenExchangeState(
11981188
connection_name=connection_name,
1199-
conversation=conversation,
1200-
relates_to=turn_context.activity.relates_to,
1201-
ms_app_id=client.config.credentials.microsoft_app_id,
1189+
conversation=ConversationReference(
1190+
activity_id=activity.id,
1191+
bot=activity.recipient,
1192+
channel_id=activity.channel_id,
1193+
conversation=activity.conversation,
1194+
locale=activity.locale,
1195+
service_url=activity.service_url,
1196+
user=activity.from_property,
1197+
),
1198+
relates_to=activity.relates_to,
1199+
ms_app_id=app_id,
12021200
)
12031201

1204-
final_state = base64.b64encode(
1205-
json.dumps(state.serialize()).encode(encoding="UTF-8", errors="strict")
1202+
state = base64.b64encode(
1203+
json.dumps(token_exchange_state.serialize()).encode(
1204+
encoding="UTF-8", errors="strict"
1205+
)
12061206
).decode()
12071207

1208+
client = await self._create_token_api_client(
1209+
turn_context, oauth_app_credentials
1210+
)
1211+
12081212
return client.bot_sign_in.get_sign_in_resource(
1209-
final_state, final_redirect=final_redirect
1213+
state, final_redirect=final_redirect
12101214
)
12111215

12121216
async def exchange_token(

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ async def send_message_to_teams_channel(
2222
) -> Tuple[ConversationReference, str]:
2323
if not turn_context:
2424
raise ValueError("The turn_context cannot be None")
25-
if not turn_context.activity:
26-< 10000 /span>
raise ValueError("The turn_context.activity cannot be None")
25+
if not activity:
26+
raise ValueError("The activity cannot be None")
2727
if not teams_channel_id:
2828
raise ValueError("The teams_channel_id cannot be None or empty")
2929

libraries/botbuilder-core/botbuilder/core/telemetry_logger_middleware.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
# Copyright (c) Microsoft Corporation. All rights reserved.
22
# Licensed under the MIT License.
33
"""Middleware Component for logging Activity messages."""
4-
54
from typing import Awaitable, Callable, List, Dict
65
from botbuilder.schema import Activity, ConversationReference, ActivityTypes
6+
from botbuilder.schema.teams import TeamsChannelData, TeamInfo
7+
from botframework.connector import Channels
8+
79
from .bot_telemetry_client import BotTelemetryClient
810
from .bot_assert import BotAssert
911
from .middleware_set import Middleware
@@ -183,6 +185,10 @@ async def fill_receive_event_properties(
183185
if activity.speak and activity.speak.strip():
184186
properties[TelemetryConstants.SPEAK_PROPERTY] = activity.speak
185187

188+
TelemetryLoggerMiddleware.__populate_additional_channel_properties(
189+
activity, properties
190+
)
191+
186192
# Additional properties can override "stock" properties
187193
if additional_properties:
188194
for prop in additional_properties:
@@ -288,3 +294,25 @@ async def fill_delete_event_properties(
288294
properties[prop.key] = prop.value
289295

290296
return properties
297+
298+
@staticmethod
299+
def __populate_additional_channel_properties(
300+
activity: Activity, properties: dict,
301+
):
302+
if activity.channel_id == Channels.ms_teams:
303+
teams_channel_data: TeamsChannelData = activity.channel_data
304+
305+
properties["TeamsTenantId"] = (
306+
teams_channel_data.tenant
307+
if teams_channel_data and teams_channel_data.tenant
308+
else ""
309+
)
310+
311+
properties["TeamsUserAadObjectId"] = (
312+
activity.from_property.aad_object_id if activity.from_property else ""
313+
)
314+
315+
if teams_channel_data and teams_channel_data.team:
316+
properties["TeamsTeamInfo"] = TeamInfo.serialize(
317+
teams_channel_data.team
318+
)

0 commit comments

Comments
 (0)
0