Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion libraries/botbuilder-core/botbuilder/core/adapter_extensions.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
from warnings import warn

from botbuilder.core import (
BotAdapter,
BotState,
Storage,
RegisterClassMiddleware,
UserState,
Expand All @@ -23,6 +26,39 @@ def use_storage(adapter: BotAdapter, storage: Storage) -> BotAdapter:
"""
return adapter.use(RegisterClassMiddleware(storage))

@staticmethod
def use_bot_state(
bot_adapter: BotAdapter, *bot_states: BotState, auto: bool = True
) -> BotAdapter:
"""
Registers bot state object into the TurnContext. The botstate will be available via the turn context.

:param bot_adapter: The BotAdapter on which to register the state objects.
:param bot_states: One or more BotState objects to register.
:return: The updated adapter.
"""
if not bot_states:
raise TypeError("At least one BotAdapter is required")

for bot_state in bot_states:
bot_adapter.use(
RegisterClassMiddleware(
bot_state, AdapterExtensions.fullname(bot_state)
)
)

if auto:
bot_adapter.use(AutoSaveStateMiddleware(bot_states))

return bot_adapter

@staticmethod
def fullname(obj):
module = obj.__class__.__module__
if module is None or module == str.__class__.__module__:
return obj.__class__.__name__ # Avoid reporting __builtin__
return module + "." + obj.__class__.__name__

@staticmethod
def use_state(
adapter: BotAdapter,
Expand All @@ -31,7 +67,7 @@ def use_state(
auto: bool = True,
) -> BotAdapter:
"""
Registers user and conversation state objects with the adapter. These objects will be available via
[DEPRECATED] Registers user and conversation state objects with the adapter. These objects will be available via
the turn context's `turn_state` property.

:param adapter: The BotAdapter on which to register the state objects.
Expand All @@ -40,6 +76,11 @@ def use_state(
:param auto: True to automatically persist state each turn.
:return: The BotAdapter
"""
warn(
"This method is deprecated in 4.9. You should use the method .use_bot_state() instead.",
DeprecationWarning,
)

if not adapter:
raise TypeError("BotAdapter is required")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,18 @@ class RegisterClassMiddleware(Middleware):
Middleware for adding an object to or registering a service with the current turn context.
"""

def __init__(self, service):
def __init__(self, service, key: str = None):
self.service = service
self._key = key

async def on_turn(
self, context: TurnContext, logic: Callable[[TurnContext], Awaitable]
):
# C# has TurnStateCollection with has overrides for adding items
# to TurnState. Python does not. In C#'s case, there is an 'Add'
# to handle adding object, and that uses the fully qualified class name.
context.turn_state[self.fullname(self.service)] = self.service
key = self._key or self.fullname(self.service)
context.turn_state[key] = self.service
await logic()

@staticmethod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ async def capture_eoc(
logic, TestAdapter.create_conversation_reference(conversation_id)
)
AdapterExtensions.use_storage(adapter, storage)
AdapterExtensions.use_state(adapter, user_state, convo_state)
AdapterExtensions.use_bot_state(adapter, user_state, convo_state)
adapter.use(TranscriptLoggerMiddleware(ConsoleTranscriptLogger()))

return TestFlow(None, adapter)