exerciseListAPI.py 3.05 KB
Newer Older
1 2 3 4 5 6
"""The corpus list API. Add it to your REST API to provide users with a list of metadata for available texts."""
from datetime import datetime
from typing import List, Set

import conllu
from conllu import TokenList
7 8 9
from flask_restful import Resource
from flask_restful.reqparse import RequestParser

10 11 12 13 14 15 16 17 18
from mcserver.app.models import Exercise, Language, VocabularyCorpus, UpdateInfo, ResourceType
from mcserver.app.services import NetworkService, FileService


class ExerciseListAPI(Resource):
    """The exercise list API resource. It enables some of the CRUD operations for the exercises from the database."""

    def __init__(self):
        """Initialize possible arguments for calls to the exercise list REST API."""
19
        self.reqparse: RequestParser = NetworkService.base_request_parser.copy()
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
        self.reqparse.add_argument("lang", type=str, required=True, help="No language specified")
        self.reqparse.add_argument("last_update_time", type=int, required=False, default=0,
                                   help="No milliseconds time for last update provided")
        self.reqparse.add_argument("vocabulary", type=str, required=False, help="No reference vocabulary provided")
        self.reqparse.add_argument("frequency_upper_bound", type=int, required=False,
                                   help="No upper bound for reference vocabulary frequency provided")
        super(ExerciseListAPI, self).__init__()

    def get(self):
        """The GET method for the exercise list REST API. It provides metadata for all available exercises."""
        args: dict = self.reqparse.parse_args()
        vocabulary_set: Set[str]
        last_update: int = args["last_update_time"]
        last_update_time: datetime = datetime.fromtimestamp(last_update / 1000.0)
        ui_exercises: UpdateInfo = UpdateInfo.query.filter_by(resource_type=ResourceType.exercise_list.name).first()
        if ui_exercises.last_modified_time < last_update_time:
            return NetworkService.make_json_response([])
        try:
            vc: VocabularyCorpus = VocabularyCorpus[args["vocabulary"]]
            vocabulary_set = FileService.get_vocabulary_set(vc, args["frequency_upper_bound"])
        except KeyError:
            vocabulary_set = set()
        lang: Language
        try:
            lang = Language(args["lang"])
        except ValueError:
            lang = Language.English
        exercises: List[Exercise] = Exercise.query.filter_by(language=lang.value)
        ret_val: List[dict] = [x.serialize(compress=True) for x in exercises]
        matching_degrees: List[float] = []
        if len(vocabulary_set):
            for exercise in exercises:
                conll: List[TokenList] = conllu.parse(exercise.conll)
                lemmata: List[str] = [tok["lemma"] for sent in conll for tok in sent.tokens]
                matching_degrees.append(sum((1 if x in vocabulary_set else 0) for x in lemmata) / len(lemmata) * 100)
            for i in range(len(ret_val)):
                ret_val[i]["matching_degree"] = matching_degrees[i]
        return NetworkService.make_json_response(ret_val)