Ejemplo n.º 1
0
 def get(self):
     # perhaps don't document this because it's only used by the web GUI
     """
     Get current user info
     ---
     tags: [util]
     responses:
         200:
             description: user
             type: object
             properties:
                 is_authenticated:
                     type: string
                     example: true
                 is_active:
                     type: string
                     example: true
                 is_anonymous:
                     type: string
                     example: false
                 is_admin:
                     type: string
                     example: false
                 username:
                     type: string
                     example: [email protected]
     """
     user = getAuthData()
     return user
Ejemplo n.º 2
0
    def get(self):
        # perhaps don't document this because it's only used by the web GUI
        """
        Get current user info
        ---
        tags: [users]
        responses:
            200:
                description: user
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                is_authenticated:
                                    type: string
                                    example: true
                                is_active:
                                    type: string
                                    example: true
                                is_anonymous:
                                    type: string
                                    example: false
                                is_admin:
                                    type: string
                                    example: false
                                username:
                                    type: string
                                    example: [email protected]
        """
        user = getAuthData()

        return user
Ejemplo n.º 3
0
    def get(self, qa_id):
        """
        Get answerset 
        ---
        tags: [answer]
        parameters:
          - in: path
            name: qa_id
            description: "<question_id>_<answerset_id>"
            type: string
            required: true
        responses:
            200:
                description: "answerset data"
                type: object
                properties:
                    answerset:
                        schema:
                            $ref: '#/definitions/Response'
                    user:
                        type: object
                    question:
                        type: object
                    other_questions:
                        type: array
                        items:
                            type: object
                    other_answersets:
                        type: array
                        items:
                            type: object
                    feedback:
                        type: array
                        items:
                            type: object
            404:
                description: "invalid answerset id"
                type: string
        """
        try:
            question_id, answerset_id = qa_id.split('_')
            question = get_question_by_id(question_id)
            answerset = get_answerset_by_id(answerset_id)
            answersets = question.answersets
            if not answerset in answersets:
                raise AssertionError()
        except Exception as err:
            return "Invalid answerset key.", 404

        user = getAuthData()

        feedback = list_feedback_by_question_answerset(question, answerset)

        return {'question': question.toJSON(),\
                'answerset': answerset.toStandard(),\
                'feedback': [f.toJSON() for f in feedback],\
                'other_answersets': [],
                'other_questions': []}, 200
Ejemplo n.º 4
0
    def delete(self, question_id):
        """
        Delete question
        ---
        tags: [questions]
        parameters:
          - in: path
            name: question_id
            description: "question id"
            schema:
                type: string
            required: true
        responses:
            200:
                description: "question deleted"
                content:
                    text/plain:
                        schema:
                            type: string
            401:
                description: "unauthorized"
                content:
                    text/plain:
                        schema:
                            type: string
            404:
                description: "invalid question key"
                content:
                    text/plain:
                        schema:
                            type: string
        """
        auth = request.authorization
        if auth:
            user_email = auth.username
            user = get_user_by_email(user_email)
            user_id = user['id']
        else:
            user = getAuthData()
            user_id = user['id']
            user_email = user['email']

        try:
            question = get_question_by_id(question_id)
        except Exception as err:
            return "Invalid question id.", 404

        if not (user_email == question['owner_email'] or user['is_admin']):
            return "UNAUTHORIZED", 401  # not authorized

        # User is authoriced
        logger.info('Deleting question %s at the request of %s', question_id,
                    user_email)
        delete_question_by_id(question_id)

        return "SUCCESS", 200
Ejemplo n.º 5
0
    def post(self, question_id):
        """
        Refresh KG for question
        ---
        tags: [questions]
        parameters:
          - in: path
            name: question_id
            description: "question id"
            schema:
                type: string
            required: true
        responses:
            202:
                description: "refreshing in progress"
                content:
                    text/plain:
                        schema:
                            type: string
            404:
                description: "invalid question key"
                content:
                    text/plain:
                        schema:
                            type: string
        """
        auth = request.authorization
        if auth:
            user_email = auth.username
            user = get_user_by_email(user_email)
            user_id = user['id']
        else:
            user = getAuthData()
            user_id = user['id']
            user_email = user['email']

        # Update the knowledge graph for a question
        logger.info(
            f'Adding update task for question {question_id} for user {user_email} to the queue'
        )
        task = update_kg.apply_async(args=[question_id],
                                     kwargs={'user_email': user_email})
        logger.info(
            f'Update task for question {question_id} for user {user_email} to the queue has recieved task_id {task.id}'
        )
        return {'task_id': task.id}, 202
Ejemplo n.º 6
0
    def post(self, question_id):
        """
        Edit question metadata
        ---
        tags: [questions]
        parameters:
          - in: path
            name: question_id
            description: "question id"
            schema:
                type: string
            required: true
        requestBody:
            description: request body
            content:
                application/json:
                    schema:
                        type: object
                        required:
                          - name
                          - natural_question
                          - notes
                        properties:
                            name:
                                description: "name of question"
                                schema:
                                    type: string
                            natural_question:
                                description: "natural-language question"
                                schema:
                                    type: string
                            notes:
                                description: "notes"
                                schema:
                                    type: string
        responses:
            200:
                description: "question edited"
                content:
                    text/plain:
                        schema:
                            type: string
            401:
                description: "unauthorized"
                content:
                    text/plain:
                        schema:
                            type: string
            404:
                description: "invalid question key"
                content:
                    text/plain:
                        schema:
                            type: string
        """
        auth = request.authorization
        if auth:
            user_email = auth.username
            user = get_user_by_email(user_email)
            user_id = user['id']
        else:
            user = getAuthData()
            user_id = user['id']
            user_email = user['email']
        
        try:
            question = get_question_by_id(question_id)
        except Exception as err:
            return "Invalid question id.", 404
        
        if not (user_email == question['owner_email'] or user['is_admin']):
            return "UNAUTHORIZED", 401 # not authorized

        # User is authorized
        logger.info('Editing question %s at the request of %s', question_id, user_email)
        mods = {}
        if 'notes' in request.json:
            mods['notes'] = request.json['notes']
        if 'natural_question' in request.json:
            mods['natural_question'] = request.json['natural_question']
        
        modify_question_by_id(question_id, mods)

        return "SUCCESS", 200
Ejemplo n.º 7
0
    def post(self, question_id):
        """
        Set Question Visiblity.
        ---
        tags: [questions]
        parameters:
          - in: path
            name: question_id
            description: "question id"
            schema:
                type: string
            required: true
          - in: query
            name: visibility
            description: "question visibility"
            required: true
            schema:
                type: string
                enum:
                  - private
                  - public
                  - promoted
                default: private
                example: private
        responses:
            200:
                description: "question visibility edited"
                content:
                    text/plain:
                        schema:
                            type: string
            401:
                description: "unauthorized"
                content:
                    text/plain:
                        schema:
                            type: string
            404:
                description: "invalid question key"
                content:
                    text/plain:
                        schema:
                            type: string
        """

        auth = request.authorization
        if auth:
            user_email = auth.username
            user = get_user_by_email(user_email)
            user_id = user['id']
        else:
            user = getAuthData()
            user_id = user['id']
            user_email = user['email']

        try:
            question = get_question_by_id(question_id)
        except Exception as err:
            return "Invalid question id.", 404

        visibility = request.args.get('visibility', default='private')

        if 'roles' in user:
            user_is_admin = any(role['name'] == 'admin' for role in user['roles'])
        else:
            user_is_admin = user['is_admin']

        if not (user_email == question['owner_email'] or user_is_admin):
            return "UNAUTHORIZED", 401  # not authorized

        if visibility == 'promoted' and not user_is_admin:
            return "UNAUTHORIZED", 401

        # User is authorized
        mods = {
            'visibility': visibility
        }

        modify_question_by_id(question_id, mods)

        return "SUCCESS", 200
Ejemplo n.º 8
0
    def post(self):
        """
        Create a question.
        ---
        tags: [questions]
        requestBody:
            name: question
            content:
                application/json:
                    schema:
                        $ref: '#/components/schemas/Question'
            required: true
        responses:
            201:
                description: "question id"
                content:
                    text/plain:
                        schema:
                            type: string
        """
        auth = request.authorization
        if auth:
            user_email = auth.username
            user = get_user_by_email(user_email)
            user_id = user['id']
        else:
            user = getAuthData()
            user_id = user['id']
            user_email = user['email']

        logger.debug(f"Creating new question for user {user_email}.")
        request_json = request.json
        if 'question_graph' not in request_json:
            request_json['question_graph'] = request_json.pop(
                'machine_question', None)

        question_id = add_question(request.json, owner_id=user_id)

        if request.headers.get('RebuildCache', default='true') == 'true':
            # To speed things along we start an answerset generation task for this question
            # This isn't the standard answerset generation task because we might also trigger a KG Update

            logger.info(
                f'Adding update and answer tasks for question {question_id} for user {user_email} to the queue'
            )
            ug_task = update_kg.signature(args=[question_id],
                                          kwargs={'user_email': user_email},
                                          immutable=True)
            as_task = answer_question.signature(
                args=[question_id],
                kwargs={'user_email': user_email},
                immutable=True)
            task = answer_question.apply_async(
                args=[question_id],
                kwargs={'user_email': user_email},
                link_error=ug_task | as_task)
            logger.info(
                f'Update task for question {question_id} for user {user_email} to the queue has recieved task_id {task.id}'
            )

        elif request.headers.get('AnswerNow', default='true') == 'true':
            logger.info(
                f'Adding answer task for question {question_id} for user {user_email} to the queue'
            )
            task = answer_question.apply_async(
                args=[question_id], kwargs={'user_email': user_email})
            logger.info(
                f'Answer task for question {question_id} for user {user_email} to the queue has recieved task_id {task.id}'
            )

        return question_id, 201
Ejemplo n.º 9
0
    def get(self, qa_id, answer_id):
        """
        Get answer
        ---
        tags: [answer]
        parameters:
          - in: path
            name: qa_id
            description: "<question_id>_<answerset_id>"
            type: string
            required: true
          - in: path
            name: answer_id
            description: "answer/result id"
            type: string
            required: true
        responses:
            200:
                description: "answer data"
                type: object
                properties:
                    answer:
                        schema:
                            $ref: '#/definitions/Result'
                    answerset:
                        schema:
                            $ref: '#/definitions/Response'
                    user:
                        type: object
                    question:
                        type: object
                    other_questions:
                        type: array
                        items:
                            type: object
                    other_answersets:
                        type: array
                        items:
                            type: object
                    feedback:
                        type: array
                        items:
                            type: object
            404:
                description: "invalid answerset/answer id"
                type: string
        """

        try:
            question_id, answerset_id = qa_id.split('_')
            question = get_question_by_id(question_id)
            answerset = get_answerset_by_id(answerset_id)
            answersets = question.answersets
            if not answerset in answersets:
                raise AssertionError()
            answer = get_answer_by_id(answer_id)
            if not answer in answerset.answers:
                raise AssertionError()
        except Exception as err:
            return "Invalid answerset or answer key.", 404

        questions = answerset.questions
        idx = questions.index(question)
        questions.pop(idx)
        idx = answersets.index(answerset)
        answersets.pop(idx)

        feedback = list_feedback_by_question_answer(question, answer)

        user = getAuthData()

        return {'user': user,\
                'answerset': answerset.toJSON(),\
                'answer': answer.toJSON(),\
                'feedback': [f.toJSON() for f in feedback],\
                'question': question.toJSON(),\
                'other_answersets': [aset.toJSON() for aset in answersets],
                'other_questions': [q.toJSON() for q in questions]}, 200
Ejemplo n.º 10
0
    def get(self):
        """
        Get list of questions
        ---
        tags: [question]
        responses:
            200:
                description: list of questions
                schema:
                    type: "array"
                    items:
                        $ref: '#/definitions/Question'
        """
        user = getAuthData()
        question_list = list_questions()
        # user_question_list = list_questions_by_username(user['username'])
        # nonuser_question_list = list_questions_by_username(user['username'], invert=True)

        tasks = get_tasks().values()

        # filter out the SUCCESS/FAILURE tasks
        tasks = [
            t for t in tasks
            if not (t['state'] == 'SUCCESS' or t['state'] == 'FAILURE'
                    or t['state'] == 'REVOKED')
        ]

        # get question hashes
        question_tasks = {q.id: [] for q in question_list}
        for t in tasks:
            if not t['args']:
                continue
            match = re.match(r"[\[(]'(.*)',?[)\]]", t['args'])
            if not match:
                continue
            question_id = match.group(1)
            question_tasks[question_id].append(t)

        # split into answer and update tasks
        for t in tasks:
            t['type'] = 'answering' if t['name'] == 'manager.tasks.answer_question' else \
                'refreshing KG' if t['name'] == 'manager.tasks.update_kg' else \
                'something?'

        def augment_info(question):
            answerset_timestamps = [a.timestamp for a in question.answersets]
            if answerset_timestamps:
                latest_idx = answerset_timestamps.index(
                    max(answerset_timestamps))
                latest_answerset_id = question.answersets[latest_idx].id
                latest_answerset_timestamp = question.answersets[
                    latest_idx].timestamp
            else:
                latest_answerset_id = None
                latest_answerset_timestamp = None
            q = question.toJSON()
            q['user_email'] = question.user.email
            q.pop('user_id')
            q.pop('machine_question')
            return {
                'latest_answerset_id':
                latest_answerset_id,
                'latest_answerset_timestamp':
                latest_answerset_timestamp.isoformat()
                if latest_answerset_timestamp else None,
                'tasks': [t['type'] for t in question_tasks[question.id]],
                **q
            }

        return [augment_info(q) for q in question_list], 200