From fbe71baea5dc63c2ee812c64804f9b9bf685cf7e Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Fri, 10 Jan 2020 11:14:18 -0800 Subject: [PATCH 01/56] Test Line break to test PR build --- .../botbuilder-testing/botbuilder/testing/dialog_test_client.py | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/botbuilder-testing/botbuilder/testing/dialog_test_client.py b/libraries/botbuilder-testing/botbuilder/testing/dialog_test_client.py index 4ead12a3e..2ca60fa07 100644 --- a/libraries/botbuilder-testing/botbuilder/testing/dialog_test_client.py +++ b/libraries/botbuilder-testing/botbuilder/testing/dialog_test_client.py @@ -1,6 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + from typing import List, Union from botbuilder.core import ( From 43cec24b9e434eeb9a61f474d900459c897f5554 Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Fri, 10 Jan 2020 15:45:47 -0800 Subject: [PATCH 02/56] Update prompt.py (#591) Added ref documentation --- .../botbuilder/dialogs/prompts/prompt.py | 156 ++++++++++++++---- 1 file changed, 128 insertions(+), 28 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py index 0ab60ba17..09f43bdbd 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py @@ -23,22 +23,30 @@ class Prompt(Dialog): - """ Base class for all prompts.""" - + """ Prompts base class + Defines the core behavior of prompt dialogs. Extends `Dialog` base class. + + .. remarks:: + When the prompt ends, it should return an object that represents the + value that was prompted for. + Use `DialogSet.Add(Dialog)` or `ComponentDialog.AddDialog(Dialog)` to add a prompt + to a dialog set or component dialog, respectively. + Use `DialogContext.PromptAsync(string, PromptOptions, CancellationToken)` or + `DialogContext.BeginDialogAsync(string, object, CancellationToken)` to start the prompt. + If you start a prompt from a `WaterfallStep` in a `WaterfallDialog`, then the prompt + result will be available in the next step of the waterfall. + """ ATTEMPT_COUNT_KEY = "AttemptCount" persisted_options = "options" persisted_state = "state" def __init__(self, dialog_id: str, validator: object = None): - """Creates a new Prompt instance. - Parameters - ---------- - dialog_id - Unique ID of the prompt within its parent `DialogSet` or - `ComponentDialog`. - validator - (Optional) custom validator used to provide additional validation and - re-prompting logic for the prompt. + """Creates a new Prompt instance + :param dialog_id: Unique ID of the prompt within its parent :class:DialogSet or + :class:ComponentDialog. + :type dialog_id: str + :param validator: Optional custom validator used to provide additional validation and re-prompting logic for the prompt. + :type validator: object """ super(Prompt, self).__init__(dialog_id) @@ -47,6 +55,20 @@ def __init__(self, dialog_id: str, validator: object = None): async def begin_dialog( self, dialog_context: DialogContext, options: object = None ) -> DialogTurnResult: + """ Starts a prompt dialog. + Called when a prompt dialog is pushed onto the dialog stack and is being activated. + + :param dialog_context: The dialog context for the current turn of the conversation. + :type dialog_context: :class:DialogContext + :param options: Optional, additional information to pass to the prompt being started. + :type options: object + :return: A :class:Task representing the asynchronous operation. + :rtype: :class:Task + + .. remarks:: + If the task is successful, the result indicates whether the prompt is still active + after the turn has been processed by the prompt. + """ if not dialog_context: raise TypeError("Prompt(): dc cannot be None.") if not isinstance(options, PromptOptions): @@ -74,6 +96,21 @@ async def begin_dialog( return Dialog.end_of_turn async def continue_dialog(self, dialog_context: DialogContext): + """ Continues a dialog. + Called when a prompt dialog is the active dialog and the user replied with a new activity. + + :param dialog_context: The dialog context for the current turn of the conversation. + :type dialog_context: :class:DialogContext + + :return: A :class:Task representing the asynchronous operation. + :rtype: :class:Task + + .. remarks:: + If the task is successful, the result indicates whether the dialog is still + active after the turn has been processed by the dialog. + The prompt generally continues to receive the user's replies until it accepts the + user's reply as valid input for the prompt. + """ if not dialog_context: raise TypeError("Prompt(): dc cannot be None.") @@ -111,15 +148,42 @@ async def continue_dialog(self, dialog_context: DialogContext): async def resume_dialog( self, dialog_context: DialogContext, reason: DialogReason, result: object ) -> DialogTurnResult: - # Prompts are typically leaf nodes on the stack but the dev is free to push other dialogs - # on top of the stack which will result in the prompt receiving an unexpected call to - # dialog_resume() when the pushed on dialog ends. - # To avoid the prompt prematurely ending we need to implement this method and - # simply re-prompt the user. + """ Resumes a dialog. + Called when a prompt dialog resumes being the active dialog on the dialog stack, such as + when the previous active dialog on the stack completes. + + :param dialog_context: The dialog context for the current turn of the conversation. + :type dialog_context: :class:DialogContext + :param reason: An enum indicating why the dialog resumed. + :type reason: :class:DialogReason + :param result: Optional, value returned from the previous dialog on the stack. + The type of the value returned is dependent on the previous dialog. + :type result: object + :return: A :class:Task representing the asynchronous operation. + :rtype: :class:Task + + .. remarks:: + If the task is successful, the result indicates whether the dialog is still + active after the turn has been processed by the dialog. + Prompts are typically leaf nodes on the stack but the dev is free to push other dialogs + on top of the stack which will result in the prompt receiving an unexpected call to + :meth:resume_dialog() when the pushed on dialog ends. + To avoid the prompt prematurely ending we need to simply re-prompt the user. + """ await self.reprompt_dialog(dialog_context.context, dialog_context.active_dialog) return Dialog.end_of_turn async def reprompt_dialog(self, context: TurnContext, instance: DialogInstance): + """ Reprompts user for input. + Called when a prompt dialog has been requested to reprompt the user for input. + + :param context: Context for the current turn of conversation with the user. + :type context: :class:TurnContext + :param instance: The instance of the dialog on the stack. + :type instance: :class:DialogInstance + :return: A :class:Task representing the asynchronous operation. + :rtype: :class:Task + """ state = instance.state[self.persisted_state] options = instance.state[self.persisted_options] await self.on_prompt(context, state, options, False) @@ -132,6 +196,23 @@ async def on_prompt( options: PromptOptions, is_retry: bool, ): + """ Prompts user for input. + When overridden in a derived class, prompts the user for input. + + :param turn_context: Context for the current turn of conversation with the user. + :type turn_context: :class:TurnContext + :param state: Contains state for the current instance of the prompt on the dialog stack. + :type state: :class:Dict + :param options: A prompt options object constructed from the options initially provided + in the call :meth:DialogContext.PromptAsync(string, PromptOptions, CancellationToken). + :type options: :class:PromptOptions + :param is_retry: true if this is the first time this prompt dialog instance on the stack is prompting + the user for input; otherwise, false. + :type is_retry: bool + + :return: A :class:Task representing the asynchronous operation. + :rtype: :class:Task + """ pass @abstractmethod @@ -141,6 +222,20 @@ async def on_recognize( state: Dict[str, object], options: PromptOptions, ): + """ Recognizes the user's input. + When overridden in a derived class, attempts to recognize the user's input. + + :param turn_context: Context for the current turn of conversation with the user. + :type turn_context: :class:TurnContext + :param state: Contains state for the current instance of the prompt on the dialog stack. + :type state: :class:Dict + :param options: A prompt options object constructed from the options initially provided + in the call :meth:DialogContext.PromptAsync(string, PromptOptions, CancellationToken). + :type options: :class:PromptOptions + + :return: A :class:Task representing the asynchronous operation. + :rtype: :class:Task + """ pass def append_choices( @@ -151,20 +246,25 @@ def append_choices( style: ListStyle, options: ChoiceFactoryOptions = None, ) -> Activity: - """ + """ Composes an output activity containing a set of choices. + When overridden in a derived class, appends choices to the activity when the user is prompted for input. Helper function to compose an output activity containing a set of choices. - Parameters: - ----------- - prompt: The prompt to append the user's choice to. - - channel_id: ID of the channel the prompt is being sent to. - - choices: List of choices to append. - - style: Configured style for the list of choices. - - options: (Optional) options to configure the underlying `ChoiceFactory` call. + :param prompt: The prompt to append the user's choice to. + :type prompt: + :param channel_id: ID of the channel the prompt is being sent to. + :type channel_id: str + :param: choices: List of choices to append. + :type choices: :class:List + :param: style: Configured style for the list of choices. + :type style: :class:ListStyle + :param: options: Optional formatting options to use when presenting the choices. + :type style: :class:ChoiceFactoryOptions + :return: A :class:Task representing the asynchronous operation. + :rtype: :class:Task + + .. remarks:: + If the task is successful, the result contains the updated activity. """ # Get base prompt text (if any) text = prompt.text if prompt is not None and prompt.text else "" From f6f69b74015040c2d96aee033f30b8e941aaa77e Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Fri, 10 Jan 2020 15:46:33 -0800 Subject: [PATCH 03/56] Update conversation_state.py (#590) Added ref documentation. --- .../botbuilder/core/conversation_state.py | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/libraries/botbuilder-core/botbuilder/core/conversation_state.py b/libraries/botbuilder-core/botbuilder/core/conversation_state.py index 94bc8fedb..11f6b328d 100644 --- a/libraries/botbuilder-core/botbuilder/core/conversation_state.py +++ b/libraries/botbuilder-core/botbuilder/core/conversation_state.py @@ -7,16 +7,41 @@ class ConversationState(BotState): - """Conversation State - Reads and writes conversation state for your bot to storage. + """Conversation state + Defines a state management object for conversation state. + Extends `BootState` base class. + + .. remarks:: + Conversation state is available in any turn in a specific conversation, regardless of user, such as in a group conversation. """ no_key_error_message = "ConversationState: channelId and/or conversation missing from context.activity." def __init__(self, storage: Storage): + """ Creates a :class:ConversationState instance + Creates a new instance of the :class:ConversationState class. + :param storage: The storage containing the conversation state. + :type storage: Storage + """ super(ConversationState, self).__init__(storage, "ConversationState") def get_storage_key(self, turn_context: TurnContext) -> object: + """ Get storage key + Gets the key to use when reading and writing state to and from storage. + + :param turn_context: The context object for this turn. + :type turn_context: TurnContext + + :raise: `TypeError` if the `ITurnContext.Activity` for the current turn is missing + :any::Schema.Activity.ChannelId or :any::Schema.Activity.Conversation information, or + the conversation's :any::Schema.ConversationAccount.Id is missing. + + :return: The storage key. + :rtype: str + + .. remarks:: + Conversation state includes the channel ID and conversation ID as part of its storage key. + """ channel_id = turn_context.activity.channel_id or self.__raise_type_error( "invalid activity-missing channel_id" ) @@ -31,4 +56,7 @@ def get_storage_key(self, turn_context: TurnContext) -> object: return storage_key def __raise_type_error(self, err: str = "NoneType found while expecting value"): + """ Raise type error + :raises: :class:TypeError This function raises exception. + """ raise TypeError(err) From 8037ff2ec40de49e7ba0607628d60d8622050dbb Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Mon, 13 Jan 2020 14:02:54 -0800 Subject: [PATCH 04/56] Update conversation_state.py Added reference documentation. --- .../botbuilder/core/conversation_state.py | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/libraries/botbuilder-core/botbuilder/core/conversation_state.py b/libraries/botbuilder-core/botbuilder/core/conversation_state.py index 11f6b328d..954620de1 100644 --- a/libraries/botbuilder-core/botbuilder/core/conversation_state.py +++ b/libraries/botbuilder-core/botbuilder/core/conversation_state.py @@ -9,19 +9,18 @@ class ConversationState(BotState): """Conversation state Defines a state management object for conversation state. - Extends `BootState` base class. + Extends :class:`BootState` base class. .. remarks:: Conversation state is available in any turn in a specific conversation, regardless of user, such as in a group conversation. """ - no_key_error_message = "ConversationState: channelId and/or conversation missing from context.activity." def __init__(self, storage: Storage): - """ Creates a :class:ConversationState instance - Creates a new instance of the :class:ConversationState class. + """ Creates a :class:`ConversationState` instance + Creates a new instance of the :class:`ConversationState` class. :param storage: The storage containing the conversation state. - :type storage: Storage + :type storage: :class:`Storage` """ super(ConversationState, self).__init__(storage, "ConversationState") @@ -30,17 +29,17 @@ def get_storage_key(self, turn_context: TurnContext) -> object: Gets the key to use when reading and writing state to and from storage. :param turn_context: The context object for this turn. - :type turn_context: TurnContext + :type turn_context: :class:`TurnContext` - :raise: `TypeError` if the `ITurnContext.Activity` for the current turn is missing - :any::Schema.Activity.ChannelId or :any::Schema.Activity.Conversation information, or - the conversation's :any::Schema.ConversationAccount.Id is missing. + :raise: :class:`TypeError` if the :meth:`TurnContext.activity` for the current turn is missing + :class:`botbuilder.schema.Activity` channelId or conversation information or the conversation's + account id is missing. :return: The storage key. :rtype: str .. remarks:: - Conversation state includes the channel ID and conversation ID as part of its storage key. + Conversation state includes the channel Id and conversation Id as part of its storage key. """ channel_id = turn_context.activity.channel_id or self.__raise_type_error( "invalid activity-missing channel_id" @@ -56,7 +55,7 @@ def get_storage_key(self, turn_context: TurnContext) -> object: return storage_key def __raise_type_error(self, err: str = "NoneType found while expecting value"): - """ Raise type error - :raises: :class:TypeError This function raises exception. + """ Raise type error exception + :raises: :class:`TypeError` """ raise TypeError(err) From 98b47c74390f617d3d9d1baa033e515630c72781 Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Mon, 13 Jan 2020 15:28:30 -0800 Subject: [PATCH 05/56] Update prompt.py Added reference documentation. --- .../botbuilder/dialogs/prompts/prompt.py | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py index 09f43bdbd..d3ab5a80f 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py @@ -24,17 +24,18 @@ class Prompt(Dialog): """ Prompts base class - Defines the core behavior of prompt dialogs. Extends `Dialog` base class. + Defines the core behavior of prompt dialogs. Extends the :class:`Dialog` base class. .. remarks:: - When the prompt ends, it should return an object that represents the - value that was prompted for. - Use `DialogSet.Add(Dialog)` or `ComponentDialog.AddDialog(Dialog)` to add a prompt + When the prompt ends, it returns an object that represents the value it was prompted for. + Use :method:`DialogSet.add(self, dialog: Dialog)` or :method:`ComponentDialog.add_dialog(self, dialog: Dialog)` to add a prompt to a dialog set or component dialog, respectively. - Use `DialogContext.PromptAsync(string, PromptOptions, CancellationToken)` or - `DialogContext.BeginDialogAsync(string, object, CancellationToken)` to start the prompt. - If you start a prompt from a `WaterfallStep` in a `WaterfallDialog`, then the prompt - result will be available in the next step of the waterfall. + Use :method:`DialogContext.prompt(self, dialog_id: str, options)` or + :meth:`DialogContext.begin_dialog( + self, dialog_context: DialogContext, options: object = None)` to start the prompt. + .. note:: + If you start a prompt from a :class:`WaterfallStep` in a :class:`WaterfallDialog`, then the prompt result will be + available in the next step of the waterfall. """ ATTEMPT_COUNT_KEY = "AttemptCount" persisted_options = "options" @@ -42,11 +43,11 @@ class Prompt(Dialog): def __init__(self, dialog_id: str, validator: object = None): """Creates a new Prompt instance - :param dialog_id: Unique ID of the prompt within its parent :class:DialogSet or - :class:ComponentDialog. + :param dialog_id: Unique Id of the prompt within its parent :class:`DialogSet` or + :class:`ComponentDialog`. :type dialog_id: str :param validator: Optional custom validator used to provide additional validation and re-prompting logic for the prompt. - :type validator: object + :type validator: Object """ super(Prompt, self).__init__(dialog_id) @@ -59,11 +60,11 @@ async def begin_dialog( Called when a prompt dialog is pushed onto the dialog stack and is being activated. :param dialog_context: The dialog context for the current turn of the conversation. - :type dialog_context: :class:DialogContext + :type dialog_context: :class:`DialogContext` :param options: Optional, additional information to pass to the prompt being started. - :type options: object - :return: A :class:Task representing the asynchronous operation. - :rtype: :class:Task + :type options: Object + :return: The dialog turn result + :rtype: :class:`DialogTurnResult` .. remarks:: If the task is successful, the result indicates whether the prompt is still active @@ -100,10 +101,9 @@ async def continue_dialog(self, dialog_context: DialogContext): Called when a prompt dialog is the active dialog and the user replied with a new activity. :param dialog_context: The dialog context for the current turn of the conversation. - :type dialog_context: :class:DialogContext - - :return: A :class:Task representing the asynchronous operation. - :rtype: :class:Task + :type dialog_context: :class:`DialogContext` + :return: The dialog turn result + :rtype: :class:`DialogTurnResult` .. remarks:: If the task is successful, the result indicates whether the dialog is still @@ -159,8 +159,8 @@ async def resume_dialog( :param result: Optional, value returned from the previous dialog on the stack. The type of the value returned is dependent on the previous dialog. :type result: object - :return: A :class:Task representing the asynchronous operation. - :rtype: :class:Task + :return: The dialog turn result + :rtype: :class:`DialogTurnResult` .. remarks:: If the task is successful, the result indicates whether the dialog is still @@ -175,7 +175,7 @@ async def resume_dialog( async def reprompt_dialog(self, context: TurnContext, instance: DialogInstance): """ Reprompts user for input. - Called when a prompt dialog has been requested to reprompt the user for input. + Called when a prompt dialog has been requested to re-prompt the user for input. :param context: Context for the current turn of conversation with the user. :type context: :class:TurnContext @@ -200,12 +200,12 @@ async def on_prompt( When overridden in a derived class, prompts the user for input. :param turn_context: Context for the current turn of conversation with the user. - :type turn_context: :class:TurnContext + :type turn_context: :class:`TurnContext` :param state: Contains state for the current instance of the prompt on the dialog stack. :type state: :class:Dict :param options: A prompt options object constructed from the options initially provided - in the call :meth:DialogContext.PromptAsync(string, PromptOptions, CancellationToken). - :type options: :class:PromptOptions + in the call :meth:`DialogContext.prompt(self, dialog_id: str, options)`. + :type options: :class:`PromptOptions` :param is_retry: true if this is the first time this prompt dialog instance on the stack is prompting the user for input; otherwise, false. :type is_retry: bool @@ -226,11 +226,11 @@ async def on_recognize( When overridden in a derived class, attempts to recognize the user's input. :param turn_context: Context for the current turn of conversation with the user. - :type turn_context: :class:TurnContext + :type turn_context: :class:`TurnContext` :param state: Contains state for the current instance of the prompt on the dialog stack. :type state: :class:Dict :param options: A prompt options object constructed from the options initially provided - in the call :meth:DialogContext.PromptAsync(string, PromptOptions, CancellationToken). + in the call :meth:`DialogContext.prompt(self, dialog_id: str, options)` :type options: :class:PromptOptions :return: A :class:Task representing the asynchronous operation. @@ -252,14 +252,14 @@ def append_choices( :param prompt: The prompt to append the user's choice to. :type prompt: - :param channel_id: ID of the channel the prompt is being sent to. + :param channel_id: Id of the channel the prompt is being sent to. :type channel_id: str :param: choices: List of choices to append. - :type choices: :class:List + :type choices: :class:`List` :param: style: Configured style for the list of choices. - :type style: :class:ListStyle + :type style: :class:`ListStyle` :param: options: Optional formatting options to use when presenting the choices. - :type style: :class:ChoiceFactoryOptions + :type style: :class:`ChoiceFactoryOptions` :return: A :class:Task representing the asynchronous operation. :rtype: :class:Task From bb83c8277aa146403acd09a88cba82ec5bf284dc Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Mon, 13 Jan 2020 16:06:46 -0800 Subject: [PATCH 06/56] Update oauth_prompt.py Added reference documentation. --- .../dialogs/prompts/oauth_prompt.py | 116 ++++++++++++++---- 1 file changed, 91 insertions(+), 25 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/oauth_prompt.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/oauth_prompt.py index 49ab9624d..731ac6ecd 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/oauth_prompt.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/oauth_prompt.py @@ -32,39 +32,54 @@ class OAuthPrompt(Dialog): - """ + """Creates a new prompt for the user to sign in Creates a new prompt that asks the user to sign in using the Bot Framework Single Sign On (SSO) service. - The prompt will attempt to retrieve the users current token and if the user isn't signed in, it - will send them an `OAuthCard` containing a button they can press to sign in. Depending on the channel, - the user will be sent through one of two possible sign-in flows: - - The automatic sign-in flow where once the user signs in, the SSO service will forward - the bot the users access token using either an `event` or `invoke` activity. - - The "magic code" flow where once the user signs in, they will be prompted by the SSO service - to send the bot a six digit code confirming their identity. This code will be sent as a - standard `message` activity. - Both flows are automatically supported by the `OAuthPrompt` and they only thing you need to be careful of - is that you don't block the `event` and `invoke` activities that the prompt might be waiting on. - Note: - You should avaoid persisting the access token with your bots other state. The Bot Frameworks SSO service - will securely store the token on your behalf. If you store it in your bots state, - it could expire or be revoked in between turns. - When calling the prompt from within a waterfall step, you should use the token within the step - following the prompt and then let the token go out of scope at the end of your function - Prompt Usage - When used with your bots `DialogSet`, you can simply add a new instance of the prompt as a named dialog using - `DialogSet.add()`. - You can then start the prompt from a waterfall step using either - `DialogContext.begin()` or `DialogContext.prompt()`. - The user will be prompted to sign in as needed and their access token will be passed as an argument to the callers - next waterfall step. - """ + .. remarks:: + The prompt will attempt to retrieve the users current token and if the user isn't signed in, it + will send them an `OAuthCard` containing a button they can press to sign in. Depending on the channel, + the user will be sent through one of two possible sign-in flows: + - The automatic sign-in flow where once the user signs in, the SSO service will forward + the bot the users access token using either an `event` or `invoke` activity. + - The "magic code" flow where once the user signs in, they will be prompted by the SSO service + to send the bot a six digit code confirming their identity. This code will be sent as a + standard `message` activity. + Both flows are automatically supported by the `OAuthPrompt` and they only thing you need to be careful of + is that you don't block the `event` and `invoke` activities that the prompt might be waiting on. + + .. note:: + You should avoid persisting the access token with your bots other state. The Bot Frameworks SSO service + will securely store the token on your behalf. If you store it in your bots state, + it could expire or be revoked in between turns. + When calling the prompt from within a waterfall step, you should use the token within the step + following the prompt and then let the token go out of scope at the end of your function. + + **Prompt Usage** + When used with your bots :class:`DialogSet`, you can simply add a new instance of the prompt as a named dialog using + :meth`DialogSet.add()`. + You can then start the prompt from a waterfall step using either :meth:`DialogContext.begin()` or :meth:`DialogContext.prompt()`. + The user will be prompted to sign in as needed and their access token will be passed as an argument to the callers + next waterfall step. + """ def __init__( self, dialog_id: str, settings: OAuthPromptSettings, validator: Callable[[PromptValidatorContext], Awaitable[bool]] = None, ): + """ Creates a :class:`OAuthPrompt` instance + Creates a new instance of the :class:`OAuthPrompt` class. + + :param dialogId: The Id to assign to this prompt. + :type dialogId: str + :param settings: Additional authentication settings to use with this instance of the prompt. + :type settings: :class:`OAuthPromptSettings` + :param validator: Optional, a :class:`PromptValidator` that contains additional, custom validation for this prompt. + :type validator: :class:`PromptValidatorContext` + + .. remarks:: + The value of :param dialogId: must be unique within the :class:`DialogSet`or :class:`ComponentDialog` to which the prompt is added. + """ super().__init__(dialog_id) self._validator = validator @@ -79,6 +94,20 @@ def __init__( async def begin_dialog( self, dialog_context: DialogContext, options: PromptOptions = None ) -> DialogTurnResult: + """ Starts an authentication prompt dialog. + Called when an authentication prompt dialog is pushed onto the dialog stack and is being activated. + + :param dialog_context: The dialog context for the current turn of the conversation. + :type dialog_context: :class:`DialogContext` + :param options: Optional, additional information to pass to the prompt being started. + :type options: :class:PromptOptions + :return: Dialog turn result + :rtype: :class:DialogTurnResult + + .. remarks:: + If the task is successful, the result indicates whether the prompt is still active + after the turn has been processed by the prompt. + """ if dialog_context is None: raise TypeError( f"OAuthPrompt.begin_dialog: Expected DialogContext but got NoneType instead" @@ -120,6 +149,20 @@ async def begin_dialog( return Dialog.end_of_turn async def continue_dialog(self, dialog_context: DialogContext) -> DialogTurnResult: + """ Continues a dialog. + Called when a prompt dialog is the active dialog and the user replied with a new activity. + + :param dialog_context: The dialog context for the current turn of the conversation. + :type dialog_context: :class:`DialogContext` + :return: Dialog turn result + :rtype: :class:DialogTurnResult + + .. remarks:: + If the task is successful, the result indicates whether the dialog is still + active after the turn has been processed by the dialog. + The prompt generally continues to receive the user's replies until it accepts the + user's reply as valid input for the prompt. + """ # Recognize token recognized = await self._recognize_token(dialog_context.context) @@ -167,6 +210,18 @@ async def continue_dialog(self, dialog_context: DialogContext) -> DialogTurnResu async def get_user_token( self, context: TurnContext, code: str = None ) -> TokenResponse: + """Gets the user's token + Attempts to get the user's token. + + :param context: Context for the current turn of conversation with the user. + :type context: :class:TurnContext + :return: A response that includes the user's token + :rtype: :class:TokenResponse + + .. remarks:: + If the task is successful and the user already has a token or the user successfully signs in, + the result contains the user's token. + """ adapter = context.adapter # Validate adapter type @@ -180,6 +235,17 @@ async def get_user_token( ) async def sign_out_user(self, context: TurnContext): + """Signs out the user + + :param context: Context for the current turn of conversation with the user. + :type context: :class:`TurnContext` + :return: A :class:`Task` representing the work queued to execute. + :rtype: :class:`Task` + + .. remarks:: + If the task is successful and the user already has a token or the user successfully signs in, + the result contains the user's token. + """ adapter = context.adapter # Validate adapter type From 9e24ae2580202b9db2b091fb07f90b8a62b9aa8e Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Mon, 13 Jan 2020 16:37:28 -0800 Subject: [PATCH 07/56] Update prompt_options.py Added ref documentation --- .../dialogs/prompts/prompt_options.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt_options.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt_options.py index 8d9801424..2a3d6ef38 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt_options.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt_options.py @@ -8,6 +8,10 @@ class PromptOptions: + """ Contains prompt settings + Contains settings to pass to a :class:`Prompt` object when the prompt is started. + """ + def __init__( self, prompt: Activity = None, @@ -17,6 +21,22 @@ def __init__( validations: object = None, number_of_attempts: int = 0, ): + """ Sets the initial prompt to send to the user as an :class:`botbuilder.schema.Activity`. + + :param prompt: The initial prompt to send to the user + :type prompt: :class:`botbuilder.schema.Activity` + :param retry_prompt: The retry prompt to send to the user + :type retry_prompt: :class:`botbuilder.schema.Activity` + :param choices: The choices to send to the user + :type choices: :class:`List` + :param style: The style of the list of choices to send to the user + :type style: :class:`ListStyle` + :param validations: The prompt validations + :type validations: :class:`Object` + :param number_of_attempts: The number of attempts allowed + :type number_of_attempts: :class:`int` + + """ self.prompt = prompt self.retry_prompt = retry_prompt self.choices = choices From 4d4ceb4b5f332cbf3b83d8838aff0cd0ef47bea1 Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Tue, 14 Jan 2020 14:00:48 -0800 Subject: [PATCH 08/56] emolsh/api-ref-docs-dialogturnstatus --- .../botbuilder/dialogs/dialog_turn_status.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py index e734405a8..36441fe7c 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py @@ -2,16 +2,23 @@ # Licensed under the MIT License. from enum import Enum - class DialogTurnStatus(Enum): - # Indicates that there is currently nothing on the dialog stack. + """Codes indicating the state of the dialog stack after a call to `DialogContext.continueDialog()` + + :var Empty: Indicates that there is currently nothing on the dialog stack. + :vartype Empty: int + :var Waiting: Indicates that the dialog on top is waiting for a response from the user. + :vartype Waiting: int + :var Complete: Indicates that the dialog completed successfully, the result is available, and the stack is empty. + :vartype Complete: int + :var Cancelled: Indicates that the dialog was cancelled and the stack is empty. + :vartype Cancelled: int + """ + Empty = 1 - # Indicates that the dialog on top is waiting for a response from the user. Waiting = 2 - # Indicates that the dialog completed successfully, the result is available, and the stack is empty. Complete = 3 - # Indicates that the dialog was cancelled and the stack is empty. Cancelled = 4 From 70ed08f6335e87847a69968c10da1e76722bca59 Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Tue, 14 Jan 2020 16:02:19 -0800 Subject: [PATCH 09/56] Update bot_state.py Added ref documentation. --- .../botbuilder/core/bot_state.py | 112 +++++++++++++----- 1 file changed, 82 insertions(+), 30 deletions(-) diff --git a/libraries/botbuilder-core/botbuilder/core/bot_state.py b/libraries/botbuilder-core/botbuilder/core/bot_state.py index 4e615dda0..a05244832 100644 --- a/libraries/botbuilder-core/botbuilder/core/bot_state.py +++ b/libraries/botbuilder-core/botbuilder/core/bot_state.py @@ -12,11 +12,12 @@ class CachedBotState: - """ - Internal cached bot state. + """ + Internal cached bot state """ def __init__(self, state: Dict[str, object] = None): + self.state = state if state is not None else {} self.hash = self.compute_hash(state) @@ -29,17 +30,43 @@ def compute_hash(self, obj: object) -> str: class BotState(PropertyManager): + """ Defines a state management object + Defines a state management object and automates the reading and writing of + associated state properties to a storage layer + + .. remarks:: + Each state management object defines a scope for a storage layer. + State properties are created within a state management scope, and the Bot Framework + defines these scopes: :class:`ConversationState`, :class:`UserState`, and :class:`PrivateConversationState`. + You can define additional scopes for your bot. + """ + def __init__(self, storage: Storage, context_service_key: str): + """ Initializes a new instance of the :class:`BotState` class. + + :param storage: The storage layer this state management object will use to store and retrieve state + :type storage: :class:`bptbuilder.core.Storage` + :param context_service_key: The key for the state cache for this :class:`BotState` + :type context_service_key: str + + .. remarks:: + This constructor creates a state management object and associated scope. The object uses + the :param storage: to persist state property values and the :param context_service_key: to cache state + within the context for each turn. + + :raises: It raises an argument null exception + """ self.state_key = "state" self._storage = storage self._context_service_key = context_service_key def create_property(self, name: str) -> StatePropertyAccessor: """ - Create a property definition and register it with this BotState. - :param name: The name of the property. - :param force: + Create a property definition and register it with this :class:`BotState`. + :param name: The name of the property + :type name: str :return: If successful, the state property accessor created. + :rtype: :class:`StatePropertyAccessor` """ if not name: raise TypeError("BotState.create_property(): name cannot be None or empty.") @@ -52,9 +79,11 @@ def get(self, turn_context: TurnContext) -> Dict[str, object]: async def load(self, turn_context: TurnContext, force: bool = False) -> None: """ - Reads in the current state object and caches it in the context object for this turm. - :param turn_context: The context object for this turn. - :param force: Optional. True to bypass the cache. + Reads in the current state object and caches it in the context object for this turn. + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + :param force: Optional, true to bypass the cache + :type force: bool """ if turn_context is None: raise TypeError("BotState.load(): turn_context cannot be None.") @@ -70,11 +99,13 @@ async def load(self, turn_context: TurnContext, force: bool = False) -> None: async def save_changes( self, turn_context: TurnContext, force: bool = False ) -> None: - """ - If it has changed, writes to storage the state object that is cached in the current context object - for this turn. - :param turn_context: The context object for this turn. - :param force: Optional. True to save state to storage whether or not there are changes. + """Save the state cached in the current context for this turn + If it has changed, save the state cached in the current context for this turn. + + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + :param force: Optional, true to save state to storage whether or not there are changes. + :type force: bool """ if turn_context is None: raise TypeError("BotState.save_changes(): turn_context cannot be None.") @@ -88,11 +119,15 @@ async def save_changes( cached_state.hash = cached_state.compute_hash(cached_state.state) async def clear_state(self, turn_context: TurnContext): - """ - Clears any state currently stored in this state scope. - NOTE: that save_changes must be called in order for the cleared state to be persisted to the underlying store. - :param turn_context: The context object for this turn. + """Clears any state currently stored in this state scope + + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + :return: None + + .. notes:: + This function must be called in order for the cleared state to be persisted to the underlying store. """ if turn_context is None: raise TypeError("BotState.clear_state(): turn_context cannot be None.") @@ -103,9 +138,11 @@ async def clear_state(self, turn_context: TurnContext): turn_context.turn_state[self._context_service_key] = cache_value async def delete(self, turn_context: TurnContext) -> None: - """ - Delete any state currently stored in this state scope. - :param turn_context: The context object for this turn. + """Deletes any state currently stored in this state scope. + + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + :return: None """ if turn_context is None: @@ -121,6 +158,15 @@ def get_storage_key(self, turn_context: TurnContext) -> str: raise NotImplementedError() async def get_property_value(self, turn_context: TurnContext, property_name: str): + """Gets the value of the specified property in the turn context + + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + :param property_name: The property name + :type property_name: str + + :return: The value of the property + """ if turn_context is None: raise TypeError( "BotState.get_property_value(): turn_context cannot be None." @@ -138,13 +184,15 @@ async def get_property_value(self, turn_context: TurnContext, property_name: str async def delete_property_value( self, turn_context: TurnContext, property_name: str ) -> None: - """ - Deletes a property from the state cache in the turn context. - :param turn_context: The context object for this turn. - :param property_name: The name of the property to delete. + """Deletes a property from the state cache in the turn context + + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + :param property_name: The name of the property to delete + :type property_name: str + :return: None """ - if turn_context is None: raise TypeError("BotState.delete_property(): turn_context cannot be None.") if not property_name: @@ -155,13 +203,17 @@ async def delete_property_value( async def set_property_value( self, turn_context: TurnContext, property_name: str, value: object ) -> None: - """ - Deletes a property from the state cache in the turn context. - :param turn_context: The context object for this turn. - :param property_name: The value to set on the property. + """Sets a property to the specified value in the turn context + + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + :param property_name: The property name + :type property_name: str + :param value: The value to assign to the property + :type value: Object + :return: None """ - if turn_context is None: raise TypeError("BotState.delete_property(): turn_context cannot be None.") if not property_name: From d01d46ba0a8f87143197f1442972703dde664e7a Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Wed, 15 Jan 2020 16:53:51 -0800 Subject: [PATCH 10/56] Update bot_framework_adapter.py Added ref documentation (WIP). --- .../botbuilder/core/bot_framework_adapter.py | 104 ++++++++++++++---- 1 file changed, 81 insertions(+), 23 deletions(-) diff --git a/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py b/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py index 7309bdbef..10b0c91c2 100644 --- a/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py +++ b/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py @@ -83,6 +83,12 @@ def __init__( channel_provider: ChannelProvider = None, auth_configuration: AuthenticationConfiguration = None, ): + """ + :param app_id: The application Id of the bot. This is the appId returned by the Azure portal registration, and is + generally found in the `MicrosoftAppId` parameter in the *config.py* file. + :type app_id: str + + """ self.app_id = app_id self.app_password = app_password self.channel_auth_tenant = channel_auth_tenant @@ -94,9 +100,27 @@ def __init__( class BotFrameworkAdapter(BotAdapter, UserTokenProvider): + """Defines an adapter to connect a bot to a service endpoint + + .. remarks:: + The bot adapter encapsulates authentication processes and sends activities to and + receives activities from the Bot Connector Service. When your bot receives an activity, + the adapter creates a context object, passes it to your bot's application logic, and + sends responses back to the user's channel. + The adapter processes and directs incoming activities in through the bot middleware + pipeline to your bot’s logic and then back out again. + As each activity flows in and out of the bot, each piece of middleware can inspect or act + upon the activity, both before and after the bot logic runs. + """ + _INVOKE_RESPONSE_KEY = "BotFrameworkAdapter.InvokeResponse" def __init__(self, settings: BotFrameworkAdapterSettings): + """ Initializes a new instance of the :class:`BotFrameworkAdapter` class + + :param settings: The settings to initialize the adapter + :type settings: :class:`BotFrameworkAdapterSettings` + """ super(BotFrameworkAdapter, self).__init__() self.settings = settings or BotFrameworkAdapterSettings("", "") self.settings.channel_service = self.settings.channel_service or os.environ.get( @@ -140,16 +164,23 @@ async def continue_conversation( bot_id: str = None, claims_identity: ClaimsIdentity = None, # pylint: disable=unused-argument ): - """ - Continues a conversation with a user. This is often referred to as the bots "Proactive Messaging" - flow as its lets the bot proactively send messages to a conversation or user that its already - communicated with. Scenarios like sending notifications or coupons to a user are enabled by this - method. - :param bot_id: - :param reference: - :param callback: - :param claims_identity: - :return: + """Continues a conversation with a user + + :param reference: A reference to the conversation to continue + :type reference: :class:`botbuilder.schema.ConversationReference + :param callback: The method to call for the resulting bot turn + :type callback: :class:`typing.Callable` + :param bot_id: The application Id of the bot. This is the appId returned by the Azure portal registration, + and is generally found in the `MicrosoftAppId` parameter in `config.py`. + :type bot_id: :class:`typing.str` + :param claims_identity: The bot claims identity + :type claims_identity: :class:`botframework.connector.auth.ClaimsIdentity` + + .. remarks:: + This is often referred to as the bots *proactive messaging* flow as it lets the bot proactively + send messages to a conversation or user that are already in a communication. + Scenarios such as sending notifications or coupons to a user are enabled by this function. + """ # TODO: proactive messages @@ -176,12 +207,27 @@ async def create_conversation( logic: Callable[[TurnContext], Awaitable] = None, conversation_parameters: ConversationParameters = None, ): - """ - Starts a new conversation with a user. This is typically used to Direct Message (DM) a member - of a group. - :param reference: - :param logic: - :return: + """Starts a new conversation with a user + Used to direct message to a member of a group + :param reference: A conversation reference that contains the tenant. + :type reference: :class:`botbuilder.schema.ConversationReference` + :param logic: The logic to use for the creation of the conversation + :type logic: :class:`typing.Callable` + :param conversation_parameters: The information to use to create the conversation + :type conversation_parameters: + + :return: A task representing the work queued to execute + + .. remarks:: + To start a conversation, your bot must know its account information and the user's + account information on that channel. + Most channels only support initiating a direct message (non-group) conversation. + The adapter attempts to create a new conversation on the channel, and + then sends a conversation update activity through its middleware pipeline + to the the callback method. + If the conversation is established with the specified users, the ID of the activity + will contain the ID of the new conversation. + """ try: if reference.service_url is None: @@ -231,14 +277,26 @@ async def create_conversation( raise error async def process_activity(self, req, auth_header: str, logic: Callable): - """ + """Creates a turn context and runs the middleware pipeline for an incoming activity Processes an activity received by the bots web server. This includes any messages sent from a - user and is the method that drives what's often referred to as the bots "Reactive Messaging" - flow. - :param req: - :param auth_header: - :param logic: - :return: + user and is the method that drives what's often referred to as the bots *reactive messaging* flow. + + :param req: The incoming activity + :type req: :class:`typing.str` + :param auth_header: The HTTP authentication header of the request + :type auth_header: :class:`typing.str` + :param logic: The logic to execute at the end of the adapter's middleware pipeline. + :type logic: :class:`typing.Callable` + + :return: A task that represents the work queued to execute. If the activity type + was `Invoke` and the corresponding key (`channelId` + `activityId`) was found then + an :class:`InvokeResponse` is returned; otherwise, `null` is returned. + + .. remarks:: + Call this method to reactively send a message to a conversation. + If the task completes successfully, then an :class:`InvokeResponse` is returned; + otherwise. `null` is returned. + """ activity = await self.parse_request(req) auth_header = auth_header or "" From 43699188b7e82e7209519623486cca9d4d56c43c Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Thu, 16 Jan 2020 11:39:20 -0800 Subject: [PATCH 11/56] Update bot_framework_adapter.py Partially documented the BotFrameworkAdapterSettings class. --- .../botbuilder/core/bot_framework_adapter.py | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py b/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py index 10b0c91c2..1210bb9f0 100644 --- a/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py +++ b/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py @@ -83,10 +83,26 @@ def __init__( channel_provider: ChannelProvider = None, auth_configuration: AuthenticationConfiguration = None, ): - """ - :param app_id: The application Id of the bot. This is the appId returned by the Azure portal registration, and is - generally found in the `MicrosoftAppId` parameter in the *config.py* file. + """Contains the settings used to initialize a :class:`BotFrameworkAdapter` instance. + + :param app_id: The bot application ID. This is the appId returned by the Azure portal registration, and is + the value of the `MicrosoftAppId` parameter in the `config.py` file. :type app_id: str + :param app_password: The bot application password. This is the password returned by the Azure portal registration, and is + the value os the `MicrosoftAppPassword` parameter in the `config.py` file. + :type app_password: str + :param channel_auth_tenant: The channel tenant to use in conversation + :type channel_auth_tenant: str + :param oauth_endpoint: + :type oauth_endpoint: str + :param open_id_metadata: + :type open_id_metadata: str + :param channel_service: + :type channel_service: str + :param channel_provider: + :type channel_provider: :class:`ChannelProvider` + :param auth_configuration: + :type auth_configuration: :class:`AuthenticationConfiguration` """ self.app_id = app_id From 8559317cc0d3171cb6610fda98486481974c87fe Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Thu, 16 Jan 2020 14:03:01 -0800 Subject: [PATCH 12/56] emolsh/api-ref-docs-dialogreason --- .../botbuilder/dialogs/dialog_reason.py | 42 ++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py index c20f2e3b2..57f20f73b 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py @@ -2,17 +2,47 @@ # Licensed under the MIT License. from enum import Enum +""" +NOTE: Multiple formats added, will remove whatever formatting isn't needed +""" class DialogReason(Enum): - # A dialog is being started through a call to `DialogContext.begin()`. + """ Indicates in which a dialog-related method is being called. + :var BeginCalled: A dialog is being started through a call to `DialogContext.begin()`. + :vartype BeginCalled: int + :var ContinuCalled: A dialog is being continued through a call to `DialogContext.continue_dialog()`. + :vartype ContinueCalled: int + :var EndCalled: A dialog ended normally through a call to `DialogContext.end_dialog() + :vartype EndCalled: int + :var ReplaceCalled: A dialog is ending because it's being replaced through a call to `DialogContext.replace_dialog()`. + :vartype ReplacedCalled: int + :var CancelCalled: A dialog was cancelled as part of a call to `DialogContext.cancel_all_dialogs()`. + :vartype CancelCalled: int + :var NextCalled: A preceding step was skipped through a call to `WaterfallStepContext.next()`. + :vartype NextCalled: int + """ + + """ + A dialog is being started through a call to `DialogContext.begin()`. + """ BeginCalled = 1 - # A dialog is being continued through a call to `DialogContext.continue_dialog()`. + """ + A dialog is being continued through a call to `DialogContext.continue_dialog()`. + """ ContinueCalled = 2 - # A dialog ended normally through a call to `DialogContext.end_dialog()`. + """ + A dialog ended normally through a call to `DialogContext.end_dialog() + """ EndCalled = 3 - # A dialog is ending because it's being replaced through a call to `DialogContext.replace_dialog()`. + """ + A dialog is ending because it's being replaced through a call to `DialogContext.replace_dialog()`. + """ ReplaceCalled = 4 - # A dialog was cancelled as part of a call to `DialogContext.cancel_all_dialogs()`. + """ + A dialog was cancelled as part of a call to `DialogContext.cancel_all_dialogs()`. + """ CancelCalled = 5 - # A step was advanced through a call to `WaterfallStepContext.next()`. + """ + A preceding step was skipped through a call to `WaterfallStepContext.next()`. + """ NextCalled = 6 From a334b6ddbbadd128d85cacdca3f494aac7dc2a4d Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Thu, 16 Jan 2020 15:30:46 -0800 Subject: [PATCH 13/56] Fixed variable formatting --- .../botbuilder/dialogs/dialog_reason.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py index 57f20f73b..36aed9558 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py @@ -9,17 +9,17 @@ class DialogReason(Enum): """ Indicates in which a dialog-related method is being called. :var BeginCalled: A dialog is being started through a call to `DialogContext.begin()`. - :vartype BeginCalled: int + :vartype BeginCalled: :class:`int` :var ContinuCalled: A dialog is being continued through a call to `DialogContext.continue_dialog()`. - :vartype ContinueCalled: int + :vartype ContinueCalled: i:class:`int` :var EndCalled: A dialog ended normally through a call to `DialogContext.end_dialog() - :vartype EndCalled: int + :vartype EndCalled: :class:`int` :var ReplaceCalled: A dialog is ending because it's being replaced through a call to `DialogContext.replace_dialog()`. - :vartype ReplacedCalled: int + :vartype ReplacedCalled: :class:`int` :var CancelCalled: A dialog was cancelled as part of a call to `DialogContext.cancel_all_dialogs()`. - :vartype CancelCalled: int + :vartype CancelCalled: :class:`int` :var NextCalled: A preceding step was skipped through a call to `WaterfallStepContext.next()`. - :vartype NextCalled: int + :vartype NextCalled: :class:`int` """ """ From c824f4cd758483c5a94a3963ad7458a6e74f3072 Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Thu, 16 Jan 2020 15:32:12 -0800 Subject: [PATCH 14/56] Fixed variable formatting --- .../botbuilder/dialogs/dialog_turn_status.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py index 36441fe7c..395cda883 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py @@ -6,13 +6,13 @@ class DialogTurnStatus(Enum): """Codes indicating the state of the dialog stack after a call to `DialogContext.continueDialog()` :var Empty: Indicates that there is currently nothing on the dialog stack. - :vartype Empty: int + :vartype Empty: :class:`int` :var Waiting: Indicates that the dialog on top is waiting for a response from the user. - :vartype Waiting: int + :vartype Waiting: :class:`int` :var Complete: Indicates that the dialog completed successfully, the result is available, and the stack is empty. - :vartype Complete: int + :vartype Complete: :class:`int` :var Cancelled: Indicates that the dialog was cancelled and the stack is empty. - :vartype Cancelled: int + :vartype Cancelled: :class:`int` """ Empty = 1 From 4a3ee8407238fc0558add058bfa7aad8cb4ef910 Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Thu, 16 Jan 2020 15:38:54 -0800 Subject: [PATCH 15/56] emolsh/api-ref-docs-dialoginstance --- .../botbuilder/dialogs/dialog_instance.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py index 3b5b4423f..392697155 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py @@ -10,10 +10,28 @@ class DialogInstance: """ def __init__(self): + """ + Gets or sets the ID of the dialog and gets or sets the instance's persisted state. + + :var self.id: The ID of the dialog + :vartype self.id: :class:`str` + :var self.state: The instance's persisted state. + :vartype self.state: :class:`Dict` + """ self.id: str = None # pylint: disable=invalid-name + self.state: Dict[str, object] = {} def __str__(self): + """ + Gets or sets a stack index. + + .. remarks:: + Positive values are indexes within the current DC and negative values are indexes in the parent DC. + + :return: result + :rtype: :class:`str` + """ result = "\ndialog_instance_id: %s\n" % self.id if self.state is not None: for key, value in self.state.items(): From e03f7e1dc751c792090ae897a0d760ebfec20ec3 Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Thu, 16 Jan 2020 17:44:09 -0800 Subject: [PATCH 16/56] Update bot_framework_adapter.py Added remaining ref documentation --- .../botbuilder/core/bot_framework_adapter.py | 200 ++++++++++++++---- 1 file changed, 160 insertions(+), 40 deletions(-) diff --git a/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py b/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py index 1210bb9f0..bc7f09b92 100644 --- a/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py +++ b/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py @@ -99,10 +99,10 @@ def __init__( :type open_id_metadata: str :param channel_service: :type channel_service: str - :param channel_provider: - :type channel_provider: :class:`ChannelProvider` + :param channel_provider: The channel provider + :type channel_provider: :class:`botframework.connector.auth.ChannelProvider` :param auth_configuration: - :type auth_configuration: :class:`AuthenticationConfiguration` + :type auth_configuration: :class:`botframework.connector.auth.AuthenticationConfiguration` """ self.app_id = app_id @@ -192,13 +192,15 @@ async def continue_conversation( :param claims_identity: The bot claims identity :type claims_identity: :class:`botframework.connector.auth.ClaimsIdentity` + :raises: It raises an argument null exception + + :return: A task that represents the work queued to execute + .. remarks:: This is often referred to as the bots *proactive messaging* flow as it lets the bot proactively send messages to a conversation or user that are already in a communication. Scenarios such as sending notifications or coupons to a user are enabled by this function. - """ - # TODO: proactive messages if not claims_identity: if not bot_id: @@ -225,13 +227,15 @@ async def create_conversation( ): """Starts a new conversation with a user Used to direct message to a member of a group - :param reference: A conversation reference that contains the tenant. + :param reference: The conversation reference that contains the tenant :type reference: :class:`botbuilder.schema.ConversationReference` :param logic: The logic to use for the creation of the conversation :type logic: :class:`typing.Callable` :param conversation_parameters: The information to use to create the conversation :type conversation_parameters: + :raises: It raises a generic exception error + :return: A task representing the work queued to execute .. remarks:: @@ -243,7 +247,6 @@ async def create_conversation( to the the callback method. If the conversation is established with the specified users, the ID of the activity will contain the ID of the new conversation. - """ try: if reference.service_url is None: @@ -353,11 +356,15 @@ async def process_activity(self, req, auth_header: str, logic: Callable): async def authenticate_request( self, request: Activity, auth_header: str ) -> ClaimsIdentity: - """ - Allows for the overriding of authentication in unit tests. - :param request: - :param auth_header: - :return: + """Allows for the overriding of authentication in unit tests. + :param request: The request to authenticate + :type request: :class:`botbuilder.schema.Activity` + :param auth_header: The authentication header + + :raises: A permission exception error + + :return: The request claims identity + :rtype: :class:`botframework.connector.auth.ClaimsIdentity` """ claims = await JwtTokenValidation.authenticate_request( request, @@ -428,9 +435,22 @@ async def update_activity(self, context: TurnContext, activity: Activity): """ Replaces an activity that was previously sent to a channel. It should be noted that not all channels support this feature. - :param context: - :param activity: - :return: + + :param context: The context object for the turn + :type context: :class:`TurnContext' + :param activity: New replacement activity + :type activity: :class:`botbuilder.schema.Activity` + + :raises: A generic exception error + + :return: A task that represents the work queued to execute + + .. remarks:: + If the activity is successfully sent, the task result contains + a :class:`botbuilder.schema.ResourceResponse` object containing the ID that + the receiving channel assigned to the activity. + Before calling this function, set the ID of the replacement activity to the ID + of the activity to replace. """ try: identity: ClaimsIdentity = context.turn_state.get(BOT_IDENTITY_KEY) @@ -447,9 +467,18 @@ async def delete_activity( """ Deletes an activity that was previously sent to a channel. It should be noted that not all channels support this feature. - :param context: - :param reference: - :return: + + :param context: The context object for the turn + :type context: :class:`TurnContext' + :param reference: Conversation reference for the activity to delete + :type reference: :class:`botbuilder.schema.ConversationReference` + + :raises: A exception error + + :return: A task that represents the work queued to execute + + .. remarks:: + The activity_id of the :class:`botbuilder.schema.ConversationReference` identifies the activity to delete. """ try: identity: ClaimsIdentity = context.turn_state.get(BOT_IDENTITY_KEY) @@ -520,11 +549,15 @@ async def send_activities( async def delete_conversation_member( self, context: TurnContext, member_id: str ) -> None: - """ - Deletes a member from the current conversation. - :param context: - :param member_id: - :return: + """Deletes a member from the current conversation + :param context: The context object for the turn + :type context: :class:`TurnContext` + :param member_id: The ID of the member to remove from the conversation + :type member_id: str + + :raises: A exception error + + :return: A task that represents the work queued to execute. TokenResponse: + + """Attempts to retrieve the token for a user that's in a login flow + + :param context: Context for the current turn of conversation with the user + :type context: :class:`TurnContext` + :param connection_name: Name of the auth connection to use + :type connection_name: str + :param magic_code" (Optional) user entered code to validate + :str magic_code" str + + :raises: An exception error + + :returns: Token Response + :rtype: :class:'botbuilder.schema.TokenResponse` + + """ + if ( context.activity.from_property is None or not context.activity.from_property.id @@ -659,6 +728,17 @@ async def get_user_token( async def sign_out_user( self, context: TurnContext, connection_name: str = None, user_id: str = None ) -> str: + """Signs the user out with the token server + + :param context: Context for the current turn of conversation with the user + :type context: :class:`TurnContext` + :param connection_name: Name of the auth connection to use + :type connection_name: str + :param user_id: User id of user to sign out + :type user_id: str + + :returns: A task that represents the work queued to execute + """ if not context.activity.from_property or not context.activity.from_property.id: raise Exception( "BotFrameworkAdapter.sign_out_user(): missing from_property or from_property.id" @@ -676,6 +756,18 @@ async def sign_out_user( async def get_oauth_sign_in_link( self, context: TurnContext, connection_name: str ) -> str: + """Gets the raw sign-in link to be sent to the user for sign-in for a connection name. + + :param context: Context for the current turn of conversation with the user + :type context: :class:`TurnContext` + :param connection_name: Name of the auth connection to use + :type connection_name: str + + :returns: A task that represents the work queued to execute + + .. remarks:: + If the task completes successfully, the result contains the raw sign-in link + """ self.check_emulating_oauth_cards(context) conversation = TurnContext.get_conversation_reference(context.activity) url = self.oauth_api_url(context) @@ -695,6 +787,20 @@ async def get_oauth_sign_in_link( async def get_token_status( self, context: TurnContext, user_id: str = None, include_filter: str = None ) -> List[TokenStatus]: + + """Retrieves the token status for each configured connection for the given user + + :param context: Context for the current turn of conversation with the user + :type context: :class:`TurnContext` + :param user_id: The user Id for which token status is retrieved + :type user_id: str + :param include_filter: (Optional) Comma separated list of connection's to include. + Blank will return token status for all configured connections. + :type include_filter: str + + :returns: Array of :class:`botframework.connector.token_api.modelsTokenStatus` + """ + if not user_id and ( not context.activity.from_property or not context.activity.from_property.id ): @@ -715,6 +821,20 @@ async def get_token_status( async def get_aad_tokens( self, context: TurnContext, connection_name: str, resource_urls: List[str] ) -> Dict[str, TokenResponse]: + """Retrieves Azure Active Directory tokens for particular resources on a configured connection + + :param context: Context for the current turn of conversation with the user + :type context: :class:`TurnContext` + + :param connection_name: The name of the Azure Active Directory connection configured with this bot + :type connection_name: str + + :param resource_urls: The list of resource URLs to retrieve tokens for + :type resource_urls: :class:`typing.List` + + :returns: Dictionary of resource Urls to the corresponding :class:'botbuilder.schema.TokenResponse` + :rtype: :class:`typing.Dict` + """ if not context.activity.from_property or not context.activity.from_property.id: raise Exception( "BotFrameworkAdapter.get_aad_tokens(): missing from_property or from_property.id" @@ -733,11 +853,11 @@ async def get_aad_tokens( async def create_connector_client( self, service_url: str, identity: ClaimsIdentity = None ) -> ConnectorClient: - """ - Allows for mocking of the connector client in unit tests. - :param service_url: - :param identity: - :return: + """Allows for mocking of the connector client in unit tests + :param service_url: The service URL + :param identity: The claims identity + + :return: An instance of the :class:`ConnectorClient` class """ if identity: bot_app_id_claim = identity.claims.get( From dc6108bbf7973d61c46b73e94084aa20b4db8907 Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Fri, 17 Jan 2020 16:09:57 -0800 Subject: [PATCH 17/56] Update activity_handler.py Added ref docuimentation --- .../botbuilder/core/activity_handler.py | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/libraries/botbuilder-core/botbuilder/core/activity_handler.py b/libraries/botbuilder-core/botbuilder/core/activity_handler.py index 40c06d91e..27b24a3ea 100644 --- a/libraries/botbuilder-core/botbuilder/core/activity_handler.py +++ b/libraries/botbuilder-core/botbuilder/core/activity_handler.py @@ -8,6 +8,23 @@ class ActivityHandler: async def on_turn(self, turn_context: TurnContext): + """ Called by the adapter (for example, :class:`BotFrameworkAdapter`) at runtime + in order to process an inbound :class:`botbuilder.schema.Activity`. + + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + + :returns: A task that represents the work queued to execute + + .. remarks:: + It calls other methods in this class based on the type of the activity to + process, which allows a derived class to provide type-specific logic in a controlled way. + In a derived class, override this method to add logic that applies to all activity types. + + .. note:: + - Add logic to apply before the type-specific logic and before the call to the base class `OnTurnAsync` method. + - Add logic to apply after the type-specific logic after the call to the base class `OnTurnAsync` method. + """ if turn_context is None: raise TypeError("ActivityHandler.on_turn(): turn_context cannot be None.") @@ -40,6 +57,18 @@ async def on_turn(self, turn_context: TurnContext): async def on_message_activity( # pylint: disable=unused-argument self, turn_context: TurnContext ): + """Override this method in a derived class to provide logic specific to activities, + such as the conversational logic. + + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + + :returns: A task that represents the work queued to execute + + .. remarks:: + The `OnTurnAsync` method calls this method when it receives a message activity. + + """ return async def on_conversation_update_activity(self, turn_context: TurnContext): From a136b9a2f93d0eebb481e78abe501c597b6d1120 Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Mon, 20 Jan 2020 10:46:14 -0800 Subject: [PATCH 18/56] emolsh/api-ref-docs-dialogturnresult --- .../botbuilder/dialogs/dialog_turn_result.py | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py index e36504f8b..a3d6230ab 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py @@ -3,16 +3,41 @@ from .dialog_turn_status import DialogTurnStatus - class DialogTurnResult: + """ + Result returned to the caller of one of the various stack manipulation methods. + """ def __init__(self, status: DialogTurnStatus, result: object = None): + """ + :param status: The current status of the stack. + :type status: :class:`DialogTurnStatus` + :param result: The result returned by a dialog that was just ended. + :type result: object + """ self._status = status self._result = result - + @property def status(self): + """ + Gets or sets the current status of the stack. + + :return self._status: + :rtype self._status: :class:`DialogTurnStatus` + + """ return self._status + + """ + Final result returned by a dialog that just completed. + ..remarks: + This will only be populated in certain cases: + - The bot calls `DialogContext.begin_dialog()` to start a new dialog and the dialog ends immediately. + - The bot calls `DialogContext.continue_dialog()` and a dialog that was active ends. + :return self._result: + :rtype self._result: object + """ @property def result(self): return self._result From 2034c6b7ad5b5b80c88479d7b3fc7b7b33a5fe1e Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Mon, 20 Jan 2020 11:19:39 -0800 Subject: [PATCH 19/56] emolsh/apu-ref-docs-dialogstate --- .../botbuilder/dialogs/dialog_state.py | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py index 278e6b14d..ba557631a 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py @@ -4,9 +4,18 @@ from typing import List from .dialog_instance import DialogInstance - class DialogState: + """ + Contains state information for the dialog stack. + """ def __init__(self, stack: List[DialogInstance] = None): + """ + Initializes a new instance of the `DialogState` class. + .. remarks:: + The new instance is created with an empty dialog stack. + :param stack: The state information to initialize the stack with. + :type stack: List + """ if stack is None: self._dialog_stack = [] else: @@ -14,9 +23,22 @@ def __init__(self, stack: List[DialogInstance] = None): @property def dialog_stack(self): + """ + Initializes a new instance of the `DialogState` class. + .. remarks:: + The new instance has a dialog stack that is populated using the information + :return: The state information to initialize the stack with. + :rtype: List + """ return self._dialog_stack def __str__(self): + """ + Gets or sets the state information for a dialog stack. + + :return: State information for a dialog stack + :rtype: str + """ if not self._dialog_stack: return "dialog stack empty!" return " ".join(map(str, self._dialog_stack)) From 161791e2041976d0fafb22a3f6a55697ae16aeab Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Mon, 20 Jan 2020 11:22:22 -0800 Subject: [PATCH 20/56] Fixed formatting --- .../botbuilder/dialogs/dialog_turn_status.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py index 395cda883..36441fe7c 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py @@ -6,13 +6,13 @@ class DialogTurnStatus(Enum): """Codes indicating the state of the dialog stack after a call to `DialogContext.continueDialog()` :var Empty: Indicates that there is currently nothing on the dialog stack. - :vartype Empty: :class:`int` + :vartype Empty: int :var Waiting: Indicates that the dialog on top is waiting for a response from the user. - :vartype Waiting: :class:`int` + :vartype Waiting: int :var Complete: Indicates that the dialog completed successfully, the result is available, and the stack is empty. - :vartype Complete: :class:`int` + :vartype Complete: int :var Cancelled: Indicates that the dialog was cancelled and the stack is empty. - :vartype Cancelled: :class:`int` + :vartype Cancelled: int """ Empty = 1 From 8680347629eb53700076ccd14970870afc8446c1 Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Mon, 20 Jan 2020 11:23:01 -0800 Subject: [PATCH 21/56] Fixed formatting --- .../botbuilder/dialogs/dialog_reason.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py index 36aed9558..57f20f73b 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py @@ -9,17 +9,17 @@ class DialogReason(Enum): """ Indicates in which a dialog-related method is being called. :var BeginCalled: A dialog is being started through a call to `DialogContext.begin()`. - :vartype BeginCalled: :class:`int` + :vartype BeginCalled: int :var ContinuCalled: A dialog is being continued through a call to `DialogContext.continue_dialog()`. - :vartype ContinueCalled: i:class:`int` + :vartype ContinueCalled: int :var EndCalled: A dialog ended normally through a call to `DialogContext.end_dialog() - :vartype EndCalled: :class:`int` + :vartype EndCalled: int :var ReplaceCalled: A dialog is ending because it's being replaced through a call to `DialogContext.replace_dialog()`. - :vartype ReplacedCalled: :class:`int` + :vartype ReplacedCalled: int :var CancelCalled: A dialog was cancelled as part of a call to `DialogContext.cancel_all_dialogs()`. - :vartype CancelCalled: :class:`int` + :vartype CancelCalled: int :var NextCalled: A preceding step was skipped through a call to `WaterfallStepContext.next()`. - :vartype NextCalled: :class:`int` + :vartype NextCalled: int """ """ From 84ebf4153a8b4028191c356b6e81b6b4a5062b91 Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Mon, 20 Jan 2020 11:29:14 -0800 Subject: [PATCH 22/56] Update dialog_instance.py --- .../botbuilder/dialogs/dialog_instance.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py index 392697155..3fb59a0c3 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py @@ -14,9 +14,9 @@ def __init__(self): Gets or sets the ID of the dialog and gets or sets the instance's persisted state. :var self.id: The ID of the dialog - :vartype self.id: :class:`str` + :vartype self.id: str :var self.state: The instance's persisted state. - :vartype self.state: :class:`Dict` + :vartype self.state: Dict """ self.id: str = None # pylint: disable=invalid-name @@ -30,7 +30,7 @@ def __str__(self): Positive values are indexes within the current DC and negative values are indexes in the parent DC. :return: result - :rtype: :class:`str` + :rtype: str """ result = "\ndialog_instance_id: %s\n" % self.id if self.state is not None: From 1ff4e09de5c969a760b097867c118c5000efdde8 Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Tue, 21 Jan 2020 11:07:42 -0800 Subject: [PATCH 23/56] Update activity_handler.py Added comments to n_conversation_update_activity method --- .../botbuilder/core/activity_handler.py | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/libraries/botbuilder-core/botbuilder/core/activity_handler.py b/libraries/botbuilder-core/botbuilder/core/activity_handler.py index 27b24a3ea..a429894dd 100644 --- a/libraries/botbuilder-core/botbuilder/core/activity_handler.py +++ b/libraries/botbuilder-core/botbuilder/core/activity_handler.py @@ -65,13 +65,31 @@ async def on_message_activity( # pylint: disable=unused-argument :returns: A task that represents the work queued to execute - .. remarks:: - The `OnTurnAsync` method calls this method when it receives a message activity. - """ return async def on_conversation_update_activity(self, turn_context: TurnContext): + """Invoked when a conversation update activity is received from the channel when the base behavior of + `OnTurnAsync` is used. + Conversation update activities are useful when it comes to responding to users being added to or removed from the conversation. + For example, a bot could respond to a user being added by greeting the user. + By default, this method calls :meth:`ActivityHandler.on_members_added_activity()` if any users have been added or + :meth:`ActivityHandler.on_members_removed_activity()` if any users have been removed. + The method checks the member ID so that it only responds to updates regarding members other than the bot itself. + + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + :returns: A task that represents the work queued to execute + + .. remarks:: + When the :meth:'ActivityHandler.on_turn()` method receives a conversation update activity, it calls this method. + If the conversation update activity indicates that members other than the bot joined the conversation, + it calls the :meth:`ActivityHandler.on_members_added_activity()` method. + If the conversation update activity indicates that members other than the bot left the conversation, + it calls the :meth:`ActivityHandler.on_members_removed_activity()` method. + In a derived class, override this method to add logic that applies to all conversation update activities. + Add logic to apply before the member added or removed logic before the call to this base class method. + """ if ( turn_context.activity.members_added is not None and turn_context.activity.members_added From feb1c5afef7d2861c7ece02a11091e9d88552d3c Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Tue, 21 Jan 2020 13:49:30 -0800 Subject: [PATCH 24/56] emolsh/api-ref-docs-activityprompt --- .../dialogs/prompts/activity_prompt.py | 89 ++++++++++++++----- 1 file changed, 65 insertions(+), 24 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py index 5930441e1..0cfa4739f 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py @@ -24,9 +24,15 @@ class ActivityPrompt(Dialog, ABC): """ Waits for an activity to be received. - This prompt requires a validator be passed in and is useful when waiting for non-message - activities like an event to be received. The validator can ignore received events until the - expected activity is received. + ..remarks: + This prompt requires a validator be passed in and is useful when waiting for non-message + activities like an event to be received. The validator can ignore received events until the + expected activity is received. + + :var persisted_options: ? + :typevar persisted_options: str + :var persisted_state: ? + :vartype persisted_state: str """ persisted_options = "options" @@ -36,13 +42,12 @@ def __init__( self, dialog_id: str, validator: Callable[[PromptValidatorContext], bool] ): """ - Initializes a new instance of the ActivityPrompt class. + Initializes a new instance of the :class:`ActivityPrompt` class. - Parameters: - ---------- - dialog_id (str): Unique ID of the dialog within its parent DialogSet or ComponentDialog. - - validator: Validator that will be called each time a new activity is received. + :param dialog_id: Unique ID of the dialog within its parent :class:`DialogSet` or :class:`ComponentDialog`. + :type dialog_id: str + :param validator: Validator that will be called each time a new activity is received. + :type validator: Callable[[PromptValidatorContext], bool] """ Dialog.__init__(self, dialog_id) @@ -53,6 +58,16 @@ def __init__( async def begin_dialog( self, dialog_context: DialogContext, options: PromptOptions = None ) -> DialogTurnResult: + """ + Called when a prompt dialog is pushed onto the dialog stack and is being activated. + + :param dialog_context: The dialog context for the current turn of the conversation. + :type dialog_context: :class:`DialogContext` + :param options: Optional, additional information to pass to the prompt being started. + :type options: :class:`PromptOptions` + :return Dialog.end_of_turn: + :rtype Dialog.end_of_turn: :class:`Dialog.DialogTurnResult` + """ if not dialog_context: raise TypeError("ActivityPrompt.begin_dialog(): dc cannot be None.") if not isinstance(options, PromptOptions): @@ -84,6 +99,14 @@ async def begin_dialog( async def continue_dialog(self, dialog_context: DialogContext) -> DialogTurnResult: if not dialog_context: + """ + Called when a prompt dialog is the active dialog and the user replied with a new activity. + + :param dialog_context: The dialog context for the current turn of the conversation. + :type dialog_context: :class:`DialogContext` + :return Dialog.end_of_turn: + :rtype Dialog.end_of_turn: :class:`Dialog.DialogTurnResult` + """ raise TypeError( "ActivityPrompt.continue_dialog(): DialogContext cannot be None." ) @@ -130,11 +153,19 @@ async def resume_dialog( # pylint: disable=unused-argument self, dialog_context: DialogContext, reason: DialogReason, result: object = None ): """ - Prompts are typically leaf nodes on the stack but the dev is free to push other dialogs - on top of the stack which will result in the prompt receiving an unexpected call to - resume_dialog() when the pushed on dialog ends. - To avoid the prompt prematurely ending, we need to implement this method and - simply re-prompt the user + Called when a prompt dialog resumes being the active dialog on the dialog stack, such as when the previous active dialog on the stack completes. + ..remarks: + Prompts are typically leaf nodes on the stack but the dev is free to push other dialogs + on top of the stack which will result in the prompt receiving an unexpected call to + resume_dialog() when the pushed on dialog ends. + To avoid the prompt prematurely ending, we need to implement this method and + simply re-prompt the user. + :param dialog_context: The dialog context for the current turn of the conversation + :type dialog_context: :class:`DialogContext` + :param reason: An enum indicating why the dialog resumed. + :type reason: :class:`DialogReason` + :param result: >Optional, value returned from the previous dialog on the stack. The type of the value returned is dependent on the previous dialog. + :type result: object """ await self.reprompt_dialog(dialog_context.context, dialog_context.active_dialog) @@ -155,15 +186,14 @@ async def on_prompt( """ Called anytime the derived class should send the user a prompt. - Parameters: - ---------- - context: Context for the current turn of conversation with the user. - - state: Additional state being persisted for the prompt. - - options: Options that the prompt started with in the call to `DialogContext.prompt()`. - - isRetry: If `true` the users response wasn't recognized and the re-prompt should be sent. + :param dialog_context: The dialog context for the current turn of the conversation + :type dialog_context: :class:`DialogContext` + :param state: Additional state being persisted for the prompt. + :type state: Dict[str, dict] + :param options: Options that the prompt started with in the call to `DialogContext.prompt()`. + :type options: :class:`PromptOptions` + :param isRetry: If `true` the users response wasn't recognized and the re-prompt should be sent. + :type isRetry: bool """ if is_retry and options.retry_prompt: options.retry_prompt.input_hint = InputHints.expecting_input @@ -175,7 +205,18 @@ async def on_prompt( async def on_recognize( # pylint: disable=unused-argument self, context: TurnContext, state: Dict[str, object], options: PromptOptions ) -> PromptRecognizerResult: - + """ + When overridden in a derived class, attempts to recognize the incoming activity. + + :param context: Context for the current turn of conversation with the user. + :type context: :class:`TurnContext` + :param state: Contains state for the current instance of the prompt on the dialog stack. + :type state: Dict[str, object] + :param options: A prompt options object + :type options: :class:`PromptOptions` + :return result: constructed from the options initially provided in the call to `async def on_prompt()` + :rtype result: :class:`PromptRecognizerResult` + """ result = PromptRecognizerResult() result.succeeded = (True,) result.value = context.activity From ff0b5c3d64365ad384f4404dbad38593e5d5c2b6 Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Tue, 21 Jan 2020 13:51:47 -0800 Subject: [PATCH 25/56] Update activity_prompt.py --- .../botbuilder/dialogs/prompts/activity_prompt.py | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py index 0cfa4739f..3a70d17cc 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py @@ -19,7 +19,6 @@ from .prompt_recognizer_result import PromptRecognizerResult from .prompt_validator_context import PromptValidatorContext - class ActivityPrompt(Dialog, ABC): """ Waits for an activity to be received. From ee0ec4795e50b3814d45ee06bd321de98609bcb4 Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Tue, 21 Jan 2020 17:06:04 -0800 Subject: [PATCH 26/56] Update activity_handler.py Added remaining ref doc --- .../botbuilder/core/activity_handler.py | 160 ++++++++++++++++-- 1 file changed, 150 insertions(+), 10 deletions(-) diff --git a/libraries/botbuilder-core/botbuilder/core/activity_handler.py b/libraries/botbuilder-core/botbuilder/core/activity_handler.py index a429894dd..9d4bfb6f1 100644 --- a/libraries/botbuilder-core/botbuilder/core/activity_handler.py +++ b/libraries/botbuilder-core/botbuilder/core/activity_handler.py @@ -22,8 +22,8 @@ async def on_turn(self, turn_context: TurnContext): In a derived class, override this method to add logic that applies to all activity types. .. note:: - - Add logic to apply before the type-specific logic and before the call to the base class `OnTurnAsync` method. - - Add logic to apply after the type-specific logic after the call to the base class `OnTurnAsync` method. + - Add logic to apply before the type-specific logic and before the call to the :meth:`ActivityHandler.on_turn()` method. + - Add logic to apply after the type-specific logic after the call to the :meth:`ActivityHandler.on_turn()` method. """ if turn_context is None: raise TypeError("ActivityHandler.on_turn(): turn_context cannot be None.") @@ -69,13 +69,7 @@ async def on_message_activity( # pylint: disable=unused-argument return async def on_conversation_update_activity(self, turn_context: TurnContext): - """Invoked when a conversation update activity is received from the channel when the base behavior of - `OnTurnAsync` is used. - Conversation update activities are useful when it comes to responding to users being added to or removed from the conversation. - For example, a bot could respond to a user being added by greeting the user. - By default, this method calls :meth:`ActivityHandler.on_members_added_activity()` if any users have been added or - :meth:`ActivityHandler.on_members_removed_activity()` if any users have been removed. - The method checks the member ID so that it only responds to updates regarding members other than the bot itself. + """Invoked when a conversation update activity is received from the channel when the base behavior of :meth:`ActivityHandler.on_turn()` is used. :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` @@ -108,15 +102,63 @@ async def on_conversation_update_activity(self, turn_context: TurnContext): async def on_members_added_activity( self, members_added: List[ChannelAccount], turn_context: TurnContext - ): # pylint: disable=unused-argument + ): # pylint: disable=unused-argument + """Override this method in a derived class to provide logic for when members other than the bot join the conversation. + You can add your bot's welcome logic. + + :param members_added: A list of all the members added to the conversation, as described by the conversation update activity + :type members_added: :class:`typing.List` + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + + :returns: A task that represents the work queued to execute + + .. remarks:: + When the :meth:'ActivityHandler.on_conversation_update_activity()` method receives a conversation update activity that indicates + one or more users other than the bot are joining the conversation, it calls this method. + """ return async def on_members_removed_activity( self, members_removed: List[ChannelAccount], turn_context: TurnContext ): # pylint: disable=unused-argument + """Override this method in a derived class to provide logic for when members other than the bot leave the conversation. + You can add your bot's good-bye logic. + + :param members_added: A list of all the members removed from the conversation, as described by the conversation update activity + :type members_added: :class:`typing.List` + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + + :returns: A task that represents the work queued to execute + + .. remarks:: + When the :meth:'ActivityHandler.on_conversation_update_activity()` method receives a conversation update activity that indicates + one or more users other than the bot are leaving the conversation, it calls this method. + """ + return async def on_message_reaction_activity(self, turn_context: TurnContext): + """Invoked when an event activity is received from the connector when the base behavior of :meth:'ActivityHandler.on_turn()` is used. + Message reactions correspond to the user adding a 'like' or 'sad' etc. (often an emoji) to a previously sent activity. + Message reactions are only supported by a few channels. The activity that the message reaction corresponds to is indicated in the + reply to Id property. The value of this property is the activity id of a previously sent activity given back to the bot as the response + from a send call. + + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + + :returns: A task that represents the work queued to execute + + .. remarks:: + When the :meth:'ActivityHandler.on_turn()` method receives a message reaction activity, it calls this method. + If the message reaction indicates that reactions were added to a message, it calls :meth:'ActivityHandler.on_reaction_added(). + If the message reaction indicates that reactions were removed from a message, it calls :meth:'ActivityHandler.on_reaction_removed(). + In a derived class, override this method to add logic that applies to all message reaction activities. + Add logic to apply before the reactions added or removed logic before the call to the this base class method. + Add logic to apply after the reactions added or removed logic after the call to the this base class method. + """ if turn_context.activity.reactions_added is not None: await self.on_reactions_added( turn_context.activity.reactions_added, turn_context @@ -130,14 +172,68 @@ async def on_message_reaction_activity(self, turn_context: TurnContext): async def on_reactions_added( # pylint: disable=unused-argument self, message_reactions: List[MessageReaction], turn_context: TurnContext ): + """Override this method in a derived class to provide logic for when reactions to a previous activity + are added to the conversation. + + :param message_reactions: The list of reactions added + :type message_reactions: :class:`typing.List` + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + + :returns: A task that represents the work queued to execute + + .. remarks:: + Message reactions correspond to the user adding a 'like' or 'sad' etc. (often an emoji) + to a previously sent message on the conversation. Message reactions are supported by only a few channels. + The activity that the message is in reaction to is identified by the activity's reply to Id property. + The value of this property is the activity ID of a previously sent activity. When the bot sends an activity, + the channel assigns an ID to it, which is available in the resource response Id of the result. + """ return async def on_reactions_removed( # pylint: disable=unused-argument self, message_reactions: List[MessageReaction], turn_context: TurnContext ): + """Override this method in a derived class to provide logic for when reactions to a previous activity + are removed from the conversation. + + :param message_reactions: The list of reactions removed + :type message_reactions: :class:`typing.List` + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + + :returns: A task that represents the work queued to execute + + .. remarks:: + Message reactions correspond to the user adding a 'like' or 'sad' etc. (often an emoji) + to a previously sent message on the conversation. Message reactions are supported by only a few channels. + The activity that the message is in reaction to is identified by the activity's reply to Id property. + The value of this property is the activity ID of a previously sent activity. When the bot sends an activity, + the channel assigns an ID to it, which is available in the resource response Id of the result. + """ return async def on_event_activity(self, turn_context: TurnContext): + """Invoked when an event activity is received from the connector when the base behavior of :meth:'ActivityHandler.on_turn()` is used. + + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + + :returns: A task that represents the work queued to execute + + .. remarks:: + When the :meth:'ActivityHandler.on_turn()` method receives an event activity, it calls this method. + If the activity name is `tokens/response`, it calls :meth:'ActivityHandler.on_token_response_event()`; + otherwise, it calls :meth:'ActivityHandler.on_event()`. + + In a derived class, override this method to add logic that applies to all event activities. + Add logic to apply before the specific event-handling logic before the call to this base class method. + Add logic to apply after the specific event-handling logic after the call to this base class method. + + Event activities communicate programmatic information from a client or channel to a bot. + The meaning of an event activity is defined by the event activity name property, which is meaningful within + the scope of a channel. + """ if turn_context.activity.name == "tokens/response": return await self.on_token_response_event(turn_context) @@ -146,19 +242,63 @@ async def on_event_activity(self, turn_context: TurnContext): async def on_token_response_event( # pylint: disable=unused-argument self, turn_context: TurnContext ): + """Invoked when a `tokens/response` event is received when the base behavior of :meth:'ActivityHandler.on_event_activity()` is used. + If using an `oauth_prompt`, override this method to forward this activity to the current dialog. + + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + + :returns: A task that represents the work queued to execute + + .. remarks:: + When the :meth:'ActivityHandler.on_event()` method receives an event with an activity name of `tokens/response`, + it calls this method. If your bot uses an `oauth_prompt`, forward the incoming activity to the current dialog. + """ return async def on_event( # pylint: disable=unused-argument self, turn_context: TurnContext ): + """Invoked when an event other than `tokens/response` is received when the base behavior of + :meth:'ActivityHandler.on_event_activity()` is used. + This method could optionally be overridden if the bot is meant to handle miscellaneous events. + + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + + :returns: A task that represents the work queued to execute + + .. remarks:: + When the :meth:'ActivityHandler.on_event_activity()` is used method receives an event with an + activity name other than `tokens/response`, it calls this method. + """ return async def on_end_of_conversation_activity( # pylint: disable=unused-argument self, turn_context: TurnContext ): + """Invoked when a conversation end activity is received from the channel. + + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + :returns: A task that represents the work queued to execute + """ return async def on_unrecognized_activity_type( # pylint: disable=unused-argument self, turn_context: TurnContext ): + """Invoked when an activity other than a message, conversation update, or event is received when the base behavior of + :meth:`ActivityHandler.on_turn()` is used. + If overridden, this method could potentially respond to any of the other activity types. + + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + + :returns: A task that represents the work queued to execute + + .. remarks:: + When the :meth:`ActivityHandler.on_turn()` method receives an activity that is not a message, conversation update, message reaction, + or event activity, it calls this method. + """ return From 31dc353ae0b0cf4216ada3b4ed76a7c29e1db6df Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Wed, 22 Jan 2020 12:30:21 -0800 Subject: [PATCH 27/56] emolsh/api-ref-docs-componentdialog - Formatting issues start at line 197 - comments not showing, can't find error - ? where I didn't know what to put for that section (feel free to edit/suggest correct content) --- .../botbuilder/dialogs/component_dialog.py | 185 +++++++++++++++++- 1 file changed, 175 insertions(+), 10 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py index b4c531b23..ed676119d 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py @@ -14,9 +14,25 @@ class ComponentDialog(Dialog): + """ + A :class:`Dialog` that is composed of other dialogs + + ..remarks: + + A component dialog has an inner :class:`DialogSet` :class:`DialogContext`, + which provides an inner dialog stack that is hidden from the parent dialog. + :var persisted_dialog state: ? + :vartype persisted_dialog_state: str + """ persisted_dialog_state = "dialogs" def __init__(self, dialog_id: str): + """ + Initializes a new instance of the :class:`ComponentDialog` + + :param dialog_id: The ID to assign to the new dialog within the parent dialog set. + :type dialog_id: str + """ super(ComponentDialog, self).__init__(dialog_id) if dialog_id is None: @@ -30,6 +46,21 @@ def __init__(self, dialog_id: str): async def begin_dialog( self, dialog_context: DialogContext, options: object = None ) -> DialogTurnResult: + """ + Called when the dialog is started and pushed onto the parent's dialog stack. + + ..remarks:: + + If the task is successful, the result indicates whether the dialog is still + active after the turn has been processed by the dialog. + + :param dialog_context: The :class:`DialogContext` for the current turn of the conversation. + :type dialog_context: :class:`DialogContext` + :param options: Optional, initial information to pass to the dialog. + :type options: object + :return: Signals the end of the turn + :rtype: :class:`Dialog.end_of_turn` + """ if dialog_context is None: raise TypeError("ComponentDialog.begin_dialog(): outer_dc cannot be None.") @@ -49,6 +80,28 @@ async def begin_dialog( return Dialog.end_of_turn async def continue_dialog(self, dialog_context: DialogContext) -> DialogTurnResult: + """ + Called when the dialog is continued, where it is the active dialog and the + user replies with a new activity. + + ..remarks:: + + If the task is successful, the result indicates whether the dialog is still + active after the turn has been processed by the dialog. The result may also + contain a return value. + + If this method is *not* overriden the component dialog calls the + :meth:`DialogContext.continue_dialog` method on it's inner dialog + context. If the inner dialog stack is empty, the component dialog ends, + and if a :class:`DialogTurnResult.result` is available, the component dialog + uses that as it's return value. + + + :param dialog_context: The parent :class:`DialogContext` for the current turn of the conversation. + :type dialog_context: :class:`DialogContext` + :return: Signals the end of the turn + :rtype: :class:`Dialog.end_of_turn` + """ if dialog_context is None: raise TypeError("ComponentDialog.begin_dialog(): outer_dc cannot be None.") # Continue execution of inner dialog. @@ -65,17 +118,53 @@ async def continue_dialog(self, dialog_context: DialogContext) -> DialogTurnResu async def resume_dialog( self, dialog_context: DialogContext, reason: DialogReason, result: object = None ) -> DialogTurnResult: - # Containers are typically leaf nodes on the stack but the dev is free to push other dialogs - # on top of the stack which will result in the container receiving an unexpected call to - # resume_dialog() when the pushed on dialog ends. - # To avoid the container prematurely ending we need to implement this method and simply - # ask our inner dialog stack to re-prompt. + """ + Called when a child dialog on the parent's dialog stack completed this turn, returning + control to this dialog component. + + ..remarks:: + + If the task is successful, the result indicates whether this dialog is still + active after this dialog turn has been processed. + + Generally, the child dialog was started with a call to :meth:`def async begin_dialog()` + in the parent's context. However, if the :meth:`DialogContext.replace_dialog()` method is + is called, the logical child dialog may be different than the original. + + If this method is *not* overridden, the dialog automatically calls its + :meth:`asyn def reprompt_dialog()` when the user replies. + + :param dialog_context: The :class:`DialogContext` for the current turn of the conversation. + :type dialog_context: :class:`DialogContext` + :param reason: Reason why the dialog resumed. + :type reason: :class:`DialogReason` + :param result: Optional, value returned from the dialog that was called. The type of the value returned is dependent on the child dialog. + :type result: object + :return: Signals the end of the turn + :rtype: :class:`Dialog.end_of_turn` + """ + + """ (not sure where to put this information) + Containers are typically leaf nodes on the stack but the dev is free to push other dialogs + on top of the stack which will result in the container receiving an unexpected call to + resume_dialog() when the pushed on dialog ends. + To avoid the container prematurely ending we need to implement this method and simply + ask our inner dialog stack to re-prompt. + """ await self.reprompt_dialog(dialog_context.context, dialog_context.active_dialog) return Dialog.end_of_turn async def reprompt_dialog( self, context: TurnContext, instance: DialogInstance ) -> None: + """ + Called when the dialog should re-prompt the user for input. + + :param context: The context object for this turn. + :type context: :class:`TurnContext` + :param instance: State information for this dialog. + :type instance: :class:`DialogInstance` + """ # Delegate to inner dialog. dialog_state = instance.state[self.persisted_dialog_state] inner_dc = DialogContext(self._dialogs, context, dialog_state) @@ -87,7 +176,17 @@ async def reprompt_dialog( async def end_dialog( self, context: TurnContext, instance: DialogInstance, reason: DialogReason ) -> None: - # Forward cancel to inner dialogs + """ + Called when the dialog is ending. + + :param context: The context object for this turn. + :type context: :class:`TurnContext` + :param instance: State information associated with the instance of this component dialog on its parent's dialog stack. + :type instance: :class:`DialogInstance` + :param reason: Reason why the dialog ended. + :type reason: :class:`DialogReason` + """ + # Forward cancel to inner dialog if reason == DialogReason.CancelCalled: dialog_state = instance.state[self.persisted_dialog_state] inner_dc = DialogContext(self._dialogs, context, dialog_state) @@ -96,10 +195,13 @@ async def end_dialog( def add_dialog(self, dialog: Dialog) -> object: """ - Adds a dialog to the component dialog. - Adding a new dialog will inherit the BotTelemetryClient of the ComponentDialog. + Adds a :class:`Dialog` to the component dialog and returns the updated component. + + ..remarks:: + Adding a new dialog will inherit the :class:`BotTelemetryClient` of the :class:`ComponentDialog`. :param dialog: The dialog to add. - :return: The updated ComponentDialog + :return: The updated :class:`ComponentDialog` + :rtype: :class:`ComponentDialog` """ self._dialogs.add(dialog) if not self.initial_dialog_id: @@ -109,15 +211,39 @@ def add_dialog(self, dialog: Dialog) -> object: def find_dialog(self, dialog_id: str) -> Dialog: """ Finds a dialog by ID. - Adding a new dialog will inherit the BotTelemetryClient of the ComponentDialog. + + ..remarks:: + Adding a new dialog will inherit the :class:`BotTelemetryClient` of the :class:`ComponentDialog`. + :param dialog_id: The dialog to add. :return: The dialog; or None if there is not a match for the ID. + :rtype: :class:Dialog """ return self._dialogs.find(dialog_id) async def on_begin_dialog( self, inner_dc: DialogContext, options: object ) -> DialogTurnResult: + """ + Called when the dialog is started and pushed onto the parent's dialog stack. + + ..remarks:: + + If the task is successful, the result indicates whether the dialog is still + active after the turn has been processed by the dialog. + + By default, this calls the :meth:`Dialog.begin_dialog()` method of the component + dialog's initial dialog, as defined by ?. + + Override this method in a derived class to implement interrupt logic. + + :param inner_dc: The inner :class:`DialogContext` for the current turn of conversation. + :type inner_dc: :class:`DialogContext` + :param options: Optional, initial information to pass to the dialog. + :type options: object + :return: ? + :rtype: ? + """ return await inner_dc.begin_dialog(self.initial_dialog_id, options) async def on_continue_dialog(self, inner_dc: DialogContext) -> DialogTurnResult: @@ -126,14 +252,53 @@ async def on_continue_dialog(self, inner_dc: DialogContext) -> DialogTurnResult: async def on_end_dialog( # pylint: disable=unused-argument self, context: TurnContext, instance: DialogInstance, reason: DialogReason ) -> None: + """ + Ends the component dialog in its parent's context. + + :param turn_context: The :class:`TurnContext` for the current turn of the conversation. + :type turn_context: :class:`TurnContext` + :param instance: State information associated with the instance of this component dialog on its parent's dialog stack. + :type instance: :class:`DialogInstance` + :param reason: Reason why the dialog ended. + :type reason: :class:`DialogReason` + """ return async def on_reprompt_dialog( # pylint: disable=unused-argument self, turn_context: TurnContext, instance: DialogInstance ) -> None: + """ + :param turn_context: + :type turn_context: :class:`DialogInstance` + :param instance: State information associated with the instance of this component dialog on its parent's dialog stack. + :type instance: :class:`DialogInstance` + """ return async def end_component( self, outer_dc: DialogContext, result: object # pylint: disable=unused-argument ) -> DialogTurnResult: + """ + Ends the component dialog in its parent's context. + + ..remarks:: + If the task is successful, the result indicates that the dialog ended after the + turn was processed by the dialog. + + In general, the parent context is the dialog or bot turn handler that started the dialog. + If the parent is a dialog, the stack calls the parent's :meth:`Dialog.resume_dialog()` method + to return a result to the parent dialog. If the parent dialog does not implement + :meth:`Dialog.resume_dialog()`, then the parent will end, too, and the result is passed to the next + parent context, if one exists. + + The returned :class:`DialogTurnResult`contains the return value in its + :class:`DialogTurnResult.result` property. + + :param outer_dc: The parent class:`DialogContext` for the current turn of conversation. + :type outer_dc: class:`DialogContext` + :param result: Optional, value to return from the dialog component to the parent context. + :type result: object + :return: Value to return. + :rtype: :class:`DialogTurnResult.result` + """ return await outer_dc.end_dialog(result) From 6de16337534910fb25fd1b43737998220e6579b4 Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Wed, 22 Jan 2020 15:18:30 -0800 Subject: [PATCH 28/56] Updated formatting --- .../botbuilder/dialogs/dialog_turn_status.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py index 36441fe7c..46be68c85 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py @@ -3,7 +3,8 @@ from enum import Enum class DialogTurnStatus(Enum): - """Codes indicating the state of the dialog stack after a call to `DialogContext.continueDialog()` + """ + Codes indicating the state of the dialog stack after a call to `DialogContext.continueDialog()` :var Empty: Indicates that there is currently nothing on the dialog stack. :vartype Empty: int From e28409d563a82228de2100b428cf149a1c1d42f4 Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Wed, 22 Jan 2020 15:19:38 -0800 Subject: [PATCH 29/56] Updated formatting --- .../botbuilder/dialogs/dialog_reason.py | 33 +++++-------------- 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py index 57f20f73b..fa24bc3ea 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py @@ -2,12 +2,10 @@ # Licensed under the MIT License. from enum import Enum -""" -NOTE: Multiple formats added, will remove whatever formatting isn't needed -""" - class DialogReason(Enum): - """ Indicates in which a dialog-related method is being called. + """ + Indicates in which a dialog-related method is being called. + :var BeginCalled: A dialog is being started through a call to `DialogContext.begin()`. :vartype BeginCalled: int :var ContinuCalled: A dialog is being continued through a call to `DialogContext.continue_dialog()`. @@ -21,28 +19,15 @@ class DialogReason(Enum): :var NextCalled: A preceding step was skipped through a call to `WaterfallStepContext.next()`. :vartype NextCalled: int """ - - """ - A dialog is being started through a call to `DialogContext.begin()`. - """ + BeginCalled = 1 - """ - A dialog is being continued through a call to `DialogContext.continue_dialog()`. - """ + ContinueCalled = 2 - """ - A dialog ended normally through a call to `DialogContext.end_dialog() - """ + EndCalled = 3 - """ - A dialog is ending because it's being replaced through a call to `DialogContext.replace_dialog()`. - """ + ReplaceCalled = 4 - """ - A dialog was cancelled as part of a call to `DialogContext.cancel_all_dialogs()`. - """ + CancelCalled = 5 - """ - A preceding step was skipped through a call to `WaterfallStepContext.next()`. - """ + NextCalled = 6 From 00cb3a8fd7e1a17bca9cf39ce6d77653da726de2 Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Wed, 22 Jan 2020 15:28:53 -0800 Subject: [PATCH 30/56] Updated formatting --- .../botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py index 3fb59a0c3..83afefbe6 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py @@ -16,7 +16,7 @@ def __init__(self): :var self.id: The ID of the dialog :vartype self.id: str :var self.state: The instance's persisted state. - :vartype self.state: Dict + :vartype self.state: Dict[str, object] """ self.id: str = None # pylint: disable=invalid-name @@ -29,7 +29,7 @@ def __str__(self): .. remarks:: Positive values are indexes within the current DC and negative values are indexes in the parent DC. - :return: result + :return: Returns stack index. :rtype: str """ result = "\ndialog_instance_id: %s\n" % self.id From bef05785573e85b946f797d288ac26b03c6f1dc6 Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Wed, 22 Jan 2020 15:32:25 -0800 Subject: [PATCH 31/56] Updated formatting --- .../botbuilder/dialogs/dialog_turn_result.py | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py index a3d6230ab..6a09a690e 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py @@ -6,6 +6,10 @@ class DialogTurnResult: """ Result returned to the caller of one of the various stack manipulation methods. + + ..remarks: + Use :class:`DialogContext.end_dialogAsync()` to end a :class:`Dialog` and + return a result to the calling context. """ def __init__(self, status: DialogTurnStatus, result: object = None): """ @@ -19,25 +23,25 @@ def __init__(self, status: DialogTurnStatus, result: object = None): @property def status(self): - """ - Gets or sets the current status of the stack. - - :return self._status: - :rtype self._status: :class:`DialogTurnStatus` + """ + Gets or sets the current status of the stack. - """ + :return self._status: + :rtype self._status: :class:`DialogTurnStatus` + """ return self._status + + @property + def result(self): + """ + Final result returned by a dialog that just completed. - """ - Final result returned by a dialog that just completed. - ..remarks: - This will only be populated in certain cases: - - The bot calls `DialogContext.begin_dialog()` to start a new dialog and the dialog ends immediately. - - The bot calls `DialogContext.continue_dialog()` and a dialog that was active ends. + ..remarks: + This will only be populated in certain cases: + - The bot calls `DialogContext.begin_dialog()` to start a new dialog and the dialog ends immediately. + - The bot calls `DialogContext.continue_dialog()` and a dialog that was active ends. :return self._result: :rtype self._result: object """ - @property - def result(self): return self._result From 299cec4da6bd4fb4359ece5b5e0b43325253d6b8 Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Wed, 22 Jan 2020 15:33:04 -0800 Subject: [PATCH 32/56] Updated formatting --- .../botbuilder/dialogs/dialog_turn_result.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py index 6a09a690e..7e1bb4075 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py @@ -7,7 +7,7 @@ class DialogTurnResult: """ Result returned to the caller of one of the various stack manipulation methods. - ..remarks: + ..remarks:: Use :class:`DialogContext.end_dialogAsync()` to end a :class:`Dialog` and return a result to the calling context. """ @@ -36,7 +36,7 @@ def result(self): """ Final result returned by a dialog that just completed. - ..remarks: + ..remarks:: This will only be populated in certain cases: - The bot calls `DialogContext.begin_dialog()` to start a new dialog and the dialog ends immediately. - The bot calls `DialogContext.continue_dialog()` and a dialog that was active ends. From c1cb806e886aa3f16e91a2b9c2489cccc38a65e9 Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Wed, 22 Jan 2020 15:39:26 -0800 Subject: [PATCH 33/56] Updated formatting Not sure how to document method on line 36 --- .../botbuilder/dialogs/dialog_state.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py index ba557631a..42bf51fc2 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py @@ -11,10 +11,12 @@ class DialogState: def __init__(self, stack: List[DialogInstance] = None): """ Initializes a new instance of the `DialogState` class. + .. remarks:: The new instance is created with an empty dialog stack. + :param stack: The state information to initialize the stack with. - :type stack: List + :type stack: List[:class:`DialogInstance`] """ if stack is None: self._dialog_stack = [] @@ -24,9 +26,8 @@ def __init__(self, stack: List[DialogInstance] = None): @property def dialog_stack(self): """ - Initializes a new instance of the `DialogState` class. - .. remarks:: - The new instance has a dialog stack that is populated using the information + Initializes a new instance of the :class:`DialogState` class. + :return: The state information to initialize the stack with. :rtype: List """ @@ -34,9 +35,8 @@ def dialog_stack(self): def __str__(self): """ - Gets or sets the state information for a dialog stack. - - :return: State information for a dialog stack + ? + :return: :rtype: str """ if not self._dialog_stack: From 9759e56d9be4c1203e64d3f226eb442b4c006079 Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Fri, 24 Jan 2020 13:45:00 -0800 Subject: [PATCH 34/56] Fixed formatting Removed docstring for `def __str__(self)` --- .../botbuilder/dialogs/dialog_state.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py index 42bf51fc2..218caf5d0 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py @@ -10,10 +10,8 @@ class DialogState: """ def __init__(self, stack: List[DialogInstance] = None): """ - Initializes a new instance of the `DialogState` class. - - .. remarks:: - The new instance is created with an empty dialog stack. + Initializes a new instance of the :class:`DialogState` class. + The new instance is created with an empty dialog stack. :param stack: The state information to initialize the stack with. :type stack: List[:class:`DialogInstance`] @@ -34,11 +32,6 @@ def dialog_stack(self): return self._dialog_stack def __str__(self): - """ - ? - :return: - :rtype: str - """ if not self._dialog_stack: return "dialog stack empty!" return " ".join(map(str, self._dialog_stack)) From 695bd5d33c733e2730ab6e1cdd7d85f1e2dce9c5 Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Fri, 24 Jan 2020 13:48:47 -0800 Subject: [PATCH 35/56] Fixed formatting --- .../botbuilder/dialogs/dialog_turn_result.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py index 7e1bb4075..d02ecaa4a 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py @@ -6,10 +6,9 @@ class DialogTurnResult: """ Result returned to the caller of one of the various stack manipulation methods. - - ..remarks:: - Use :class:`DialogContext.end_dialogAsync()` to end a :class:`Dialog` and - return a result to the calling context. + + Use :meth:`DialogContext.end_dialogAsync()` to end a :class:`Dialog` and + return a result to the calling context. """ def __init__(self, status: DialogTurnStatus, result: object = None): """ @@ -36,12 +35,12 @@ def result(self): """ Final result returned by a dialog that just completed. - ..remarks:: - This will only be populated in certain cases: - - The bot calls `DialogContext.begin_dialog()` to start a new dialog and the dialog ends immediately. - - The bot calls `DialogContext.continue_dialog()` and a dialog that was active ends. + .. note:: + This will only be populated in certain cases: + * The bot calls :meth:`DialogContext.begin_dialog()` to start a new dialog and the dialog ends immediately. + * The bot calls :meth:`DialogContext.continue_dialog()` and a dialog that was active ends. - :return self._result: + :return self._result: Final result returned by a dialog that just completed. :rtype self._result: object """ return self._result From ce58a6fd830ac0447e3afa513ff81d50cc674aac Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Fri, 24 Jan 2020 13:50:47 -0800 Subject: [PATCH 36/56] Fixed formatting --- .../botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py index 83afefbe6..e4aa2bf24 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py @@ -26,9 +26,6 @@ def __str__(self): """ Gets or sets a stack index. - .. remarks:: - Positive values are indexes within the current DC and negative values are indexes in the parent DC. - :return: Returns stack index. :rtype: str """ From af0dc932e9e67e95898543d1aad708cdc7667afd Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Fri, 24 Jan 2020 14:21:08 -0800 Subject: [PATCH 37/56] Fixed formatting --- .../botbuilder/dialogs/component_dialog.py | 105 ++++++++---------- 1 file changed, 48 insertions(+), 57 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py index ed676119d..288bc7b5d 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py @@ -16,12 +16,11 @@ class ComponentDialog(Dialog): """ A :class:`Dialog` that is composed of other dialogs - - ..remarks: - - A component dialog has an inner :class:`DialogSet` :class:`DialogContext`, - which provides an inner dialog stack that is hidden from the parent dialog. - :var persisted_dialog state: ? + + A component dialog has an inner :class:`DialogSet` :class:`DialogContext`, + which provides an inner dialog stack that is hidden from the parent dialog. + + :var persisted_dialog state: :vartype persisted_dialog_state: str """ persisted_dialog_state = "dialogs" @@ -49,10 +48,8 @@ async def begin_dialog( """ Called when the dialog is started and pushed onto the parent's dialog stack. - ..remarks:: - - If the task is successful, the result indicates whether the dialog is still - active after the turn has been processed by the dialog. + If the task is successful, the result indicates whether the dialog is still + active after the turn has been processed by the dialog. :param dialog_context: The :class:`DialogContext` for the current turn of the conversation. :type dialog_context: :class:`DialogContext` @@ -84,17 +81,16 @@ async def continue_dialog(self, dialog_context: DialogContext) -> DialogTurnResu Called when the dialog is continued, where it is the active dialog and the user replies with a new activity. - ..remarks:: + .. note:: + If the task is successful, the result indicates whether the dialog is still + active after the turn has been processed by the dialog. The result may also + contain a return value. - If the task is successful, the result indicates whether the dialog is still - active after the turn has been processed by the dialog. The result may also - contain a return value. - - If this method is *not* overriden the component dialog calls the - :meth:`DialogContext.continue_dialog` method on it's inner dialog - context. If the inner dialog stack is empty, the component dialog ends, - and if a :class:`DialogTurnResult.result` is available, the component dialog - uses that as it's return value. + If this method is *not* overriden the component dialog calls the + :meth:`DialogContext.continue_dialog` method on it's inner dialog + context. If the inner dialog stack is empty, the component dialog ends, + and if a :class:`DialogTurnResult.result` is available, the component dialog + uses that as it's return value. :param dialog_context: The parent :class:`DialogContext` for the current turn of the conversation. @@ -122,17 +118,16 @@ async def resume_dialog( Called when a child dialog on the parent's dialog stack completed this turn, returning control to this dialog component. - ..remarks:: - - If the task is successful, the result indicates whether this dialog is still - active after this dialog turn has been processed. + .. note:: + If the task is successful, the result indicates whether this dialog is still + active after this dialog turn has been processed. - Generally, the child dialog was started with a call to :meth:`def async begin_dialog()` - in the parent's context. However, if the :meth:`DialogContext.replace_dialog()` method is - is called, the logical child dialog may be different than the original. + Generally, the child dialog was started with a call to :meth:`def async begin_dialog()` + in the parent's context. However, if the :meth:`DialogContext.replace_dialog()` method is + is called, the logical child dialog may be different than the original. - If this method is *not* overridden, the dialog automatically calls its - :meth:`asyn def reprompt_dialog()` when the user replies. + If this method is *not* overridden, the dialog automatically calls its + :meth:`asyn def reprompt_dialog()` when the user replies. :param dialog_context: The :class:`DialogContext` for the current turn of the conversation. :type dialog_context: :class:`DialogContext` @@ -144,7 +139,7 @@ async def resume_dialog( :rtype: :class:`Dialog.end_of_turn` """ - """ (not sure where to put this information) + """ Containers are typically leaf nodes on the stack but the dev is free to push other dialogs on top of the stack which will result in the container receiving an unexpected call to resume_dialog() when the pushed on dialog ends. @@ -177,7 +172,7 @@ async def end_dialog( self, context: TurnContext, instance: DialogInstance, reason: DialogReason ) -> None: """ - Called when the dialog is ending. + Called when the dialog is ending. :param context: The context object for this turn. :type context: :class:`TurnContext` @@ -196,9 +191,8 @@ async def end_dialog( def add_dialog(self, dialog: Dialog) -> object: """ Adds a :class:`Dialog` to the component dialog and returns the updated component. - - ..remarks:: - Adding a new dialog will inherit the :class:`BotTelemetryClient` of the :class:`ComponentDialog`. + Adding a new dialog will inherit the :class:`BotTelemetryClient` of the :class:`ComponentDialog`. + :param dialog: The dialog to add. :return: The updated :class:`ComponentDialog` :rtype: :class:`ComponentDialog` @@ -211,9 +205,7 @@ def add_dialog(self, dialog: Dialog) -> object: def find_dialog(self, dialog_id: str) -> Dialog: """ Finds a dialog by ID. - - ..remarks:: - Adding a new dialog will inherit the :class:`BotTelemetryClient` of the :class:`ComponentDialog`. + Adding a new dialog will inherit the :class:`BotTelemetryClient` of the :class:`ComponentDialog`. :param dialog_id: The dialog to add. :return: The dialog; or None if there is not a match for the ID. @@ -227,15 +219,15 @@ async def on_begin_dialog( """ Called when the dialog is started and pushed onto the parent's dialog stack. - ..remarks:: + .. note:: - If the task is successful, the result indicates whether the dialog is still - active after the turn has been processed by the dialog. + If the task is successful, the result indicates whether the dialog is still + active after the turn has been processed by the dialog. - By default, this calls the :meth:`Dialog.begin_dialog()` method of the component - dialog's initial dialog, as defined by ?. + By default, this calls the :meth:`Dialog.begin_dialog()` method of the component + dialog's initial dialog. - Override this method in a derived class to implement interrupt logic. + Override this method in a derived class to implement interrupt logic. :param inner_dc: The inner :class:`DialogContext` for the current turn of conversation. :type inner_dc: :class:`DialogContext` @@ -268,7 +260,7 @@ async def on_reprompt_dialog( # pylint: disable=unused-argument self, turn_context: TurnContext, instance: DialogInstance ) -> None: """ - :param turn_context: + :param turn_context: The :class:`TurnContext` for the current turn of the conversation. :type turn_context: :class:`DialogInstance` :param instance: State information associated with the instance of this component dialog on its parent's dialog stack. :type instance: :class:`DialogInstance` @@ -280,19 +272,18 @@ async def end_component( ) -> DialogTurnResult: """ Ends the component dialog in its parent's context. - - ..remarks:: - If the task is successful, the result indicates that the dialog ended after the - turn was processed by the dialog. - - In general, the parent context is the dialog or bot turn handler that started the dialog. - If the parent is a dialog, the stack calls the parent's :meth:`Dialog.resume_dialog()` method - to return a result to the parent dialog. If the parent dialog does not implement - :meth:`Dialog.resume_dialog()`, then the parent will end, too, and the result is passed to the next - parent context, if one exists. - - The returned :class:`DialogTurnResult`contains the return value in its - :class:`DialogTurnResult.result` property. + .. note:: + If the task is successful, the result indicates that the dialog ended after the + turn was processed by the dialog. + + In general, the parent context is the dialog or bot turn handler that started the dialog. + If the parent is a dialog, the stack calls the parent's :meth:`Dialog.resume_dialog()` method + to return a result to the parent dialog. If the parent dialog does not implement + :meth:`Dialog.resume_dialog()`, then the parent will end, too, and the result is passed to the next + parent context, if one exists. + + The returned :class:`DialogTurnResult`contains the return value in its + :class:`DialogTurnResult.result` property. :param outer_dc: The parent class:`DialogContext` for the current turn of conversation. :type outer_dc: class:`DialogContext` From f75cffd0a1ab4fe8cd727fbfb28ae75ee47b7904 Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Fri, 24 Jan 2020 14:22:53 -0800 Subject: [PATCH 38/56] Update bot_state.py --- .../botbuilder/core/bot_state.py | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/libraries/botbuilder-core/botbuilder/core/bot_state.py b/libraries/botbuilder-core/botbuilder/core/bot_state.py index a05244832..eadbefc16 100644 --- a/libraries/botbuilder-core/botbuilder/core/bot_state.py +++ b/libraries/botbuilder-core/botbuilder/core/bot_state.py @@ -13,7 +13,7 @@ class CachedBotState: """ - Internal cached bot state + Internal cached bot state. """ def __init__(self, state: Dict[str, object] = None): @@ -30,9 +30,9 @@ def compute_hash(self, obj: object) -> str: class BotState(PropertyManager): - """ Defines a state management object + """ Defines a state management object and automates the reading and writing of - associated state properties to a storage layer + associated state properties to a storage layer. .. remarks:: Each state management object defines a scope for a storage layer. @@ -42,7 +42,8 @@ class BotState(PropertyManager): """ def __init__(self, storage: Storage, context_service_key: str): - """ Initializes a new instance of the :class:`BotState` class. + """ + Initializes a new instance of the :class:`BotState` class. :param storage: The storage layer this state management object will use to store and retrieve state :type storage: :class:`bptbuilder.core.Storage` @@ -54,7 +55,7 @@ def __init__(self, storage: Storage, context_service_key: str): the :param storage: to persist state property values and the :param context_service_key: to cache state within the context for each turn. - :raises: It raises an argument null exception + :raises: It raises an argument null exception. """ self.state_key = "state" self._storage = storage @@ -63,9 +64,10 @@ def __init__(self, storage: Storage, context_service_key: str): def create_property(self, name: str) -> StatePropertyAccessor: """ Create a property definition and register it with this :class:`BotState`. + :param name: The name of the property :type name: str - :return: If successful, the state property accessor created. + :return: If successful, the state property accessor created :rtype: :class:`StatePropertyAccessor` """ if not name: @@ -79,7 +81,8 @@ def get(self, turn_context: TurnContext) -> Dict[str, object]: async def load(self, turn_context: TurnContext, force: bool = False) -> None: """ - Reads in the current state object and caches it in the context object for this turn. + Reads the current state object and caches it in the context object for this turn. + :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` :param force: Optional, true to bypass the cache @@ -99,12 +102,13 @@ async def load(self, turn_context: TurnContext, force: bool = False) -> None: async def save_changes( self, turn_context: TurnContext, force: bool = False ) -> None: - """Save the state cached in the current context for this turn - If it has changed, save the state cached in the current context for this turn. + """ + Saves the state cached in the current context for this turn. + If the state has changed, it saves the state cached in the current context for this turn. :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` - :param force: Optional, true to save state to storage whether or not there are changes. + :param force: Optional, true to save state to storage whether or not there are changes :type force: bool """ if turn_context is None: @@ -119,7 +123,8 @@ async def save_changes( cached_state.hash = cached_state.compute_hash(cached_state.state) async def clear_state(self, turn_context: TurnContext): - """Clears any state currently stored in this state scope + """ + Clears any state currently stored in this state scope. :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` @@ -138,7 +143,8 @@ async def clear_state(self, turn_context: TurnContext): turn_context.turn_state[self._context_service_key] = cache_value async def delete(self, turn_context: TurnContext) -> None: - """Deletes any state currently stored in this state scope. + """ + Deletes any state currently stored in this state scope. :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` @@ -158,7 +164,8 @@ def get_storage_key(self, turn_context: TurnContext) -> str: raise NotImplementedError() async def get_property_value(self, turn_context: TurnContext, property_name: str): - """Gets the value of the specified property in the turn context + """ + Gets the value of the specified property in the turn context. :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` @@ -184,7 +191,8 @@ async def get_property_value(self, turn_context: TurnContext, property_name: str async def delete_property_value( self, turn_context: TurnContext, property_name: str ) -> None: - """Deletes a property from the state cache in the turn context + """ + Deletes a property from the state cache in the turn context. :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` @@ -203,7 +211,8 @@ async def delete_property_value( async def set_property_value( self, turn_context: TurnContext, property_name: str, value: object ) -> None: - """Sets a property to the specified value in the turn context + """ + Sets a property to the specified value in the turn context. :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` From 7e72b0fe83e13d5e34c2e014a613a7c0b2a504a1 Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Fri, 24 Jan 2020 14:24:42 -0800 Subject: [PATCH 39/56] Fixed formatting --- .../dialogs/prompts/activity_prompt.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py index 3a70d17cc..e849e47c0 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py @@ -23,14 +23,14 @@ class ActivityPrompt(Dialog, ABC): """ Waits for an activity to be received. - ..remarks: + .. remarks: This prompt requires a validator be passed in and is useful when waiting for non-message activities like an event to be received. The validator can ignore received events until the expected activity is received. - :var persisted_options: ? + :var persisted_options: :typevar persisted_options: str - :var persisted_state: ? + :var persisted_state: :vartype persisted_state: str """ @@ -153,17 +153,19 @@ async def resume_dialog( # pylint: disable=unused-argument ): """ Called when a prompt dialog resumes being the active dialog on the dialog stack, such as when the previous active dialog on the stack completes. - ..remarks: + + .. note: Prompts are typically leaf nodes on the stack but the dev is free to push other dialogs on top of the stack which will result in the prompt receiving an unexpected call to - resume_dialog() when the pushed on dialog ends. + :meth:resume_dialog() when the pushed on dialog ends. To avoid the prompt prematurely ending, we need to implement this method and - simply re-prompt the user. + simply re-prompt the user. + :param dialog_context: The dialog context for the current turn of the conversation :type dialog_context: :class:`DialogContext` :param reason: An enum indicating why the dialog resumed. :type reason: :class:`DialogReason` - :param result: >Optional, value returned from the previous dialog on the stack. The type of the value returned is dependent on the previous dialog. + :param result: Optional, value returned from the previous dialog on the stack. The type of the value returned is dependent on the previous dialog. :type result: object """ await self.reprompt_dialog(dialog_context.context, dialog_context.active_dialog) From 63ff9814ddd79fa9509a983c4b54b94a83cda142 Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Fri, 24 Jan 2020 14:25:51 -0800 Subject: [PATCH 40/56] Update activity_prompt.py --- .../botbuilder/dialogs/prompts/activity_prompt.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py index e849e47c0..15f7f9cdc 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py @@ -152,7 +152,8 @@ async def resume_dialog( # pylint: disable=unused-argument self, dialog_context: DialogContext, reason: DialogReason, result: object = None ): """ - Called when a prompt dialog resumes being the active dialog on the dialog stack, such as when the previous active dialog on the stack completes. + Called when a prompt dialog resumes being the active dialog on the dialog stack, such + as when the previous active dialog on the stack completes. .. note: Prompts are typically leaf nodes on the stack but the dev is free to push other dialogs @@ -165,7 +166,7 @@ async def resume_dialog( # pylint: disable=unused-argument :type dialog_context: :class:`DialogContext` :param reason: An enum indicating why the dialog resumed. :type reason: :class:`DialogReason` - :param result: Optional, value returned from the previous dialog on the stack. The type of the value returned is dependent on the previous dialog. + :param result: Optional, value returned from the previous dialog on the stack. :type result: object """ await self.reprompt_dialog(dialog_context.context, dialog_context.active_dialog) From 7426e9fb86b078c130bd1a9b68eda3e2f72011b7 Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Fri, 24 Jan 2020 14:31:07 -0800 Subject: [PATCH 41/56] Fixed formatting --- .../botbuilder/dialogs/component_dialog.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py index 288bc7b5d..b297443df 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py @@ -119,6 +119,12 @@ async def resume_dialog( control to this dialog component. .. note:: + Containers are typically leaf nodes on the stack but the dev is free to push other dialogs + on top of the stack which will result in the container receiving an unexpected call to + :meth:resume_dialog() when the pushed on dialog ends. + To avoid the container prematurely ending we need to implement this method and simply + ask our inner dialog stack to re-prompt. + If the task is successful, the result indicates whether this dialog is still active after this dialog turn has been processed. @@ -139,13 +145,6 @@ async def resume_dialog( :rtype: :class:`Dialog.end_of_turn` """ - """ - Containers are typically leaf nodes on the stack but the dev is free to push other dialogs - on top of the stack which will result in the container receiving an unexpected call to - resume_dialog() when the pushed on dialog ends. - To avoid the container prematurely ending we need to implement this method and simply - ask our inner dialog stack to re-prompt. - """ await self.reprompt_dialog(dialog_context.context, dialog_context.active_dialog) return Dialog.end_of_turn @@ -220,7 +219,6 @@ async def on_begin_dialog( Called when the dialog is started and pushed onto the parent's dialog stack. .. note:: - If the task is successful, the result indicates whether the dialog is still active after the turn has been processed by the dialog. @@ -272,6 +270,7 @@ async def end_component( ) -> DialogTurnResult: """ Ends the component dialog in its parent's context. + .. note:: If the task is successful, the result indicates that the dialog ended after the turn was processed by the dialog. From 6b97814b469d8441edc6725cf12668221c981611 Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Fri, 24 Jan 2020 14:34:33 -0800 Subject: [PATCH 42/56] Update conversation_state.py Code comments formatting. --- .../botbuilder/core/conversation_state.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libraries/botbuilder-core/botbuilder/core/conversation_state.py b/libraries/botbuilder-core/botbuilder/core/conversation_state.py index 954620de1..fd39935e0 100644 --- a/libraries/botbuilder-core/botbuilder/core/conversation_state.py +++ b/libraries/botbuilder-core/botbuilder/core/conversation_state.py @@ -7,17 +7,19 @@ class ConversationState(BotState): - """Conversation state + """ Defines a state management object for conversation state. Extends :class:`BootState` base class. .. remarks:: - Conversation state is available in any turn in a specific conversation, regardless of user, such as in a group conversation. + Conversation state is available in any turn in a specific conversation, regardless of the user, such as in a group conversation. """ no_key_error_message = "ConversationState: channelId and/or conversation missing from context.activity." def __init__(self, storage: Storage): - """ Creates a :class:`ConversationState` instance + """ + Creates a :class:`ConversationState` instance. + Creates a new instance of the :class:`ConversationState` class. :param storage: The storage containing the conversation state. :type storage: :class:`Storage` @@ -25,7 +27,7 @@ def __init__(self, storage: Storage): super(ConversationState, self).__init__(storage, "ConversationState") def get_storage_key(self, turn_context: TurnContext) -> object: - """ Get storage key + """ Gets the key to use when reading and writing state to and from storage. :param turn_context: The context object for this turn. @@ -39,7 +41,7 @@ def get_storage_key(self, turn_context: TurnContext) -> object: :rtype: str .. remarks:: - Conversation state includes the channel Id and conversation Id as part of its storage key. + Conversation state includes the channel ID and conversation ID as part of its storage key. """ channel_id = turn_context.activity.channel_id or self.__raise_type_error( "invalid activity-missing channel_id" From f98a391411f72d4c87a9e80d1ad5bb2b1793fa0d Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Fri, 24 Jan 2020 14:56:20 -0800 Subject: [PATCH 43/56] Update prompt.py Code comments formatting. --- .../botbuilder/dialogs/prompts/prompt.py | 83 ++++++++++--------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py index d3ab5a80f..c64b8ad39 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py @@ -23,16 +23,14 @@ class Prompt(Dialog): - """ Prompts base class + """ Defines the core behavior of prompt dialogs. Extends the :class:`Dialog` base class. .. remarks:: When the prompt ends, it returns an object that represents the value it was prompted for. - Use :method:`DialogSet.add(self, dialog: Dialog)` or :method:`ComponentDialog.add_dialog(self, dialog: Dialog)` to add a prompt - to a dialog set or component dialog, respectively. - Use :method:`DialogContext.prompt(self, dialog_id: str, options)` or - :meth:`DialogContext.begin_dialog( - self, dialog_context: DialogContext, options: object = None)` to start the prompt. + Use :method:`DialogSet.add()` or :method:`ComponentDialog.add_dialog()` to add a prompt to a dialog set or + component dialog, respectively. + Use :method:`DialogContext.prompt()` or :meth:`DialogContext.begin_dialog()` to start the prompt. .. note:: If you start a prompt from a :class:`WaterfallStep` in a :class:`WaterfallDialog`, then the prompt result will be available in the next step of the waterfall. @@ -42,7 +40,9 @@ class Prompt(Dialog): persisted_state = "state" def __init__(self, dialog_id: str, validator: object = None): - """Creates a new Prompt instance + """ + Creates a new :class:`Prompt` instance. + :param dialog_id: Unique Id of the prompt within its parent :class:`DialogSet` or :class:`ComponentDialog`. :type dialog_id: str @@ -56,12 +56,12 @@ def __init__(self, dialog_id: str, validator: object = None): async def begin_dialog( self, dialog_context: DialogContext, options: object = None ) -> DialogTurnResult: - """ Starts a prompt dialog. - Called when a prompt dialog is pushed onto the dialog stack and is being activated. + """ + Starts a prompt dialog. Called when a prompt dialog is pushed onto the dialog stack and is being activated. - :param dialog_context: The dialog context for the current turn of the conversation. + :param dialog_context: The dialog context for the current turn of the conversation :type dialog_context: :class:`DialogContext` - :param options: Optional, additional information to pass to the prompt being started. + :param options: Optional, additional information to pass to the prompt being started :type options: Object :return: The dialog turn result :rtype: :class:`DialogTurnResult` @@ -97,10 +97,10 @@ async def begin_dialog( return Dialog.end_of_turn async def continue_dialog(self, dialog_context: DialogContext): - """ Continues a dialog. - Called when a prompt dialog is the active dialog and the user replied with a new activity. + """ + Continues a dialog. Called when a prompt dialog is the active dialog and the user replied with a new activity. - :param dialog_context: The dialog context for the current turn of the conversation. + :param dialog_context: The dialog context for the current turn of the conversation :type dialog_context: :class:`DialogContext` :return: The dialog turn result :rtype: :class:`DialogTurnResult` @@ -148,16 +148,16 @@ async def continue_dialog(self, dialog_context: DialogContext): async def resume_dialog( self, dialog_context: DialogContext, reason: DialogReason, result: object ) -> DialogTurnResult: - """ Resumes a dialog. - Called when a prompt dialog resumes being the active dialog on the dialog stack, such as - when the previous active dialog on the stack completes. + """ + Resumes a dialog. Called when a prompt dialog resumes being the active dialog + on the dialog stack, such as when the previous active dialog on the stack completes. :param dialog_context: The dialog context for the current turn of the conversation. :type dialog_context: :class:DialogContext :param reason: An enum indicating why the dialog resumed. :type reason: :class:DialogReason - :param result: Optional, value returned from the previous dialog on the stack. - The type of the value returned is dependent on the previous dialog. + :param result: Optional, value returned from the previous dialog on the stack. + The type of the value returned is dependent on the previous dialog. :type result: object :return: The dialog turn result :rtype: :class:`DialogTurnResult` @@ -174,14 +174,14 @@ async def resume_dialog( return Dialog.end_of_turn async def reprompt_dialog(self, context: TurnContext, instance: DialogInstance): - """ Reprompts user for input. - Called when a prompt dialog has been requested to re-prompt the user for input. + """ + Reprompts user for input. Called when a prompt dialog has been requested to re-prompt the user for input. - :param context: Context for the current turn of conversation with the user. + :param context: Context for the current turn of conversation with the user :type context: :class:TurnContext - :param instance: The instance of the dialog on the stack. + :param instance: The instance of the dialog on the stack :type instance: :class:DialogInstance - :return: A :class:Task representing the asynchronous operation. + :return: A :class:Task representing the asynchronous operation :rtype: :class:Task """ state = instance.state[self.persisted_state] @@ -196,18 +196,18 @@ async def on_prompt( options: PromptOptions, is_retry: bool, ): - """ Prompts user for input. - When overridden in a derived class, prompts the user for input. + """ + Prompts user for input. When overridden in a derived class, prompts the user for input. - :param turn_context: Context for the current turn of conversation with the user. + :param turn_context: Context for the current turn of conversation with the user :type turn_context: :class:`TurnContext` - :param state: Contains state for the current instance of the prompt on the dialog stack. + :param state: Contains state for the current instance of the prompt on the dialog stack :type state: :class:Dict :param options: A prompt options object constructed from the options initially provided - in the call :meth:`DialogContext.prompt(self, dialog_id: str, options)`. + in the call :meth:`DialogContext.prompt(self, dialog_id: str, options)` :type options: :class:`PromptOptions` :param is_retry: true if this is the first time this prompt dialog instance on the stack is prompting - the user for input; otherwise, false. + the user for input; otherwise, false :type is_retry: bool :return: A :class:Task representing the asynchronous operation. @@ -222,12 +222,12 @@ async def on_recognize( state: Dict[str, object], options: PromptOptions, ): - """ Recognizes the user's input. - When overridden in a derived class, attempts to recognize the user's input. + """ + Recognizes the user's input. When overridden in a derived class, attempts to recognize the user's input. - :param turn_context: Context for the current turn of conversation with the user. + :param turn_context: Context for the current turn of conversation with the user :type turn_context: :class:`TurnContext` - :param state: Contains state for the current instance of the prompt on the dialog stack. + :param state: Contains state for the current instance of the prompt on the dialog stack :type state: :class:Dict :param options: A prompt options object constructed from the options initially provided in the call :meth:`DialogContext.prompt(self, dialog_id: str, options)` @@ -246,21 +246,22 @@ def append_choices( style: ListStyle, options: ChoiceFactoryOptions = None, ) -> Activity: - """ Composes an output activity containing a set of choices. + """ + Composes an output activity containing a set of choices. When overridden in a derived class, appends choices to the activity when the user is prompted for input. Helper function to compose an output activity containing a set of choices. - :param prompt: The prompt to append the user's choice to. + :param prompt: The prompt to append the user's choice to :type prompt: - :param channel_id: Id of the channel the prompt is being sent to. + :param channel_id: Id of the channel the prompt is being sent to :type channel_id: str - :param: choices: List of choices to append. + :param: choices: List of choices to append :type choices: :class:`List` - :param: style: Configured style for the list of choices. + :param: style: Configured style for the list of choices :type style: :class:`ListStyle` - :param: options: Optional formatting options to use when presenting the choices. + :param: options: Optional formatting options to use when presenting the choices :type style: :class:`ChoiceFactoryOptions` - :return: A :class:Task representing the asynchronous operation. + :return: A :class:Task representing the asynchronous operation :rtype: :class:Task .. remarks:: From 1a2cc75d0eee62764f8399e0956fb320b382c652 Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Fri, 24 Jan 2020 15:07:35 -0800 Subject: [PATCH 44/56] Update bot_state.py Chaanged remarks to note in method as per feedback. --- libraries/botbuilder-core/botbuilder/core/bot_state.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/botbuilder-core/botbuilder/core/bot_state.py b/libraries/botbuilder-core/botbuilder/core/bot_state.py index eadbefc16..2718c1889 100644 --- a/libraries/botbuilder-core/botbuilder/core/bot_state.py +++ b/libraries/botbuilder-core/botbuilder/core/bot_state.py @@ -50,7 +50,7 @@ def __init__(self, storage: Storage, context_service_key: str): :param context_service_key: The key for the state cache for this :class:`BotState` :type context_service_key: str - .. remarks:: + .. note:: This constructor creates a state management object and associated scope. The object uses the :param storage: to persist state property values and the :param context_service_key: to cache state within the context for each turn. @@ -131,7 +131,7 @@ async def clear_state(self, turn_context: TurnContext): :return: None - .. notes:: + .. note:: This function must be called in order for the cleared state to be persisted to the underlying store. """ if turn_context is None: From 8703ddb15ec8ac7ec4461a5f6127e1483babc6bd Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Fri, 24 Jan 2020 15:18:55 -0800 Subject: [PATCH 45/56] Update oauth_prompt.py Code comments formatting and replaced remarks with note in methods. --- .../dialogs/prompts/oauth_prompt.py | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/oauth_prompt.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/oauth_prompt.py index 731ac6ecd..b6f726689 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/oauth_prompt.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/oauth_prompt.py @@ -32,8 +32,8 @@ class OAuthPrompt(Dialog): - """Creates a new prompt for the user to sign in - Creates a new prompt that asks the user to sign in using the Bot Framework Single Sign On (SSO) service. + """ + Creates a new prompt that asks the user to sign in, using the Bot Framework Single Sign On (SSO) service. .. remarks:: The prompt will attempt to retrieve the users current token and if the user isn't signed in, it @@ -67,17 +67,17 @@ def __init__( settings: OAuthPromptSettings, validator: Callable[[PromptValidatorContext], Awaitable[bool]] = None, ): - """ Creates a :class:`OAuthPrompt` instance + """ Creates a new instance of the :class:`OAuthPrompt` class. :param dialogId: The Id to assign to this prompt. :type dialogId: str - :param settings: Additional authentication settings to use with this instance of the prompt. + :param settings: Additional authentication settings to use with this instance of the prompt :type settings: :class:`OAuthPromptSettings` - :param validator: Optional, a :class:`PromptValidator` that contains additional, custom validation for this prompt. + :param validator: Optional, a :class:`PromptValidator` that contains additional, custom validation for this prompt :type validator: :class:`PromptValidatorContext` - .. remarks:: + .. note:: The value of :param dialogId: must be unique within the :class:`DialogSet`or :class:`ComponentDialog` to which the prompt is added. """ super().__init__(dialog_id) @@ -94,19 +94,18 @@ def __init__( async def begin_dialog( self, dialog_context: DialogContext, options: PromptOptions = None ) -> DialogTurnResult: - """ Starts an authentication prompt dialog. - Called when an authentication prompt dialog is pushed onto the dialog stack and is being activated. + """ + Starts an authentication prompt dialog. Called when an authentication prompt dialog is pushed onto the dialog stack and is being activated. - :param dialog_context: The dialog context for the current turn of the conversation. + :param dialog_context: The dialog context for the current turn of the conversation :type dialog_context: :class:`DialogContext` - :param options: Optional, additional information to pass to the prompt being started. + :param options: Optional, additional information to pass to the prompt being started :type options: :class:PromptOptions :return: Dialog turn result :rtype: :class:DialogTurnResult - .. remarks:: - If the task is successful, the result indicates whether the prompt is still active - after the turn has been processed by the prompt. + .. note:: + If the task is successful, the result indicates whether the prompt is still active after the turn has been processed by the prompt. """ if dialog_context is None: raise TypeError( @@ -149,15 +148,15 @@ async def begin_dialog( return Dialog.end_of_turn async def continue_dialog(self, dialog_context: DialogContext) -> DialogTurnResult: - """ Continues a dialog. - Called when a prompt dialog is the active dialog and the user replied with a new activity. + """ + Continues a dialog. Called when a prompt dialog is the active dialog and the user replied with a new activity. - :param dialog_context: The dialog context for the current turn of the conversation. + :param dialog_context: The dialog context for the current turn of the conversation :type dialog_context: :class:`DialogContext` :return: Dialog turn result :rtype: :class:DialogTurnResult - .. remarks:: + .. note:: If the task is successful, the result indicates whether the dialog is still active after the turn has been processed by the dialog. The prompt generally continues to receive the user's replies until it accepts the @@ -210,15 +209,15 @@ async def continue_dialog(self, dialog_context: DialogContext) -> DialogTurnResu async def get_user_token( self, context: TurnContext, code: str = None ) -> TokenResponse: - """Gets the user's token - Attempts to get the user's token. + """ + Gets the user's tokeN. - :param context: Context for the current turn of conversation with the user. + :param context: Context for the current turn of conversation with the user :type context: :class:TurnContext :return: A response that includes the user's token :rtype: :class:TokenResponse - .. remarks:: + .. note:: If the task is successful and the user already has a token or the user successfully signs in, the result contains the user's token. """ @@ -235,14 +234,15 @@ async def get_user_token( ) async def sign_out_user(self, context: TurnContext): - """Signs out the user + """ + Signs out the user - :param context: Context for the current turn of conversation with the user. + :param context: Context for the current turn of conversation with the user :type context: :class:`TurnContext` - :return: A :class:`Task` representing the work queued to execute. + :return: A :class:`Task` representing the work queued to execute :rtype: :class:`Task` - .. remarks:: + .. note:: If the task is successful and the user already has a token or the user successfully signs in, the result contains the user's token. """ From 1a2e82968de8fe4402626563c25242d2a386c7b9 Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Fri, 24 Jan 2020 15:42:10 -0800 Subject: [PATCH 46/56] Update prompt.py Changed reamrks to note in methods. --- .../botbuilder/dialogs/prompts/prompt.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py index c64b8ad39..842c606f1 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py @@ -66,7 +66,7 @@ async def begin_dialog( :return: The dialog turn result :rtype: :class:`DialogTurnResult` - .. remarks:: + .. note:: If the task is successful, the result indicates whether the prompt is still active after the turn has been processed by the prompt. """ @@ -105,7 +105,7 @@ async def continue_dialog(self, dialog_context: DialogContext): :return: The dialog turn result :rtype: :class:`DialogTurnResult` - .. remarks:: + .. note:: If the task is successful, the result indicates whether the dialog is still active after the turn has been processed by the dialog. The prompt generally continues to receive the user's replies until it accepts the @@ -162,7 +162,7 @@ async def resume_dialog( :return: The dialog turn result :rtype: :class:`DialogTurnResult` - .. remarks:: + .. note:: If the task is successful, the result indicates whether the dialog is still active after the turn has been processed by the dialog. Prompts are typically leaf nodes on the stack but the dev is free to push other dialogs @@ -264,7 +264,7 @@ def append_choices( :return: A :class:Task representing the asynchronous operation :rtype: :class:Task - .. remarks:: + .. note:: If the task is successful, the result contains the updated activity. """ # Get base prompt text (if any) From 8fa2dee563975b2bf90068a6cf7a0312463a7317 Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Fri, 24 Jan 2020 15:46:40 -0800 Subject: [PATCH 47/56] Update prompt_options.py Code comments formatting. --- .../botbuilder/dialogs/prompts/prompt_options.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt_options.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt_options.py index 2a3d6ef38..ea0c74825 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt_options.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt_options.py @@ -8,7 +8,7 @@ class PromptOptions: - """ Contains prompt settings + """ Contains settings to pass to a :class:`Prompt` object when the prompt is started. """ @@ -21,7 +21,8 @@ def __init__( validations: object = None, number_of_attempts: int = 0, ): - """ Sets the initial prompt to send to the user as an :class:`botbuilder.schema.Activity`. + """ + Sets the initial prompt to send to the user as an :class:`botbuilder.schema.Activity`. :param prompt: The initial prompt to send to the user :type prompt: :class:`botbuilder.schema.Activity` From 526d2ebbf9d71383ebaa77cdd18cb92edb7462cd Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Fri, 24 Jan 2020 16:04:07 -0800 Subject: [PATCH 48/56] Update bot_framework_adapter.py Code comments formatting and replaced remarks with note in methods. --- .../botbuilder/core/bot_framework_adapter.py | 79 +++++++++++-------- 1 file changed, 48 insertions(+), 31 deletions(-) diff --git a/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py b/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py index bc7f09b92..a717051e7 100644 --- a/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py +++ b/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py @@ -83,7 +83,8 @@ def __init__( channel_provider: ChannelProvider = None, auth_configuration: AuthenticationConfiguration = None, ): - """Contains the settings used to initialize a :class:`BotFrameworkAdapter` instance. + """ + Contains the settings used to initialize a :class:`BotFrameworkAdapter` instance. :param app_id: The bot application ID. This is the appId returned by the Azure portal registration, and is the value of the `MicrosoftAppId` parameter in the `config.py` file. @@ -116,7 +117,8 @@ def __init__( class BotFrameworkAdapter(BotAdapter, UserTokenProvider): - """Defines an adapter to connect a bot to a service endpoint + """ + Defines an adapter to connect a bot to a service endpoint. .. remarks:: The bot adapter encapsulates authentication processes and sends activities to and @@ -132,10 +134,11 @@ class BotFrameworkAdapter(BotAdapter, UserTokenProvider): _INVOKE_RESPONSE_KEY = "BotFrameworkAdapter.InvokeResponse" def __init__(self, settings: BotFrameworkAdapterSettings): - """ Initializes a new instance of the :class:`BotFrameworkAdapter` class + """ + Initializes a new instance of the :class:`BotFrameworkAdapter` class. - :param settings: The settings to initialize the adapter - :type settings: :class:`BotFrameworkAdapterSettings` + :param settings: The settings to initialize the adapter + :type settings: :class:`BotFrameworkAdapterSettings` """ super(BotFrameworkAdapter, self).__init__() self.settings = settings or BotFrameworkAdapterSettings("", "") @@ -180,7 +183,8 @@ async def continue_conversation( bot_id: str = None, claims_identity: ClaimsIdentity = None, # pylint: disable=unused-argument ): - """Continues a conversation with a user + """ + Continues a conversation with a user. :param reference: A reference to the conversation to continue :type reference: :class:`botbuilder.schema.ConversationReference @@ -192,11 +196,11 @@ async def continue_conversation( :param claims_identity: The bot claims identity :type claims_identity: :class:`botframework.connector.auth.ClaimsIdentity` - :raises: It raises an argument null exception + :raises: It raises an argument null exception. - :return: A task that represents the work queued to execute + :return: A task that represents the work queued to execute. - .. remarks:: + .. note:: This is often referred to as the bots *proactive messaging* flow as it lets the bot proactively send messages to a conversation or user that are already in a communication. Scenarios such as sending notifications or coupons to a user are enabled by this function. @@ -225,8 +229,9 @@ async def create_conversation( logic: Callable[[TurnContext], Awaitable] = None, conversation_parameters: ConversationParameters = None, ): - """Starts a new conversation with a user - Used to direct message to a member of a group + """ + Starts a new conversation with a user. Used to direct message to a member of a group. + :param reference: The conversation reference that contains the tenant :type reference: :class:`botbuilder.schema.ConversationReference` :param logic: The logic to use for the creation of the conversation @@ -234,11 +239,11 @@ async def create_conversation( :param conversation_parameters: The information to use to create the conversation :type conversation_parameters: - :raises: It raises a generic exception error + :raises: It raises a generic exception error. - :return: A task representing the work queued to execute + :return: A task representing the work queued to execute. - .. remarks:: + .. note:: To start a conversation, your bot must know its account information and the user's account information on that channel. Most channels only support initiating a direct message (non-group) conversation. @@ -296,7 +301,8 @@ async def create_conversation( raise error async def process_activity(self, req, auth_header: str, logic: Callable): - """Creates a turn context and runs the middleware pipeline for an incoming activity + """ + Creates a turn context and runs the middleware pipeline for an incoming activity, Processes an activity received by the bots web server. This includes any messages sent from a user and is the method that drives what's often referred to as the bots *reactive messaging* flow. @@ -311,7 +317,7 @@ async def process_activity(self, req, auth_header: str, logic: Callable): was `Invoke` and the corresponding key (`channelId` + `activityId`) was found then an :class:`InvokeResponse` is returned; otherwise, `null` is returned. - .. remarks:: + .. note:: Call this method to reactively send a message to a conversation. If the task completes successfully, then an :class:`InvokeResponse` is returned; otherwise. `null` is returned. @@ -356,12 +362,14 @@ async def process_activity(self, req, auth_header: str, logic: Callable): async def authenticate_request( self, request: Activity, auth_header: str ) -> ClaimsIdentity: - """Allows for the overriding of authentication in unit tests. + """ + Allows for the overriding of authentication in unit tests. + :param request: The request to authenticate :type request: :class:`botbuilder.schema.Activity` :param auth_header: The authentication header - :raises: A permission exception error + :raises: A permission exception error. :return: The request claims identity :rtype: :class:`botframework.connector.auth.ClaimsIdentity` @@ -383,7 +391,7 @@ def create_context(self, activity): """ Allows for the overriding of the context object in unit tests and derived adapters. :param activity: - :return: + :return: """ return TurnContext(self, activity) @@ -445,7 +453,7 @@ async def update_activity(self, context: TurnContext, activity: Activity): :return: A task that represents the work queued to execute - .. remarks:: + .. note:: If the activity is successfully sent, the task result contains a :class:`botbuilder.schema.ResourceResponse` object containing the ID that the receiving channel assigned to the activity. @@ -477,7 +485,7 @@ async def delete_activity( :return: A task that represents the work queued to execute - .. remarks:: + .. note:: The activity_id of the :class:`botbuilder.schema.ConversationReference` identifies the activity to delete. """ try: @@ -549,7 +557,9 @@ async def send_activities( async def delete_conversation_member( self, context: TurnContext, member_id: str ) -> None: - """Deletes a member from the current conversation + """ + Deletes a member from the current conversation. + :param context: The context object for the turn :type context: :class:`TurnContext` :param member_id: The ID of the member to remove from the conversation @@ -585,7 +595,8 @@ async def delete_conversation_member( raise error async def get_activity_members(self, context: TurnContext, activity_id: str): - """Lists the members of a given activity + """ + Lists the members of a given activity. :param context: The context object for the turn :type context: :class:`TurnContext` @@ -626,7 +637,8 @@ async def get_activity_members(self, context: TurnContext, activity_id: str): raise error async def get_conversation_members(self, context: TurnContext): - """Lists the members of a current conversation. + """ + Lists the members of a current conversation. :param context: The context object for the turn :type context: :class:`TurnContext` @@ -672,7 +684,7 @@ async def get_conversations(self, service_url: str, continuation_token: str = No :return: A task that represents the work queued to execute - .. remarks:: If the task completes successfully, the result contains a page of the members of the current conversation. + .. note:: If the task completes successfully, the result contains a page of the members of the current conversation. This overload may be called from outside the context of a conversation, as only the bot's service URL and credentials are required. """ client = await self.create_connector_client(service_url) @@ -682,7 +694,8 @@ async def get_user_token( self, context: TurnContext, connection_name: str, magic_code: str = None ) -> TokenResponse: - """Attempts to retrieve the token for a user that's in a login flow + """ + Attempts to retrieve the token for a user that's in a login flow. :param context: Context for the current turn of conversation with the user :type context: :class:`TurnContext` @@ -728,7 +741,8 @@ async def get_user_token( async def sign_out_user( self, context: TurnContext, connection_name: str = None, user_id: str = None ) -> str: - """Signs the user out with the token server + """ + Signs the user out with the token server. :param context: Context for the current turn of conversation with the user :type context: :class:`TurnContext` @@ -756,7 +770,8 @@ async def sign_out_user( async def get_oauth_sign_in_link( self, context: TurnContext, connection_name: str ) -> str: - """Gets the raw sign-in link to be sent to the user for sign-in for a connection name. + """ + Gets the raw sign-in link to be sent to the user for sign-in for a connection name. :param context: Context for the current turn of conversation with the user :type context: :class:`TurnContext` @@ -765,7 +780,7 @@ async def get_oauth_sign_in_link( :returns: A task that represents the work queued to execute - .. remarks:: + .. note:: If the task completes successfully, the result contains the raw sign-in link """ self.check_emulating_oauth_cards(context) @@ -788,7 +803,8 @@ async def get_token_status( self, context: TurnContext, user_id: str = None, include_filter: str = None ) -> List[TokenStatus]: - """Retrieves the token status for each configured connection for the given user + """ + Retrieves the token status for each configured connection for the given user. :param context: Context for the current turn of conversation with the user :type context: :class:`TurnContext` @@ -821,7 +837,8 @@ async def get_token_status( async def get_aad_tokens( self, context: TurnContext, connection_name: str, resource_urls: List[str] ) -> Dict[str, TokenResponse]: - """Retrieves Azure Active Directory tokens for particular resources on a configured connection + """ + Retrieves Azure Active Directory tokens for particular resources on a configured connection. :param context: Context for the current turn of conversation with the user :type context: :class:`TurnContext` From 5e36083cecf04cae87175a6be0647c90cd4b82bd Mon Sep 17 00:00:00 2001 From: Michael Miele Date: Fri, 24 Jan 2020 16:26:41 -0800 Subject: [PATCH 49/56] Update activity_handler.py Code comments formatting.and repplaced remarks with note in methods. --- .../botbuilder/core/activity_handler.py | 92 +++++++++++-------- 1 file changed, 54 insertions(+), 38 deletions(-) diff --git a/libraries/botbuilder-core/botbuilder/core/activity_handler.py b/libraries/botbuilder-core/botbuilder/core/activity_handler.py index 9d4bfb6f1..54a16c056 100644 --- a/libraries/botbuilder-core/botbuilder/core/activity_handler.py +++ b/libraries/botbuilder-core/botbuilder/core/activity_handler.py @@ -8,22 +8,23 @@ class ActivityHandler: async def on_turn(self, turn_context: TurnContext): - """ Called by the adapter (for example, :class:`BotFrameworkAdapter`) at runtime + """ + Called by the adapter (for example, :class:`BotFrameworkAdapter`) at runtime in order to process an inbound :class:`botbuilder.schema.Activity`. - :param turn_context: The context object for this turn - :type turn_context: :class:`TurnContext` + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` - :returns: A task that represents the work queued to execute + :returns: A task that represents the work queued to execute - .. remarks:: - It calls other methods in this class based on the type of the activity to - process, which allows a derived class to provide type-specific logic in a controlled way. - In a derived class, override this method to add logic that applies to all activity types. + .. remarks:: + It calls other methods in this class based on the type of the activity to + process, which allows a derived class to provide type-specific logic in a controlled way. + In a derived class, override this method to add logic that applies to all activity types. - .. note:: - - Add logic to apply before the type-specific logic and before the call to the :meth:`ActivityHandler.on_turn()` method. - - Add logic to apply after the type-specific logic after the call to the :meth:`ActivityHandler.on_turn()` method. + .. note:: + - Add logic to apply before the type-specific logic and before the call to the :meth:`ActivityHandler.on_turn()` method. + - Add logic to apply after the type-specific logic after the call to the :meth:`ActivityHandler.on_turn()` method. """ if turn_context is None: raise TypeError("ActivityHandler.on_turn(): turn_context cannot be None.") @@ -57,7 +58,8 @@ async def on_turn(self, turn_context: TurnContext): async def on_message_activity( # pylint: disable=unused-argument self, turn_context: TurnContext ): - """Override this method in a derived class to provide logic specific to activities, + """ + Override this method in a derived class to provide logic specific to activities, such as the conversational logic. :param turn_context: The context object for this turn @@ -69,13 +71,15 @@ async def on_message_activity( # pylint: disable=unused-argument return async def on_conversation_update_activity(self, turn_context: TurnContext): - """Invoked when a conversation update activity is received from the channel when the base behavior of :meth:`ActivityHandler.on_turn()` is used. + """ + Invoked when a conversation update activity is received from the channel when the base behavior of :meth:`ActivityHandler.on_turn()` is used. :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` + :returns: A task that represents the work queued to execute - .. remarks:: + .. note:: When the :meth:'ActivityHandler.on_turn()` method receives a conversation update activity, it calls this method. If the conversation update activity indicates that members other than the bot joined the conversation, it calls the :meth:`ActivityHandler.on_members_added_activity()` method. @@ -103,7 +107,8 @@ async def on_conversation_update_activity(self, turn_context: TurnContext): async def on_members_added_activity( self, members_added: List[ChannelAccount], turn_context: TurnContext ): # pylint: disable=unused-argument - """Override this method in a derived class to provide logic for when members other than the bot join the conversation. + """ + Override this method in a derived class to provide logic for when members other than the bot join the conversation. You can add your bot's welcome logic. :param members_added: A list of all the members added to the conversation, as described by the conversation update activity @@ -113,7 +118,7 @@ async def on_members_added_activity( :returns: A task that represents the work queued to execute - .. remarks:: + .. note:: When the :meth:'ActivityHandler.on_conversation_update_activity()` method receives a conversation update activity that indicates one or more users other than the bot are joining the conversation, it calls this method. """ @@ -122,7 +127,8 @@ async def on_members_added_activity( async def on_members_removed_activity( self, members_removed: List[ChannelAccount], turn_context: TurnContext ): # pylint: disable=unused-argument - """Override this method in a derived class to provide logic for when members other than the bot leave the conversation. + """ + Override this method in a derived class to provide logic for when members other than the bot leave the conversation. You can add your bot's good-bye logic. :param members_added: A list of all the members removed from the conversation, as described by the conversation update activity @@ -132,7 +138,7 @@ async def on_members_removed_activity( :returns: A task that represents the work queued to execute - .. remarks:: + .. note:: When the :meth:'ActivityHandler.on_conversation_update_activity()` method receives a conversation update activity that indicates one or more users other than the bot are leaving the conversation, it calls this method. """ @@ -140,18 +146,20 @@ async def on_members_removed_activity( return async def on_message_reaction_activity(self, turn_context: TurnContext): - """Invoked when an event activity is received from the connector when the base behavior of :meth:'ActivityHandler.on_turn()` is used. - Message reactions correspond to the user adding a 'like' or 'sad' etc. (often an emoji) to a previously sent activity. - Message reactions are only supported by a few channels. The activity that the message reaction corresponds to is indicated in the - reply to Id property. The value of this property is the activity id of a previously sent activity given back to the bot as the response - from a send call. + """ + Invoked when an event activity is received from the connector when the base behavior of :meth:'ActivityHandler.on_turn()` is used. + :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` :returns: A task that represents the work queued to execute - .. remarks:: + .. note:: + Message reactions correspond to the user adding a 'like' or 'sad' etc. (often an emoji) to a previously sent activity. + Message reactions are only supported by a few channels. The activity that the message reaction corresponds to is indicated in the + reply to Id property. The value of this property is the activity id of a previously sent activity given back to the bot as the response + from a send call. When the :meth:'ActivityHandler.on_turn()` method receives a message reaction activity, it calls this method. If the message reaction indicates that reactions were added to a message, it calls :meth:'ActivityHandler.on_reaction_added(). If the message reaction indicates that reactions were removed from a message, it calls :meth:'ActivityHandler.on_reaction_removed(). @@ -172,7 +180,8 @@ async def on_message_reaction_activity(self, turn_context: TurnContext): async def on_reactions_added( # pylint: disable=unused-argument self, message_reactions: List[MessageReaction], turn_context: TurnContext ): - """Override this method in a derived class to provide logic for when reactions to a previous activity + """ + Override this method in a derived class to provide logic for when reactions to a previous activity are added to the conversation. :param message_reactions: The list of reactions added @@ -182,7 +191,7 @@ async def on_reactions_added( # pylint: disable=unused-argument :returns: A task that represents the work queued to execute - .. remarks:: + .. note:: Message reactions correspond to the user adding a 'like' or 'sad' etc. (often an emoji) to a previously sent message on the conversation. Message reactions are supported by only a few channels. The activity that the message is in reaction to is identified by the activity's reply to Id property. @@ -194,7 +203,8 @@ async def on_reactions_added( # pylint: disable=unused-argument async def on_reactions_removed( # pylint: disable=unused-argument self, message_reactions: List[MessageReaction], turn_context: TurnContext ): - """Override this method in a derived class to provide logic for when reactions to a previous activity + """ + Override this method in a derived class to provide logic for when reactions to a previous activity are removed from the conversation. :param message_reactions: The list of reactions removed @@ -204,7 +214,7 @@ async def on_reactions_removed( # pylint: disable=unused-argument :returns: A task that represents the work queued to execute - .. remarks:: + .. note:: Message reactions correspond to the user adding a 'like' or 'sad' etc. (often an emoji) to a previously sent message on the conversation. Message reactions are supported by only a few channels. The activity that the message is in reaction to is identified by the activity's reply to Id property. @@ -214,14 +224,15 @@ async def on_reactions_removed( # pylint: disable=unused-argument return async def on_event_activity(self, turn_context: TurnContext): - """Invoked when an event activity is received from the connector when the base behavior of :meth:'ActivityHandler.on_turn()` is used. + """ + Invoked when an event activity is received from the connector when the base behavior of :meth:'ActivityHandler.on_turn()` is used. :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` :returns: A task that represents the work queued to execute - .. remarks:: + .. note:: When the :meth:'ActivityHandler.on_turn()` method receives an event activity, it calls this method. If the activity name is `tokens/response`, it calls :meth:'ActivityHandler.on_token_response_event()`; otherwise, it calls :meth:'ActivityHandler.on_event()`. @@ -242,7 +253,8 @@ async def on_event_activity(self, turn_context: TurnContext): async def on_token_response_event( # pylint: disable=unused-argument self, turn_context: TurnContext ): - """Invoked when a `tokens/response` event is received when the base behavior of :meth:'ActivityHandler.on_event_activity()` is used. + """ + Invoked when a `tokens/response` event is received when the base behavior of :meth:'ActivityHandler.on_event_activity()` is used. If using an `oauth_prompt`, override this method to forward this activity to the current dialog. :param turn_context: The context object for this turn @@ -250,7 +262,7 @@ async def on_token_response_event( # pylint: disable=unused-argument :returns: A task that represents the work queued to execute - .. remarks:: + .. note:: When the :meth:'ActivityHandler.on_event()` method receives an event with an activity name of `tokens/response`, it calls this method. If your bot uses an `oauth_prompt`, forward the incoming activity to the current dialog. """ @@ -259,25 +271,28 @@ async def on_token_response_event( # pylint: disable=unused-argument async def on_event( # pylint: disable=unused-argument self, turn_context: TurnContext ): - """Invoked when an event other than `tokens/response` is received when the base behavior of + """ + Invoked when an event other than `tokens/response` is received when the base behavior of :meth:'ActivityHandler.on_event_activity()` is used. - This method could optionally be overridden if the bot is meant to handle miscellaneous events. + :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` :returns: A task that represents the work queued to execute - .. remarks:: + .. note:: When the :meth:'ActivityHandler.on_event_activity()` is used method receives an event with an activity name other than `tokens/response`, it calls this method. + This method could optionally be overridden if the bot is meant to handle miscellaneous events. """ return async def on_end_of_conversation_activity( # pylint: disable=unused-argument self, turn_context: TurnContext ): - """Invoked when a conversation end activity is received from the channel. + """ + Invoked when a conversation end activity is received from the channel. :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` @@ -288,7 +303,8 @@ async def on_end_of_conversation_activity( # pylint: disable=unused-argument async def on_unrecognized_activity_type( # pylint: disable=unused-argument self, turn_context: TurnContext ): - """Invoked when an activity other than a message, conversation update, or event is received when the base behavior of + """ + Invoked when an activity other than a message, conversation update, or event is received when the base behavior of :meth:`ActivityHandler.on_turn()` is used. If overridden, this method could potentially respond to any of the other activity types. @@ -297,7 +313,7 @@ async def on_unrecognized_activity_type( # pylint: disable=unused-argument :returns: A task that represents the work queued to execute - .. remarks:: + .. note:: When the :meth:`ActivityHandler.on_turn()` method receives an activity that is not a message, conversation update, message reaction, or event activity, it calls this method. """ From 33bc1a7097211e08e383d65c12555ca6d486bed2 Mon Sep 17 00:00:00 2001 From: Emily Olshefski Date: Tue, 28 Jan 2020 11:39:01 -0800 Subject: [PATCH 50/56] Fixed formatting --- .../botbuilder/dialogs/component_dialog.py | 3 --- .../botbuilder/dialogs/dialog_instance.py | 2 +- .../botbuilder/dialogs/dialog_state.py | 4 ++-- .../botbuilder/dialogs/prompts/activity_prompt.py | 10 +++++----- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py index b297443df..cddd8e00a 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py @@ -204,7 +204,6 @@ def add_dialog(self, dialog: Dialog) -> object: def find_dialog(self, dialog_id: str) -> Dialog: """ Finds a dialog by ID. - Adding a new dialog will inherit the :class:`BotTelemetryClient` of the :class:`ComponentDialog`. :param dialog_id: The dialog to add. :return: The dialog; or None if there is not a match for the ID. @@ -231,8 +230,6 @@ async def on_begin_dialog( :type inner_dc: :class:`DialogContext` :param options: Optional, initial information to pass to the dialog. :type options: object - :return: ? - :rtype: ? """ return await inner_dc.begin_dialog(self.initial_dialog_id, options) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py index e4aa2bf24..3d06d6205 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py @@ -16,7 +16,7 @@ def __init__(self): :var self.id: The ID of the dialog :vartype self.id: str :var self.state: The instance's persisted state. - :vartype self.state: Dict[str, object] + :vartype self.state: :class:`typing.Dict[str, object]` """ self.id: str = None # pylint: disable=invalid-name diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py index 218caf5d0..cf5cb1344 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py @@ -14,7 +14,7 @@ def __init__(self, stack: List[DialogInstance] = None): The new instance is created with an empty dialog stack. :param stack: The state information to initialize the stack with. - :type stack: List[:class:`DialogInstance`] + :type stack: :class:`typing.List[:class:`DialogInstance`]` """ if stack is None: self._dialog_stack = [] @@ -27,7 +27,7 @@ def dialog_stack(self): Initializes a new instance of the :class:`DialogState` class. :return: The state information to initialize the stack with. - :rtype: List + :rtype: list """ return self._dialog_stack diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py index 15f7f9cdc..dc255cd33 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py @@ -46,7 +46,7 @@ def __init__( :param dialog_id: Unique ID of the dialog within its parent :class:`DialogSet` or :class:`ComponentDialog`. :type dialog_id: str :param validator: Validator that will be called each time a new activity is received. - :type validator: Callable[[PromptValidatorContext], bool] + :type validator: :class:`typing.Callable[[:class:`PromptValidatorContext`], bool]` """ Dialog.__init__(self, dialog_id) @@ -191,8 +191,8 @@ async def on_prompt( :param dialog_context: The dialog context for the current turn of the conversation :type dialog_context: :class:`DialogContext` :param state: Additional state being persisted for the prompt. - :type state: Dict[str, dict] - :param options: Options that the prompt started with in the call to `DialogContext.prompt()`. + :type state: :class:`typing.Dict[str, dict]` + :param options: Options that the prompt started with in the call to :meth:`DialogContext.prompt()`. :type options: :class:`PromptOptions` :param isRetry: If `true` the users response wasn't recognized and the re-prompt should be sent. :type isRetry: bool @@ -213,10 +213,10 @@ async def on_recognize( # pylint: disable=unused-argument :param context: Context for the current turn of conversation with the user. :type context: :class:`TurnContext` :param state: Contains state for the current instance of the prompt on the dialog stack. - :type state: Dict[str, object] + :type state: :class:`typing.Dict[str, dict]` :param options: A prompt options object :type options: :class:`PromptOptions` - :return result: constructed from the options initially provided in the call to `async def on_prompt()` + :return result: constructed from the options initially provided in the call to :meth:`async def on_prompt()` :rtype result: :class:`PromptRecognizerResult` """ result = PromptRecognizerResult() From a9b37ec70b80f1ea817547d77d98c61cf5ef944c Mon Sep 17 00:00:00 2001 From: tracyboehrer Date: Tue, 28 Jan 2020 14:04:06 -0600 Subject: [PATCH 51/56] FIxed pylint errors --- .../botbuilder/dialogs/component_dialog.py | 31 +++++++++++-------- .../botbuilder/dialogs/dialog_turn_result.py | 22 +++++++------ 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py index cddd8e00a..6857ad5b4 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/component_dialog.py @@ -16,13 +16,14 @@ class ComponentDialog(Dialog): """ A :class:`Dialog` that is composed of other dialogs - + A component dialog has an inner :class:`DialogSet` :class:`DialogContext`, which provides an inner dialog stack that is hidden from the parent dialog. - + :var persisted_dialog state: :vartype persisted_dialog_state: str """ + persisted_dialog_state = "dialogs" def __init__(self, dialog_id: str): @@ -47,7 +48,7 @@ async def begin_dialog( ) -> DialogTurnResult: """ Called when the dialog is started and pushed onto the parent's dialog stack. - + If the task is successful, the result indicates whether the dialog is still active after the turn has been processed by the dialog. @@ -86,7 +87,7 @@ async def continue_dialog(self, dialog_context: DialogContext) -> DialogTurnResu active after the turn has been processed by the dialog. The result may also contain a return value. - If this method is *not* overriden the component dialog calls the + If this method is *not* overriden the component dialog calls the :meth:`DialogContext.continue_dialog` method on it's inner dialog context. If the inner dialog stack is empty, the component dialog ends, and if a :class:`DialogTurnResult.result` is available, the component dialog @@ -124,7 +125,7 @@ async def resume_dialog( :meth:resume_dialog() when the pushed on dialog ends. To avoid the container prematurely ending we need to implement this method and simply ask our inner dialog stack to re-prompt. - + If the task is successful, the result indicates whether this dialog is still active after this dialog turn has been processed. @@ -133,13 +134,14 @@ async def resume_dialog( is called, the logical child dialog may be different than the original. If this method is *not* overridden, the dialog automatically calls its - :meth:`asyn def reprompt_dialog()` when the user replies. + :meth:`asyn def reprompt_dialog()` when the user replies. :param dialog_context: The :class:`DialogContext` for the current turn of the conversation. :type dialog_context: :class:`DialogContext` :param reason: Reason why the dialog resumed. :type reason: :class:`DialogReason` - :param result: Optional, value returned from the dialog that was called. The type of the value returned is dependent on the child dialog. + :param result: Optional, value returned from the dialog that was called. The type of the + value returned is dependent on the child dialog. :type result: object :return: Signals the end of the turn :rtype: :class:`Dialog.end_of_turn` @@ -175,7 +177,8 @@ async def end_dialog( :param context: The context object for this turn. :type context: :class:`TurnContext` - :param instance: State information associated with the instance of this component dialog on its parent's dialog stack. + :param instance: State information associated with the instance of this component dialog + on its parent's dialog stack. :type instance: :class:`DialogInstance` :param reason: Reason why the dialog ended. :type reason: :class:`DialogReason` @@ -191,7 +194,7 @@ def add_dialog(self, dialog: Dialog) -> object: """ Adds a :class:`Dialog` to the component dialog and returns the updated component. Adding a new dialog will inherit the :class:`BotTelemetryClient` of the :class:`ComponentDialog`. - + :param dialog: The dialog to add. :return: The updated :class:`ComponentDialog` :rtype: :class:`ComponentDialog` @@ -204,7 +207,7 @@ def add_dialog(self, dialog: Dialog) -> object: def find_dialog(self, dialog_id: str) -> Dialog: """ Finds a dialog by ID. - + :param dialog_id: The dialog to add. :return: The dialog; or None if there is not a match for the ID. :rtype: :class:Dialog @@ -244,7 +247,8 @@ async def on_end_dialog( # pylint: disable=unused-argument :param turn_context: The :class:`TurnContext` for the current turn of the conversation. :type turn_context: :class:`TurnContext` - :param instance: State information associated with the instance of this component dialog on its parent's dialog stack. + :param instance: State information associated with the instance of this component dialog on + its parent's dialog stack. :type instance: :class:`DialogInstance` :param reason: Reason why the dialog ended. :type reason: :class:`DialogReason` @@ -257,7 +261,8 @@ async def on_reprompt_dialog( # pylint: disable=unused-argument """ :param turn_context: The :class:`TurnContext` for the current turn of the conversation. :type turn_context: :class:`DialogInstance` - :param instance: State information associated with the instance of this component dialog on its parent's dialog stack. + :param instance: State information associated with the instance of this component dialog + on its parent's dialog stack. :type instance: :class:`DialogInstance` """ return @@ -267,7 +272,7 @@ async def end_component( ) -> DialogTurnResult: """ Ends the component dialog in its parent's context. - + .. note:: If the task is successful, the result indicates that the dialog ended after the turn was processed by the dialog. diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py index d02ecaa4a..7fd1b5632 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_result.py @@ -3,23 +3,25 @@ from .dialog_turn_status import DialogTurnStatus + class DialogTurnResult: - """ + """ Result returned to the caller of one of the various stack manipulation methods. Use :meth:`DialogContext.end_dialogAsync()` to end a :class:`Dialog` and return a result to the calling context. """ + def __init__(self, status: DialogTurnStatus, result: object = None): - """ - :param status: The current status of the stack. - :type status: :class:`DialogTurnStatus` - :param result: The result returned by a dialog that was just ended. - :type result: object - """ + """ + :param status: The current status of the stack. + :type status: :class:`DialogTurnStatus` + :param result: The result returned by a dialog that was just ended. + :type result: object + """ self._status = status self._result = result - + @property def status(self): """ @@ -29,12 +31,12 @@ def status(self): :rtype self._status: :class:`DialogTurnStatus` """ return self._status - + @property def result(self): """ Final result returned by a dialog that just completed. - + .. note:: This will only be populated in certain cases: * The bot calls :meth:`DialogContext.begin_dialog()` to start a new dialog and the dialog ends immediately. From 9f722d26e67a4fb831bad8a64c7dd91304d31b0c Mon Sep 17 00:00:00 2001 From: tracyboehrer Date: Tue, 28 Jan 2020 14:22:01 -0600 Subject: [PATCH 52/56] pylint corrections in dialogs --- .../botbuilder/dialogs/dialog_instance.py | 8 +-- .../botbuilder/dialogs/dialog_reason.py | 5 +- .../botbuilder/dialogs/dialog_state.py | 6 +- .../dialogs/prompts/activity_prompt.py | 27 ++++---- .../dialogs/prompts/oauth_prompt.py | 57 +++++++++-------- .../botbuilder/dialogs/prompts/prompt.py | 62 ++++++++++--------- .../dialogs/prompts/prompt_options.py | 8 +-- 7 files changed, 93 insertions(+), 80 deletions(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py index 3d06d6205..add9e2dc6 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_instance.py @@ -10,7 +10,7 @@ class DialogInstance: """ def __init__(self): - """ + """ Gets or sets the ID of the dialog and gets or sets the instance's persisted state. :var self.id: The ID of the dialog @@ -24,9 +24,9 @@ def __init__(self): def __str__(self): """ - Gets or sets a stack index. - - :return: Returns stack index. + Gets or sets a stack index. + + :return: Returns stack index. :rtype: str """ result = "\ndialog_instance_id: %s\n" % self.id diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py index fa24bc3ea..a017a33df 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py @@ -2,10 +2,11 @@ # Licensed under the MIT License. from enum import Enum + class DialogReason(Enum): - """ + """ Indicates in which a dialog-related method is being called. - + :var BeginCalled: A dialog is being started through a call to `DialogContext.begin()`. :vartype BeginCalled: int :var ContinuCalled: A dialog is being continued through a call to `DialogContext.continue_dialog()`. diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py index cf5cb1344..940ee73ff 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_state.py @@ -4,15 +4,17 @@ from typing import List from .dialog_instance import DialogInstance + class DialogState: """ Contains state information for the dialog stack. """ + def __init__(self, stack: List[DialogInstance] = None): """ Initializes a new instance of the :class:`DialogState` class. The new instance is created with an empty dialog stack. - + :param stack: The state information to initialize the stack with. :type stack: :class:`typing.List[:class:`DialogInstance`]` """ @@ -25,7 +27,7 @@ def __init__(self, stack: List[DialogInstance] = None): def dialog_stack(self): """ Initializes a new instance of the :class:`DialogState` class. - + :return: The state information to initialize the stack with. :rtype: list """ diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py index dc255cd33..db0e87e01 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/activity_prompt.py @@ -19,6 +19,7 @@ from .prompt_recognizer_result import PromptRecognizerResult from .prompt_validator_context import PromptValidatorContext + class ActivityPrompt(Dialog, ABC): """ Waits for an activity to be received. @@ -64,7 +65,7 @@ async def begin_dialog( :type dialog_context: :class:`DialogContext` :param options: Optional, additional information to pass to the prompt being started. :type options: :class:`PromptOptions` - :return Dialog.end_of_turn: + :return Dialog.end_of_turn: :rtype Dialog.end_of_turn: :class:`Dialog.DialogTurnResult` """ if not dialog_context: @@ -97,15 +98,15 @@ async def begin_dialog( return Dialog.end_of_turn async def continue_dialog(self, dialog_context: DialogContext) -> DialogTurnResult: + """ + Called when a prompt dialog is the active dialog and the user replied with a new activity. + + :param dialog_context: The dialog context for the current turn of the conversation. + :type dialog_context: :class:`DialogContext` + :return Dialog.end_of_turn: + :rtype Dialog.end_of_turn: :class:`Dialog.DialogTurnResult` + """ if not dialog_context: - """ - Called when a prompt dialog is the active dialog and the user replied with a new activity. - - :param dialog_context: The dialog context for the current turn of the conversation. - :type dialog_context: :class:`DialogContext` - :return Dialog.end_of_turn: - :rtype Dialog.end_of_turn: :class:`Dialog.DialogTurnResult` - """ raise TypeError( "ActivityPrompt.continue_dialog(): DialogContext cannot be None." ) @@ -152,21 +153,21 @@ async def resume_dialog( # pylint: disable=unused-argument self, dialog_context: DialogContext, reason: DialogReason, result: object = None ): """ - Called when a prompt dialog resumes being the active dialog on the dialog stack, such + Called when a prompt dialog resumes being the active dialog on the dialog stack, such as when the previous active dialog on the stack completes. - + .. note: Prompts are typically leaf nodes on the stack but the dev is free to push other dialogs on top of the stack which will result in the prompt receiving an unexpected call to :meth:resume_dialog() when the pushed on dialog ends. To avoid the prompt prematurely ending, we need to implement this method and simply re-prompt the user. - + :param dialog_context: The dialog context for the current turn of the conversation :type dialog_context: :class:`DialogContext` :param reason: An enum indicating why the dialog resumed. :type reason: :class:`DialogReason` - :param result: Optional, value returned from the previous dialog on the stack. + :param result: Optional, value returned from the previous dialog on the stack. :type result: object """ await self.reprompt_dialog(dialog_context.context, dialog_context.active_dialog) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/oauth_prompt.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/oauth_prompt.py index b6f726689..736637d30 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/oauth_prompt.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/oauth_prompt.py @@ -5,6 +5,8 @@ from datetime import datetime, timedelta from typing import Union, Awaitable, Callable +from botframework.connector import Channels +from botframework.connector.auth import ClaimsIdentity, SkillValidation from botbuilder.core import ( CardFactory, MessageFactory, @@ -23,8 +25,6 @@ OAuthCard, TokenResponse, ) -from botframework.connector import Channels -from botframework.connector.auth import ClaimsIdentity, SkillValidation from .prompt_options import PromptOptions from .oauth_prompt_settings import OAuthPromptSettings from .prompt_validator_context import PromptValidatorContext @@ -46,8 +46,8 @@ class OAuthPrompt(Dialog): standard `message` activity. Both flows are automatically supported by the `OAuthPrompt` and they only thing you need to be careful of is that you don't block the `event` and `invoke` activities that the prompt might be waiting on. - - .. note:: + + .. note:: You should avoid persisting the access token with your bots other state. The Bot Frameworks SSO service will securely store the token on your behalf. If you store it in your bots state, it could expire or be revoked in between turns. @@ -55,30 +55,35 @@ class OAuthPrompt(Dialog): following the prompt and then let the token go out of scope at the end of your function. **Prompt Usage** - When used with your bots :class:`DialogSet`, you can simply add a new instance of the prompt as a named dialog using + When used with your bots :class:`DialogSet`, you can simply add a new instance of the prompt as a named + dialog using :meth`DialogSet.add()`. - You can then start the prompt from a waterfall step using either :meth:`DialogContext.begin()` or :meth:`DialogContext.prompt()`. - The user will be prompted to sign in as needed and their access token will be passed as an argument to the callers - next waterfall step. + You can then start the prompt from a waterfall step using either :meth:`DialogContext.begin()` or + :meth:`DialogContext.prompt()`. + The user will be prompted to sign in as needed and their access token will be passed as an argument to + the callers next waterfall step. """ + def __init__( self, dialog_id: str, settings: OAuthPromptSettings, validator: Callable[[PromptValidatorContext], Awaitable[bool]] = None, ): - """ + """ Creates a new instance of the :class:`OAuthPrompt` class. :param dialogId: The Id to assign to this prompt. :type dialogId: str :param settings: Additional authentication settings to use with this instance of the prompt :type settings: :class:`OAuthPromptSettings` - :param validator: Optional, a :class:`PromptValidator` that contains additional, custom validation for this prompt + :param validator: Optional, a :class:`PromptValidator` that contains additional, custom validation + for this prompt :type validator: :class:`PromptValidatorContext` - .. note:: - The value of :param dialogId: must be unique within the :class:`DialogSet`or :class:`ComponentDialog` to which the prompt is added. + .. note:: + The value of :param dialogId: must be unique within the :class:`DialogSet`or :class:`ComponentDialog` + to which the prompt is added. """ super().__init__(dialog_id) self._validator = validator @@ -95,7 +100,8 @@ async def begin_dialog( self, dialog_context: DialogContext, options: PromptOptions = None ) -> DialogTurnResult: """ - Starts an authentication prompt dialog. Called when an authentication prompt dialog is pushed onto the dialog stack and is being activated. + Starts an authentication prompt dialog. Called when an authentication prompt dialog is pushed onto the + dialog stack and is being activated. :param dialog_context: The dialog context for the current turn of the conversation :type dialog_context: :class:`DialogContext` @@ -104,8 +110,9 @@ async def begin_dialog( :return: Dialog turn result :rtype: :class:DialogTurnResult - .. note:: - If the task is successful, the result indicates whether the prompt is still active after the turn has been processed by the prompt. + .. note:: + If the task is successful, the result indicates whether the prompt is still active after the turn + has been processed by the prompt. """ if dialog_context is None: raise TypeError( @@ -148,15 +155,15 @@ async def begin_dialog( return Dialog.end_of_turn async def continue_dialog(self, dialog_context: DialogContext) -> DialogTurnResult: - """ + """ Continues a dialog. Called when a prompt dialog is the active dialog and the user replied with a new activity. :param dialog_context: The dialog context for the current turn of the conversation - :type dialog_context: :class:`DialogContext` + :type dialog_context: :class:`DialogContext` :return: Dialog turn result :rtype: :class:DialogTurnResult - .. note:: + .. note:: If the task is successful, the result indicates whether the dialog is still active after the turn has been processed by the dialog. The prompt generally continues to receive the user's replies until it accepts the @@ -209,15 +216,15 @@ async def continue_dialog(self, dialog_context: DialogContext) -> DialogTurnResu async def get_user_token( self, context: TurnContext, code: str = None ) -> TokenResponse: - """ + """ Gets the user's tokeN. :param context: Context for the current turn of conversation with the user - :type context: :class:TurnContext + :type context: :class:TurnContext :return: A response that includes the user's token - :rtype: :class:TokenResponse + :rtype: :class:TokenResponse - .. note:: + .. note:: If the task is successful and the user already has a token or the user successfully signs in, the result contains the user's token. """ @@ -238,11 +245,11 @@ async def sign_out_user(self, context: TurnContext): Signs out the user :param context: Context for the current turn of conversation with the user - :type context: :class:`TurnContext` + :type context: :class:`TurnContext` :return: A :class:`Task` representing the work queued to execute - :rtype: :class:`Task` + :rtype: :class:`Task` - .. note:: + .. note:: If the task is successful and the user already has a token or the user successfully signs in, the result contains the user's token. """ diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py index 842c606f1..e1df46e6f 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py @@ -26,15 +26,16 @@ class Prompt(Dialog): """ Defines the core behavior of prompt dialogs. Extends the :class:`Dialog` base class. - .. remarks:: + .. remarks:: When the prompt ends, it returns an object that represents the value it was prompted for. - Use :method:`DialogSet.add()` or :method:`ComponentDialog.add_dialog()` to add a prompt to a dialog set or + Use :method:`DialogSet.add()` or :method:`ComponentDialog.add_dialog()` to add a prompt to a dialog set or component dialog, respectively. Use :method:`DialogContext.prompt()` or :meth:`DialogContext.begin_dialog()` to start the prompt. .. note:: - If you start a prompt from a :class:`WaterfallStep` in a :class:`WaterfallDialog`, then the prompt result will be - available in the next step of the waterfall. + If you start a prompt from a :class:`WaterfallStep` in a :class:`WaterfallDialog`, then the prompt result + will be available in the next step of the waterfall. """ + ATTEMPT_COUNT_KEY = "AttemptCount" persisted_options = "options" persisted_state = "state" @@ -46,7 +47,8 @@ def __init__(self, dialog_id: str, validator: object = None): :param dialog_id: Unique Id of the prompt within its parent :class:`DialogSet` or :class:`ComponentDialog`. :type dialog_id: str - :param validator: Optional custom validator used to provide additional validation and re-prompting logic for the prompt. + :param validator: Optional custom validator used to provide additional validation and re-prompting + logic for the prompt. :type validator: Object """ super(Prompt, self).__init__(dialog_id) @@ -56,7 +58,7 @@ def __init__(self, dialog_id: str, validator: object = None): async def begin_dialog( self, dialog_context: DialogContext, options: object = None ) -> DialogTurnResult: - """ + """ Starts a prompt dialog. Called when a prompt dialog is pushed onto the dialog stack and is being activated. :param dialog_context: The dialog context for the current turn of the conversation @@ -66,8 +68,8 @@ async def begin_dialog( :return: The dialog turn result :rtype: :class:`DialogTurnResult` - .. note:: - If the task is successful, the result indicates whether the prompt is still active + .. note:: + If the task is successful, the result indicates whether the prompt is still active after the turn has been processed by the prompt. """ if not dialog_context: @@ -97,15 +99,15 @@ async def begin_dialog( return Dialog.end_of_turn async def continue_dialog(self, dialog_context: DialogContext): - """ + """ Continues a dialog. Called when a prompt dialog is the active dialog and the user replied with a new activity. :param dialog_context: The dialog context for the current turn of the conversation - :type dialog_context: :class:`DialogContext` + :type dialog_context: :class:`DialogContext` :return: The dialog turn result :rtype: :class:`DialogTurnResult` - .. note:: + .. note:: If the task is successful, the result indicates whether the dialog is still active after the turn has been processed by the dialog. The prompt generally continues to receive the user's replies until it accepts the @@ -148,17 +150,17 @@ async def continue_dialog(self, dialog_context: DialogContext): async def resume_dialog( self, dialog_context: DialogContext, reason: DialogReason, result: object ) -> DialogTurnResult: - """ - Resumes a dialog. Called when a prompt dialog resumes being the active dialog + """ + Resumes a dialog. Called when a prompt dialog resumes being the active dialog on the dialog stack, such as when the previous active dialog on the stack completes. :param dialog_context: The dialog context for the current turn of the conversation. - :type dialog_context: :class:DialogContext + :type dialog_context: :class:DialogContext :param reason: An enum indicating why the dialog resumed. - :type reason: :class:DialogReason - :param result: Optional, value returned from the previous dialog on the stack. + :type reason: :class:DialogReason + :param result: Optional, value returned from the previous dialog on the stack. The type of the value returned is dependent on the previous dialog. - :type result: object + :type result: object :return: The dialog turn result :rtype: :class:`DialogTurnResult` @@ -174,13 +176,13 @@ async def resume_dialog( return Dialog.end_of_turn async def reprompt_dialog(self, context: TurnContext, instance: DialogInstance): - """ + """ Reprompts user for input. Called when a prompt dialog has been requested to re-prompt the user for input. :param context: Context for the current turn of conversation with the user - :type context: :class:TurnContext + :type context: :class:TurnContext :param instance: The instance of the dialog on the stack - :type instance: :class:DialogInstance + :type instance: :class:DialogInstance :return: A :class:Task representing the asynchronous operation :rtype: :class:Task """ @@ -196,19 +198,19 @@ async def on_prompt( options: PromptOptions, is_retry: bool, ): - """ + """ Prompts user for input. When overridden in a derived class, prompts the user for input. :param turn_context: Context for the current turn of conversation with the user - :type turn_context: :class:`TurnContext` + :type turn_context: :class:`TurnContext` :param state: Contains state for the current instance of the prompt on the dialog stack :type state: :class:Dict :param options: A prompt options object constructed from the options initially provided in the call :meth:`DialogContext.prompt(self, dialog_id: str, options)` - :type options: :class:`PromptOptions` - :param is_retry: true if this is the first time this prompt dialog instance on the stack is prompting + :type options: :class:`PromptOptions` + :param is_retry: true if this is the first time this prompt dialog instance on the stack is prompting the user for input; otherwise, false - :type is_retry: bool + :type is_retry: bool :return: A :class:Task representing the asynchronous operation. :rtype: :class:Task @@ -222,16 +224,16 @@ async def on_recognize( state: Dict[str, object], options: PromptOptions, ): - """ + """ Recognizes the user's input. When overridden in a derived class, attempts to recognize the user's input. :param turn_context: Context for the current turn of conversation with the user - :type turn_context: :class:`TurnContext` + :type turn_context: :class:`TurnContext` :param state: Contains state for the current instance of the prompt on the dialog stack :type state: :class:Dict :param options: A prompt options object constructed from the options initially provided in the call :meth:`DialogContext.prompt(self, dialog_id: str, options)` - :type options: :class:PromptOptions + :type options: :class:PromptOptions :return: A :class:Task representing the asynchronous operation. :rtype: :class:Task @@ -246,13 +248,13 @@ def append_choices( style: ListStyle, options: ChoiceFactoryOptions = None, ) -> Activity: - """ + """ Composes an output activity containing a set of choices. When overridden in a derived class, appends choices to the activity when the user is prompted for input. Helper function to compose an output activity containing a set of choices. :param prompt: The prompt to append the user's choice to - :type prompt: + :type prompt: :param channel_id: Id of the channel the prompt is being sent to :type channel_id: str :param: choices: List of choices to append diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt_options.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt_options.py index ea0c74825..c341a4b52 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt_options.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt_options.py @@ -8,7 +8,7 @@ class PromptOptions: - """ + """ Contains settings to pass to a :class:`Prompt` object when the prompt is started. """ @@ -21,7 +21,7 @@ def __init__( validations: object = None, number_of_attempts: int = 0, ): - """ + """ Sets the initial prompt to send to the user as an :class:`botbuilder.schema.Activity`. :param prompt: The initial prompt to send to the user @@ -32,11 +32,11 @@ def __init__( :type choices: :class:`List` :param style: The style of the list of choices to send to the user :type style: :class:`ListStyle` - :param validations: The prompt validations + :param validations: The prompt validations :type validations: :class:`Object` :param number_of_attempts: The number of attempts allowed :type number_of_attempts: :class:`int` - + """ self.prompt = prompt self.retry_prompt = retry_prompt From 60a274d41a83cbdcd1222da39c96c8e228d6513c Mon Sep 17 00:00:00 2001 From: tracyboehrer Date: Tue, 28 Jan 2020 14:29:35 -0600 Subject: [PATCH 53/56] pylint corrections in core --- .../botbuilder/core/activity_handler.py | 108 ++++++------ .../botbuilder/core/bot_framework_adapter.py | 158 +++++++++--------- .../botbuilder/core/bot_state.py | 28 ++-- .../botbuilder/core/conversation_state.py | 12 +- 4 files changed, 153 insertions(+), 153 deletions(-) diff --git a/libraries/botbuilder-core/botbuilder/core/activity_handler.py b/libraries/botbuilder-core/botbuilder/core/activity_handler.py index 54a16c056..5fe2ac086 100644 --- a/libraries/botbuilder-core/botbuilder/core/activity_handler.py +++ b/libraries/botbuilder-core/botbuilder/core/activity_handler.py @@ -8,24 +8,24 @@ class ActivityHandler: async def on_turn(self, turn_context: TurnContext): - """ - Called by the adapter (for example, :class:`BotFrameworkAdapter`) at runtime - in order to process an inbound :class:`botbuilder.schema.Activity`. - - :param turn_context: The context object for this turn - :type turn_context: :class:`TurnContext` - - :returns: A task that represents the work queued to execute - - .. remarks:: - It calls other methods in this class based on the type of the activity to - process, which allows a derived class to provide type-specific logic in a controlled way. - In a derived class, override this method to add logic that applies to all activity types. - - .. note:: - - Add logic to apply before the type-specific logic and before the call to the :meth:`ActivityHandler.on_turn()` method. - - Add logic to apply after the type-specific logic after the call to the :meth:`ActivityHandler.on_turn()` method. - """ + """ + Called by the adapter (for example, :class:`BotFrameworkAdapter`) at runtime + in order to process an inbound :class:`botbuilder.schema.Activity`. + + :param turn_context: The context object for this turn + :type turn_context: :class:`TurnContext` + + :returns: A task that represents the work queued to execute + + .. remarks:: + It calls other methods in this class based on the type of the activity to + process, which allows a derived class to provide type-specific logic in a controlled way. + In a derived class, override this method to add logic that applies to all activity types. + + .. note:: + - Add logic to apply before the type-specific logic and before the call to the :meth:`ActivityHandler.on_turn()` method. + - Add logic to apply after the type-specific logic after the call to the :meth:`ActivityHandler.on_turn()` method. + """ if turn_context is None: raise TypeError("ActivityHandler.on_turn(): turn_context cannot be None.") @@ -59,9 +59,9 @@ async def on_message_activity( # pylint: disable=unused-argument self, turn_context: TurnContext ): """ - Override this method in a derived class to provide logic specific to activities, + Override this method in a derived class to provide logic specific to activities, such as the conversational logic. - + :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` @@ -73,7 +73,7 @@ async def on_message_activity( # pylint: disable=unused-argument async def on_conversation_update_activity(self, turn_context: TurnContext): """ Invoked when a conversation update activity is received from the channel when the base behavior of :meth:`ActivityHandler.on_turn()` is used. - + :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` @@ -81,9 +81,9 @@ async def on_conversation_update_activity(self, turn_context: TurnContext): .. note:: When the :meth:'ActivityHandler.on_turn()` method receives a conversation update activity, it calls this method. - If the conversation update activity indicates that members other than the bot joined the conversation, + If the conversation update activity indicates that members other than the bot joined the conversation, it calls the :meth:`ActivityHandler.on_members_added_activity()` method. - If the conversation update activity indicates that members other than the bot left the conversation, + If the conversation update activity indicates that members other than the bot left the conversation, it calls the :meth:`ActivityHandler.on_members_removed_activity()` method. In a derived class, override this method to add logic that applies to all conversation update activities. Add logic to apply before the member added or removed logic before the call to this base class method. @@ -110,7 +110,7 @@ async def on_members_added_activity( """ Override this method in a derived class to provide logic for when members other than the bot join the conversation. You can add your bot's welcome logic. - + :param members_added: A list of all the members added to the conversation, as described by the conversation update activity :type members_added: :class:`typing.List` :param turn_context: The context object for this turn @@ -119,7 +119,7 @@ async def on_members_added_activity( :returns: A task that represents the work queued to execute .. note:: - When the :meth:'ActivityHandler.on_conversation_update_activity()` method receives a conversation update activity that indicates + When the :meth:'ActivityHandler.on_conversation_update_activity()` method receives a conversation update activity that indicates one or more users other than the bot are joining the conversation, it calls this method. """ return @@ -130,7 +130,7 @@ async def on_members_removed_activity( """ Override this method in a derived class to provide logic for when members other than the bot leave the conversation. You can add your bot's good-bye logic. - + :param members_added: A list of all the members removed from the conversation, as described by the conversation update activity :type members_added: :class:`typing.List` :param turn_context: The context object for this turn @@ -139,7 +139,7 @@ async def on_members_removed_activity( :returns: A task that represents the work queued to execute .. note:: - When the :meth:'ActivityHandler.on_conversation_update_activity()` method receives a conversation update activity that indicates + When the :meth:'ActivityHandler.on_conversation_update_activity()` method receives a conversation update activity that indicates one or more users other than the bot are leaving the conversation, it calls this method. """ @@ -148,24 +148,24 @@ async def on_members_removed_activity( async def on_message_reaction_activity(self, turn_context: TurnContext): """ Invoked when an event activity is received from the connector when the base behavior of :meth:'ActivityHandler.on_turn()` is used. - - + + :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` :returns: A task that represents the work queued to execute .. note:: - Message reactions correspond to the user adding a 'like' or 'sad' etc. (often an emoji) to a previously sent activity. - Message reactions are only supported by a few channels. The activity that the message reaction corresponds to is indicated in the - reply to Id property. The value of this property is the activity id of a previously sent activity given back to the bot as the response + Message reactions correspond to the user adding a 'like' or 'sad' etc. (often an emoji) to a previously sent activity. + Message reactions are only supported by a few channels. The activity that the message reaction corresponds to is indicated in the + reply to Id property. The value of this property is the activity id of a previously sent activity given back to the bot as the response from a send call. When the :meth:'ActivityHandler.on_turn()` method receives a message reaction activity, it calls this method. If the message reaction indicates that reactions were added to a message, it calls :meth:'ActivityHandler.on_reaction_added(). If the message reaction indicates that reactions were removed from a message, it calls :meth:'ActivityHandler.on_reaction_removed(). In a derived class, override this method to add logic that applies to all message reaction activities. Add logic to apply before the reactions added or removed logic before the call to the this base class method. - Add logic to apply after the reactions added or removed logic after the call to the this base class method. + Add logic to apply after the reactions added or removed logic after the call to the this base class method. """ if turn_context.activity.reactions_added is not None: await self.on_reactions_added( @@ -181,9 +181,9 @@ async def on_reactions_added( # pylint: disable=unused-argument self, message_reactions: List[MessageReaction], turn_context: TurnContext ): """ - Override this method in a derived class to provide logic for when reactions to a previous activity + Override this method in a derived class to provide logic for when reactions to a previous activity are added to the conversation. - + :param message_reactions: The list of reactions added :type message_reactions: :class:`typing.List` :param turn_context: The context object for this turn @@ -192,10 +192,10 @@ async def on_reactions_added( # pylint: disable=unused-argument :returns: A task that represents the work queued to execute .. note:: - Message reactions correspond to the user adding a 'like' or 'sad' etc. (often an emoji) + Message reactions correspond to the user adding a 'like' or 'sad' etc. (often an emoji) to a previously sent message on the conversation. Message reactions are supported by only a few channels. - The activity that the message is in reaction to is identified by the activity's reply to Id property. - The value of this property is the activity ID of a previously sent activity. When the bot sends an activity, + The activity that the message is in reaction to is identified by the activity's reply to Id property. + The value of this property is the activity ID of a previously sent activity. When the bot sends an activity, the channel assigns an ID to it, which is available in the resource response Id of the result. """ return @@ -204,9 +204,9 @@ async def on_reactions_removed( # pylint: disable=unused-argument self, message_reactions: List[MessageReaction], turn_context: TurnContext ): """ - Override this method in a derived class to provide logic for when reactions to a previous activity + Override this method in a derived class to provide logic for when reactions to a previous activity are removed from the conversation. - + :param message_reactions: The list of reactions removed :type message_reactions: :class:`typing.List` :param turn_context: The context object for this turn @@ -215,10 +215,10 @@ async def on_reactions_removed( # pylint: disable=unused-argument :returns: A task that represents the work queued to execute .. note:: - Message reactions correspond to the user adding a 'like' or 'sad' etc. (often an emoji) + Message reactions correspond to the user adding a 'like' or 'sad' etc. (often an emoji) to a previously sent message on the conversation. Message reactions are supported by only a few channels. - The activity that the message is in reaction to is identified by the activity's reply to Id property. - The value of this property is the activity ID of a previously sent activity. When the bot sends an activity, + The activity that the message is in reaction to is identified by the activity's reply to Id property. + The value of this property is the activity ID of a previously sent activity. When the bot sends an activity, the channel assigns an ID to it, which is available in the resource response Id of the result. """ return @@ -226,7 +226,7 @@ async def on_reactions_removed( # pylint: disable=unused-argument async def on_event_activity(self, turn_context: TurnContext): """ Invoked when an event activity is received from the connector when the base behavior of :meth:'ActivityHandler.on_turn()` is used. - + :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` @@ -235,14 +235,14 @@ async def on_event_activity(self, turn_context: TurnContext): .. note:: When the :meth:'ActivityHandler.on_turn()` method receives an event activity, it calls this method. If the activity name is `tokens/response`, it calls :meth:'ActivityHandler.on_token_response_event()`; - otherwise, it calls :meth:'ActivityHandler.on_event()`. - + otherwise, it calls :meth:'ActivityHandler.on_event()`. + In a derived class, override this method to add logic that applies to all event activities. Add logic to apply before the specific event-handling logic before the call to this base class method. Add logic to apply after the specific event-handling logic after the call to this base class method. - + Event activities communicate programmatic information from a client or channel to a bot. - The meaning of an event activity is defined by the event activity name property, which is meaningful within + The meaning of an event activity is defined by the event activity name property, which is meaningful within the scope of a channel. """ if turn_context.activity.name == "tokens/response": @@ -256,7 +256,7 @@ async def on_token_response_event( # pylint: disable=unused-argument """ Invoked when a `tokens/response` event is received when the base behavior of :meth:'ActivityHandler.on_event_activity()` is used. If using an `oauth_prompt`, override this method to forward this activity to the current dialog. - + :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` @@ -274,15 +274,15 @@ async def on_event( # pylint: disable=unused-argument """ Invoked when an event other than `tokens/response` is received when the base behavior of :meth:'ActivityHandler.on_event_activity()` is used. - - + + :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` :returns: A task that represents the work queued to execute .. note:: - When the :meth:'ActivityHandler.on_event_activity()` is used method receives an event with an + When the :meth:'ActivityHandler.on_event_activity()` is used method receives an event with an activity name other than `tokens/response`, it calls this method. This method could optionally be overridden if the bot is meant to handle miscellaneous events. """ @@ -293,7 +293,7 @@ async def on_end_of_conversation_activity( # pylint: disable=unused-argument ): """ Invoked when a conversation end activity is received from the channel. - + :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` :returns: A task that represents the work queued to execute @@ -307,7 +307,7 @@ async def on_unrecognized_activity_type( # pylint: disable=unused-argument Invoked when an activity other than a message, conversation update, or event is received when the base behavior of :meth:`ActivityHandler.on_turn()` is used. If overridden, this method could potentially respond to any of the other activity types. - + :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` diff --git a/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py b/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py index a717051e7..cf2c8032d 100644 --- a/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py +++ b/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py @@ -7,15 +7,7 @@ import os from typing import List, Callable, Awaitable, Union, Dict from msrest.serialization import Model -from botbuilder.schema import ( - Activity, - ActivityTypes, - ConversationAccount, - ConversationParameters, - ConversationReference, - TokenResponse, - ResourceResponse, -) + from botframework.connector import Channels, EmulatorApiClient from botframework.connector.aio import ConnectorClient from botframework.connector.auth import ( @@ -33,6 +25,15 @@ ) from botframework.connector.token_api import TokenApiClient from botframework.connector.token_api.models import TokenStatus +from botbuilder.schema import ( + Activity, + ActivityTypes, + ConversationAccount, + ConversationParameters, + ConversationReference, + TokenResponse, + ResourceResponse, +) from . import __version__ from .bot_adapter import BotAdapter @@ -83,29 +84,28 @@ def __init__( channel_provider: ChannelProvider = None, auth_configuration: AuthenticationConfiguration = None, ): - """ - Contains the settings used to initialize a :class:`BotFrameworkAdapter` instance. - - :param app_id: The bot application ID. This is the appId returned by the Azure portal registration, and is - the value of the `MicrosoftAppId` parameter in the `config.py` file. - :type app_id: str - :param app_password: The bot application password. This is the password returned by the Azure portal registration, and is - the value os the `MicrosoftAppPassword` parameter in the `config.py` file. - :type app_password: str - :param channel_auth_tenant: The channel tenant to use in conversation - :type channel_auth_tenant: str - :param oauth_endpoint: - :type oauth_endpoint: str - :param open_id_metadata: - :type open_id_metadata: str - :param channel_service: - :type channel_service: str - :param channel_provider: The channel provider - :type channel_provider: :class:`botframework.connector.auth.ChannelProvider` - :param auth_configuration: - :type auth_configuration: :class:`botframework.connector.auth.AuthenticationConfiguration` - - """ + """ + Contains the settings used to initialize a :class:`BotFrameworkAdapter` instance. + + :param app_id: The bot application ID. This is the appId returned by the Azure portal registration, and is + the value of the `MicrosoftAppId` parameter in the `config.py` file. + :type app_id: str + :param app_password: The bot application password. This is the password returned by the Azure portal registration, and is + the value os the `MicrosoftAppPassword` parameter in the `config.py` file. + :type app_password: str + :param channel_auth_tenant: The channel tenant to use in conversation + :type channel_auth_tenant: str + :param oauth_endpoint: + :type oauth_endpoint: str + :param open_id_metadata: + :type open_id_metadata: str + :param channel_service: + :type channel_service: str + :param channel_provider: The channel provider + :type channel_provider: :class:`botframework.connector.auth.ChannelProvider` + :param auth_configuration: + :type auth_configuration: :class:`botframework.connector.auth.AuthenticationConfiguration` + """ self.app_id = app_id self.app_password = app_password self.channel_auth_tenant = channel_auth_tenant @@ -121,20 +121,20 @@ class BotFrameworkAdapter(BotAdapter, UserTokenProvider): Defines an adapter to connect a bot to a service endpoint. .. remarks:: - The bot adapter encapsulates authentication processes and sends activities to and - receives activities from the Bot Connector Service. When your bot receives an activity, - the adapter creates a context object, passes it to your bot's application logic, and - sends responses back to the user's channel. - The adapter processes and directs incoming activities in through the bot middleware - pipeline to your bot’s logic and then back out again. - As each activity flows in and out of the bot, each piece of middleware can inspect or act + The bot adapter encapsulates authentication processes and sends activities to and + receives activities from the Bot Connector Service. When your bot receives an activity, + the adapter creates a context object, passes it to your bot's application logic, and + sends responses back to the user's channel. + The adapter processes and directs incoming activities in through the bot middleware + pipeline to your bot’s logic and then back out again. + As each activity flows in and out of the bot, each piece of middleware can inspect or act upon the activity, both before and after the bot logic runs. """ _INVOKE_RESPONSE_KEY = "BotFrameworkAdapter.InvokeResponse" def __init__(self, settings: BotFrameworkAdapterSettings): - """ + """ Initializes a new instance of the :class:`BotFrameworkAdapter` class. :param settings: The settings to initialize the adapter @@ -184,25 +184,25 @@ async def continue_conversation( claims_identity: ClaimsIdentity = None, # pylint: disable=unused-argument ): """ - Continues a conversation with a user. + Continues a conversation with a user. :param reference: A reference to the conversation to continue - :type reference: :class:`botbuilder.schema.ConversationReference + :type reference: :class:`botbuilder.schema.ConversationReference :param callback: The method to call for the resulting bot turn :type callback: :class:`typing.Callable` - :param bot_id: The application Id of the bot. This is the appId returned by the Azure portal registration, + :param bot_id: The application Id of the bot. This is the appId returned by the Azure portal registration, and is generally found in the `MicrosoftAppId` parameter in `config.py`. :type bot_id: :class:`typing.str` :param claims_identity: The bot claims identity :type claims_identity: :class:`botframework.connector.auth.ClaimsIdentity` :raises: It raises an argument null exception. - + :return: A task that represents the work queued to execute. - + .. note:: - This is often referred to as the bots *proactive messaging* flow as it lets the bot proactively - send messages to a conversation or user that are already in a communication. + This is often referred to as the bots *proactive messaging* flow as it lets the bot proactively + send messages to a conversation or user that are already in a communication. Scenarios such as sending notifications or coupons to a user are enabled by this function. """ # TODO: proactive messages @@ -233,9 +233,9 @@ async def create_conversation( Starts a new conversation with a user. Used to direct message to a member of a group. :param reference: The conversation reference that contains the tenant - :type reference: :class:`botbuilder.schema.ConversationReference` + :type reference: :class:`botbuilder.schema.ConversationReference` :param logic: The logic to use for the creation of the conversation - :type logic: :class:`typing.Callable` + :type logic: :class:`typing.Callable` :param conversation_parameters: The information to use to create the conversation :type conversation_parameters: @@ -244,7 +244,7 @@ async def create_conversation( :return: A task representing the work queued to execute. .. note:: - To start a conversation, your bot must know its account information and the user's + To start a conversation, your bot must know its account information and the user's account information on that channel. Most channels only support initiating a direct message (non-group) conversation. The adapter attempts to create a new conversation on the channel, and @@ -309,17 +309,17 @@ async def process_activity(self, req, auth_header: str, logic: Callable): :param req: The incoming activity :type req: :class:`typing.str` :param auth_header: The HTTP authentication header of the request - :type auth_header: :class:`typing.str` + :type auth_header: :class:`typing.str` :param logic: The logic to execute at the end of the adapter's middleware pipeline. - :type logic: :class:`typing.Callable` + :type logic: :class:`typing.Callable` :return: A task that represents the work queued to execute. If the activity type - was `Invoke` and the corresponding key (`channelId` + `activityId`) was found then + was `Invoke` and the corresponding key (`channelId` + `activityId`) was found then an :class:`InvokeResponse` is returned; otherwise, `null` is returned. - .. note:: + .. note:: Call this method to reactively send a message to a conversation. - If the task completes successfully, then an :class:`InvokeResponse` is returned; + If the task completes successfully, then an :class:`InvokeResponse` is returned; otherwise. `null` is returned. """ @@ -368,9 +368,9 @@ async def authenticate_request( :param request: The request to authenticate :type request: :class:`botbuilder.schema.Activity` :param auth_header: The authentication header - + :raises: A permission exception error. - + :return: The request claims identity :rtype: :class:`botframework.connector.auth.ClaimsIdentity` """ @@ -391,7 +391,7 @@ def create_context(self, activity): """ Allows for the overriding of the context object in unit tests and derived adapters. :param activity: - :return: + :return: """ return TurnContext(self, activity) @@ -453,9 +453,9 @@ async def update_activity(self, context: TurnContext, activity: Activity): :return: A task that represents the work queued to execute - .. note:: + .. note:: If the activity is successfully sent, the task result contains - a :class:`botbuilder.schema.ResourceResponse` object containing the ID that + a :class:`botbuilder.schema.ResourceResponse` object containing the ID that the receiving channel assigned to the activity. Before calling this function, set the ID of the replacement activity to the ID of the activity to replace. @@ -479,13 +479,13 @@ async def delete_activity( :param context: The context object for the turn :type context: :class:`TurnContext' :param reference: Conversation reference for the activity to delete - :type reference: :class:`botbuilder.schema.ConversationReference` + :type reference: :class:`botbuilder.schema.ConversationReference` :raises: A exception error :return: A task that represents the work queued to execute - .. note:: + .. note:: The activity_id of the :class:`botbuilder.schema.ConversationReference` identifies the activity to delete. """ try: @@ -597,12 +597,12 @@ async def delete_conversation_member( async def get_activity_members(self, context: TurnContext, activity_id: str): """ Lists the members of a given activity. - + :param context: The context object for the turn :type context: :class:`TurnContext` - :param activity_id: (Optional) Activity ID to enumerate. + :param activity_id: (Optional) Activity ID to enumerate. If not specified the current activities ID will be used. - + :raises: An exception error :return: List of Members of the activity @@ -639,7 +639,7 @@ async def get_activity_members(self, context: TurnContext, activity_id: str): async def get_conversation_members(self, context: TurnContext): """ Lists the members of a current conversation. - + :param context: The context object for the turn :type context: :class:`TurnContext` @@ -676,7 +676,7 @@ async def get_conversations(self, service_url: str, continuation_token: str = No :param service_url: The URL of the channel server to query. This can be retrieved from `context.activity.serviceUrl` :type service_url: str - + :param continuation_token: The continuation token from the previous page of results :type continuation_token: str @@ -696,14 +696,14 @@ async def get_user_token( """ Attempts to retrieve the token for a user that's in a login flow. - + :param context: Context for the current turn of conversation with the user :type context: :class:`TurnContext` :param connection_name: Name of the auth connection to use :type connection_name: str :param magic_code" (Optional) user entered code to validate :str magic_code" str - + :raises: An exception error :returns: Token Response @@ -743,14 +743,14 @@ async def sign_out_user( ) -> str: """ Signs the user out with the token server. - + :param context: Context for the current turn of conversation with the user :type context: :class:`TurnContext` :param connection_name: Name of the auth connection to use :type connection_name: str :param user_id: User id of user to sign out :type user_id: str - + :returns: A task that represents the work queued to execute """ if not context.activity.from_property or not context.activity.from_property.id: @@ -772,14 +772,14 @@ async def get_oauth_sign_in_link( ) -> str: """ Gets the raw sign-in link to be sent to the user for sign-in for a connection name. - + :param context: Context for the current turn of conversation with the user :type context: :class:`TurnContext` :param connection_name: Name of the auth connection to use :type connection_name: str :returns: A task that represents the work queued to execute - + .. note:: If the task completes successfully, the result contains the raw sign-in link """ @@ -805,12 +805,12 @@ async def get_token_status( """ Retrieves the token status for each configured connection for the given user. - + :param context: Context for the current turn of conversation with the user :type context: :class:`TurnContext` :param user_id: The user Id for which token status is retrieved :type user_id: str - :param include_filter: (Optional) Comma separated list of connection's to include. + :param include_filter: (Optional) Comma separated list of connection's to include. Blank will return token status for all configured connections. :type include_filter: str @@ -839,7 +839,7 @@ async def get_aad_tokens( ) -> Dict[str, TokenResponse]: """ Retrieves Azure Active Directory tokens for particular resources on a configured connection. - + :param context: Context for the current turn of conversation with the user :type context: :class:`TurnContext` @@ -848,7 +848,7 @@ async def get_aad_tokens( :param resource_urls: The list of resource URLs to retrieve tokens for :type resource_urls: :class:`typing.List` - + :returns: Dictionary of resource Urls to the corresponding :class:'botbuilder.schema.TokenResponse` :rtype: :class:`typing.Dict` """ @@ -873,8 +873,8 @@ async def create_connector_client( """Allows for mocking of the connector client in unit tests :param service_url: The service URL :param identity: The claims identity - - :return: An instance of the :class:`ConnectorClient` class + + :return: An instance of the :class:`ConnectorClient` class """ if identity: bot_app_id_claim = identity.claims.get( diff --git a/libraries/botbuilder-core/botbuilder/core/bot_state.py b/libraries/botbuilder-core/botbuilder/core/bot_state.py index 2718c1889..7f2c26984 100644 --- a/libraries/botbuilder-core/botbuilder/core/bot_state.py +++ b/libraries/botbuilder-core/botbuilder/core/bot_state.py @@ -12,12 +12,12 @@ class CachedBotState: - """ + """ Internal cached bot state. """ def __init__(self, state: Dict[str, object] = None): - + self.state = state if state is not None else {} self.hash = self.compute_hash(state) @@ -31,7 +31,7 @@ def compute_hash(self, obj: object) -> str: class BotState(PropertyManager): """ - Defines a state management object and automates the reading and writing of + Defines a state management object and automates the reading and writing of associated state properties to a storage layer. .. remarks:: @@ -42,7 +42,7 @@ class BotState(PropertyManager): """ def __init__(self, storage: Storage, context_service_key: str): - """ + """ Initializes a new instance of the :class:`BotState` class. :param storage: The storage layer this state management object will use to store and retrieve state @@ -51,8 +51,8 @@ def __init__(self, storage: Storage, context_service_key: str): :type context_service_key: str .. note:: - This constructor creates a state management object and associated scope. The object uses - the :param storage: to persist state property values and the :param context_service_key: to cache state + This constructor creates a state management object and associated scope. The object uses + the :param storage: to persist state property values and the :param context_service_key: to cache state within the context for each turn. :raises: It raises an argument null exception. @@ -105,7 +105,7 @@ async def save_changes( """ Saves the state cached in the current context for this turn. If the state has changed, it saves the state cached in the current context for this turn. - + :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` :param force: Optional, true to save state to storage whether or not there are changes @@ -125,12 +125,12 @@ async def save_changes( async def clear_state(self, turn_context: TurnContext): """ Clears any state currently stored in this state scope. - + :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` :return: None - + .. note:: This function must be called in order for the cleared state to be persisted to the underlying store. """ @@ -166,12 +166,12 @@ def get_storage_key(self, turn_context: TurnContext) -> str: async def get_property_value(self, turn_context: TurnContext, property_name: str): """ Gets the value of the specified property in the turn context. - + :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` :param property_name: The property name :type property_name: str - + :return: The value of the property """ if turn_context is None: @@ -193,12 +193,12 @@ async def delete_property_value( ) -> None: """ Deletes a property from the state cache in the turn context. - + :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` :param property_name: The name of the property to delete :type property_name: str - + :return: None """ if turn_context is None: @@ -213,7 +213,7 @@ async def set_property_value( ) -> None: """ Sets a property to the specified value in the turn context. - + :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` :param property_name: The property name diff --git a/libraries/botbuilder-core/botbuilder/core/conversation_state.py b/libraries/botbuilder-core/botbuilder/core/conversation_state.py index fd39935e0..333139cbd 100644 --- a/libraries/botbuilder-core/botbuilder/core/conversation_state.py +++ b/libraries/botbuilder-core/botbuilder/core/conversation_state.py @@ -17,9 +17,9 @@ class ConversationState(BotState): no_key_error_message = "ConversationState: channelId and/or conversation missing from context.activity." def __init__(self, storage: Storage): - """ + """ Creates a :class:`ConversationState` instance. - + Creates a new instance of the :class:`ConversationState` class. :param storage: The storage containing the conversation state. :type storage: :class:`Storage` @@ -27,14 +27,14 @@ def __init__(self, storage: Storage): super(ConversationState, self).__init__(storage, "ConversationState") def get_storage_key(self, turn_context: TurnContext) -> object: - """ + """ Gets the key to use when reading and writing state to and from storage. :param turn_context: The context object for this turn. - :type turn_context: :class:`TurnContext` + :type turn_context: :class:`TurnContext` :raise: :class:`TypeError` if the :meth:`TurnContext.activity` for the current turn is missing - :class:`botbuilder.schema.Activity` channelId or conversation information or the conversation's + :class:`botbuilder.schema.Activity` channelId or conversation information or the conversation's account id is missing. :return: The storage key. @@ -58,6 +58,6 @@ def get_storage_key(self, turn_context: TurnContext) -> object: def __raise_type_error(self, err: str = "NoneType found while expecting value"): """ Raise type error exception - :raises: :class:`TypeError` + :raises: :class:`TypeError` """ raise TypeError(err) From fd0059ae7bdf2d6a6c25868b817a11b8296b2320 Mon Sep 17 00:00:00 2001 From: tracyboehrer Date: Tue, 28 Jan 2020 14:39:47 -0600 Subject: [PATCH 54/56] black corrections --- libraries/botbuilder-core/botbuilder/core/activity_handler.py | 2 +- .../botbuilder-core/botbuilder/core/conversation_state.py | 1 + .../botbuilder/dialogs/dialog_turn_status.py | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/botbuilder-core/botbuilder/core/activity_handler.py b/libraries/botbuilder-core/botbuilder/core/activity_handler.py index 5fe2ac086..ef3f4b627 100644 --- a/libraries/botbuilder-core/botbuilder/core/activity_handler.py +++ b/libraries/botbuilder-core/botbuilder/core/activity_handler.py @@ -106,7 +106,7 @@ async def on_conversation_update_activity(self, turn_context: TurnContext): async def on_members_added_activity( self, members_added: List[ChannelAccount], turn_context: TurnContext - ): # pylint: disable=unused-argument + ): # pylint: disable=unused-argument """ Override this method in a derived class to provide logic for when members other than the bot join the conversation. You can add your bot's welcome logic. diff --git a/libraries/botbuilder-core/botbuilder/core/conversation_state.py b/libraries/botbuilder-core/botbuilder/core/conversation_state.py index 333139cbd..4014f54a0 100644 --- a/libraries/botbuilder-core/botbuilder/core/conversation_state.py +++ b/libraries/botbuilder-core/botbuilder/core/conversation_state.py @@ -14,6 +14,7 @@ class ConversationState(BotState): .. remarks:: Conversation state is available in any turn in a specific conversation, regardless of the user, such as in a group conversation. """ + no_key_error_message = "ConversationState: channelId and/or conversation missing from context.activity." def __init__(self, storage: Storage): diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py index 46be68c85..b88cd359b 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_turn_status.py @@ -2,6 +2,7 @@ # Licensed under the MIT License. from enum import Enum + class DialogTurnStatus(Enum): """ Codes indicating the state of the dialog stack after a call to `DialogContext.continueDialog()` @@ -15,7 +16,7 @@ class DialogTurnStatus(Enum): :var Cancelled: Indicates that the dialog was cancelled and the stack is empty. :vartype Cancelled: int """ - + Empty = 1 Waiting = 2 From a68c5e8d2ee439fda4ba51cf74cbfef725fe41f0 Mon Sep 17 00:00:00 2001 From: tracyboehrer Date: Tue, 28 Jan 2020 14:57:19 -0600 Subject: [PATCH 55/56] More pylint corrections --- .../botbuilder/core/activity_handler.py | 78 +++++++++++-------- .../botbuilder/core/bot_framework_adapter.py | 12 ++- .../botbuilder/dialogs/dialog_reason.py | 3 +- .../botbuilder/dialogs/prompts/prompt.py | 2 - 4 files changed, 57 insertions(+), 38 deletions(-) diff --git a/libraries/botbuilder-core/botbuilder/core/activity_handler.py b/libraries/botbuilder-core/botbuilder/core/activity_handler.py index ef3f4b627..8d7b7cccc 100644 --- a/libraries/botbuilder-core/botbuilder/core/activity_handler.py +++ b/libraries/botbuilder-core/botbuilder/core/activity_handler.py @@ -23,8 +23,10 @@ async def on_turn(self, turn_context: TurnContext): In a derived class, override this method to add logic that applies to all activity types. .. note:: - - Add logic to apply before the type-specific logic and before the call to the :meth:`ActivityHandler.on_turn()` method. - - Add logic to apply after the type-specific logic after the call to the :meth:`ActivityHandler.on_turn()` method. + - Add logic to apply before the type-specific logic and before the call to the + :meth:`ActivityHandler.on_turn()` method. + - Add logic to apply after the type-specific logic after the call to the + :meth:`ActivityHandler.on_turn()` method. """ if turn_context is None: raise TypeError("ActivityHandler.on_turn(): turn_context cannot be None.") @@ -72,7 +74,8 @@ async def on_message_activity( # pylint: disable=unused-argument async def on_conversation_update_activity(self, turn_context: TurnContext): """ - Invoked when a conversation update activity is received from the channel when the base behavior of :meth:`ActivityHandler.on_turn()` is used. + Invoked when a conversation update activity is received from the channel when the base behavior of + :meth:`ActivityHandler.on_turn()` is used. :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` @@ -80,7 +83,8 @@ async def on_conversation_update_activity(self, turn_context: TurnContext): :returns: A task that represents the work queued to execute .. note:: - When the :meth:'ActivityHandler.on_turn()` method receives a conversation update activity, it calls this method. + When the :meth:'ActivityHandler.on_turn()` method receives a conversation update activity, it calls this + method. If the conversation update activity indicates that members other than the bot joined the conversation, it calls the :meth:`ActivityHandler.on_members_added_activity()` method. If the conversation update activity indicates that members other than the bot left the conversation, @@ -108,10 +112,11 @@ async def on_members_added_activity( self, members_added: List[ChannelAccount], turn_context: TurnContext ): # pylint: disable=unused-argument """ - Override this method in a derived class to provide logic for when members other than the bot join the conversation. - You can add your bot's welcome logic. + Override this method in a derived class to provide logic for when members other than the bot join + the conversation. You can add your bot's welcome logic. - :param members_added: A list of all the members added to the conversation, as described by the conversation update activity + :param members_added: A list of all the members added to the conversation, as described by the + conversation update activity :type members_added: :class:`typing.List` :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` @@ -119,7 +124,8 @@ async def on_members_added_activity( :returns: A task that represents the work queued to execute .. note:: - When the :meth:'ActivityHandler.on_conversation_update_activity()` method receives a conversation update activity that indicates + When the :meth:'ActivityHandler.on_conversation_update_activity()` method receives a conversation + update activity that indicates one or more users other than the bot are joining the conversation, it calls this method. """ return @@ -128,10 +134,11 @@ async def on_members_removed_activity( self, members_removed: List[ChannelAccount], turn_context: TurnContext ): # pylint: disable=unused-argument """ - Override this method in a derived class to provide logic for when members other than the bot leave the conversation. - You can add your bot's good-bye logic. + Override this method in a derived class to provide logic for when members other than the bot leave + the conversation. You can add your bot's good-bye logic. - :param members_added: A list of all the members removed from the conversation, as described by the conversation update activity + :param members_added: A list of all the members removed from the conversation, as described by the + conversation update activity :type members_added: :class:`typing.List` :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` @@ -139,16 +146,17 @@ async def on_members_removed_activity( :returns: A task that represents the work queued to execute .. note:: - When the :meth:'ActivityHandler.on_conversation_update_activity()` method receives a conversation update activity that indicates - one or more users other than the bot are leaving the conversation, it calls this method. + When the :meth:'ActivityHandler.on_conversation_update_activity()` method receives a conversation + update activity that indicates one or more users other than the bot are leaving the conversation, + it calls this method. """ return async def on_message_reaction_activity(self, turn_context: TurnContext): """ - Invoked when an event activity is received from the connector when the base behavior of :meth:'ActivityHandler.on_turn()` is used. - + Invoked when an event activity is received from the connector when the base behavior of + :meth:'ActivityHandler.on_turn()` is used. :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` @@ -156,15 +164,20 @@ async def on_message_reaction_activity(self, turn_context: TurnContext): :returns: A task that represents the work queued to execute .. note:: - Message reactions correspond to the user adding a 'like' or 'sad' etc. (often an emoji) to a previously sent activity. - Message reactions are only supported by a few channels. The activity that the message reaction corresponds to is indicated in the - reply to Id property. The value of this property is the activity id of a previously sent activity given back to the bot as the response - from a send call. - When the :meth:'ActivityHandler.on_turn()` method receives a message reaction activity, it calls this method. - If the message reaction indicates that reactions were added to a message, it calls :meth:'ActivityHandler.on_reaction_added(). - If the message reaction indicates that reactions were removed from a message, it calls :meth:'ActivityHandler.on_reaction_removed(). + Message reactions correspond to the user adding a 'like' or 'sad' etc. (often an emoji) to a previously + sent activity. + Message reactions are only supported by a few channels. The activity that the message reaction corresponds + to is indicated in the reply to Id property. The value of this property is the activity id of a previously + sent activity given back to the bot as the response from a send call. + When the :meth:'ActivityHandler.on_turn()` method receives a message reaction activity, it calls this + method. + If the message reaction indicates that reactions were added to a message, it calls + :meth:'ActivityHandler.on_reaction_added(). + If the message reaction indicates that reactions were removed from a message, it calls + :meth:'ActivityHandler.on_reaction_removed(). In a derived class, override this method to add logic that applies to all message reaction activities. - Add logic to apply before the reactions added or removed logic before the call to the this base class method. + Add logic to apply before the reactions added or removed logic before the call to the this base class + method. Add logic to apply after the reactions added or removed logic after the call to the this base class method. """ if turn_context.activity.reactions_added is not None: @@ -225,7 +238,8 @@ async def on_reactions_removed( # pylint: disable=unused-argument async def on_event_activity(self, turn_context: TurnContext): """ - Invoked when an event activity is received from the connector when the base behavior of :meth:'ActivityHandler.on_turn()` is used. + Invoked when an event activity is received from the connector when the base behavior of + :meth:'ActivityHandler.on_turn()` is used. :param turn_context: The context object for this turn :type turn_context: :class:`TurnContext` @@ -254,7 +268,8 @@ async def on_token_response_event( # pylint: disable=unused-argument self, turn_context: TurnContext ): """ - Invoked when a `tokens/response` event is received when the base behavior of :meth:'ActivityHandler.on_event_activity()` is used. + Invoked when a `tokens/response` event is received when the base behavior of + :meth:'ActivityHandler.on_event_activity()` is used. If using an `oauth_prompt`, override this method to forward this activity to the current dialog. :param turn_context: The context object for this turn @@ -263,8 +278,9 @@ async def on_token_response_event( # pylint: disable=unused-argument :returns: A task that represents the work queued to execute .. note:: - When the :meth:'ActivityHandler.on_event()` method receives an event with an activity name of `tokens/response`, - it calls this method. If your bot uses an `oauth_prompt`, forward the incoming activity to the current dialog. + When the :meth:'ActivityHandler.on_event()` method receives an event with an activity name of + `tokens/response`, it calls this method. If your bot uses an `oauth_prompt`, forward the incoming + activity to the current dialog. """ return @@ -304,8 +320,8 @@ async def on_unrecognized_activity_type( # pylint: disable=unused-argument self, turn_context: TurnContext ): """ - Invoked when an activity other than a message, conversation update, or event is received when the base behavior of - :meth:`ActivityHandler.on_turn()` is used. + Invoked when an activity other than a message, conversation update, or event is received when the base + behavior of :meth:`ActivityHandler.on_turn()` is used. If overridden, this method could potentially respond to any of the other activity types. :param turn_context: The context object for this turn @@ -314,7 +330,7 @@ async def on_unrecognized_activity_type( # pylint: disable=unused-argument :returns: A task that represents the work queued to execute .. note:: - When the :meth:`ActivityHandler.on_turn()` method receives an activity that is not a message, conversation update, message reaction, - or event activity, it calls this method. + When the :meth:`ActivityHandler.on_turn()` method receives an activity that is not a message, + conversation update, message reaction, or event activity, it calls this method. """ return diff --git a/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py b/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py index cf2c8032d..6f4681437 100644 --- a/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py +++ b/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py @@ -90,7 +90,8 @@ def __init__( :param app_id: The bot application ID. This is the appId returned by the Azure portal registration, and is the value of the `MicrosoftAppId` parameter in the `config.py` file. :type app_id: str - :param app_password: The bot application password. This is the password returned by the Azure portal registration, and is + :param app_password: The bot application password. This is the password returned by the Azure portal + registration, and is the value os the `MicrosoftAppPassword` parameter in the `config.py` file. :type app_password: str :param channel_auth_tenant: The channel tenant to use in conversation @@ -674,7 +675,8 @@ async def get_conversations(self, service_url: str, continuation_token: str = No returns results in pages and each page will include a `continuationToken` that can be used to fetch the next page of results from the server. - :param service_url: The URL of the channel server to query. This can be retrieved from `context.activity.serviceUrl` + :param service_url: The URL of the channel server to query. This can be retrieved from + `context.activity.serviceUrl` :type service_url: str :param continuation_token: The continuation token from the previous page of results @@ -684,8 +686,10 @@ async def get_conversations(self, service_url: str, continuation_token: str = No :return: A task that represents the work queued to execute - .. note:: If the task completes successfully, the result contains a page of the members of the current conversation. - This overload may be called from outside the context of a conversation, as only the bot's service URL and credentials are required. + .. note:: If the task completes successfully, the result contains a page of the members of the current + conversation. + This overload may be called from outside the context of a conversation, as only the bot's service URL and + credentials are required. """ client = await self.create_connector_client(service_url) return await client.conversations.get_conversations(continuation_token) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py index a017a33df..7c8eb9bef 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog_reason.py @@ -13,7 +13,8 @@ class DialogReason(Enum): :vartype ContinueCalled: int :var EndCalled: A dialog ended normally through a call to `DialogContext.end_dialog() :vartype EndCalled: int - :var ReplaceCalled: A dialog is ending because it's being replaced through a call to `DialogContext.replace_dialog()`. + :var ReplaceCalled: A dialog is ending because it's being replaced through a call to + `DialogContext.replace_dialog()`. :vartype ReplacedCalled: int :var CancelCalled: A dialog was cancelled as part of a call to `DialogContext.cancel_all_dialogs()`. :vartype CancelCalled: int diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py index e1df46e6f..8c9c0edc5 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/prompt.py @@ -215,7 +215,6 @@ async def on_prompt( :return: A :class:Task representing the asynchronous operation. :rtype: :class:Task """ - pass @abstractmethod async def on_recognize( @@ -238,7 +237,6 @@ async def on_recognize( :return: A :class:Task representing the asynchronous operation. :rtype: :class:Task """ - pass def append_choices( self, From 5685d77d6c657865131c18e21f731271b338e6d4 Mon Sep 17 00:00:00 2001 From: tracyboehrer Date: Tue, 28 Jan 2020 15:05:34 -0600 Subject: [PATCH 56/56] ConversationState pylint --- .../botbuilder-core/botbuilder/core/conversation_state.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/botbuilder-core/botbuilder/core/conversation_state.py b/libraries/botbuilder-core/botbuilder/core/conversation_state.py index 4014f54a0..445b8949d 100644 --- a/libraries/botbuilder-core/botbuilder/core/conversation_state.py +++ b/libraries/botbuilder-core/botbuilder/core/conversation_state.py @@ -12,7 +12,8 @@ class ConversationState(BotState): Extends :class:`BootState` base class. .. remarks:: - Conversation state is available in any turn in a specific conversation, regardless of the user, such as in a group conversation. + Conversation state is available in any turn in a specific conversation, regardless of the user, such as + in a group conversation. """ no_key_error_message = "ConversationState: channelId and/or conversation missing from context.activity."