async def get_grouped_responses(request: Request) -> HTTPResponse: rasa_x_utils.handle_deprecated_request_parameters( request, "template", RESPONSE_NAME_KEY) text_query = utils.default_arg(request, "q", None) response_query = utils.default_arg(request, RESPONSE_NAME_KEY, None) responses, total_number = _nlg_service(request).get_grouped_responses( text_query, response_query) return response.json(responses, headers={"X-Total-Count": total_number})
async def get_responses(request: Request) -> HTTPResponse: text_query = utils.default_arg(request, "q", None) response_query = utils.default_arg(request, RESPONSE_NAME_KEY, None) fields = utils.fields_arg(request, {"text", RESPONSE_NAME_KEY, "id"}) limit = utils.int_arg(request, "limit") offset = utils.int_arg(request, "offset", 0) responses, total_number = _nlg_service(request).fetch_responses( text_query, response_query, fields, limit, offset) return response.json(responses, headers={"X-Total-Count": total_number})
async def list_users(request: Request) -> HTTPResponse: user_service = UserService(request[REQUEST_DB_SESSION_KEY]) username_query = utils.default_arg(request, "username", None) role_query = utils.default_arg(request, "role", None) users = user_service.fetch_all_users(config.team_name, username_query, role_query) if not users: return rasa_x_utils.error(404, "NoUsersFound", "No users found") profiles = [user_service.fetch_user(u["username"]) for u in users] return response.json(profiles, headers={"X-Total-Count": len(profiles)})
async def get_story(request, story_id): from rasa.core.domain import Domain story = _story_service(request).fetch_story(story_id) content_type = request.headers.get("Accept") if content_type == "text/vnd.graphviz": project_id = rasa_x_utils.default_arg(request, "project_id", config.project_name) domain_dict = _domain_service(request).get_or_create_domain( project_id) domain = Domain.from_dict(domain_dict) visualization = await _story_service(request).visualize_stories( [story], domain) if visualization: return response.text(visualization) else: return rasa_x_utils.error( HTTPStatus.NOT_ACCEPTABLE, "VisualizationNotAvailable", "Cannot produce a visualization for the requested story", ) else: if story: return response.json(story) return rasa_x_utils.error( HTTPStatus.NOT_FOUND, "StoryNotFound", f"Story for id {story_id} could not be found", )
async def unique_slot_values(request: Request) -> HTTPResponse: """Return a list of unique slot values found in existing conversations, according to certain filters. Args: request: HTTP request being processed. Returns: HTTP response. """ query = rasa_x_utils.default_arg(request, "q") slot = rasa_x_utils.default_arg(request, "slot") slot_values = _event_service(request).get_unique_slot_values( slot, query) return response.json(slot_values, headers={"X-Total-Count": len(slot_values)})
async def retrieve_user( request: Request, payload: Dict, allow_api_token: bool, extract_user_from_jwt: bool, *args: Any, **kwargs: Any, ) -> Optional[Dict]: if extract_user_from_jwt and payload and has_role(payload.get("user"), GUEST): return payload["user"] user_service = UserService(request[REQUEST_DB_SESSION_KEY]) if allow_api_token: api_token = rasa_x_utils.default_arg(request, "api_token") if api_token: return user_service.api_token_auth(api_token) if payload: username = payload.get("username", None) if username is not None: return user_service.fetch_user(username) else: # user is first-time enterprise user and has username None # in this case we'll fetch the profile using name_id name_id = payload.get("user", {}).get("name_id", None) return user_service.fetch_user(name_id) return None
async def get_conversation_tracker_impl(request: Request, conversation_id: Text, user: Dict[Text, Any] = None): event_service = _event_service(request) if not _has_access_to_conversation(event_service, conversation_id, user): return rasa_x_utils.error(HTTPStatus.UNAUTHORIZED, "NoPermission", "Access denied") until_time = rasa_x_utils.float_arg(request, "until", None) since_time = rasa_x_utils.float_arg(request, "since", None) rasa_environment_query = rasa_x_utils.default_arg( request, "rasa_environment", DEFAULT_RASA_ENVIRONMENT) event_verbosity = _event_verbosity_from_request(request) exclude_leading_action_session_start = rasa_x_utils.bool_arg( request, "exclude_leading_action_session_start", False) tracker = event_service.get_tracker_with_message_flags( conversation_id, until_time, since_time, event_verbosity, rasa_environment_query, exclude_leading_action_session_start, ) if not tracker: return rasa_x_utils.error( HTTPStatus.NOT_FOUND, "ClientNotFound", f"Client for conversation_id '{conversation_id}' could not be found", ) requested_format = request.headers.get("Accept") if requested_format == "application/json": dispo = f"attachment;filename={conversation_id}-dump.json" return response.json( tracker, content_type="application/json", headers={"Content-Disposition": dispo}, ) elif requested_format == "text/markdown": _events = events.deserialise_events(tracker["events"]) story = Story.from_events(_events) exported = story.as_story_string(flat=True) return response.text( exported, content_type="text/markdown", headers={ "Content-Disposition": f"attachment;filename={conversation_id}-story.md" }, ) else: return response.json(tracker, headers={"Content-Disposition": "inline"})
async def get_stories(request): from rasa.core.domain import Domain text_query = rasa_x_utils.default_arg(request, "q", None) fields = rasa_x_utils.fields_arg(request, {"name", "annotation.user", "id"}) id_query = rasa_x_utils.list_arg(request, "id") distinct = rasa_x_utils.bool_arg(request, "distinct", True) stories = _story_service(request).fetch_stories(text_query, fields, id_query=id_query, distinct=distinct) content_type = request.headers.get("Accept") if content_type == "text/vnd.graphviz": project_id = rasa_x_utils.default_arg(request, "project_id", config.project_name) domain_dict = _domain_service(request).get_or_create_domain( project_id) domain = Domain.from_dict(domain_dict) visualization = await _story_service(request).visualize_stories( stories, domain) if visualization: return response.text(visualization) else: return rasa_x_utils.error( HTTPStatus.NOT_ACCEPTABLE, "VisualizationNotAvailable", "Cannot produce a visualization for the requested stories", ) elif content_type == "text/markdown": markdown = _story_service(request).get_stories_markdown(stories) return response.text( markdown, content_type="text/markdown", headers={ "Content-Disposition": "attachment;filename=stories.md" }, ) else: return response.json(stories, headers={"X-Total-Count": len(stories)})
async def get_models(request, project_id): limit = utils.int_arg(request, "limit") offset = utils.int_arg(request, "offset", 0) tag = rasa_x_utils.default_arg(request, "tag") models, total_models = await _model_service(request).get_models( project_id, limit, offset, tag) return response.json(models, headers={"X-Total-Count": total_models})
async def delete_message_correction( request: Request, conversation_id: Text, message_timestamp: float) -> HTTPResponse: try: project_id = rasa_x_utils.default_arg(request, "project_id", config.project_name) _event_service(request).delete_message_correction( conversation_id, message_timestamp, project_id) return response.text("", HTTPStatus.OK) except ValueError as e: return rasa_x_utils.error(HTTPStatus.BAD_REQUEST, "MessageRelabellingError.", e)
async def predict_next_action(request, conversation_id): included_events = rasa_x_utils.default_arg(request, "include_events", "ALL") try: content = await _stack_service( request, RASA_PRODUCTION_ENVIRONMENT).predict_next_action( conversation_id, included_events) return response.json(content) except ClientError as e: logger.warning(f"Model training failed. Error: {e}") return rasa_x_utils.error( HTTPStatus.BAD_REQUEST, "ActionPredictionFailed", f"Failed to predict the next action for conversation_id '{conversation_id}'.", details=e, )
async def correct_message( request: Request, conversation_id: Text, message_timestamp: float, user: Dict[Text, Text], ) -> HTTPResponse: try: intent = request.json project_id = rasa_x_utils.default_arg(request, "project_id", config.project_name) _event_service(request).correct_message(conversation_id, message_timestamp, intent, user, project_id) return response.text("", HTTPStatus.OK) except ValueError as e: return rasa_x_utils.error(HTTPStatus.BAD_REQUEST, "MessageRelabellingError.", e)
def _get_clients(request: Request, user: Dict[Text, Any]) -> rasa_x_utils.QueryResult: role_service = _role_service(request) event_service = _event_service(request) sort_by_latest_event_time = rasa_x_utils.bool_arg( request, "sort_by_latest_event_time", True) sort_by_confidence = rasa_x_utils.bool_arg(request, "sort_by_confidence", True) in_training_data = rasa_x_utils.default_arg(request, "in_training_data", None) if in_training_data is not None: in_training_data = in_training_data.lower() == "true" include_interactive = rasa_x_utils.bool_arg(request, "interactive", True) start = rasa_x_utils.time_arg(request, "start", None) until = rasa_x_utils.time_arg(request, "until", None) minimum_confidence = rasa_x_utils.float_arg(request, "minimumConfidence") maximum_confidence = rasa_x_utils.float_arg(request, "maximumConfidence") minimum_nlu_confidence = rasa_x_utils.float_arg( request, "minimumNluConfidence") maximum_nlu_confidence = rasa_x_utils.float_arg( request, "maximumNluConfidence") minimum_user_messages = rasa_x_utils.int_arg(request, "minimumUserMessages") policies = rasa_x_utils.default_arg(request, "policies", None) intent_query = rasa_x_utils.default_arg(request, "intent", None) entity_query = rasa_x_utils.default_arg(request, "entity", None) text_query = rasa_x_utils.default_arg(request, "text", None) rasa_environment_query = rasa_x_utils.default_arg( request, "rasa_environment", DEFAULT_RASA_ENVIRONMENT) action_query = rasa_x_utils.default_arg(request, "action", None) flag_query = rasa_x_utils.bool_arg(request, "is_flagged", False) limit = rasa_x_utils.int_arg(request, "limit") offset = rasa_x_utils.int_arg(request, "offset", 0) slots = rasa_x_utils.list_arg(request, "slots") input_channels = rasa_x_utils.list_arg(request, "input_channels") conversations_tags_filter_any = rasa_x_utils.list_arg( request, TAGS_ANY_REQUEST_PARAMETER) exclude = ([user[USERNAME_KEY]] if rasa_x_utils.bool_arg( request, "exclude_self", False) else None) filter_created_by = None if not role_service.is_user_allowed_to_view_all_conversations(user): filter_created_by = user[USERNAME_KEY] return event_service.get_conversation_metadata_for_all_clients( start=start, until=until, minimum_confidence=minimum_confidence, maximum_confidence=maximum_confidence, minimum_nlu_confidence=minimum_nlu_confidence, maximum_nlu_confidence=maximum_nlu_confidence, minimum_user_messages=minimum_user_messages, policies=policies, in_training_data=in_training_data, intent_query=intent_query, entity_query=entity_query, action_query=action_query, sort_by_date=sort_by_latest_event_time, sort_by_confidence=sort_by_confidence, text_query=text_query, rasa_environment_query=rasa_environment_query, only_flagged=flag_query, include_interactive=include_interactive, exclude=exclude, limit=limit, offset=offset, conversations_tags_filter_any=conversations_tags_filter_any, slots=slots, input_channels=input_channels, created_by=filter_created_by, )
async def decorated_function(request, *args, **kwargs): user_service = UserService(request[REQUEST_DB_SESSION_KEY]) if initialized_on and isinstance(initialized_on, Blueprint): instance = initialized_on else: instance = request.app with instant_config(instance, request=request, **kw): if request.method == "OPTIONS": return await sanic_jwt_utils.call(f, request, *args, **kwargs) is_authenticated = False user_scopes = None reasons = None status = None if allow_rasa_x_token: rasa_x_token = default_arg(request, "token", None) if rasa_x_token == config.rasa_x_token: return await await_and_return_response(args, kwargs, request) if allow_api_token: # if decorator allows api_tokens for authentication # skip the usual JWT authentication api_token = default_arg(request, "api_token") if api_token: user = user_service.api_token_auth(api_token) is_authenticated = True status = 200 permissions = user["permissions"] user_scopes = normalise_permissions(permissions) if not is_authenticated: try: ( is_authenticated, status, reasons, ) = instance.auth._check_authentication( request, request_args=args, request_kwargs=kwargs ) except AttributeError: raise exceptions.SanicJWTException( "Authentication instance not found. Perhaps you " "used @scoped without passing in a blueprint? " "Try @scoped(..., initialized_on=blueprint)", status_code=500, ) except exceptions.SanicJWTException as e: status = e.status_code reasons = e.args[0] if is_authenticated: is_authorized, reasons, status = await authorise_user( args, kwargs, instance, reasons, request, status, user_scopes ) else: is_authorized = False if is_authorized: # the user is authorized. # run the handler method and return the response # NOTE: it's possible to use return await.utils(f, ...) in # here, but inside the @protected decorator it wont work, # so this is left as is for now return await await_and_return_response(args, kwargs, request) else: raise exceptions.Unauthorized(reasons, status_code=status)