8000 SkillDialog dev testing samples · LucaSavio/botbuilder-python@c434ce3 · GitHub
[go: up one dir, main page]

Skip to content

Commit c434ce3

Browse files
committed
SkillDialog dev testing samples
1 parent faf4eed commit c434ce3

Some content is hidden

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

50 files changed

+3243
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# EchoBot
2+
3+
Bot Framework v4 echo bot sample.
4+
5+
This bot has been created using [Bot Framework](https://dev.botframework.com), it shows how to create a simple bot that accepts input from the user and echoes it back.
6+
7+
## Running the sample
8+
- Clone the repository
9+
```bash
10+
git clone https://github.com/Microsoft/botbuilder-samples.git
11+
```
12+
- Bring up a terminal, navigate to `botbuilder-samples\samples\python\02.echo-bot` folder
13+
- Activate your desired virtual environment
14+
- In the terminal, type `pip install -r requirements.txt`
15+
- Run your bot with `python app.py`
16+
17+
## Testing the bot using Bot Framework Emulator
18+
[Microsoft Bot Framework Emulator](https://github.com/microsoft/botframework-emulator) is a desktop application that allows bot developers to test and debug their bots on localhost or running remotely through a tunnel.
19+
20+
- Install the Bot Framework emulator from [here](https://github.com/Microsoft/BotFramework-Emulator/releases)
21+
22+
### Connect to bot using Bot Framework Emulator
23+
- Launch Bot Framework Emulator
24+
- Paste this URL in the emulator window - http://localhost:3978/api/messages
25+
26+
## Deploy the bot to Azure
27+
28+
To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions.
29+
30+
# Further reading
31+
32+
- [Bot Framework Documentation](https://docs.botframework.com)
33+
- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0)
34+
- [Activity processing](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-concept-activity-processing?view=azure-bot-service-4.0)
35+
- [Azure Bot Service Introduction](https://docs.microsoft.com/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0)
36+
- [Azure Bot Service Documentation](https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0)
37+
- [Azure CLI](https://docs.microsoft.com/cli/azure/?view=azure-cli-latest)
38+
- [Azure Portal](https://portal.azure.com)
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
from aiohttp import web
5+
from aiohttp.web import Request, Response, json_response
6+
from botbuilder.core import (
7+
BotFrameworkAdapterSettings,
8+
ConversationState,
9+
MemoryStorage,
10+
UserState,
11+
)
12+
from botbuilder.core.integration import aiohttp_error_middleware
13+
from botbuilder.schema import Activity
14+
from botframework.connector.auth import AuthenticationConfiguration
15+
16+
from authentication import AllowedCallersClaimsValidator
17+
from bots import EchoBot
18+
from config import DefaultConfig
19+
from skill_adapter_with_error_handler import SkillAdapterWithErrorHandler
20+
21+
CONFIG = DefaultConfig()
22+
23+
# Create MemoryStorage, UserState and ConversationState
24+
MEMORY = MemoryStorage()
25+
USER_STATE = UserState(MEMORY)
26+
CONVERSATION_STATE = ConversationState(MEMORY)
27+
28+
# Create adapter.
29+
# See https://aka.ms/about-bot-adapter to learn more about how bots work.
30+
VALIDATOR = AllowedCallersClaimsValidator(CONFIG).claims_validator
31+
SETTINGS = BotFrameworkAdapterSettings(
32+
CONFIG.APP_ID,
33+
CONFIG.APP_PASSWORD,
34+
auth_configuration=AuthenticationConfiguration(claims_validator=VALIDATOR),
35+
)
36+
ADAPTER = SkillAdapterWithErrorHandler(SETTINGS, CONVERSATION_STATE)
37+
38+
# Create the Bot
39+
BOT = EchoBot()
40+
41+
42+
# Listen for incoming requests on /api/messages
43+
async def messages(req: Request) -> Response:
44+
# Main bot message handler.
45+
if "application/json" in req.headers["Content-Type"]:
46+
body = await req.json()
47+
else:
48+
return Response(status=415)
49+
50+
activity = Activity().deserialize(body)
51+
auth_header = req.headers["Authorization"] if "Authorization" in req.headers else ""
52+
53+
response = await ADAPTER.process_activity(activity, auth_header, BOT.on_turn)
54+
if response:
55+
return json_response(data=response.body, status=response.status)
56+
return Response(status=201)
57+
58+
59+
APP = web.Application(middlewares=[aiohttp_error_middleware])
60+
APP.router.add_post("/api/messages", messages)
61+
62+
if __name__ == "__main__":
63+
try:
64+
web.run_app(APP, host="localhost", port=CONFIG.PORT)
65+
except Exception as error:
66+
raise error
Original file line numberDiff line number 1C6A Diff line change
@@ -0,0 +1,3 @@
1+
from .allow_callers_claims_validation import AllowedCallersClaimsValidator
2+
3+
__all__ = ["AllowedCallersClaimsValidator"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from typing import Awaitable, Callable, Dict, List
2+
3+
from botframework.connector.auth import JwtTokenValidation, SkillValidation
4+
5+
from config import DefaultConfig
6+
7+
8+
class AllowedCallersClaimsValidator:
9+
10+
config_key = "ALLOWED_CALLERS"
11+
12+
def __init__(self, config: DefaultConfig):
13+
if not config:
14+
raise TypeError(
15+
"AllowedCallersClaimsValidator: config object cannot be None."
16+
)
17+
18+
# ALLOWED_CALLERS is the setting in config.py file
19+
# that consists of the list of parent bot ids that are allowed to access the skill
20+
# to add a new parent bot simply go to the AllowedCallers and add
21+
# the parent bot's microsoft app id to the list
22+
self._allowed_callers = config.ALLOWED_CALLERS
23+
24+
@property
25+
def claims_validator(self) -> Callable[[List[Dict]], Awaitable]:
26+
async def allow_callers_claims_validator(claims: Dict[str, object]):
27+
# if _allowedCallers is None we allow all calls
28+
if self._allowed_callers and SkillValidation.is_skill_claim(claims):
29+
# Check that the appId claim in the skill request is in the list of skills configured for this bot.
30+
app_id = JwtTokenValidation.get_app_id_from_claims(claims)
31+
if app_id not in self._allowed_callers:
32+
raise PermissionError(
33+
f'Received a request from a bot with an app ID of "{app_id}".'
34+
f" To enable requests from this caller, add the app ID to your configuration file."
35+
)
36+
37+
return
38+
39+
return allow_callers_claims_validator
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
from .echo_bot import EchoBot
5+
6+
__all__ = ["EchoBot"]
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
from botbuilder.core import ActivityHandler, TurnContext
5+
from botbuilder.schema import (
6+
ChannelAccount,
7+
Activity,
8+
ActivityTypes,
9+
EndOfConversationCodes,
10+
)
11+
12+
13+
class EchoBot(ActivityHandler):
14+
async def on_members_added_activity(
15+
self, members_added: [ChannelAccount], turn_context: TurnContext
16+
):
17+
for member in members_added:
18+
if member.id != turn_context.activity.recipient.id:
19+
await turn_context.send_activity("Hello and welcome!")
20+
21+
async def on_message_activity(self, turn_context: TurnContext):
22+
if "end" in turn_context.activity.text or "stop" in turn_context.activity.text:
23+
await turn_context.send_activity("ending conversation from the skill...")
24+
end_of_conversation = Activity(
25+
type=ActivityTypes.end_of_conversation,
26+
code=EndOfConversationCodes.completed_successfully,
27+
)
28+
await turn_context.send_activity(end_of_conversation)
29+
else:
30+
await turn_context.send_activity(
31+
f"Echo: (Python) : {turn_context.activity.text}"
32+
)
33+
await turn_context.send_activity(
34+
'Say "end" or "stop" and I\'ll end the conversation and back to the parent.'
35+
)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) Microsoft Corporation. All rights reserved.
3+
# Licensed under the MIT License.
4+
5+
import os
6+
7+
8+
class DefaultConfig:
9+
""" Bot Configuration """
10+
11+
PORT = 39793
12+
APP_ID = os.environ.get("MicrosoftAppId", "")
13+
APP_PASSWORD = os.environ.get("MicrosoftAppPassword", "")
14+
15+
# If ALLOWED_CALLERS is empty, any bot can call this Skill. Add MicrosoftAppIds to restrict
16+
# callers to only those specified.
17+
# Example: os.environ.get("AllowedCallers", ["54d3bb6a-3b6d-4ccd-bbfd-cad5c72fb53a"])
18+
ALLOWED_CALLERS = os.environ.get("AllowedCallers", [])

0 commit comments

Comments
 (0)
0