def _get_saved_replies(request, number_of_items=30, offset=0, saved_reply_ids=None):
    user_token = request['user'].token
    search_term = optional_parameter(request, 'searchTerm', None)
    saved_replies = AnnotationStore.get_annotations(user_token, annotation_ids=saved_reply_ids,
                                                    search_term=search_term, saved_replies=True)
    return {'totalItems': len(saved_replies),
            'items': saved_replies[offset:offset+number_of_items]}
Beispiel #2
0
 def get_answers_from_similar_questions(
         user_token: str,
         question: str,
         type: str = 'all',
         document_ids: List[str] = None,
         threshold: str = 'MEDIUM') -> List[dict]:
     """
     Returns answers from the most similar saved replies and annotations.
     :param user_token:                          User's ID token
     :param question:                            question in string format
     :param type:                                'saved_reply', 'annotation' or 'all'
     :param document_ids:                        Limit annotation search to specified document IDs
     :param threshold:                           Only return results with the given confidence
     """
     type_to_param = {'all': None, 'saved_reply': True, 'annotation': False}
     results = AnnotationStore.similar_annotations(
         user_token,
         question,
         document_ids,
         saved_replies=type_to_param[type])
     threshold_value = THRESHOLD_MAP['savedreply'][threshold]
     results = list(
         filter(lambda reply: reply['confidence'] >= threshold_value,
                results))
     return results
def test_eval():
    init_db(reset_database=True)
    answer = "42"
    document_id = "Pizza"
    AnnotationStore.create_annotation(LOGIN, 'This is a potato bla', answer, document_id)
    AnnotationStore.create_annotation(LOGIN, 'Sandwich.', answer, document_id)
    AnnotationStore.create_annotation(LOGIN, 'Not a potato sandwich', answer, document_id)
    annotations = AnnotationStore.get_annotations(LOGIN)
    pprint(AnnotationStore.similar_annotations(LOGIN, similar_query="This is a potato."))
def test_saved_reply():
    saved_reply_id = AnnotationStore.create_annotation('fake-user',
                                                       'What is the time?',
                                                       'Lunch time!')
    response = Responder.get_answers_from_similar_questions(
        'fake-user', 'What time is it?')
    pprint(response)
    assert response[0]['answerText'] == 'Lunch time!'
def test_annotation():
    annotation_id = AnnotationStore.create_annotation('fake-user',
                                                      'What is this?',
                                                      'This is an annotation',
                                                      document_id='doc1',
                                                      page=3,
                                                      metadata={'test': True})
    response = Responder.get_answers_from_similar_questions(
        'fake-user', 'What is this?')
    pprint(response)
    assert response[0]['answerText'] == 'This is an annotation'
    assert response[0]['page'] == 3
    assert response[0]['metadata']['test'] == True
def _add_annotation(request, metadata=None):
    question = required_parameter(request, 'question')
    answer = required_parameter(request, 'answer')
    document_id = required_parameter(request, 'documentId')
    page = optional_parameter(request, 'page', None)
    start_offset = optional_parameter(request, 'startOffset', None)
    end_offset = optional_parameter(request, 'endOffset', None)
    if start_offset is None or end_offset is None:
        raise UserException(ERROR_ANNOTATION_MISSING_PARAMS)
    if metadata is None:
        metadata = {}

    metadata['startOffset'] = int(start_offset)
    metadata['endOffset'] = int(end_offset)

    return AnnotationStore.create_annotation(request['user'].token, question, answer,
                                             document_id, page, metadata)
def delete_all_user_data(user_id):
    """Delete user, depending on global settings this will be in production or info DB."""
    user = User.get('user_id', user_id)
    if user is None:
        raise UserException(ERROR_USER_DOES_NOT_EXIST % user_id)
    documents = DocumentStore.get_documents(user.token)
    for document in documents:
        DocumentStore.delete_document(user.token, document['id'])
    saved_replies = AnnotationStore.get_annotations(user.token,
                                                    saved_replies=True)
    for saved_reply in saved_replies:
        AnnotationStore.delete_annotation(user.token, saved_reply['id'])
    annotations = AnnotationStore.get_annotations(user.token,
                                                  saved_replies=False)
    for annotation in annotations:
        AnnotationStore.delete_annotation(user.token, annotation['id'])

    user.delete_instance()
    info("User " + user_id + " data deleted successfully")
    info("Looking for session data")
    del_counter = 0
    sessions = Session.all('user_id', user_id)
    for session in sessions:
        session.delete_instance()
        del_counter += 1
    info("Deleted " + str(del_counter) + " sessions")
    del_counter = 0
    events = Event.all('user_id', user_id)
    for event in events:
        event.delete_instance()
        del_counter += 1
    info("Deleted " + str(del_counter) + " events")
    del_counter = 0
    bots = Bot.all('user_id', user_id)
    for bot in bots:
        bot.delete_instance()
        del_counter += 1
    info("Deleted " + str(del_counter) + " bots")
    del_counter = 0
    coverage_entries = Coverage.all('user_id', user_id)
    for coverage in coverage_entries:
        coverage.delete_instance()
        del_counter += 1
    info("Deleted " + str(del_counter) + " coveragae entries")
    del_counter = 0
    email_events = EmailEvent.all('user_id', user_id)
    for event in email_events:
        event.delete_instance()
        del_counter += 1
    info("Deleted " + str(del_counter) + " email events")
def test_saved_reply():
    init_db(reset_database=True)
    question = "What's the time, Mr Wolf?"
    answer = "Lunch time!"
    AnnotationStore.create_annotation(LOGIN, question, answer)
    AnnotationStore.create_annotation(LOGIN, question, answer, document_id='bla.txt')
    # return saved replies only
    annotations = AnnotationStore.similar_annotations(LOGIN, question, saved_replies=True)
    assert len(annotations) == 1
    assert annotations[0]["sourceType"] == "saved_reply"
    # return annotations only
    annotations = AnnotationStore.similar_annotations(LOGIN, question, saved_replies=False)
    assert len(annotations) == 1
    assert annotations[0]["sourceType"] == "annotation"
    # return both
    annotations = AnnotationStore.similar_annotations(LOGIN, question, saved_replies=None)
    assert len(annotations) == 2
    assert annotations[0]["sourceType"] != annotations[1]["sourceType"]
def _add_answer(request):
    user_token = request['user'].token
    reply_id = required_parameter(request, 'replyId')
    answer = required_parameter(request, 'answer')
    return AnnotationStore.add_answer(user_token, reply_id, answer)
def _delete_annotation(request):
    annotation_id = required_parameter(request, 'annotationId')
    return AnnotationStore.delete_annotation(request['user'].token, annotation_id)
def _edit_answer(request):
    answer_id = required_parameter(request, 'answerId')
    answer = required_parameter(request, 'answer')
    return AnnotationStore.edit_answer(request['user'].token, answer_id, answer)
def _get_annotations(request, number_of_items=30, offset=0, annotation_ids=None, document_ids=None, pages=None):
    search_term = optional_parameter(request, 'searchTerm', None)
    annotations = AnnotationStore.get_annotations(request['user'].token, search_term, annotation_ids, document_ids,
                                                  pages, saved_replies=False)
    return {'totalItems': len(annotations), 'items': annotations[offset:offset + number_of_items]}
def _delete_paraphrase_question(request):
    question_id = required_parameter(request, 'questionId')
    return AnnotationStore.delete_paraphrase_question(request['user'].token, question_id)
def _add_answer(request):
    annotation_id = required_parameter(request, 'annotationId')
    answer = required_parameter(request, 'answer')
    return AnnotationStore.add_answer(request['user'].token, annotation_id, answer)
Beispiel #15
0
def cleanup():
    for annotation in AnnotationStore.get_annotations('fake-user'):
        AnnotationStore.delete_annotation('fake-user', annotation['id'])
    for document in DocumentStore.get_documents('fake-user'):
        DocumentStore.delete_document('fake-user', document['id'])
def test_annotations():
    init_db(reset_database=True)
    question = "What is the meaning of life?"
    answer = "42"
    document_id = "Pizza"
    AnnotationStore.create_annotation(LOGIN, question, answer, document_id)
    annotations = AnnotationStore.get_annotations(LOGIN)
    assert len(annotations) == 1

    annotations = AnnotationStore.get_annotations(LOGIN, document_ids=[document_id])
    assert len(annotations) == 1

    annotation_id = annotations[0]['id']
    annotations = AnnotationStore.get_annotations(LOGIN, annotation_ids=[annotation_id])
    assert len(annotations) == 1
    assert len(annotations[0]['answers']) == 1

    answer_id = AnnotationStore.add_answer(LOGIN, annotation_id, "New answer")['answerId']
    annotations = AnnotationStore.get_annotations(LOGIN, annotation_ids=[annotation_id])
    assert len(annotations[0]['answers']) == 2

    AnnotationStore.edit_answer(LOGIN, answer_id, "Old answer")
    annotations = AnnotationStore.get_annotations(LOGIN, annotation_ids=[annotation_id])
    assert annotations[0]['answers'][1]['answer'] == "Old answer"

    AnnotationStore.delete_answer(LOGIN, answer_id)
    annotations = AnnotationStore.get_annotations(LOGIN, annotation_ids=[annotation_id])
    assert len(annotations[0]['answers']) == 1

    with pytest.raises(UserException):
        AnnotationStore.edit_answer(LOGIN, answer_id, "editing a deleted answer")

    with pytest.raises(UserException):
        AnnotationStore.delete_answer(LOGIN, annotations[0]['answers'][0]['id'])

    AnnotationStore.edit_canonical_question(LOGIN, annotation_id, "What is a new question?")
    annotations = AnnotationStore.get_annotations(LOGIN, annotation_ids=[annotation_id])
    assert annotations[0]['canonicalQuestion'] == "What is a new question?"

    with pytest.raises(UserException):
        AnnotationStore.edit_canonical_question(LOGIN, 'blas', "What is a new question?")

    question_id = AnnotationStore.add_paraphrase_question(LOGIN, annotation_id, "Another question?")['questionId']
    annotations = AnnotationStore.get_annotations(LOGIN, annotation_ids=[annotation_id])
    assert annotations[0]['paraphraseQuestions'][0]['question'] == 'Another question?'

    AnnotationStore.edit_paraphrase_question(LOGIN, question_id, "Yet another question?")
    annotations = AnnotationStore.get_annotations(LOGIN, annotation_ids=[annotation_id])
    assert annotations[0]['paraphraseQuestions'][0]['question'] == 'Yet another question?'

    AnnotationStore.delete_paraphrase_question(LOGIN, question_id)
    annotations = AnnotationStore.get_annotations(LOGIN, annotation_ids=[annotation_id])
    assert len(annotations[0]['paraphraseQuestions']) == 0

    question = "What should I search for?"
    answer = "This."
    document_id = "Pizza"
    AnnotationStore.create_annotation(LOGIN, question, answer, document_id)
    annotations = AnnotationStore.get_annotations(LOGIN, search_term='SEARCH')
    assert len(annotations) == 1
    annotations = AnnotationStore.get_annotations(LOGIN, search_term='what')
    assert len(annotations) == 2
    annotations = AnnotationStore.get_annotations(LOGIN, search_term='this')
    assert len(annotations) == 1

    question = "What document is this in?"
    answer = "Another one."
    document_id = "Doc2"
    AnnotationStore.create_annotation(LOGIN, question, answer, document_id)
    annotations = AnnotationStore.get_annotations(LOGIN, document_ids=["Pizza"])
    assert len(annotations) == 2
    annotations = AnnotationStore.get_annotations(LOGIN, document_ids=["Doc2"])
    assert len(annotations) == 1

    AnnotationStore.delete_annotation(LOGIN, annotation_id)
    annotations = AnnotationStore.get_annotations(LOGIN, annotation_ids=[annotation_id])
    assert len(annotations) == 0

    with pytest.raises(UserException):
        AnnotationStore.edit_canonical_question(LOGIN, annotation_id, "What is a new question?")

    AnnotationStore.create_annotation(LOGIN, "What's the time?", "Bed time", "Night", page=4, metadata={
        'custom': 'testing'
    })
    annotations = AnnotationStore.get_annotations(LOGIN, document_ids=['Night'])
    assert len(annotations) == 1
    assert annotations[0]['page'] == 4
    assert annotations[0]['metadata']['custom'] == 'testing'

    annotations = AnnotationStore.get_annotations(LOGIN, document_ids=['Night'], pages=[1, 2, 3])
    assert len(annotations) == 0
    annotations = AnnotationStore.get_annotations(LOGIN, document_ids=['Night'], pages=[4, 5])
    assert len(annotations) == 1

    annotations_new = AnnotationStore.get_annotations(LOGIN, search_term="bed")
    assert len(annotations_new) == 1 and annotations[0]['id'] == annotations_new[0]['id']
    annotations_new = AnnotationStore.get_annotations(LOGIN, search_term="time")
    assert len(annotations_new) == 1 and annotations[0]['id'] == annotations_new[0]['id']
    annotations_new = AnnotationStore.get_annotations(LOGIN, search_term="98ahf98e")
    assert len(annotations_new) == 0

    AnnotationStore.create_annotation(LOGIN, "What's the time?", "yesterday")
    AnnotationStore.create_annotation(LOGIN, "What is the time", "today")

    # pprint(AnnotationStore.get_annotations(LOGIN))
    # pprint(AnnotationStore.get_annotations(LOGIN, search_term="What's the time?"))
    assert OrderedDict(
        map(lambda x: (x.unique_id, None), AnnotationStore._retriever.get(phrase="What's the time?"))) == OrderedDict(
        map(lambda x: (x.get_retrievable().unique_id, None),
            AnnotationStore._retriever.retrieve(query="What's the time?"))
    )
    assert OrderedDict(
        map(lambda x: (x.unique_id, None), AnnotationStore._retriever.get(phrase="What's the time?"))) == OrderedDict(
        map(lambda x: (x['sourceId'], None),
            AnnotationStore.similar_annotations(LOGIN, similar_query="What's the time?"))
    )
    pprint(AnnotationStore.similar_annotations(LOGIN, similar_query="What's the time?"))
def _edit_canonical_question(request):
    annotation_id = required_parameter(request, 'annotationId')
    question = required_parameter(request, 'question')
    return AnnotationStore.edit_canonical_question(request['user'].token, annotation_id, question)
def _delete_saved_reply(request):
    user_token = request['user'].token
    reply_id = required_parameter(request, 'replyId')
    AnnotationStore.delete_annotation(user_token, reply_id)
    return {'replyId': reply_id}
def _create_saved_reply(request):
    user_token = request['user'].token
    question = required_parameter(request, 'question')
    answer = required_parameter(request, 'answer')
    response = AnnotationStore.create_annotation(user_token, question, answer)
    return {'replyId': response['annotationId'], 'answerId': response['answerId']}
def _stats(request):
    user_id = request['user'].user_id
    events = Event.select().where(Event.user_id == user_id).order_by(Event.created.desc())
    total = events.count()
    automatic = 0
    assisted = 0
    unanswered = 0
    total_duration = 0
    average_response_time = 0
    questions = []
    source_count = {}
    coverage = []

    # Find total number of saved replies
    total_saved_replies = len(AnnotationStore.get_annotations(request['user'].token, saved_replies=True))

    # Find total number of documents
    documents = DocumentStore.get_documents(request['user'].token)
    total_documents = len(documents)

    for event in events:
        question = {
            'created': event.created.isoformat(),
            'duration': event.duration,
            'question': event.question
        }
        if event.answered:
            answer = event.answers[0]
            total_duration += event.duration
            question['answer'] = answer['answerText']
            if answer['sourceType'] == 'saved_reply':
                automatic += 1
                question['status'] = 'automatic'
                question['matchedQuestion'] = answer['matchedQuestion']
            else:
                assisted += 1
                question['status'] = 'assisted'
                if answer['sourceId'] in source_count:
                    source_count[answer['sourceId']] += 1
                else:
                    source_count[answer['sourceId']] = 1
        else:
            unanswered += 1
            question['status'] = 'unanswered'
        questions.append(question)

    source_count['saved_reply'] = automatic
    source_count['unanswered'] = unanswered
    sources = sorted(source_count.items(), key=lambda x: x[1], reverse=True)
    sources_percent = []
    if total > 0:
        for source in sources:
            if source[0] == 'saved_reply':
                document_title = 'Saved replies'
            elif source[0] == 'unanswered':
                document_title = 'Unanswered'
            else:
                document_title = source[0]
                if source[0] in documents:
                    if documents:
                        if len(documents[source[0]]['title']) > 0:
                            document_title = documents[source[0]]['title']
                else:
                    document_title = 'Deleted document'
            sources_percent.append({'source': source[0], 'title': document_title, 'percent': (source[1] / total) * 100})
        average_response_time = total_duration / total

    coverage_stats = Coverage.select().where(Coverage.user_id == user_id)
    for stat in coverage_stats:
        coverage.append({'coverage': stat.coverage, 'time': stat.created})

    return {'averageResponseTime': average_response_time, 'totalSavedReplies': total_saved_replies,
            'totalDocuments': total_documents, 'totalQuestions': total, 'automatic': automatic, 'assisted': assisted,
            'unanswered': unanswered, 'sources': sources_percent, 'questions': questions, 'coverage': coverage}
def _delete_answer(request):
    user_token = request['user'].token
    answer_id = required_parameter(request, 'answerId')
    return AnnotationStore.delete_answer(user_token, answer_id)
def _add_paraphrase_question(request):
    annotation_id = required_parameter(request, 'annotationId')
    question = required_parameter(request, 'question')
    return AnnotationStore.add_paraphrase_question(request['user'].token, annotation_id, question)
def _add_paraphrase_question(request):
    user_token = request['user'].token
    reply_id = required_parameter(request, 'replyId')
    question = required_parameter(request, 'question')
    return AnnotationStore.add_paraphrase_question(user_token, reply_id, question)
def _edit_canonical_question(request):
    user_token = request['user'].token
    reply_id = required_parameter(request, 'replyId')
    question = required_parameter(request, 'question')
    AnnotationStore.edit_canonical_question(user_token, reply_id, question)
    return {'replyId': reply_id}
def _edit_paraphrase_question(request):
    user_token = request['user'].token
    question_id = required_parameter(request, 'questionId')
    question = required_parameter(request, 'question')
    return AnnotationStore.edit_paraphrase_question(user_token, question_id, question)