-
Notifications
You must be signed in to change notification settings - Fork 56
Adding Storage wrappers for internal use cases #159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
8029318
3426524
089ff32
2b746aa
b250532
66e4b4a
76c92a6
b1c79c9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. | ||
|
|
||
| from ._error_handling import ( | ||
| _raise_if_falsey, | ||
| _raise_if_none, | ||
| ) | ||
| from ._load_configuration import load_configuration_from_env | ||
|
|
||
| __all__ = [ | ||
| "_raise_if_falsey", | ||
| "_raise_if_none", | ||
| "load_configuration_from_env", | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. | ||
|
|
||
| def _raise_if_none(label: str, **kwargs) -> None: | ||
| """Raises an exception if any of the provided keyword arguments are None. | ||
|
|
||
| :param label: A label to include in the exception message. | ||
| :param kwargs: The keyword arguments to check. | ||
| :raises ValueError: If any of the provided keyword arguments are None. | ||
| """ | ||
|
|
||
| none_args = [name for name, value in kwargs.items() if value is None] | ||
| if none_args: | ||
| raise ValueError( | ||
| f"{label}: The following arguments must be set and non-None: {', '.join(none_args)}" | ||
| ) | ||
|
|
||
| def _raise_if_falsey(label: str, **kwargs) -> None: | ||
| """Raises an exception if any of the provided keyword arguments are falsey. | ||
|
|
||
| :param label: A label to include in the exception message. | ||
| :param kwargs: The keyword arguments to check. | ||
| :raises ValueError: If any of the provided keyword arguments are falsey. | ||
| """ | ||
|
|
||
| falsey_args = [name for name, value in kwargs.items() if not value] | ||
| if falsey_args: | ||
| raise ValueError( | ||
| f"{label}: The following arguments must be set and non-falsey (cannot be None or an empty string, for example): {', '.join(falsey_args)}" | ||
| ) |
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -11,7 +11,11 @@ | |||
| from microsoft_agents.activity import Activity, TokenResponse | ||||
|
|
||||
| from ...turn_context import TurnContext | ||||
| from ...storage import Storage | ||||
| from ...storage import ( | ||||
| Storage, | ||||
| _ItemNamespace, | ||||
| _Namespaces | ||||
| ) | ||||
| from ...authorization import Connections | ||||
| from ..._oauth import _FlowStateTag | ||||
| from ..state import TurnState | ||||
|
|
@@ -67,6 +71,11 @@ def __init__( | |||
|
|
||||
| self._storage = storage | ||||
| self._connection_manager = connection_manager | ||||
| self._sign_in_state_store = _ItemNamespace( | ||||
| _Namespaces.AUTHORIZATION, | ||||
| self._storage, | ||||
| _SignInState, | ||||
| ) | ||||
|
|
||||
| self._sign_in_success_handler: Optional[ | ||||
| Callable[[TurnContext, TurnState, Optional[str]], Awaitable[None]] | ||||
|
|
@@ -117,20 +126,10 @@ def _init_handlers(self) -> None: | |||
| connection_manager=self._connection_manager, | ||||
| auth_handler=auth_handler, | ||||
| ) | ||||
|
|
||||
| @staticmethod | ||||
| def _sign_in_state_key(context: TurnContext) -> str: | ||||
| """Generate a unique storage key for the sign-in state based on the context. | ||||
|
|
||||
| This is the key used to store and retrieve the sign-in state from storage, and | ||||
| can be used to inspect or manipulate the state directly if needed. | ||||
|
|
||||
| :param context: The turn context for the current turn of conversation. | ||||
| :type context: :class:`microsoft_agents.hosting.core.turn_context.TurnContext` | ||||
| :return: A unique (across other values of channel_id and user_id) key for the sign-in state. | ||||
| :rtype: str | ||||
| """ | ||||
| return f"auth:_SignInState:{context.activity.channel_id}:{context.activity.from_property.id}" | ||||
| def _sign_in_state_vkey(context: TurnContext) -> str: | ||||
| return f"{context.activity.channel_id}:{context.activity.from_property.id}" | ||||
|
|
||||
| async def _load_sign_in_state(self, context: TurnContext) -> Optional[_SignInState]: | ||||
| """Load the sign-in state from storage for the given context. | ||||
|
|
@@ -228,7 +227,7 @@ async def _start_or_continue_sign_in( | |||
| auth_handler_id = auth_handler_id or self._default_handler_id | ||||
|
|
||||
| # check cached sign in state | ||||
| sign_in_state = await self._load_sign_in_state(context) | ||||
| sign_in_state = await self._sign_in_state_store.read(self._sign_in_state_vkey(context)) | ||||
| if not sign_in_state: | ||||
| # no existing sign-in state, create a new one | ||||
| sign_in_state = _SignInState(active_handler_id=auth_handler_id) | ||||
|
|
@@ -243,6 +242,7 @@ async def _start_or_continue_sign_in( | |||
| if sign_in_response.tag == _FlowStateTag.COMPLETE: | ||||
| if self._sign_in_success_handler: | ||||
| await self._sign_in_success_handler(context, state, auth_handler_id) | ||||
| await self._sign_in_state_store.delete(self._sign_in_state_vkey(context)) | ||||
|
||||
| await self._sign_in_state_store.delete(self._sign_in_state_vkey(context)) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. | ||
|
|
||
| class _Namespaces: | ||
| """Storage key namespaces used by various components.""" | ||
|
|
||
| USER_AUTHORIZATION = "auth/{channel_id}/{user_id}" | ||
| AUTHORIZATION = "auth/{channel_id}/{from_property_id}" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| from .transcript_info import TranscriptInfo | ||
| from .transcript_logger import ( | ||
| TranscriptLogger, | ||
| ConsoleTranscriptLogger, | ||
| TranscriptLoggerMiddleware, | ||
| FileTranscriptLogger, | ||
| PagedResult, | ||
| ) | ||
| from .transcript_store import TranscriptStore | ||
| from .transcript_file_store import FileTranscriptStore | ||
| from .transcript_memory_store import TranscriptMemoryStore | ||
|
|
||
| __all__ = [ | ||
| "TranscriptInfo", | ||
| "TranscriptLogger", | ||
| "ConsoleTranscriptLogger", | ||
| "TranscriptLoggerMiddleware", | ||
| "FileTranscriptLogger", | ||
| "PagedResult", | ||
| "TranscriptStore", | ||
| "TranscriptMemoryStore", | ||
| "FileTranscriptStore", | ||
| ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Importing
Namespacesbut the constant class is named_Namespaces(with underscore prefix) as shown in the_namespaces.pyfile. This import will fail. Should be_Namespaces.