botbuilder-python | Microsoft Bot Framework provides what you need to build | Bot library

 by   microsoft Python Version: 4.14.1 License: MIT

kandi X-RAY | botbuilder-python Summary

botbuilder-python is a Python library typically used in Automation, Bot applications. botbuilder-python has no bugs, it has no vulnerabilities, it has a Permissive License and it has low support. However botbuilder-python build file is not available. You can download it from GitHub.
The Microsoft Bot Framework provides what you need to build and connect intelligent bots that interact naturally wherever your users are talking, from text/sms to Skype, Slack, Office 365 mail and other popular services.
    Support
      Quality
        Security
          License
            Reuse
            Support
              Quality
                Security
                  License
                    Reuse

                      kandi-support Support

                        summary
                        botbuilder-python has a low active ecosystem.
                        summary
                        It has 517 star(s) with 202 fork(s). There are 71 watchers for this library.
                        summary
                        It had no major release in the last 12 months.
                        summary
                        There are 170 open issues and 1071 have been closed. On average issues are closed in 72 days. There are 8 open pull requests and 0 closed requests.
                        summary
                        It has a neutral sentiment in the developer community.
                        summary
                        The latest version of botbuilder-python is 4.14.1
                        botbuilder-python Support
                          Best in #Bot
                            Average in #Bot
                            botbuilder-python Support
                              Best in #Bot
                                Average in #Bot

                                  kandi-Quality Quality

                                    summary
                                    botbuilder-python has 0 bugs and 0 code smells.
                                    botbuilder-python Quality
                                      Best in #Bot
                                        Average in #Bot
                                        botbuilder-python Quality
                                          Best in #Bot
                                            Average in #Bot

                                              kandi-Security Security

                                                summary
                                                botbuilder-python has no vulnerabilities reported, and its dependent libraries have no vulnerabilities reported.
                                                summary
                                                botbuilder-python code analysis shows 0 unresolved vulnerabilities.
                                                summary
                                                There are 0 security hotspots that need review.
                                                botbuilder-python Security
                                                  Best in #Bot
                                                    Average in #Bot
                                                    botbuilder-python Security
                                                      Best in #Bot
                                                        Average in #Bot

                                                          kandi-License License

                                                            summary
                                                            botbuilder-python is licensed under the MIT License. This license is Permissive.
                                                            summary
                                                            Permissive licenses have the least restrictions, and you can use them in most projects.
                                                            botbuilder-python License
                                                              Best in #Bot
                                                                Average in #Bot
                                                                botbuilder-python License
                                                                  Best in #Bot
                                                                    Average in #Bot

                                                                      kandi-Reuse Reuse

                                                                        summary
                                                                        botbuilder-python releases are available to install and integrate.
                                                                        summary
                                                                        botbuilder-python has no build file. You will be need to create the build yourself to build the component from source.
                                                                        summary
                                                                        Installation instructions, examples and code snippets are available.
                                                                        summary
                                                                        botbuilder-python saves you 20247 person hours of effort in developing the same functionality from scratch.
                                                                        summary
                                                                        It has 48941 lines of code, 3635 functions and 696 files.
                                                                        summary
                                                                        It has medium code complexity. Code complexity directly impacts maintainability of the code.
                                                                        botbuilder-python Reuse
                                                                          Best in #Bot
                                                                            Average in #Bot
                                                                            botbuilder-python Reuse
                                                                              Best in #Bot
                                                                                Average in #Bot
                                                                                  Top functions reviewed by kandi - BETA
                                                                                  kandi has reviewed botbuilder-python and discovered the below as its top functions. This is intended to give you an instant insight into botbuilder-python implemented functionality, and help decide if they suit your requirements.
                                                                                  • Invoke Invoke Activity
                                                                                    • Clean model data for serialization
                                                                                    • Serialize a model to a dictionary
                                                                                    • Deserializer for deserialization methods
                                                                                  • Return routes to aiohttp channel service
                                                                                    • Deserialize header
                                                                                    • Deserialize from request body
                                                                                    • Returns a JSON response
                                                                                  • Runs on_turn
                                                                                  • Reply to an activity
                                                                                  • Post an activity
                                                                                  • Gets all teams in a conversation
                                                                                  • Sends an activity to a conversation
                                                                                  • Execute a token exchange
                                                                                  • Updates an activity
                                                                                  • Sends a transcript to a conversation
                                                                                  • Get AAD tokens
                                                                                  • Process a StreamingRequest
                                                                                  • Upload an attachment to a conversation
                                                                                  • Request sign - in URL
                                                                                  • Request a token
                                                                                  • Called when a conversation update is received
                                                                                  • Constructs a signed sign - in resource
                                                                                  • Continue dialog
                                                                                  • Execute a LUIS query
                                                                                  • Get the status of a user
                                                                                  Get all kandi verified functions for this library.
                                                                                  Get all kandi verified functions for this library.

                                                                                  botbuilder-python Key Features

                                                                                  The Microsoft Bot Framework provides what you need to build and connect intelligent bots that interact naturally wherever your users are talking, from text/sms to Skype, Slack, Office 365 mail and other popular services.

                                                                                  botbuilder-python Examples and Code Snippets

                                                                                  No Code Snippets are available at this moment for botbuilder-python.
                                                                                  Community Discussions

                                                                                  Trending Discussions on botbuilder-python

                                                                                  What is the difference between TeamsActivityHandler and ActivityHandler?
                                                                                  chevron right
                                                                                  Get the active dialog id in botframework Python - Dispatch model with multiple Dialog and QnA Maker
                                                                                  chevron right

                                                                                  QUESTION

                                                                                  What is the difference between TeamsActivityHandler and ActivityHandler?
                                                                                  Asked 2021-Jan-16 at 08:33

                                                                                  In most documentation you'll see:

                                                                                  class BotHandler(ActivityHandler):
                                                                                      async def on_message_activity(self, turn_context: TurnContext):
                                                                                          await turn_context.send_activity("Hello!")
                                                                                  

                                                                                  However, some Python examples will use TeamsActivityHandler instead:

                                                                                  class BotHandler(TeamsActivityHandler):
                                                                                      async def on_message_activity(self, turn_context: TurnContext):
                                                                                          message = MessageFactory.text("first message")
                                                                                          channel_id = teams_get_channel_id(turn_context.activity)
                                                                                  

                                                                                  I've noticed that

                                                                                  1. When inheriting from TeamsActivityHandler, I can overload on_teams_channel_created() that gets called when a new channel is created.
                                                                                  2. When inheriting from ActivityHandler, I can overload on_members_added_activity() to greet new users (welcome message).

                                                                                  How can I use both at the same time?

                                                                                  ANSWER

                                                                                  Answered 2021-Jan-13 at 16:02

                                                                                  Bots created using the Microsoft Bot Framework can be used for multiple purposes (it's a general-purpose bot framework), e.g. for web chat, slack, etc. - Teams is just one of those possible "Channels", as they're called. As a result, the 'main' class at play is ActivityHandler, but for Teams development there's a derived class (TeamsActivityHandler) which has some additional Teams-specific wrappers.

                                                                                  Source https://stackoverflow.com/questions/65702917

                                                                                  QUESTION

                                                                                  Get the active dialog id in botframework Python - Dispatch model with multiple Dialog and QnA Maker
                                                                                  Asked 2020-Jul-09 at 07:39

                                                                                  My bot processes incoming user messages and takes action based on the intent. For simple, one shot answers that do not require multiple passes between users and the bot, it works well. Now when I want to implement a dialog, it's getting tough. Once the user sends the message and the Dialog gets triggered, the bot asks the user for input. Once the user provides the input, this input is being again processed by LUIS to understand the intent. However, I do not want this to happen as this abandons the ongoing Dialog.

                                                                                  I want to understand if there some way I can detect if a Dialog is under progress and what dialog is it. If I can know this, I can skip the LUIS intent check part and direct the logic to Dialog. I've used the Multi-turn Prompt as a basis for this. Below is what I expect.

                                                                                  from botbuilder.core import ActivityHandler, TurnContext, MessageFactory, IntentScore, ConversationState, UserState
                                                                                  from botbuilder.schema import ChannelAccount,Attachment
                                                                                  from botbuilder.ai.luis import LuisApplication,LuisPredictionOptions,LuisRecognizer
                                                                                  from botbuilder.ai.qna import QnAMakerEndpoint,QnAMakerOptions,QnAMaker
                                                                                  from typing import List
                                                                                  import os
                                                                                  import json
                                                                                  import os.path
                                                                                  from usecases import SimpleUseCase
                                                                                  import requests
                                                                                  
                                                                                  from botbuilder.dialogs import Dialog, DialogSet, DialogTurnStatus
                                                                                  from helpers.dialog_helper import DialogHelper
                                                                                  from dialogs import UserProfileDialog
                                                                                  
                                                                                  
                                                                                  
                                                                                  class Bot(ActivityHandler):
                                                                                  
                                                                                      def __init__(
                                                                                          self,
                                                                                          conversation_state: ConversationState,
                                                                                          user_state: UserState
                                                                                          # dialog: Dialog,
                                                                                      ):
                                                                                          if conversation_state is None:
                                                                                              raise TypeError(
                                                                                                  "[DialogBot]: Missing parameter. conversation_state is required but None was given"
                                                                                              )
                                                                                          if user_state is None:
                                                                                              raise TypeError(
                                                                                                  "[DialogBot]: Missing parameter. user_state is required but None was given"
                                                                                              )
                                                                                          # if dialog is None:
                                                                                          #     raise Exception("[DialogBot]: Missing parameter. dialog is required")
                                                                                  
                                                                                          self.conversation_state = conversation_state
                                                                                          self.user_state = user_state
                                                                                          # self.dialog = dialog###Change based on dialog
                                                                                  
                                                                                          luisApp = LuisApplication("","","https://abcd.cognitiveservices.azure.com/")
                                                                                          luisOptions = LuisPredictionOptions(include_all_intents=True,include_instance_data=True)
                                                                                          self.LuisRecog = LuisRecognizer(luisApp,luisOptions)
                                                                                          self.qnaMaker = QnAMaker(QnAMakerEndpoint("","",""))        
                                                                                      
                                                                                  
                                                                                      async def on_members_added_activity(
                                                                                          self, members_added: List[ChannelAccount], turn_context: TurnContext
                                                                                      ):
                                                                                          for member in members_added:
                                                                                              # Greet anyone that was not the target (recipient) of this message.
                                                                                              # To learn more about Adaptive Cards, see https://aka.ms/msbot-adaptivecards for more details.
                                                                                              if member.id != turn_context.activity.recipient.id:
                                                                                                  welcome_card = self.create_adaptive_card_attachment()
                                                                                                  response = MessageFactory.attachment(welcome_card)
                                                                                                  await turn_context.send_activity(response)
                                                                                  
                                                                                      # Load attachment from file.
                                                                                      def create_adaptive_card_attachment(self):
                                                                                          relative_path = os.path.abspath(os.path.dirname(__file__))
                                                                                          path = os.path.join(relative_path, "cards/welcomeCard.json")
                                                                                          with open(path) as in_file:
                                                                                              card = json.load(in_file)
                                                                                  
                                                                                          return Attachment(
                                                                                              content_type="application/vnd.microsoft.card.adaptive", content=card
                                                                                          )
                                                                                  
                                                                                      async def greetings(self,turn_context):
                                                                                          await turn_context.send_activity(MessageFactory.text("from inside greetings"))
                                                                                  
                                                                                      async def on_turn(self, turn_context: TurnContext):
                                                                                          await super().on_turn(turn_context)
                                                                                  
                                                                                          # Save any state changes that might have ocurred during the turn.
                                                                                          await self.conversation_state.save_changes(turn_context)
                                                                                          await self.user_state.save_changes(turn_context)
                                                                                  
                                                                                  
                                                                                      async def on_message_activity(self, turn_context: TurnContext):
                                                                                          luisResult = await self.LuisRecog.recognize(turn_context) 
                                                                                          print(luisResult.get_top_scoring_intent())
                                                                                          intent = LuisRecognizer.top_intent(luisResult,min_score=0.40)
                                                                                  
                                                                                          if turn_context.activity.text.lower() == 'hi':
                                                                                              await self.greetings(turn_context)
                                                                                              await turn_context.send_activity(MessageFactory.text("message sent from send greetings.."))
                                                                                          else:
                                                                                  ### Here I want to be able to understand if there is any dialog that is already present on the dialog stack and 
                                                                                  ### the dialog id. If we can get that details, I can then call the run_dialog method with the  dialog id 
                                                                                  ### instead of routing the request based on the intent. Without knowing if a dialog is already 
                                                                                  ### running, every input from user is again processed which is not desired.
                                                                                              if intent == 'UserProfileIntent':
                                                                                                  await DialogHelper.run_dialog(UserProfileDialog(self.user_state),turn_context,self.conversation_state.create_property("DialogState"))
                                                                                              else:
                                                                                                  answers = await self..get_answers(turn_context)                
                                                                                                  await turn_context.send_activity(MessageFactory.text(answers[0].answer))
                                                                                  
                                                                                                  
                                                                                  

                                                                                  This is in a way related to this question and though there was a discussion on Github here, I think my question/requirement is in a way different. I tried to understand if there's a way to get the current active dialog in other SDK but couldn't find any useful information.

                                                                                  The author of the above question has answered his approach. Though it's a good one, it only partially suits my requirements. The answer is useful when there are small number of intents and also where only Luis is used. My use cases has more than 50 intents and the list will keep increasing. I'll need to keep adding dialogs inside the maindialog. If I'm able to identify the active dialog, I'll be able to dynamically call the run_dialog method.

                                                                                  Also, I use QnA Maker to answer the user when the intent of the user input is None. When I tried to implement the QnA Maker also into a dialog, I'm ending up with certain errors below.

                                                                                  main_dialog.py

                                                                                  from botbuilder.dialogs import (
                                                                                      ComponentDialog,
                                                                                      WaterfallDialog,
                                                                                      WaterfallStepContext,
                                                                                      DialogTurnResult,
                                                                                  )
                                                                                  from botbuilder.dialogs.prompts import (
                                                                                      TextPrompt,
                                                                                      NumberPrompt,
                                                                                      ChoicePrompt,
                                                                                      ConfirmPrompt,
                                                                                      AttachmentPrompt,
                                                                                      PromptOptions,
                                                                                      PromptValidatorContext,
                                                                                  )
                                                                                  from botbuilder.dialogs.choices import Choice
                                                                                  from botbuilder.core import MessageFactory, UserState
                                                                                  from dialogs import NameDialog,UserProfileDialog,QADialog
                                                                                  from botbuilder.ai.qna import QnAMaker,QnAMakerEndpoint
                                                                                  import json
                                                                                  
                                                                                  class MainDialog(ComponentDialog):
                                                                                      def __init__(self, luis, intent, recognizer_result,user_state, turn_context):
                                                                                          super(MainDialog, self).__init__(MainDialog.__name__)
                                                                                  
                                                                                          self.luis = luis
                                                                                          self.intent = intent
                                                                                          self.recognizer_result = recognizer_result
                                                                                          self.user_state = user_state
                                                                                          self.turn_context = turn_context
                                                                                  
                                                                                          self.add_dialog(NameDialog(self.user_state))
                                                                                          self.add_dialog(UserProfileDialog(self.user_state))
                                                                                          self.add_dialog(QADialog(self.user_state))
                                                                                          self.add_dialog(
                                                                                              WaterfallDialog(
                                                                                                  "main_dialog_id", [self.main_step]
                                                                                              )
                                                                                          )
                                                                                  
                                                                                          self.initial_dialog_id = "main_dialog_id"
                                                                                  
                                                                                      async def main_step(self, step_context: WaterfallStepContext) -> DialogTurnResult:
                                                                                          # dialog_detail = self.luis.get_entities(self.intent, self.recognizer_result)
                                                                                          if self.intent == "name":
                                                                                              return await step_context.begin_dialog(NameDialog.__name__)
                                                                                          elif self.intent == "place":
                                                                                              return await step_context.begin_dialog(UserProfileDialog.__name__)
                                                                                          elif self.intent == "AGE":
                                                                                              entities = None
                                                                                              if self.recognizer_result.entities is not None:
                                                                                                  entities = json.dumps(self.recognizer_result.entities.get("number"))
                                                                                              return await step_context.begin_dialog(NameDialog.__name__,entities[0])
                                                                                              # await self.turn_context.send_activity(MessageFactory.text("age intent"))
                                                                                          elif self.intent == "None":                                    
                                                                                       ###This part ends up in error even though I close the dialog immediately after sending the answer and I'm not sure if it's the right way to do it.        
                                                                                              answers = await QnAMaker(QnAMakerEndpoint("","","")).get_answers(self.turn_context)
                                                                                              if answers and len(answers) > 0:
                                                                                                  await self.turn_context.send_activity(MessageFactory.text(answers[0].answer))
                                                                                              else:
                                                                                                  await self.turn_context.send_activity(MessageFactory.text("Sorry I cant help you with that !!"))
                                                                                  
                                                                                              await step_context.end_dialog()
                                                                                  

                                                                                  bot.py

                                                                                  from botbuilder.core import ActivityHandler, TurnContext, MessageFactory, IntentScore, ConversationState, UserState, StatePropertyAccessor
                                                                                  from botbuilder.schema import ChannelAccount,Attachment
                                                                                  from botbuilder.ai.luis import LuisApplication,LuisPredictionOptions,LuisRecognizer
                                                                                  from botbuilder.ai.qna import QnAMakerEndpoint,QnAMakerOptions,QnAMaker
                                                                                  from typing import List
                                                                                  import os
                                                                                  import json
                                                                                  import os.path
                                                                                  from usecases import SimpleUseCase
                                                                                  import requests
                                                                                  
                                                                                  from botbuilder.dialogs import Dialog, DialogSet, DialogTurnStatus, DialogContext
                                                                                  from helpers.dialog_helper import DialogHelper
                                                                                  from dialogs import UserProfileDialog,NameDialog,MainDialog
                                                                                  
                                                                                  
                                                                                  
                                                                                  class Bot(ActivityHandler):
                                                                                  
                                                                                      def __init__(
                                                                                          self,
                                                                                          conversation_state: ConversationState,
                                                                                          user_state: UserState
                                                                                          # dialog: Dialog,
                                                                                      ):
                                                                                          if conversation_state is None:
                                                                                              raise TypeError(
                                                                                                  "[DialogBot]: Missing parameter. conversation_state is required but None was given"
                                                                                              )
                                                                                          if user_state is None:
                                                                                              raise TypeError(
                                                                                                  "[DialogBot]: Missing parameter. user_state is required but None was given"
                                                                                              )
                                                                                          # if dialog is None:
                                                                                          #     raise Exception("[DialogBot]: Missing parameter. dialog is required")
                                                                                  
                                                                                          self.conversation_state = conversation_state
                                                                                          self.user_state = user_state
                                                                                          # self.dialog = dialog###Change based on dialog
                                                                                  
                                                                                          luisApp = LuisApplication("","","")
                                                                                          luisOptions = LuisPredictionOptions(include_all_intents=True,include_instance_data=True)
                                                                                          self.LuisRecog = LuisRecognizer(luisApp,luisOptions)
                                                                                        
                                                                                  
                                                                                      async def on_members_added_activity(
                                                                                          self, members_added: List[ChannelAccount], turn_context: TurnContext
                                                                                      ):
                                                                                          for member in members_added:
                                                                                              # Greet anyone that was not the target (recipient) of this message.
                                                                                              # To learn more about Adaptive Cards, see https://aka.ms/msbot-adaptivecards for more details.
                                                                                              if member.id != turn_context.activity.recipient.id:
                                                                                                  welcome_card = self.create_adaptive_card_attachment()
                                                                                                  response = MessageFactory.attachment(welcome_card)
                                                                                                  await turn_context.send_activity(response)
                                                                                  
                                                                                      # Load attachment from file.
                                                                                      def create_adaptive_card_attachment(self):
                                                                                          relative_path = os.path.abspath(os.path.dirname(__file__))
                                                                                          path = os.path.join(relative_path, "cards/welcomeCard.json")
                                                                                          with open(path) as in_file:
                                                                                              card = json.load(in_file)
                                                                                  
                                                                                          return Attachment(
                                                                                              content_type="application/vnd.microsoft.card.adaptive", content=card
                                                                                          )
                                                                                  
                                                                                      async def greetings(self,turn_context):
                                                                                          await turn_context.send_activity(MessageFactory.text("from inside greetings"))
                                                                                  
                                                                                      async def on_turn(self, turn_context: TurnContext):
                                                                                          await super().on_turn(turn_context)
                                                                                  
                                                                                          # Save any state changes that might have ocurred during the turn.
                                                                                          await self.conversation_state.save_changes(turn_context)
                                                                                          await self.user_state.save_changes(turn_context)
                                                                                  
                                                                                  
                                                                                      async def on_message_activity(self, turn_context: TurnContext):
                                                                                          luisResult = await self.LuisRecog.recognize(turn_context) 
                                                                                          print(luisResult.get_top_scoring_intent())
                                                                                          intent = LuisRecognizer.top_intent(luisResult,min_score=0.40)
                                                                                  
                                                                                  
                                                                                          if turn_context.activity.text.lower() == 'hi':
                                                                                              await self.greetings(turn_context)
                                                                                              await turn_context.send_activity(MessageFactory.text("message sent from send greetings.."))
                                                                                          else:
                                                                                              # if intent != "None":
                                                                                              dialog = MainDialog(self.LuisRecog, intent, luisResult,self.user_state,turn_context)
                                                                                              await DialogHelper.run_dialog(dialog,turn_context,self.conversation_state.create_property("DialogState"))
                                                                                  
                                                                                                  
                                                                                  

                                                                                  Error in case of None intent and Q&A Maker processes the user question. Also I've not tried the QnA Dialogs yet to see if they work in this setup.

                                                                                  It would be great if we could somehow access the current active dialog id so that we can switch the dialog easily based on the id by creating a map of intent to dialog.

                                                                                  Thanks to the author of this question for sharing his solution.

                                                                                  Approach with Dispatch

                                                                                  import os
                                                                                  from typing import List
                                                                                  import json
                                                                                  
                                                                                  from azure.cognitiveservices.language.luis.runtime.models import LuisResult, IntentModel
                                                                                  
                                                                                  from botbuilder.ai.luis import LuisApplication, LuisRecognizer, LuisPredictionOptions
                                                                                  from botbuilder.ai.qna import QnAMaker, QnAMakerEndpoint
                                                                                  from botbuilder.core import ActivityHandler, TurnContext, RecognizerResult, MessageFactory, UserState, ConversationState
                                                                                  from botbuilder.schema import ChannelAccount, Attachment
                                                                                  
                                                                                  from config import DefaultConfig
                                                                                  
                                                                                  from helpers.luis_helper import LuisDispatchResult
                                                                                  from helpers.dialog_helper import DialogHelper
                                                                                  from dialogs import NameDialog,UserProfileDialog,QADialog
                                                                                  
                                                                                  class DispatchBot(ActivityHandler):
                                                                                      def __init__(self, config: DefaultConfig,
                                                                                                   conversation_state: ConversationState,
                                                                                                   user_state: UserState):
                                                                                          self.qna_maker = QnAMaker(
                                                                                              QnAMakerEndpoint(
                                                                                                  knowledge_base_id=config.QNA_KNOWLEDGEBASE_ID,
                                                                                                  endpoint_key=config.QNA_ENDPOINT_KEY,
                                                                                                  host=config.QNA_ENDPOINT_HOST,
                                                                                              )
                                                                                          )
                                                                                  
                                                                                          # If the includeApiResults parameter is set to true, as shown below, the full response
                                                                                          # from the LUIS api will be made available in the properties  of the RecognizerResult
                                                                                          self.dialog_started = False
                                                                                          self.app_id = config.LUIS_APP_ID
                                                                                          self.api_key = config.LUIS_API_KEY
                                                                                          self.host = "https://" + config.LUIS_API_HOST_NAME
                                                                                          self.user_state = user_state
                                                                                          self.conversation_state = conversation_state
                                                                                  
                                                                                          luis_application = LuisApplication(
                                                                                              config.LUIS_APP_ID,
                                                                                              config.LUIS_API_KEY,
                                                                                              "https://" + config.LUIS_API_HOST_NAME,
                                                                                          )
                                                                                          luis_options = LuisPredictionOptions(
                                                                                              include_all_intents=True, include_instance_data=True
                                                                                          )
                                                                                          self.recognizer = LuisRecognizer(luis_application, luis_options, True)
                                                                                  
                                                                                      async def on_members_added_activity(
                                                                                          self, members_added: List[ChannelAccount], turn_context: TurnContext
                                                                                      ):
                                                                                          for member in members_added:
                                                                                              # Greet anyone that was not the target (recipient) of this message.
                                                                                              # To learn more about Adaptive Cards, see https://aka.ms/msbot-adaptivecards for more details.
                                                                                              if member.id != turn_context.activity.recipient.id:
                                                                                                  welcome_card = self.create_adaptive_card_attachment()
                                                                                                  response = MessageFactory.attachment(welcome_card)
                                                                                                  await turn_context.send_activity(response)
                                                                                  
                                                                                      # Load attachment from file.
                                                                                      def create_adaptive_card_attachment(self):
                                                                                          relative_path = os.path.abspath(os.path.dirname(__file__))
                                                                                          path = os.path.join(relative_path, "cards/welcomeCard.json")
                                                                                          with open(path) as in_file:
                                                                                              card = json.load(in_file)
                                                                                  
                                                                                          return Attachment(
                                                                                              content_type="application/vnd.microsoft.card.adaptive", content=card
                                                                                          )
                                                                                  
                                                                                  
                                                                                  
                                                                                      async def on_message_activity(self, turn_context: TurnContext):
                                                                                          # First, we use the dispatch model to determine which cognitive service (LUIS or QnA) to use.
                                                                                          # recognizer_result = await self.recognizer.recognize(turn_context)
                                                                                          # Top intent tell us which cognitive service to use.
                                                                                          # intent = LuisRecognizer.top_intent(recognizer_result)
                                                                                          topIntent,childIntent,childEntities = LuisDispatchResult().getLuisDispatchResult(self.app_id,self.api_key,self.host,turn_context.activity.text)
                                                                                  
                                                                                          # Next, we call the dispatcher with the top intent.
                                                                                          await self._dispatch_to_top_intent(turn_context, topIntent,childIntent,childEntities)
                                                                                  
                                                                                      async def _dispatch_to_top_intent(
                                                                                          self, turn_context: TurnContext, topIntent,childIntent,childEntities
                                                                                      ):
                                                                                          if topIntent == "l_myluisapp":
                                                                                              await self._process_luis_queries(
                                                                                                  turn_context, childIntent,childEntities
                                                                                              )
                                                                                          elif topIntent == "q_mybotqna":
                                                                                              await self._process_sample_qna(turn_context)
                                                                                          else:
                                                                                              await turn_context.send_activity(f"Dispatch unrecognized intent: {topIntent}.")
                                                                                  
                                                                                      async def _process_luis_queries(
                                                                                          self, turn_context: TurnContext, childIntent,childEntities
                                                                                      ):
                                                                                          await turn_context.send_activity(
                                                                                              f"LUIS intent selected {childIntent}."
                                                                                          )
                                                                                  
                                                                                          await turn_context.send_activity(
                                                                                              f"LUIS entities: {childEntities}."
                                                                                          )
                                                                                          
                                                                                              
                                                                                          if childIntent == "name":
                                                                                              self.dialog_started = True
                                                                                              dialog = NameDialog(self.user_state)
                                                                                              await DialogHelper.run_dialog(dialog,turn_context,self.conversation_state.create_property("DialogState"))
                                                                                          elif childIntent == "place":
                                                                                              self.dialog_started = True
                                                                                              dialog = UserProfileDialog(self.user_state)
                                                                                              await DialogHelper.run_dialog(dialog,turn_context,self.conversation_state.create_property("DialogState"))
                                                                                          elif childIntent == "AGE":
                                                                                              self.dialog_started = True
                                                                                              dialog = NameDialog(self.user_state)
                                                                                              await DialogHelper.run_dialog(dialog,turn_context,self.conversation_state.create_property("DialogState"))
                                                                                          else:
                                                                                              await turn_context.send_activity(MessageFactory.text("No suitable intent detected"))
                                                                                  
                                                                                  
                                                                                      async def _process_sample_qna(self, turn_context: TurnContext):
                                                                                          results = await self.qna_maker.get_answers(turn_context)
                                                                                          if results:
                                                                                              await turn_context.send_activity(results[0].answer)
                                                                                          else:
                                                                                              await turn_context.send_activity(
                                                                                                  "Sorry, could not find an answer in the Q and A system."
                                                                                              )
                                                                                  

                                                                                  Whenever an intent and there by child intent is detected from Dispatch App, the dialog is getting triggered. However, as soon as the user provides input to the question from first dialog, which results in a None intent, the conversation ends with Dispatch unrecognized intent: None. The dialog is not supposed to end until an end_dialog is called. I tried doing the same by passing the child dialog into a Main Dialog like above, but it also results in the same. What should I be doing in order to skip the intent check or what am I doing wrong here ?

                                                                                  ANSWER

                                                                                  Answered 2020-Jul-09 at 07:39

                                                                                  Finally, I'm able to do exactly what I want. The Python SDK and the community around is not as mature as the .net one which is why it took a lot more time than it actually should. I followed a .Net sample on YouTube Github Repo. Checking if a dialog is active or seemed so straightforward after watching this sample. Below is the Python implementation. What the below code does is that, it creates a DialogSet when the bot is initiated and then a DialogContext. It checks if there is any existing dialog that can be run in the on_message_activity method, which if true, continues the old dialog or else, sends the message to LuisHelper Class to detect the intent and initiate the dialog based on intent.

                                                                                  Bot

                                                                                  import os
                                                                                  import json
                                                                                  
                                                                                  from botbuilder.core import ActivityHandler, ConversationState, UserState, TurnContext, StatePropertyAccessor, MessageFactory
                                                                                  from botbuilder.dialogs import Dialog, DialogSet, DialogTurnStatus
                                                                                  from botbuilder.schema import Attachment,ChannelAccount
                                                                                  from helpers.luis_helper import LuisDispatchResult
                                                                                  from helpers.qna_helper import QnAHelper,QnAMakerEndpoint
                                                                                  from dialogs import NameDialog, UserProfileDialog
                                                                                  from typing import List
                                                                                  from botbuilder.ai.qna import QnAMaker,QnAMakerEndpoint, QnAMakerOptions
                                                                                  
                                                                                  from config import DefaultConfig
                                                                                  
                                                                                  CONFIG = DefaultConfig()
                                                                                  
                                                                                  class Bot(ActivityHandler):
                                                                                      def __init__(
                                                                                          self,
                                                                                          conversation_state: ConversationState,
                                                                                          user_state: UserState
                                                                                      ):
                                                                                          if conversation_state is None:
                                                                                              raise Exception(
                                                                                                  "[DialogBot]: Missing parameter. conversation_state is required"
                                                                                              )
                                                                                          if user_state is None:
                                                                                              raise Exception("[DialogBot]: Missing parameter. user_state is required")
                                                                                  
                                                                                  
                                                                                          self.conversation_state = conversation_state
                                                                                          self.user_state = user_state
                                                                                  
                                                                                          self.accessor = self.conversation_state.create_property("DialogState")
                                                                                          self.dialog_set = DialogSet(self.accessor)
                                                                                          self.dialog_context = None
                                                                                  
                                                                                          self.app_id = CONFIG.LUIS_APP_ID
                                                                                          self.api_key = CONFIG.LUIS_API_KEY
                                                                                          self.host = "https://" + CONFIG.LUIS_API_HOST_NAME
                                                                                  
                                                                                      async def on_turn(self, turn_context: TurnContext):
                                                                                          await super().on_turn(turn_context)
                                                                                  
                                                                                          # Save any state changes that might have occurred during the turn.
                                                                                          await self.conversation_state.save_changes(turn_context, False)
                                                                                          await self.user_state.save_changes(turn_context, False)
                                                                                  
                                                                                  
                                                                                      async def on_members_added_activity(
                                                                                          self, members_added: List[ChannelAccount], turn_context: TurnContext
                                                                                      ):
                                                                                          for member in members_added:
                                                                                              # Greet anyone that was not the target (recipient) of this message.
                                                                                              # To learn more about Adaptive Cards, see https://aka.ms/msbot-adaptivecards for more details.
                                                                                              if member.id != turn_context.activity.recipient.id:
                                                                                                  welcome_card = self.create_adaptive_card_attachment()
                                                                                                  response = MessageFactory.attachment(welcome_card)
                                                                                                  await turn_context.send_activity(response)
                                                                                  
                                                                                      # Load attachment from file.
                                                                                      def create_adaptive_card_attachment(self):
                                                                                          relative_path = os.path.abspath(os.path.dirname(__file__))
                                                                                          path = os.path.join(relative_path, "cards/welcomeCard.json")
                                                                                          with open(path) as in_file:
                                                                                              card = json.load(in_file)
                                                                                  
                                                                                          return Attachment(
                                                                                              content_type="application/vnd.microsoft.card.adaptive", content=card
                                                                                          )
                                                                                  
                                                                                      async def on_message_activity(self, turn_context: TurnContext):        
                                                                                          
                                                                                          self.dialog_context = await self.dialog_set.create_context(turn_context)
                                                                                          results = await self.dialog_context.continue_dialog()
                                                                                  
                                                                                          if results.status == DialogTurnStatus.Empty:
                                                                                              topIntent,childIntent,childEntities = LuisDispatchResult().getLuisDispatchResult(self.app_id,self.api_key,self.host,turn_context.activity.text)
                                                                                              print(topIntent,childIntent,childEntities )
                                                                                              await self._dispatch_to_top_intent(turn_context, topIntent,childIntent,childEntities)
                                                                                  
                                                                                      async def _dispatch_to_top_intent(
                                                                                          self, turn_context: TurnContext, topIntent,childIntent,childEntities
                                                                                      ):
                                                                                          if topIntent == "l_myluisapp":
                                                                                              await self._process_luis_queries(
                                                                                                  turn_context, childIntent,childEntities
                                                                                              )
                                                                                          elif topIntent == "q_mybotqna":
                                                                                              await self._process_sample_qna(turn_context)
                                                                                          else:
                                                                                              await turn_context.send_activity(f"Dispatch unrecognized intent: {topIntent}.")
                                                                                  
                                                                                      async def _process_luis_queries(
                                                                                          self, turn_context: TurnContext, childIntent,childEntities
                                                                                      ):
                                                                                  
                                                                                          if childIntent == "name":
                                                                                              dialog = NameDialog(self.user_state)
                                                                                              if not await self.dialog_set.find(dialog.id):
                                                                                                  self.dialog_set.add(dialog)            
                                                                                              await self.dialog_context.begin_dialog(dialog.id)
                                                                                          elif childIntent == "place":
                                                                                              dialog = UserProfileDialog(self.user_state)
                                                                                              if not await self.dialog_set.find(dialog.id):
                                                                                                  self.dialog_set.add(dialog)            
                                                                                              await self.dialog_context.begin_dialog(dialog.id)
                                                                                          elif childIntent == "AGE":
                                                                                              dialog = NameDialog(self.user_state)
                                                                                              if not await self.dialog_set.find(dialog.id):
                                                                                                  self.dialog_set.add(dialog)            
                                                                                              await self.dialog_context.begin_dialog(dialog.id)
                                                                                          else:
                                                                                              await turn_context.send_activity(MessageFactory.text("No suitable intent detected, Checking QnA..."))
                                                                                              await self._process_sample_qna(turn_context)
                                                                                              
                                                                                  
                                                                                      async def _process_sample_qna(self, turn_context: TurnContext):
                                                                                  
                                                                                          results = await QnAMaker(QnAMakerEndpoint(CONFIG.QNA_KNOWLEDGEBASE_ID,CONFIG.QNA_ENDPOINT_KEY,CONFIG.QNA_ENDPOINT_HOST),QnAMakerOptions(score_threshold=CONFIG.QNA_THRESHOLD)).get_answers(turn_context)
                                                                                  
                                                                                          # results = await self.qna_maker.get_answers(turn_context)
                                                                                  
                                                                                          if results:
                                                                                              await turn_context.send_activity(results[0].answer)
                                                                                          else:
                                                                                              await turn_context.send_activity(
                                                                                                  "Sorry, could not find an answer in the Q and A system."
                                                                                              )
                                                                                  

                                                                                  app.py

                                                                                  from quart import Quart, request, Response
                                                                                  from botbuilder.core import (
                                                                                      BotFrameworkAdapterSettings,
                                                                                      ConversationState,
                                                                                      MemoryStorage,
                                                                                      UserState,
                                                                                  )
                                                                                  from botbuilder.schema import Activity
                                                                                  
                                                                                  from bot import Bot
                                                                                  
                                                                                  from adapter_with_error_handler import AdapterWithErrorHandler
                                                                                  
                                                                                  app = Quart(__name__, instance_relative_config=True)
                                                                                  # app.config.from_object("config.DefaultConfig")
                                                                                  
                                                                                  from config import DefaultConfig
                                                                                  
                                                                                  CONFIG = DefaultConfig()
                                                                                  
                                                                                  # Create adapter.
                                                                                  # See https://aka.ms/about-bot-adapter to learn more about how bots work.
                                                                                  SETTINGS = BotFrameworkAdapterSettings(CONFIG.APP_ID, CONFIG.APP_PASSWORD)
                                                                                  
                                                                                  # Create MemoryStorage, UserState and ConversationState
                                                                                  MEMORY = MemoryStorage()
                                                                                  USER_STATE = UserState(MEMORY)
                                                                                  CONVERSATION_STATE = ConversationState(MEMORY)
                                                                                  
                                                                                  # Create adapter.
                                                                                  # See https://aka.ms/about-bot-adapter to learn more about how bots work.
                                                                                  ADAPTER = AdapterWithErrorHandler(SETTINGS, CONVERSATION_STATE)
                                                                                  
                                                                                  
                                                                                  # Create dialogs and Bot
                                                                                  BOT = Bot(CONVERSATION_STATE, USER_STATE)
                                                                                  
                                                                                  
                                                                                  
                                                                                  # Listen for incoming requests on /api/messages
                                                                                  @app.route("/api/messages", methods=["POST"])
                                                                                  async def messages():
                                                                                      # Main bot message handler.
                                                                                      if "application/json" in request.headers["Content-Type"]:
                                                                                          body = await request.json
                                                                                      else:
                                                                                          return Response("", status=415)
                                                                                  
                                                                                      activity = Activity().deserialize(body)
                                                                                      auth_header = (
                                                                                          request.headers["Authorization"] if "Authorization" in request.headers else ""
                                                                                      )
                                                                                  
                                                                                      try:
                                                                                          await ADAPTER.process_activity(activity, auth_header, BOT.on_turn)
                                                                                          return Response("", status=201)
                                                                                      except Exception as exception:
                                                                                          raise exception
                                                                                  
                                                                                  
                                                                                  @app.route("/", methods=["GET"])
                                                                                  async def homepage():
                                                                                      try:
                                                                                          return "Yes I'm working brother."
                                                                                      except Exception as exception:
                                                                                          raise exception
                                                                                      
                                                                                  if __name__ == "__main__":
                                                                                      try:
                                                                                          app.run()  # nosec debug
                                                                                      except Exception as exception:
                                                                                          raise exception
                                                                                  

                                                                                  A Sample Dialog - Name Dialog

                                                                                  from botbuilder.dialogs import (
                                                                                      ComponentDialog,
                                                                                      WaterfallDialog,
                                                                                      WaterfallStepContext,
                                                                                      DialogTurnResult,
                                                                                  )
                                                                                  from botbuilder.dialogs.prompts import (
                                                                                      TextPrompt,
                                                                                      NumberPrompt,
                                                                                      ChoicePrompt,
                                                                                      ConfirmPrompt,
                                                                                      AttachmentPrompt,
                                                                                      PromptOptions,
                                                                                      PromptValidatorContext,
                                                                                  )
                                                                                  from botbuilder.dialogs.choices import Choice
                                                                                  from botbuilder.core import MessageFactory, UserState
                                                                                  
                                                                                  from data_models import Name
                                                                                  
                                                                                  
                                                                                  class NameDialog(ComponentDialog):
                                                                                  
                                                                                      def __init__(self, user_state: UserState):
                                                                                          super(NameDialog, self).__init__(NameDialog.__name__)
                                                                                  
                                                                                          self.name_accessor = user_state.create_property("Name")
                                                                                  
                                                                                          self.add_dialog(
                                                                                              WaterfallDialog(
                                                                                                  WaterfallDialog.__name__,
                                                                                                  [
                                                                                                      self.name_step,
                                                                                                      self.summary_step
                                                                                                  ],
                                                                                              )
                                                                                          )
                                                                                          self.add_dialog(
                                                                                              TextPrompt(TextPrompt.__name__)
                                                                                          )
                                                                                  
                                                                                          self.initial_dialog_id = WaterfallDialog.__name__
                                                                                  
                                                                                  
                                                                                      async def name_step(self, step_context: WaterfallStepContext) -> DialogTurnResult:
                                                                                  
                                                                                          return await step_context.prompt(
                                                                                              TextPrompt.__name__,
                                                                                              PromptOptions(prompt=MessageFactory.text("My name is Hidimbi. What's yours ?")),
                                                                                          )
                                                                                          # User said "no" so we will skip the next step. Give -1 as the age.
                                                                                          # return await step_context.next(-1)
                                                                                  
                                                                                  
                                                                                      async def summary_step(
                                                                                          self, step_context: WaterfallStepContext
                                                                                      ) -> DialogTurnResult:
                                                                                          if step_context.result:
                                                                                              # Get the current profile object from user state.  Changes to it
                                                                                              # will saved during Bot.on_turn.
                                                                                              
                                                                                              msg = f"Great name {step_context.result}."
                                                                                  
                                                                                  
                                                                                              await step_context.context.send_activity(MessageFactory.text(msg))
                                                                                  
                                                                                          else:
                                                                                              await step_context.context.send_activity(
                                                                                                  MessageFactory.text("Thanks. Your data is not saved")
                                                                                              )
                                                                                  
                                                                                          # WaterfallStep always finishes with the end of the Waterfall or with another
                                                                                          # dialog, here it is the end.
                                                                                          return await step_context.end_dialog()
                                                                                  
                                                                                      @staticmethod
                                                                                      async def material_prompt_validator(prompt_context: PromptValidatorContext) -> bool:
                                                                                          # This condition is our validation rule. You can also change the value at this point.
                                                                                          return (
                                                                                              prompt_context.recognized.succeeded
                                                                                              and 0 < prompt_context.recognized.value < 150
                                                                                          )
                                                                                  

                                                                                  Source https://stackoverflow.com/questions/62655197

                                                                                  Community Discussions, Code Snippets contain sources that include Stack Exchange Network

                                                                                  Vulnerabilities

                                                                                  No vulnerabilities reported

                                                                                  Install botbuilder-python

                                                                                  | Branch | Description | Build Status | Coverage Status | Code Style | |----|---------------|--------------|-----------------|--| | Main | 4.15.0 Builds | [![Build Status](https://fuselabs.visualstudio.com/SDK_v4/_apis/build/status/Python/Python-CI-PR-yaml?branchName=main)](https://fuselabs.visualstudio.com/SDK_v4/_build/latest?definitionId=771&branchName=main) | [![Coverage Status](https://coveralls.io/repos/github/microsoft/botbuilder-python/badge.svg?branch=HEAD)](https://coveralls.io/github/microsoft/botbuilder-python?branch=HEAD) | [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) |.
                                                                                  To get started building bots using the SDK, see the [Azure Bot Service Documentation](https://docs.microsoft.com/en-us/azure/bot-service/?view=azure-bot-service-4.0). The [Bot Framework Samples](https://github.com/microsoft/botbuilder-samples) includes a rich set of samples repository.

                                                                                  Support

                                                                                  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.
                                                                                  Find more information at:
                                                                                  Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
                                                                                  Find more libraries
                                                                                  Explore Kits - Develop, implement, customize Projects, Custom Functions and Applications with kandi kits​
                                                                                  Save this library and start creating your kit

                                                                                  Share this Page

                                                                                  share link

                                                                                  Explore Related Topics

                                                                                  Reuse Pre-built Kits with botbuilder-python

                                                                                  Consider Popular Bot Libraries

                                                                                  Telegram

                                                                                  by DrKLO

                                                                                  discord.js

                                                                                  by discordjs

                                                                                  hubot

                                                                                  by hubotio

                                                                                  InstaPy

                                                                                  by timgrossmann

                                                                                  YYeTsBot

                                                                                  by tgbot-collection

                                                                                  Try Top Libraries by microsoft

                                                                                  vscode

                                                                                  by microsoftTypeScript

                                                                                  TypeScript

                                                                                  by microsoftTypeScript

                                                                                  PowerToys

                                                                                  by microsoftC#

                                                                                  terminal

                                                                                  by microsoftC++

                                                                                  Web-Dev-For-Beginners

                                                                                  by microsoftJavaScript

                                                                                  Compare Bot Libraries with Highest Support

                                                                                  Telegram

                                                                                  by DrKLO

                                                                                  discord.js

                                                                                  by discordjs

                                                                                  Red-DiscordBot

                                                                                  by Cog-Creators

                                                                                  botframework-sdk

                                                                                  by microsoft

                                                                                  beets

                                                                                  by beetbox

                                                                                  Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
                                                                                  Find more libraries
                                                                                  Explore Kits - Develop, implement, customize Projects, Custom Functions and Applications with kandi kits​
                                                                                  Save this library and start creating your kit