示例#1
0
    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})
示例#2
0
    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",
        )
示例#5
0
    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)})
示例#9
0
    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)