Commit 2e0e4b74 authored by Konstantin Schulz's avatar Konstantin Schulz

all main entry points (= mcserver) of the REST API are now documented in the openAPI specification

parent 35d4aa7a
Pipeline #11728 passed with stages
in 2 minutes and 40 seconds
...@@ -7,13 +7,11 @@ from mcserver import Config ...@@ -7,13 +7,11 @@ from mcserver import Config
bp = Blueprint("api", __name__) bp = Blueprint("api", __name__)
api = Api(bp) api = Api(bp)
from . import frequencyAPI from . import frequencyAPI, textcomplexityAPI
from csm.app.api.annisFindAPI import AnnisFindAPI from csm.app.api.annisFindAPI import AnnisFindAPI
from csm.app.api.corpusStorageManagerAPI import CorpusStorageManagerAPI from csm.app.api.corpusStorageManagerAPI import CorpusStorageManagerAPI
from csm.app.api.subgraphAPI import SubgraphAPI from csm.app.api.subgraphAPI import SubgraphAPI
from csm.app.api.textcomplexityAPI import TextComplexityAPI
api.add_resource(AnnisFindAPI, Config.SERVER_URI_ANNIS_FIND, endpoint="find") api.add_resource(AnnisFindAPI, Config.SERVER_URI_ANNIS_FIND, endpoint="find")
api.add_resource(CorpusStorageManagerAPI, Config.SERVER_URI_CSM, endpoint="csm") api.add_resource(CorpusStorageManagerAPI, Config.SERVER_URI_CSM, endpoint="csm")
api.add_resource(SubgraphAPI, Config.SERVER_URI_CSM_SUBGRAPH, endpoint="subgraph") api.add_resource(SubgraphAPI, Config.SERVER_URI_CSM_SUBGRAPH, endpoint="subgraph")
api.add_resource(TextComplexityAPI, Config.SERVER_URI_TEXT_COMPLEXITY, endpoint='textcomplexity')
import rapidjson as json from mcserver.app.models import AnnisResponse, TextComplexity
import flask
from flask_restful import Resource
from flask_restful.reqparse import RequestParser
from mcserver.app.models import AnnisResponse, GraphData, TextComplexity
from mcserver.app.services import NetworkService, CorpusService, TextComplexityService from mcserver.app.services import NetworkService, CorpusService, TextComplexityService
from openapi.openapi_server.models import TextComplexityForm
class TextComplexityAPI(Resource): def post(complexity_data: dict):
"""The Text Complexity API resource. It gives users measures for text complexity for a given text.""" tcf: TextComplexityForm = TextComplexityForm.from_dict(complexity_data)
ar: AnnisResponse = AnnisResponse.from_dict(
def __init__(self): tcf.annis_response.to_dict()) if tcf.annis_response else CorpusService.get_corpus(tcf.urn, is_csm=True)
self.reqparse: RequestParser = NetworkService.base_request_parser.copy() tc: TextComplexity = TextComplexityService.text_complexity(tcf.measure, tcf.urn, True, ar.graph_data)
self.reqparse.add_argument('urn', type=str, location="data", required=True, help='No URN provided') return NetworkService.make_json_response(tc.to_dict())
self.reqparse.add_argument('measure', type=str, location="data", required=True, help='No MEASURE provided')
self.reqparse.add_argument('annis_response', type=dict, location="data", required=False,
help='No ANNIS response provided')
super(TextComplexityAPI, self).__init__()
def post(self):
args: dict = json.loads(flask.request.data.decode("utf-8"))
urn: str = args["urn"]
measure: str = args["measure"]
ar_dict: dict = args.get("annis_response", None)
ar: AnnisResponse = AnnisResponse.from_dict(ar_dict) if ar_dict else CorpusService.get_corpus(urn, is_csm=True)
tc: TextComplexity = TextComplexityService.text_complexity(measure, urn, True, ar.graph_data)
return NetworkService.make_json_response(tc.to_dict())
...@@ -22,10 +22,21 @@ paths: ...@@ -22,10 +22,21 @@ paths:
items: items:
$ref: "../openapi_models.yaml#/components/schemas/FrequencyItem" $ref: "../openapi_models.yaml#/components/schemas/FrequencyItem"
parameters: parameters:
- name: urn - $ref: '../openapi_models.yaml#/components/parameters/UrnParam'
in: query /textcomplexity:
description: CTS URN for referencing the corpus. post:
required: true summary: Gives users measures of text complexity for a given text.
schema: operationId: csm.app.api.textcomplexityAPI.post
type: string responses:
example: urn:cts:latinLit:phi1254.phi001.perseus-lat2:5.6.21-5.6.21 200:
description: Text complexity measures for a given text.
content:
application/json:
schema:
$ref: '../openapi_models.yaml#/components/schemas/TextComplexity'
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
$ref: '../openapi_models.yaml#/components/schemas/TextComplexityFormBase'
"""The API blueprint. Register it on the main application to enable the REST API for text retrieval.""" """The API blueprint. Register it on the main application to enable the REST API for text retrieval."""
from flask import Blueprint from flask import Blueprint
from flask_restful import Api from flask_restful import Api
from mcserver import Config
bp = Blueprint("api", __name__) bp = Blueprint("api", __name__)
api = Api(bp) api = Api(bp)
from . import corpusAPI, corpusListAPI, exerciseAPI, exerciseListAPI, fileAPI, frequencyAPI, staticExercisesAPI from . import corpusAPI, corpusListAPI, exerciseAPI, exerciseListAPI, fileAPI, frequencyAPI, h5pAPI, kwicAPI, \
from mcserver.app.api.h5pAPI import H5pAPI rawTextAPI, staticExercisesAPI, textcomplexityAPI, validReffAPI, vectorNetworkAPI, vocabularyAPI
from mcserver.app.api.kwicAPI import KwicAPI
from mcserver.app.api.rawTextAPI import RawTextAPI
from mcserver.app.api.textcomplexityAPI import TextComplexityAPI
from mcserver.app.api.validReffAPI import ValidReffAPI
from mcserver.app.api.vectorNetworkAPI import VectorNetworkAPI
from mcserver.app.api.vocabularyAPI import VocabularyAPI
api.add_resource(H5pAPI, Config.SERVER_URI_H5P, endpoint="h5p")
api.add_resource(KwicAPI, Config.SERVER_URI_KWIC, endpoint="kwic")
api.add_resource(RawTextAPI, Config.SERVER_URI_RAW_TEXT, endpoint="rawtext")
api.add_resource(TextComplexityAPI, Config.SERVER_URI_TEXT_COMPLEXITY, endpoint='textcomplexity')
api.add_resource(ValidReffAPI, Config.SERVER_URI_VALID_REFF, endpoint="validReff")
api.add_resource(VectorNetworkAPI, Config.SERVER_URI_VECTOR_NETWORK, endpoint="vectorNetwork")
api.add_resource(VocabularyAPI, Config.SERVER_URI_VOCABULARY, endpoint="vocabulary")
...@@ -12,6 +12,7 @@ from mcserver.app.models import ExerciseType, Solution, ExerciseData, AnnisRespo ...@@ -12,6 +12,7 @@ from mcserver.app.models import ExerciseType, Solution, ExerciseData, AnnisRespo
from mcserver.app.services import AnnotationService, CorpusService, NetworkService, TextComplexityService from mcserver.app.services import AnnotationService, CorpusService, NetworkService, TextComplexityService
from mcserver.config import Config from mcserver.config import Config
from mcserver.models_auto import Exercise, TExercise, UpdateInfo from mcserver.models_auto import Exercise, TExercise, UpdateInfo
from openapi.openapi_server.models import ExerciseForm
def adjust_solutions(exercise_data: ExerciseData, exercise_type: str, solutions: List[Solution]) -> List[Solution]: def adjust_solutions(exercise_data: ExerciseData, exercise_type: str, solutions: List[Solution]) -> List[Solution]:
...@@ -113,19 +114,20 @@ def map_exercise_data_to_database(exercise_data: ExerciseData, exercise_type: st ...@@ -113,19 +114,20 @@ def map_exercise_data_to_database(exercise_data: ExerciseData, exercise_type: st
def post(exercise_data: dict) -> Union[Response, ConnexionResponse]: def post(exercise_data: dict) -> Union[Response, ConnexionResponse]:
exercise_type: ExerciseType = ExerciseType(exercise_data["type"]) ef: ExerciseForm = ExerciseForm.from_dict(exercise_data)
search_values_list: List[str] = json.loads(exercise_data["search_values"]) ef.urn = ef.urn if ef.urn else ""
exercise_type: ExerciseType = ExerciseType(ef.type)
search_values_list: List[str] = json.loads(ef.search_values)
aqls: List[str] = AnnotationService.map_search_values_to_aql(search_values_list=search_values_list, aqls: List[str] = AnnotationService.map_search_values_to_aql(search_values_list=search_values_list,
exercise_type=exercise_type) exercise_type=exercise_type)
search_phenomena: List[Phenomenon] = [Phenomenon().__getattribute__(x.split("=")[0].upper()) for x in search_phenomena: List[Phenomenon] = [Phenomenon().__getattribute__(x.split("=")[0].upper()) for x in
search_values_list] search_values_list]
urn: str = exercise_data.get("urn", "")
# if there is custom text instead of a URN, immediately annotate it # if there is custom text instead of a URN, immediately annotate it
conll_string_or_urn: str = urn if CorpusService.is_urn(urn) else AnnotationService.get_udpipe( conll_string_or_urn: str = ef.urn if CorpusService.is_urn(ef.urn) else AnnotationService.get_udpipe(
CorpusService.get_raw_text(urn, False)) CorpusService.get_raw_text(ef.urn, False))
try: try:
# construct graph from CONLL data # construct graph from CONLL data
response: dict = get_graph_data(title=urn, conll_string_or_urn=conll_string_or_urn, aqls=aqls, response: dict = get_graph_data(title=ef.urn, conll_string_or_urn=conll_string_or_urn, aqls=aqls,
exercise_type=exercise_type, search_phenomena=search_phenomena) exercise_type=exercise_type, search_phenomena=search_phenomena)
except ValueError: except ValueError:
return connexion.problem(500, Config.ERROR_TITLE_INTERNAL_SERVER_ERROR, return connexion.problem(500, Config.ERROR_TITLE_INTERNAL_SERVER_ERROR,
...@@ -133,12 +135,10 @@ def post(exercise_data: dict) -> Union[Response, ConnexionResponse]: ...@@ -133,12 +135,10 @@ def post(exercise_data: dict) -> Union[Response, ConnexionResponse]:
solutions_dict_list: List[Dict] = response["solutions"] solutions_dict_list: List[Dict] = response["solutions"]
solutions: List[Solution] = [Solution.from_dict(x) for x in solutions_dict_list] solutions: List[Solution] = [Solution.from_dict(x) for x in solutions_dict_list]
ar: AnnisResponse = make_new_exercise( ar: AnnisResponse = make_new_exercise(
conll=response["conll"], correct_feedback=exercise_data.get("correct_feedback", ""), conll=response["conll"], correct_feedback=ef.correct_feedback, exercise_type=ef.type,
exercise_type=exercise_data["type"], general_feedback=exercise_data.get("general_feedback", ""), general_feedback=ef.general_feedback, graph_data_raw=response["graph_data_raw"],
graph_data_raw=response["graph_data_raw"], incorrect_feedback=exercise_data.get("incorrect_feedback", ""), incorrect_feedback=ef.incorrect_feedback, instructions=ef.instructions, language=ef.language,
instructions=exercise_data["instructions"], language=exercise_data.get("language", "de"), partially_correct_feedback=ef.partially_correct_feedback, search_values=ef.search_values,
partially_correct_feedback=exercise_data.get("partially_correct_feedback", ""), solutions=solutions, type_translation=ef.type_translation, urn=ef.urn, work_author=ef.work_author,
search_values=exercise_data["search_values"], solutions=solutions, work_title=ef.work_title)
type_translation=exercise_data.get("type_translation", ""), urn=urn,
work_author=exercise_data.get("work_author", ""), work_title=exercise_data.get("work_title", ""))
return NetworkService.make_json_response(ar.to_dict()) return NetworkService.make_json_response(ar.to_dict())
import json from typing import List, Union
from typing import List import connexion
from connexion.lifecycle import ConnexionResponse
from flask_restful import Resource, abort from flask import Response
from flask_restful.reqparse import RequestParser from mcserver import Config
from mcserver.app import db from mcserver.app import db
from mcserver.app.models import Language, ExerciseType, Solution from mcserver.app.models import Language, ExerciseType, Solution
from mcserver.app.services import TextService, NetworkService from mcserver.app.services import TextService, NetworkService
from mcserver.models_auto import Exercise from mcserver.models_auto import Exercise
class H5pAPI(Resource): def get(eid: str, lang: str, solution_indices: List[int]) -> Union[Response, ConnexionResponse]:
"""The H5P API resource. It gives users access to interactive exercise layouts.""" """ The GET method for the H5P REST API. It provides JSON templates for client-side H5P exercise layouts. """
language: Language
def __init__(self): try:
"""Initialize possible arguments for calls to the H5P REST API.""" language = Language(lang)
self.reqparse: RequestParser = NetworkService.base_request_parser.copy() except ValueError:
self.reqparse.add_argument("eid", type=str, required=True, default="", help="No exercise ID provided") language = Language.English
self.reqparse.add_argument("lang", type=str, required=True, default="en", help="No language code provided") exercise: Exercise = db.session.query(Exercise).filter_by(eid=eid).first()
self.reqparse.add_argument("solution_indices", type=str, required=False, help="No solution IDs provided") db.session.commit()
self.feedback_template: str = "{0}: @score {1} @total." if exercise is None:
self.json_template_drag_text: dict = { return connexion.problem(404, Config.ERROR_TITLE_NOT_FOUND, Config.ERROR_MESSAGE_EXERCISE_NOT_FOUND)
"taskDescription": "<p>{0}</p>\n", text_field_content: str = ""
"checkAnswer": "Prüfen", if exercise.exercise_type in [ExerciseType.cloze.value, ExerciseType.markWords.value]:
"tryAgain": "Nochmal", text_field_content = TextService.get_h5p_text_with_solutions(exercise, solution_indices)
"showSolution": "Lösung", elif exercise.exercise_type == ExerciseType.matching.value:
"behaviour": { solutions: List[Solution] = TextService.get_solutions_by_index(exercise, solution_indices)
"enableRetry": True, for solution in solutions:
"enableSolutionsButton": True, text_field_content += "{0} *{1}*\n".format(solution.target.content, solution.value.content)
"instantFeedback": False, else:
"enableCheckButton": True return connexion.problem(
}, 422, Config.ERROR_TITLE_UNPROCESSABLE_ENTITY, Config.ERROR_MESSAGE_UNPROCESSABLE_ENTITY)
"textField": "Blueberries are *blue:Check the name of the berry!*.\nStrawberries are *red*.", response_dict: dict = TextService.json_template_mark_words
"overallFeedback": [{"from": 0, "to": 100, "feedback": "Punkte: @score von @total."}], response_dict = get_response(response_dict, language, TextService.json_template_drag_text, exercise,
"dropZoneIndex": "Drop Zone @index.", text_field_content, TextService.feedback_template)
"empty": "Drop Zone @index is empty.", return NetworkService.make_json_response(response_dict)
"contains": "Drop Zone @index contains draggable @draggable.",
"draggableIndex": "Draggable @text. @index of @count draggables.",
"tipLabel": "Show tip",
"correctText": "Correct!",
"incorrectText": "Incorrect!",
"resetDropTitle": "Reset drop",
"resetDropDescription": "Are you sure you want to reset this drop zone?",
"grabbed": "Draggable is grabbed.",
"cancelledDragging": "Cancelled dragging.",
"correctAnswer": "Correct answer:",
"feedbackHeader": "Feedback",
"scoreBarLabel": "You got :num out of :total points"
}
self.json_template_mark_words: dict = {
"checkAnswerButton": "Check",
"tryAgainButton": "Retry",
"showSolutionButton": "Show solution",
"behaviour": {
"enableRetry": True,
"enableSolutionsButton": True
},
"taskDescription": "<p>Click the various types of berries&nbsp;mentioned&nbsp;in the text below!<\/p>\n",
"textField": "*Bilberries*, also known as *blueberries* are edible, nearly black berries found in nutrient-poor soils.<br><br>*Cloudberries* are edible orange berries similar to *raspberries* or *blackberries* found in alpine and arctic tundra. <br><br>*Redcurrants* are red translucent berries with a diameter of 8\u201310 mm, and are closely related to *blackcurrants*.",
"overallFeedback": [{"from": 0, "to": 100, "feedback": "You got @score of @total points."}]
}
super(H5pAPI, self).__init__()
def get(self):
""" The GET method for the H5P REST API. It provides json templates for client-side H5P exercise layouts. """
args = self.reqparse.parse_args()
eid: str = args["eid"]
solution_indices: List[int] = json.loads(args["solution_indices"] if args["solution_indices"] else "null")
lang: Language
try:
lang = Language(args["lang"])
except ValueError:
lang = Language.English
exercise: Exercise = db.session.query(Exercise).filter_by(eid=eid).first()
db.session.commit()
if exercise is None:
abort(404)
text_field_content: str = ""
if exercise.exercise_type in [ExerciseType.cloze.value, ExerciseType.markWords.value]:
text_field_content = TextService.get_h5p_text_with_solutions(exercise, solution_indices)
elif exercise.exercise_type == ExerciseType.matching.value:
solutions: List[Solution] = TextService.get_solutions_by_index(exercise, solution_indices)
for solution in solutions:
text_field_content += "{0} *{1}*\n".format(solution.target.content, solution.value.content)
else:
abort(422)
response_dict: dict = self.json_template_mark_words
response_dict = get_response(response_dict, lang, self.json_template_drag_text, exercise, text_field_content,
self.feedback_template)
return NetworkService.make_json_response(response_dict)
def get_response(response_dict: dict, lang: Language, json_template_drag_text: dict, exercise: Exercise, def get_response(response_dict: dict, lang: Language, json_template_drag_text: dict, exercise: Exercise,
text_field_content: str, feedback_template: str): text_field_content: str, feedback_template: str) -> dict:
# default values for buttons and response # default values for buttons and response
button_dict: dict = {"check": ["checkAnswerButton", "Prüfen" if lang == Language.German else "Check"], button_dict: dict = {"check": ["checkAnswerButton", "Prüfen" if lang == Language.German else "Check"],
"again": ["tryAgainButton", "Nochmal" if lang == Language.German else "Retry"], "again": ["tryAgainButton", "Nochmal" if lang == Language.German else "Retry"],
......
...@@ -10,46 +10,29 @@ from typing import List, Dict ...@@ -10,46 +10,29 @@ from typing import List, Dict
import requests import requests
from bs4 import BeautifulSoup, ResultSet, Tag from bs4 import BeautifulSoup, ResultSet, Tag
from conllu import TokenList from conllu import TokenList
from flask_restful import Resource from flask import Response
from flask_restful.reqparse import RequestParser
from mcserver.app.models import ExerciseType, ExerciseData, LinkMC, NodeMC from mcserver.app.models import ExerciseType, ExerciseData, LinkMC, NodeMC
from mcserver.app.services import AnnotationService, NetworkService from mcserver.app.services import AnnotationService, NetworkService
from mcserver.config import Config from mcserver.config import Config
from openapi.openapi_server.models import KwicForm
class KwicAPI(Resource): def post(kwic_data: dict) -> Response:
"""The KWIC API resource. It gives users example contexts for a given phenomenon in a given corpus.""" """ The POST method for the KWIC REST API. It provides example contexts for a given phenomenon
in a given corpus. """
def __init__(self): kwic_form: KwicForm = KwicForm.from_dict(kwic_data)
"""Initializes possible arguments for calls to the KWIC REST API.""" search_values_list: List[str] = json.loads(kwic_form.search_values)
self.reqparse: RequestParser = NetworkService.base_request_parser.copy() aqls: List[str] = AnnotationService.map_search_values_to_aql(search_values_list, ExerciseType.kwic)
self.reqparse.add_argument("urn", type=str, required=True, default="", location="form", help="No URN provided") url: str = f"{Config.INTERNET_PROTOCOL}{Config.HOST_IP_CSM}:{Config.CORPUS_STORAGE_MANAGER_PORT}{Config.SERVER_URI_CSM_SUBGRAPH}"
self.reqparse.add_argument("search_values", type=str, required=True, location="form", data: str = json.dumps(
help="No search value(s) provided") dict(urn=kwic_data["urn"], aqls=aqls, ctx_left=str(kwic_form.ctx_left), ctx_right=str(kwic_form.ctx_right)))
self.reqparse.add_argument("ctx_left", type=int, required=False, location="form", default=5, response: requests.Response = requests.post(url, data=data)
help="No left context size provided") response_content: List[dict] = json.loads(response.text)
self.reqparse.add_argument("ctx_right", type=int, required=False, location="form", default=5, exercise_data_list: List[ExerciseData] = [ExerciseData(json_dict=x) for x in response_content]
help="No left context size provided") ret_val: str = ""
super(KwicAPI, self).__init__() for i in range(len(exercise_data_list)):
ret_val += handle_exercise_data(exercise_data_list[i], kwic_form.ctx_left, kwic_form.ctx_right)
def post(self) -> object: return NetworkService.make_json_response(ret_val)
""" The POST method for the KWIC REST API. It provides example contexts for a given phenomenon
in a given corpus. """
args = self.reqparse.parse_args()
search_values_list: List[str] = json.loads(args["search_values"])
aqls: List[str] = AnnotationService.map_search_values_to_aql(search_values_list, ExerciseType.kwic)
ctx_left: int = args["ctx_left"]
ctx_right: int = args["ctx_right"]
url: str = f"{Config.INTERNET_PROTOCOL}{Config.HOST_IP_CSM}:{Config.CORPUS_STORAGE_MANAGER_PORT}{Config.SERVER_URI_CSM_SUBGRAPH}"
data: str = json.dumps(dict(urn=args["urn"], aqls=aqls, ctx_left=str(ctx_left), ctx_right=str(ctx_right)))
response: requests.Response = requests.post(url, data=data)
response_content: List[dict] = json.loads(response.text)
exercise_data_list: List[ExerciseData] = [ExerciseData(json_dict=x) for x in response_content]
ret_val: str = ""
for i in range(len(exercise_data_list)):
ret_val += handle_exercise_data(exercise_data_list[i], ctx_left, ctx_right)
return NetworkService.make_json_response(ret_val)
def handle_exercise_data(ed: ExerciseData, ctx_left: int, ctx_right: int) -> str: def handle_exercise_data(ed: ExerciseData, ctx_left: int, ctx_right: int) -> str:
......
from flask_restful import Resource, abort from typing import Union
from flask_restful.reqparse import RequestParser
from mcserver.app.models import AnnisResponse, TextComplexityMeasure, GraphData
from mcserver.app.services import CorpusService, NetworkService, TextComplexityService
import connexion
from connexion.lifecycle import ConnexionResponse
from flask import Response
class RawTextAPI(Resource): from mcserver import Config
"""The fill the blank API resource. It creates a fill the blank exercise for a given text.""" from mcserver.app.models import AnnisResponse, TextComplexityMeasure
from mcserver.app.services import CorpusService, NetworkService, TextComplexityService
def __init__(self):
"""Initialize possible arguments for calls to the fill the blank REST API."""
self.reqparse: RequestParser = NetworkService.base_request_parser.copy()
self.reqparse.add_argument("urn", type=str, required=True, default="", help="No URN provided")
super(RawTextAPI, self).__init__()
def get(self): def get(urn: str) -> Union[Response, ConnexionResponse]:
args = self.reqparse.parse_args() """Provides the raw text for a requested text passage."""
urn: str = args["urn"] ar: AnnisResponse = CorpusService.get_corpus(cts_urn=urn, is_csm=False)
ar: AnnisResponse = CorpusService.get_corpus(cts_urn=urn, is_csm=False) if not ar.graph_data.nodes:
if not ar.graph_data.nodes: return connexion.problem(404, Config.ERROR_TITLE_NOT_FOUND, Config.ERROR_MESSAGE_CORPUS_NOT_FOUND)
abort(404) ar.text_complexity = TextComplexityService.text_complexity(TextComplexityMeasure.all.name, urn, False,
ar.text_complexity = TextComplexityService.text_complexity(TextComplexityMeasure.all.name, urn, False, ar.graph_data).to_dict()
ar.graph_data).to_dict() return NetworkService.make_json_response(ar.to_dict())
return NetworkService.make_json_response(ar.to_dict())
from flask_restful import Resource from mcserver.app.models import AnnisResponse, TextComplexity
from flask_restful.reqparse import RequestParser
from mcserver.app.models import AnnisResponse, GraphData, TextComplexity
from mcserver.app.services import NetworkService, CorpusService, TextComplexityService from mcserver.app.services import NetworkService, CorpusService, TextComplexityService
class TextComplexityAPI(Resource): def get(measure: str, urn: str):
"""The Text Complexity API resource. It gives users measures for text complexity for a given text.""" """Gives users measures of text complexity for a given text."""
ar: AnnisResponse = CorpusService.get_corpus(urn, is_csm=False)
def __init__(self): tc: TextComplexity = TextComplexityService.text_complexity(measure, urn, False, ar.graph_data)
self.reqparse: RequestParser = NetworkService.base_request_parser.copy() return NetworkService.make_json_response(tc.to_dict())
self.reqparse.add_argument('urn', type=str, required=True, help='No URN provided')
self.reqparse.add_argument('measure', type=str, required=True, help='No MEASURE provided')
super(TextComplexityAPI, self).__init__()
def get(self):
args: dict = self.reqparse.parse_args()
urn: str = args["urn"]
measure: str = args["measure"]
ar: AnnisResponse = CorpusService.get_corpus(urn, is_csm=False)
tc: TextComplexity = TextComplexityService.text_complexity(measure, urn, False, ar.graph_data)
return NetworkService.make_json_response(tc.to_dict())
from typing import List from typing import List, Union
from flask_restful import Resource, abort import connexion
from flask_restful.reqparse import RequestParser from connexion.lifecycle import ConnexionResponse
from flask import Response
from mcserver import Config
from mcserver.app.services import CorpusService, NetworkService, CustomCorpusService from mcserver.app.services import CorpusService, NetworkService, CustomCorpusService
class ValidReffAPI(Resource): def get(urn: str) -> Union[Response, ConnexionResponse]:
"""The valid references API resource. It gives users all the citable text references for a corpus.""" """The GET method for the valid references REST API. It provides references for the desired text."""
reff: List[str] = CustomCorpusService.get_custom_corpus_reff(urn) if CustomCorpusService.is_custom_corpus_urn(
def __init__(self): urn) else CorpusService.get_standard_corpus_reff(urn)
"""Initialize possible arguments for calls to the valid references REST API.""" if not reff:
self.reqparse: RequestParser = NetworkService.base_request_parser.copy() return connexion.problem(404, Config.ERROR_TITLE_NOT_FOUND, Config.ERROR_MESSAGE_CORPUS_NOT_FOUND)
self.reqparse.add_argument("urn", type=str, required=True, default="", help="No URN provided") return NetworkService.make_json_response(reff)
super(ValidReffAPI, self).__init__()
def get(self):
"""The GET method for the valid references REST API. It provides references for the desired text."""
args = self.reqparse.parse_args()
urn: str = args["urn"]
reff: List[str] = CustomCorpusService.get_custom_corpus_reff(urn) if CustomCorpusService.is_custom_corpus_urn(
urn) else CorpusService.get_standard_corpus_reff(urn)
if not reff:
abort(404)
return NetworkService.make_json_response(reff)
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
import os import os
import re import re
from typing import List, Dict, Set, Tuple, Pattern from typing import List, Dict, Set, Tuple, Pattern
from flask_restful import Resource
from flask_restful.reqparse import RequestParser from flask import Response
from gensim import matutils from gensim import matutils
from gensim.models import Word2Vec from gensim.models import Word2Vec
from matplotlib import pyplot from matplotlib import pyplot
...@@ -12,63 +12,7 @@ from numpy.core.multiarray import ndarray, dot ...@@ -12,63 +12,7 @@ from numpy.core.multiarray import ndarray, dot
from mcserver import Config from mcserver import Config
from mcserver.app.services import NetworkService from mcserver.app.services import NetworkService
from openapi.openapi_server.models import VectorNetworkForm
class VectorNetworkAPI(Resource):
"""The vector network API resource. It helps to manage network data for the vectors in an AI model."""